一、同源策略定义
同源策略(Same-origin policy)是一种在web应用中重要的安全策略,用于限制一个源(origin)的文档或者它加载的脚本如何与来自另一个源的资源进行交互。这里的“源”由协议、域名和端口组成,只要这三者不完全相同,就算是不同源。
二、同源策略作用
1、防止信息泄露:
- 同源策略阻止恶意网站通过跨域请求获取用户在其他站点上的敏感信息。例如,禁止一个网页中的脚本访问另一个不同域的网页中的数据,包括读取、修改或删除它们。
2、防止跨站脚本攻击(XSS):
- 同源策略可以防止恶意脚本通过跨域操作注入并执行恶意代码。如果不受同源策略的限制,攻击者可以在一个受信任的网站上注入恶意脚本,从而获取用户的敏感信息、篡改页面内容或进行其他恶意行为。
3、防止跨站请求伪造攻击(CSRF):
- 同源策略通过限制跨域请求,使得只有相同源的请求能够携带浏览器生成的身份凭证(如Cookie),从而有效地阻止了CSRF攻击。攻击者无法利用用户在某一网站的身份凭证发送伪造请求到其他站点,实施未经授权的操作。
三、限制的跨域操作
1、Ajax 请求:
- 限制:XMLHttpRequest (XHR) 对象只能访问同一域下的资源,不能访问其他域的资源。
- 原因:出于安全考虑,防止恶意网站读取其他网站的数据。
2、DOM 访问:
- 限制:JavaScript 脚本只能访问同一域下的 DOM 对象,不能访问其他域的 DOM 对象。
- 原因:防止跨站脚本(XSS)攻击,保护用户隐私和数据安全。
3、Web 存储访问:
- 限制:浏览器只允许网页访问自身网站的 Cookie、LocalStorage 和 IndexDB 等存储器,不能访问其他网站的存储器。
- 原因:确保网站存储的数据不会被其他网站恶意读取或篡改。
4、Frame 和 iframe:
- 限制:包含不同源页面的 Frame 和 iframe 也受到同源策略的限制,不能相互访问彼此的 DOM 或执行脚本。
- 原因:防止恶意网站通过 iframe 嵌入其他网站页面,并操纵这些页面。
四、允许的跨域操作
尽管浏览器对跨域操作有严格的限制,但也有一些方法可以实现跨域通信:
1、跨域资源共享(CORS):
- 允许:通过服务器设置特定的 HTTP 响应头(如 Access-Control-Allow-Origin),允许特定来源的跨域请求。
- 实现:CORS 是一种现代Web标准,允许服务器明确指定哪些源可以访问其资源。
2、JSONP(JSON with Padding):
- 允许:通过动态创建
<script>
标签来发送跨域请求,并接收 JSON 数据。 - 限制:只支持 GET 请求,不支持 POST 请求,且存在安全风险(如数据暴露在 URL 中)。
3、document.domain + iframe:
- 允许:当两个页面的主域名相同时,可以通过设置相同的
document.domain
来实现跨子域的通信。 - 限制:仅适用于主域名相同的情况。
4、window.postMessage:
- 允许:实现跨域窗口之间的安全通信。
- 实现:通过
window.postMessage()
方法发送数据,并监听message
事件来接收数据。
5、WebSocket:
- 允许:实现浏览器与服务器之间的全双工通信,同时允许跨域通讯。
- 实现:WebSocket 是一种在单个 TCP 连接上进行全双工通讯的协议,可以在客户端和服务器之间传输数据。
6、服务器代理:
- 允许:通过服务器(如 Nginx、Node.js 等)作为代理,转发跨域请求,从而绕过浏览器的同源策略限制。
- 实现:服务器接收到客户端的请求后,向目标服务器发送请求,并将响应返回给客户端。
7、script 标签
- 浏览器天然支持;
8、style 标签
- 浏览器天然支持;
9、img 标签
- 浏览器天然支持;
五、为什么script、style、img 不受同源策略限制?
script、style、img 标签不受同源策略限制的原因主要基于它们的功能和浏览器的设计决策。
1、功能需求:
- script 标签:用于引入或执行 JavaScript 代码。JavaScript 是一种广泛使用的编程语言,用于增强网页的交互性和动态功能。由于 JavaScript 代码经常需要从外部服务器加载,因此浏览器允许 script 标签不受同源策略限制,以便从其他域加载 JavaScript 文件。
- style 标签:虽然通常用于定义内部样式表,但也可以通过链接(link)到外部 CSS 文件来使用。这些外部 CSS 文件也可能位于不同的域上,因此浏览器同样允许 style(或更准确地说,是 link 标签引入的外部 CSS)不受同源策略限制。
- img 标签:用于在网页中嵌入图片。由于网页中的图片可能来自多个不同的源,为了支持丰富的媒体内容,浏览器允许 img 标签加载跨域的图片资源。
2、浏览器设计决策:
- 浏览器在设计时考虑到了网页的灵活性和实用性,因此允许某些资源(如 script、style、img)跨域加载。这些资源通常不会直接泄露敏感信息或执行恶意代码(尽管它们仍然可能受到其他安全威胁,如跨站脚本攻击 XSS),因此浏览器认为在合理范围内放宽同源策略的限制是可以接受的。
六、script、style、img 不受同源策略限制会造成什么问题?
script
、style
、img
等标签不受同源策略限制本身并不直接造成安全问题,但如果不正确使用或管理这些标签,可能会引发一系列安全问题。以下是对这些标签及其潜在安全问题的详细分析:
1、script 标签
潜在安全问题:
- 跨站脚本攻击(XSS):如果网站不正确地验证或转义用户输入,攻击者可能通过注入恶意
script
标签来执行跨站脚本攻击。这些脚本可以窃取用户的敏感信息(如 Cookie、会话令牌等),或者执行其他恶意操作。
处理方式:
- 内容安全策略(CSP):为了减轻 XSS 攻击的风险,网站可以使用内容安全策略来限制哪些外部资源可以被加载。这可以通过 HTTP 响应头中的
Content-Security-Policy
指令来实现。
2、style 标签
潜在安全问题:
- 样式注入攻击:虽然样式注入本身通常不会直接窃取敏感信息,但攻击者可以通过修改样式来影响网站的布局和外观,从而误导用户或进行钓鱼攻击。
处理方式:
- 内容安全策略:同样,网站可以通过内容安全策略来限制哪些外部样式表可以被加载。
3、img 标签
潜在安全问题:
- 图片盗链:虽然这不是一个直接的安全问题,但图片盗链会增加原网站的带宽消耗,并可能违反版权法。
处理方式:
添加防盗链处理:以nginx为例
# 这段配置表示只允许来自*.example.com或没有Referer头部的请求访问指定的图片文件 # 其他请求将返回403错误。 location ~* \.(jpg|jpeg|png|gif|swf)$ { valid_referers none blocked server_names *.example.com; if ($invalid_referer) { return 403; } }
七、内容安全策略(CSP)
内容安全策略(CSP,Content Security Policy)是一种网络安全技术,旨在减少网页遭受跨站脚本(XSS)攻击和数据注入攻击等恶意行为的风险。它通过限制网页中资源的获取和执行来增强网页的安全性。以下是关于内容安全策略的详细解释:
1、定义与原理
- 定义:CSP是一种Web安全策略,通过HTTP头部信息告诉浏览器哪些外部资源可以被加载和执行,哪些不可以。
原理:CSP的核心思想是“白名单制度”,即只允许在白名单中列出的可信来源提供的内容被执行或加载。这种限制可以应用于脚本、样式表、图片、字体等各种类型的资源。
2、功能与优势
- 防止XSS攻击:通过限制哪些脚本可以在页面上执行,CSP可以显著减少跨站脚本攻击的风险。如果检测到恶意脚本,浏览器会拒绝执行它们。
- 防止数据泄漏:CSP可以限制哪些域名可以加载和处理页面的内容,从而减少数据泄漏的风险。
- 提高网页安全性:CSP不仅可以防止攻击者注入恶意代码,还可以减少因第三方库或插件漏洞导致的安全风险。
辅助开发与维护:CSP还可以帮助开发者发现和修复潜在的安全问题,提高开发过程中的安全性。
3、实施方式
CSP在服务器端进行设置,并通过HTTP头部信息发送到浏览器,由浏览器进行执行和监控。CSP策略的配置非常灵活,可以根据实际需求进行调整。例如,可以设置只允许加载同源的脚本和样式表,或者允许加载指定域的资源。
4、CSP指令与指令值
CSP包含多个指令,用于指定不同类型的资源加载策略。以下是一些常用的CSP指令及其指令值示例:
- default-src:默认加载策略,适用于未明确指定的资源类型。指令值可以包括“self”(表示同源资源)、“none”(表示不允许任何外部资源)以及特定的域名或协议。
- script-src:对JavaScript的加载策略。可以指定哪些域名或协议下的脚本文件可以被加载。
- style-src:对样式表的加载策略。可以指定哪些域名或协议下的样式表文件可以被加载。
- img-src:对图片的加载策略。可以指定哪些域名或协议下的图片资源可以被加载。
report-uri:告诉浏览器如果请求的资源不被策略允许时,往哪个地址提交日志信息。这有助于开发者监控和处理违反CSP策略的行为。
4.1、nginx 如何配置 CSP
server { listen 80; # 或者443,如果启用了SSL server_name example.com; # 其他配置... # 启用CSP add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://trusted.example.com; style-src 'self' https://styles.example.com; img-src 'self' https://images.example.com; font-src 'self' https://fonts.example.com; object-src 'none';"; # 其他配置... }
参数说明:
default-src 'self'
: 默认情况下,只允许加载同源的资源。script-src 'self' https://trusted.example.com
: 允许加载同源的JavaScript脚本,以及来自https://trusted.example.com
的脚本。style-src 'self' https://styles.example.com
: 允许加载同源的样式表,以及来自https://styles.example.com
的样式表。img-src 'self' https://images.example.com
: 允许加载同源的图片,以及来自https://images.example.com
的图片。font-src 'self' https://fonts.example.com
: 允许加载同源的字体文件,以及来自https://fonts.example.com
的字体文件。object-src 'none'
: 禁止加载<object>
、<embed>
和<applet>
等插件的内容,因为这些元素可能会被用来加载恶意的内容。5、注意事项
- 兼容性:虽然现代浏览器都支持CSP,但不同浏览器的支持程度可能有所不同。因此,在配置CSP策略时,需要考虑到各种浏览器的兼容性。
- 灵活性:CSP策略的配置可以根据实际需求进行调整,但过于严格的策略可能会限制网页的正常功能。因此,在配置时需要权衡安全性和功能性。
- 维护性:随着网站内容的更新和第三方服务的引入,CSP策略可能需要定期更新和维护。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。