SOP、CORS 和 CSRF、XSS

原文地址:https://alphahinex.github.io/2021/05/23/sop-cors-csrf-xss/

cover

description: "请说出它们的含义"
date: 2021.05.23 10:26
categories:
- Web
tags: [Web, HTML]
keywords: origin, site, same origin, cross-origin, same site, corss site, SOP, CORS, CSRF, XSS


Origin 和 Site 中,我们介绍了 的概念,这两个概念在浏览器的安全策略中有着广泛的应用,接下来再介绍几个与之相关的概念。

SOP

Same Origin Policy(SOP),同源策略,是浏览器的一个重要安全机制,用来限制从某一 Origin(源)加载的文档或脚本,如何与其他源中的资源进行交互。它能帮助隔离潜在的恶意文档,减少被攻击的可能。

跨源网络访问

跨源网络访问,通常分为三类:

  1. 跨源写操作(Cross-origin writes):通常是被允许的,例如链接、重定向,以及表单提交。这类操作又分为 简单请求(simple request)预检请求(preflighted request) 两类,需预检的请求,要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。
  2. 跨源资源嵌入(Cross-origin embedding):一般是被允许的。
  3. 跨源读操作(Cross-origin reads):一般是不被允许的,但常可以通过内嵌资源来巧妙的进行读取访问。例如,可以读取嵌入图片的高度和宽度,调用内嵌脚本的方法,或像 Abusing HTTP Status Codes to Expose Private Information 中描述的方式,通过嵌入资源的请求的响应状态获得一些信息。

源的继承

在页面中通过 about:blankjavascript: URL 执行的脚本会继承打开该 URL 的文档的源,因为这些类型的 URLs 没有包含源服务器的相关信息。

CORS

Cross-Origin Resource Sharing(CORS),跨源资源共享 或 跨域资源共享,是一种基于 HTTP Header 的机制,用来使服务端指定哪些其他的源可以从这个服务端加载资源。对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨源请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。

CORS 请求失败会产生错误,但是为了安全,在 JavaScript 代码层面是无法获知到底具体是哪里出了问题。你只能查看浏览器的控制台以得知具体是哪里出现了错误。

CORS

HTTP response headers

CORS 响应头字段包括:

  • Access-Control-Allow-Origin:指定允许访问该资源的外源 URL,或设定为 * 以允许来自所有域的请求
  • Access-Control-Expose-Headers:设定除基本的响应头之外,允许浏览器访问的其他响应头
  • Access-Control-Max-Age:指定 preflight 请求的结果能被缓存多久
  • Access-Control-Allow-Credentials:预检请求的响应通过此 header 控制实际请求发送的时候是否会携带凭证
  • Access-Control-Allow-Methods:用于预检请求的响应,指明了实际请求所允许使用的 HTTP 方法
  • Access-Control-Allow-Headers:用于预检请求的响应,指明了实际请求中允许携带的 header 字段

HTTP request headers

  • Origin:表明预检请求或实际请求的源站
  • Access-Control-Request-Method:用于预检请求,其作用是,将实际请求所使用的 HTTP 方法告诉服务器
  • Access-Control-Request-Headers:用于预检请求,将实际请求所携带的 header 字段告诉服务器

简单请求(simple request)

若请求满足所有下述条件,则该请求可视为“简单请求”,不会触发“预检请求”:

  • 使用下列方法之一:
  1. GET
  2. HEAD
  3. POST
  1. Accept
  2. Accept-Language
  3. Content-Language
  4. Content-Type (需要注意下面的限制)
  • Content-Type 的值仅限于下列三者之一:
  1. application/x-www-form-urlencoded
  2. multipart/form-data
  3. text/plain
  • 如果请求中使用了 XMLHttpRequest 对象,则需要没有在 XMLHttpRequest.upload 属性返回的对象上注册任何事件监听器,比如给定一个 XMLHttpRequest 实例 xhr,没有对 xhr 实例调用过 xhr.upload.addEventListener() 来监听上传操作
  • 请求中没有使用 ReadableStream 对象
simple request

预检请求(preflight request)

不满足“简单请求”条件的请求,都需要先发送一个 HTTP method 为 OPTIONS 的预检请求(preflight request)给外源站点,并根据响应头中的设定,判断是否可以发送实际请求。

preflight request

凭证请求(requests with credentials)

XMLHttpRequest 或 Fetch 与 CORS 的一个有趣的特性是,可以基于 HTTP cookies 和 HTTP 认证信息发送身份凭证。一般而言,对于跨源 XMLHttpRequest 或 Fetch 请求,浏览器不会发送身份凭证信息。如果要发送凭证信息,需要设置 XMLHttpRequest 的某个特殊标志位,或在构造 Request 对象时指明。

即使是不需要发送预检请求的简单请求,也可以在跨源请求中携带凭证,但如果响应头中没有 Access-Control-Allow-Credentials: true,浏览器不会把响应内容返回给请求的发送者。

with credential

CSRF

Cross Site Request Forgery(CSRF),跨站请求伪造,是指利用用户已经在某网站登录的凭证,在用户不知情的情况下,伪造用户操作此网站的请求。用户在此网站的权限越大,对此网站造成的危害越大。

如何阻止跨站访问

大部分框架都提供了内置的 CSRF 支持,如 Joomla,Spring,Struts,Ruby on Rails,.NET 等。

通常的做法是设定一个 CSRF token,一个由服务端生成的随机值,请求需携带这个 token,并由服务端验证请求的合法性。

阻止跨站写操作,可以通过 CSRF token 进行校验。

阻止跨站读操作,需确保该资源是不可嵌入的。阻止跨站嵌入,需确保资源不能通过 可嵌入资源格式 使用。浏览器可能不会遵守 Content-Type 头部定义的类型,例如在 HTML 文档外面套上 <script> 标签,浏览器会尝试按照 JavaScript 来解析其中的 HTML 内容。当资源不是网站入口时,也可以考虑使用 CSRF token 来防止嵌入。

更多阻止方案,可参考 Cross-Site Request Forgery Prevention Cheat Sheet

XSS

Cross Site Scripting(XSS),跨站脚本攻击,缩写不使用 CSS 是为了避免与 层叠样式表 混淆。

跨站脚本攻击通常是指对用户通过表单等方式写入的数据未进行合法性校验,导致可能将恶意脚本注入到网站中,并对其他用户造成危害。

通常采取的防范措施是由前端对用户输入内容进行转义等,避免用户上传的恶意脚本能够被直接执行。目前大部分主流的前端框架,也对 XSS 进行了基本的防御。

更多阻止 XSS 的方案,可参考 Cross Site Scripting Prevention Cheat Sheet

参考资料

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容

  • SOP(同源策略 Same Origin Policy) 同源策略是web应用安全模型,是浏览器为了安全作出的限制...
    工藤新十一阅读 892评论 0 0
  • CSRF & CORS 下面转的两篇文章分别说明了以下两个概念和一些解决方法: 1. CSRF - Cross-S...
    Elvis_zhou阅读 712评论 0 4
  • 一、名称解释 CSRF跨站请求伪造(英语:Cross-site request forgery),也被称为 one...
    程序员小白成长记阅读 273评论 0 0
  • 在开发应用的时候,一般都要考虑应用的安全性,大公司一般还会使用各种扫描代码强制要求修改一些不安全的代码,对于和前端...
    Real_man阅读 2,024评论 0 0
  • 客户端(浏览器)安全 同源策略(Same Origin Policy) 同源策略阻止从一个源加载的文档或脚本获取或...
    人在码途阅读 1,767评论 0 8