【微服务】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() };
    }

相关推荐
五行星辰1 分钟前
Spring定时任务修仙指南:从@Scheduled到分布式调度的终极奥义
java·后端·spring
东方窅瞳9 分钟前
Bash语言的哈希表
开发语言·后端·golang
HarrisHaword35 分钟前
JAVA 导出 word
java·开发语言·word
PingdiGuo_guo40 分钟前
C++指针(四)万字图文详解!
开发语言·c++
s91236010141 分钟前
Rust Command无法执行*拓展解决办法
开发语言·后端·rust
pk_xz1234561 小时前
MATLAB编写的机械臂控制仿真程序,它主要实现了对一个二连杆机械臂的运动控制仿真,比较了PID控制和非线性模型预测控制两种方法在机械臂轨迹跟踪任务中的性能
开发语言·matlab
2301_787552871 小时前
aidigu开源微博项目程序,PHP开发的开源微博系统,自媒体个人创业、网盘推广首先
开发语言·开源·php·数据库开发·媒体
khazix1011 小时前
【C语言】--- 文件操作
c语言·开发语言
考虑考虑1 小时前
使用Jpa自带的级联注解造成死循环问题
java·后端·java ee
ctrlworks1 小时前
楼宇自控系统凭何成为建筑稳定、高效、安全运行的关键
安全·楼宇自控系统厂商·ba系统厂商·康沃思物联·建筑设备管理系统