.Net Core 微服务实战 - 安全

源码及系列文章目录

Git 源码https://github.com/tangsong1995/TS.Microservices
CSDN 资源https://download.csdn.net/download/qq_33649351/34675095

系列文章目录https://blog.csdn.net/qq_33649351/article/details/120998558

防跨站请求伪造

攻击过程

Browser GoodSite BadSite login set cookie 访问 伪造请求脚本 BadSite 伪造的请求 响应 Browser GoodSite BadSite

要素:

  • 用户已登录“GoodSite”
  • “GoodSite”通过 Cookie 存储和传递身份信息
  • 用户访问了“BadSite”

防御

  • 不使用 Cookie 来存储和传输身份信息,使用 JWT 或其他方式进行身份认证
  • 若使用了 Cookie ,使用 AntiforgeryToken 来防御
  • 避免使用 GET 作为业务操作的请求方法

AntiforgeryToken

Startup 中配置:

public void ConfigureServices(IServiceCollection services)
{
	...
    services.AddAntiforgery(options =>
    {
        options.HeaderName = "X-CSRF-TOKEN";
    });

    //开启全局AntiforgeryToken验证
    services.AddMvc(options => options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()));
	...
}

客户端需要在请求头加上 X-CSRF-TOKEN 传入 Cookie 的值,服务器会验证 header 的值与 Cookie 的值是否一致,如果不一致,会认为是非法请求。
若不想使用过滤器开启全局 AntiforgeryToken 验证,可以使用 [ValidateAntiForgeryToken] 和 [AutoValidateAntiforgeryToken] 标签对对接口开启 AntiforgeryToken 验证, [AutoValidateAntiforgeryToken] 对 get 请求不生效。

防开放重定向攻击

攻击过程

Attacker Browser GoodSite BadSite 恶意信息 访问带恶意重定向地址的登录页 响应登录页面 输入用户名密码 重定向至坏站点的响应 访问坏站点伪造登录页 响应伪造登录页 输入用户名密码 通知攻击者 重定向到好站点的响应 访问好站点 响应好站点 Attacker Browser GoodSite BadSite

要素:

  • “好站点”的重定向未验证目标 URL
  • 用户访问了“坏站点”

防御

  • 使用 LocalRedirect 来处理重定向
  • 验证重定向的目标域名是否合法
[HttpPost]
public async Task<IActionResult> Login(string returnUrl)
{
	// TODO : Login
    if (string.IsNullOrEmpty(returnUrl))
    {
        return Content("登录成功");
    }
    try
    {
        var uri = new Uri(returnUrl);
        //TODO : 验证 uri 是否有效
        return Redirect(returnUrl);
    }
    catch
    {
        return Redirect("/");
    }
}

防跨站脚本

攻击过程

Attacker GoodSite Browser BadSite 提交带有恶意脚本的内容 提交成功 访问带恶意脚本的内容页 响应带恶意脚本的页面 POST/GET提交好站点的身份信息 通知攻击者 任意响应 Attacker GoodSite Browser BadSite

防御

  • 对用户提交内容进行验证,拒绝恶意脚本
  • 对用户提交的内容进行编码 UrlEncoder、JavaScriptEncoder、UrlEncoder
  • 慎用 HtmlString 和 HtmlHelper.Raw
  • 身份信息 Cookie 设置为 HttpOnly
  • 避免使用 Path 传递带有不受信的字符,使用 Query 进行传递
public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
        {
            options.LoginPath = "/home/login";
            //options.Cookie.HttpOnly = true; //默认true
        });
	...
}

跨域请求

CORS

  • CORS 是浏览器允许跨域发起请求“君子协定”
  • 它是浏览器行为协议
  • 它并不会让服务器拒绝其它途径发起的 HTTP 请求
  • 开启时需要考虑是否存在被恶意网站攻击的情形

CORS 请求头

  • Origin 请求源
  • Access-Control-Request-Method 期望请求发起的请求方法
  • Access-Control-Request-Headers 期望请求发起的请求头

CORS 响应头

  • Access-Control-Allow-Origin 是否允许跨域
  • Access-Control-Allow-Credentials 是否允许携带身份认证信息
  • Access-Control-Expose-Headers 是否允许脚本访问响应头
  • Access-Control-Max-Age 有效时间
  • Access-Control-Allow-Methods 允许的请求方法
  • Access-Control-Allow-Headers 允许的请求头
默认支持的 Expose Headers
  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

CORS 过程

Browser a.com b.com 访问域名a.com 响应 发起对efg.com的跨域预检请求 允许访问 发起对efg.com的跨域请求 正常响应 Browser a.com b.com

启用 CORS

配置 CORS:

public void ConfigureServices(IServiceCollection services)
{
    ...
	services.AddCors(options =>
	{
	    options.AddPolicy("api", builder =>
	     {
	         builder.WithOrigins("https://localhost:5001").AllowAnyHeader().AllowCredentials().WithExposedHeaders("abc");
	
	         builder.SetIsOriginAllowed(orgin => true).AllowCredentials().AllowAnyHeader();
	     });
	});
	...
}

以上代码的意义为:

  • WithOrigins允许跨域的源是 “https://localhost:5001” ,
  • AllowAnyHeader 允许携带Header
  • AllowCredentials 允许携带身份认证信息
  • WithExposedHeaders 允许访问的响应头
  • SetIsOriginAllowed 批量设置

启用 CORS:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
	...
    app.UseCors();
	...
}

在 api 上使用 [EnableCors(“api”)] 标签允许 CORS 。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值