【微服务】06-安全问题

文章目录

    • 1.反跨站请求伪造
      • [1.1 攻击过程](#1.1 攻击过程)
      • [1.2 攻击核心](#1.2 攻击核心)
      • [1.3 如何防御](#1.3 如何防御)
      • [1.4 使用AntiforgeryToken机制来防御用到的类](#1.4 使用AntiforgeryToken机制来防御用到的类)
    • [2. 防开发重定向共计](#2. 防开发重定向共计)
      • [2.1 攻击过程](#2.1 攻击过程)
      • [2.2 攻击核心](#2.2 攻击核心)
      • [2.3 防范措施](#2.3 防范措施)
    • 3.防跨站脚本
      • [3.1 攻击过程](#3.1 攻击过程)
      • [3.2 防范措施](#3.2 防范措施)
    • 4.跨域请求
      • [4.1 同源与跨域](#4.1 同源与跨域)
      • [4.2 CORS过程](#4.2 CORS过程)
      • [4.2 CORS是什么](#4.2 CORS是什么)
      • [4.3 CORS请求头](#4.3 CORS请求头)
      • [4.4 CORS响应头](#4.4 CORS响应头)
      • [4.5 默认支持的Expose Headers](#4.5 默认支持的Expose Headers)

1.反跨站请求伪造

1.1 攻击过程

1.2 攻击核心

  • 用户已经登录"好站点"
  • "好站点"通过Cookie存储和传递身份信息
  • 用户访问了"坏站点"

1.3 如何防御

  • 不使用Cookie来存储和传输身份信息,使用JWT认证
  • 使用AntiforgeryToken机制来防御
  • 避免使用Get作为业务操作的请求方法

浏览器每次请求都会携带Cookie,这是我们控制不了的,而Jwt的Token则需要在同域下的脚本才能发起,需要在同域下运行脚本从token的存储里面去获取的,比如localstorage这样的存储

1.4 使用AntiforgeryToken机制来防御用到的类

  • ValidateAntiForgeryToken

  • AutoValidateAntiforgeryToken

    // startup
    public void ConfigureServices(IServiceCollection services)
    {
    // 防止跨站请求伪造的策略配置
    services.AddAntiforgery(options =>
    {
    options.HeaderName = "X-CSRF-TOKEN";//
    });
    }

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

如果不希望全局开启AntiForgeryToken验证,可以在API上通过特性设置

[Authorize]
[ValidateAntiForgeryToken]//这里进行AntiForgeryToken验证
public IActionResult CreateOrder(string itemId, int count)
{
    ...
}

2. 防开发重定向共计

2.1 攻击过程

2.2 攻击核心

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

2.3 防范措施

  • 使用LocalRedirect来处理重定向
  • 验证重定向的目标域名是否合法

LocalRedirect处理的重定向仅限于本站,也就是它的重定向不能跨站,所以不会重定向到坏站点

[HttpPost]
        public async Task<IActionResult> Login([FromServices]IAntiforgery antiforgery, string name, string password, string returnUrl)
        {
            HttpContext.Response.Cookies.Append("CSRF-TOKEN", antiforgery.GetTokens(HttpContext).RequestToken, new Microsoft.AspNetCore.Http.CookieOptions { HttpOnly = false });
            var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);//一定要声明AuthenticationScheme
            identity.AddClaim(new Claim("Name", "小王"));
            await this.HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity));
            if (string.IsNullOrEmpty(returnUrl))
            {
                return Content("登录成功");
            }
            try
            {
            	// 使用LocalRedirect处理,如果出现异常,重定向到首页,避免站点跳转到外部站点
            	// 如果我们需要跳转到其它站点时,我们需要验证returnUrl合法性,然后使用Redirect进行跳转
                return LocalRedirect(returnUrl);
            }
            catch
            {
                return Redirect("/");
            }
            //return Redirect(returnUrl);
        }

3.防跨站脚本

3.1 攻击过程

3.2 防范措施

  • 对用户提交内容进行验证,拒绝恶意脚本

  • 对用户提交的内容进行编码UrlEncoder,JavaScriptEncoder

  • 慎用HtmlString和HemlHelper.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;
    });
    }

4.跨域请求

4.1 同源与跨域

  • 方案相同(HTTP/HTTPS)
  • 主机(域名)相同
  • 端口相同

如果方案、主机(域名)、端口这个三个都相同则认为两个域名是同源的,如果三者中有任意一个不同,则认为请求是跨域的

4.2 CORS过程

浏览器发起了一个请求,访问了abc.com的网站,网站给予返回响应,那么浏览器当前就处于abc.com这个主域名下。这时如果向efg.com网站发起一个http ajax请求,这时则认为这是一个跨域请求。

浏览器在发起跨域请求前会向efg.com发起一个基于HTTP option的预检请求,efg.com收到预检请求后,会根据当前预检请求的一些信息,如主域,header,身份认证信息等,去判断是否允许跨域请求;如果efg.com允许发起跨域请求,浏览器会正式地向efg.com发起我们要求的跨域请求,这时efg.com会响应正常的页面Api信息

4.2 CORS是什么

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

CORS影响的是浏览器是否允许在其它域下面通过脚本来发起跨域的请求

4.3 CORS请求头

  • Origin请求源 ⇒ 指的是当前主域的地址
  • Access-Control-Request-Method ⇒ 希望的请求方法
  • Access-Control-Request-Headers ⇒ 希望请求发起的请求头

4.4 CORS响应头

  • Access-Control-Allow-Origin ⇒ 是否允许跨域
  • Access-Control-Allow-Credentials ⇒ 是否允许携带认证信息,如cookie 信息
  • Access-Control-Expose-Headers ⇒ 是否允许跨域请求的脚本访问到响应头,默认情况会暴露一些默认的头部信息
  • Access-Control-Max-Age ⇒ 跨域响策略时间
  • Access-Control-Allow-Methods ⇒ 允许的Http方法
  • Access-Control-Allow-Headers ⇒ 允许的header

4.5 默认支持的Expose Headers

  • Cache-Control

  • Content-Language

  • Content-Type

  • Expires

  • Last-Modified

  • Pragma

    // startup
    public void ConfigureServices(IServiceCollection services)
    {
    services.AddCors(options =>
    {
    options.AddPolicy("api", builder =>
    {
    // WithOrigins允许跨域的源
    //AllowAnyHeader 允许发起任何header
    // AllowCredentials 允许身份认证,发起的请求会自动携带域下面的cookie信息
    // WithExposedHeaders 设置脚本允许访问的响应header列表
    builder.WithOrigins("https://localhost:5001").AllowAnyHeader().AllowCredentials().WithExposedHeaders("abc");

      		// 允许跨域的源设置为任意,
      	   builder.SetIsOriginAllowed(orgin => true).AllowCredentials().AllowAnyHeader();
            });
       });
    

    }

    // 设置中间件
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    ...
    app.UseCors();// 注册尽量靠前,放在routing之后
    }

    // 使用
    [Authorize]
    [HttpPost]
    [EnableCors("api")]// 也可以设置在Controller上
    //[DisableCors] //不允许跨域
    public object PostCors(string name)
    {
    return new { name = name + DateTime.Now.ToString() };
    }

相关推荐
韩楚风9 分钟前
【linux 多进程并发】linux进程状态与生命周期各阶段转换,进程状态查看分析,助力高性能优化
linux·服务器·性能优化·架构·gnu
网络研究院22 分钟前
Android 安卓内存安全漏洞数量大幅下降的原因
android·安全·编程·安卓·内存·漏洞·技术
杨哥带你写代码28 分钟前
足球青训俱乐部管理:Spring Boot技术驱动
java·spring boot·后端
XKSYA(小巢校长)1 小时前
NatGo我的世界联机篇
开发语言·php
Cons.W1 小时前
Codeforces Round 975 (Div. 1) C. Tree Pruning
c语言·开发语言·剪枝
憧憬成为原神糕手1 小时前
c++_ 多态
开发语言·c++
VBA63371 小时前
VBA信息获取与处理第三个专题第三节:工作薄在空闲后自动关闭
开发语言
A尘埃1 小时前
SpringBoot的数据访问
java·spring boot·后端
yang-23071 小时前
端口冲突的解决方案以及SpringBoot自动检测可用端口demo
java·spring boot·后端
Marst Code1 小时前
(Django)初步使用
后端·python·django