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

相关推荐
new coder21 小时前
[c++语法学习]Day10:c++引用
开发语言·c++·学习
驰羽21 小时前
[GO]GORM 常用 Tag 速查手册
开发语言·后端·golang
Narcissiffo21 小时前
【C语言】str系列函数
c语言·开发语言
workflower21 小时前
软件工程与计算机科学的关系
开发语言·软件工程·团队开发·需求分析·个人开发·结对编程
失散1321 小时前
分布式专题——43 ElasticSearch概述
java·分布式·elasticsearch·架构
ajsbxi21 小时前
【Java 基础】核心知识点梳理
java·开发语言·笔记
阿珊和她的猫21 小时前
深入理解与手写发布订阅模式
开发语言·前端·javascript·vue.js·ecmascript·状态模式
忧郁的橙子.21 小时前
十六、kubernetes 1.29 之 集群安全机制
安全·容器·kubernetes
懷淰メ21 小时前
python3GUI--模仿百度网盘的本地文件管理器 By:PyQt5(详细分享)
开发语言·python·pyqt·文件管理·百度云·百度网盘·ui设计
AntBlack21 小时前
虽迟但到 :盘一盘 SpringAI 现在发展得怎么样了?
后端·spring·openai