Javascript 内容安全策略(CSP)是如何工作的?

Javascript 内容安全策略(CSP)是如何工作的?,javascript,html,security,http-headers,content-security-policy,Javascript,Html,Security,Http Headers,Content Security Policy,开发人员控制台中出现了一系列错误: 拒绝对字符串求值 拒绝执行内联脚本,因为它违反了以下内容安全策略指令 拒绝加载脚本 拒绝加载样式表 这是怎么回事?内容安全策略(CSP)是如何工作的?如何使用内容安全策略HTTP头 具体来说,如何 …允许多个来源 …使用不同的指令 …使用多个指令 …处理端口 …处理不同的协议 …是否允许文件://协议 …使用内联样式、脚本和标记和 …是否允许eval() 最后: “自我”到底是什么意思 Content Security Policymeta标记允许您定义可以从

开发人员控制台中出现了一系列错误:

拒绝对字符串求值

拒绝执行内联脚本,因为它违反了以下内容安全策略指令

拒绝加载脚本

拒绝加载样式表

这是怎么回事?内容安全策略(CSP)是如何工作的?如何使用
内容安全策略
HTTP头

具体来说,如何

  • …允许多个来源
  • …使用不同的指令
  • …使用多个指令
  • …处理端口
  • …处理不同的协议
  • …是否允许
    文件://
    协议
  • …使用内联样式、脚本和标记
  • …是否允许
    eval()
  • 最后:

  • “自我”到底是什么意思

  • Content Security Policy
    meta标记允许您定义可以从何处加载资源,防止浏览器从任何其他位置加载数据,从而降低攻击风险。这使得攻击者更难将恶意代码注入您的站点

    我把头撞在砖墙上,试图弄明白为什么CSP一个接一个地出现错误,但似乎没有任何关于它如何工作的简明、清晰的说明。以下是我试图简要解释CSP的一些要点,主要集中在我发现难以解决的问题上

    为简洁起见,我不会在每个示例中编写完整的标记。相反,我将只显示
    content
    属性,因此说
    content=“default src'self'”
    的示例意味着:

    <meta http-equiv="Content-Security-Policy" content="default-src 'self'">
    
    请注意,除了特殊的参数(如
    “self”
    )外,参数周围没有引号。此外,指令后面没有冒号(
    )。只是指令,然后是一个以空格分隔的参数列表

    所有低于指定参数的内容都是隐式允许的。这意味着在上述示例中,这些将是有效的来源:

    https://example.com/js/file.js
    https://example.com/js/subdir/anotherfile.js
    
    但是,以下内容无效:

    http://example.com/js/file.js
    ^^^^ wrong protocol
    
    https://example.com/file.js
                       ^^ above the specified path
    
    2。如何使用不同的指令?他们各自做什么?

    最常见的指令是:

    • defaultsrc
      加载javascript、图像、CSS、字体、AJAX请求等的默认策略
    • scriptsrc
      定义javascript文件的有效源
    • style src
      定义css文件的有效源
    • img src
      定义图像的有效源
    • connectsrc
      为到XMLHttpRequest(AJAX)、WebSocket或EventSource定义有效的目标。如果尝试连接此处不允许的主机,浏览器将模拟
      400
      错误
    还有其他的,但这些是你最可能需要的

    3。如何使用多个指令?

    通过使用分号(
    )终止所有指令,可以在一个元标记中定义所有指令:

    4。如何处理端口?

    除了默认端口以外的所有端口都需要通过在允许的域后添加端口号或星号来明确允许:

    content="default-src 'self' https://ajax.googleapis.com http://example.com:123/free/stuff/"
    
    上述情况将导致:

    https://ajax.googleapis.com:123
                               ^^^^ Not ok, wrong port
    
    https://ajax.googleapis.com - OK
    
    http://example.com/free/stuff/file.js
                     ^^ Not ok, only the port 123 is allowed
    
    http://example.com:123/free/stuff/file.js - OK
    
    如前所述,您还可以使用星号显式允许所有端口:

    content="default-src example.com:*"
    
    5。如何处理不同的协议?

    默认情况下,只允许使用标准协议。例如,要允许WebSocket
    ws://
    ,您必须明确允许它:

    content="default-src 'self'; connect-src ws:; style-src 'self'"
                                             ^^^ web Sockets are now allowed on all domains and ports.
    
    6。如何允许文件协议
    文件://

    如果你想把它定义为这样,那就行不通了。相反,您将使用
    filesystem
    参数来允许它:

    content="default-src filesystem"
    
    7。如何使用内联脚本和样式定义?

    除非明确允许,否则不能使用内联样式定义、标记内的代码或标记属性(如
    onclick
    )。你允许他们这样做:

    content="script-src 'unsafe-inline'; style-src 'unsafe-inline'"
    
    您还必须明确允许内联的base64编码图像:

    content="img-src data:"
    
    8。如何允许
    eval()

    我相信很多人都会说你没有,因为“eval是邪恶的”是世界末日即将到来的最可能的原因。那些人是错的。当然,你可以用eval在网站的安全性上打上大洞,但它有完全有效的用例。你只需要聪明地使用它。你是这样允许的:

    content="script-src 'unsafe-eval'"
    
    9。
    “自我”到底是什么意思?

    您可以将
    'self'
    理解为本地主机、本地文件系统或同一主机上的任何内容。这并不意味着这些。这意味着与定义内容策略的文件具有相同的方案(协议)、相同的主机和相同的端口的源。通过HTTP为您的站点提供服务?没有https,除非您明确定义它

    我在大多数示例中都使用了
    “self”
    ,因为包含它通常是有意义的,但它绝不是强制性的。如果你不需要它,就把它删掉

    但请稍等我不能只使用
    content=“default src*”
    就可以了吗

    不。除了明显的安全漏洞外,这也不会像您预期的那样起作用。即使声称它允许任何事情,那也不是真的。它不允许内联或evals,因此,要真正使您的站点更容易受到攻击,您可以使用以下方法:

    content="default-src * 'unsafe-inline' 'unsafe-eval'"
    
    。。。但我相信你不会的

    进一步阅读:

    Apache2Mod\u头文件 您还可以启用Apache2mod_头。在默认情况下,它已启用。如果您使用Ubuntu/Debian,请按如下方式启用它:

    # First enable headers module for Apache 2,
    # and then restart the Apache2 service
    a2enmod headers
    apache2 -k graceful
    
    在Ubuntu/Debian上,您可以在文件中配置标题
    /etc/apache2/conf enabled/security.conf

    #
    # Setting this header will prevent MSIE from interpreting files as something
    # else than declared by the content type in the HTTP headers.
    # Requires mod_headers to be enabled.
    #
    #Header set X-Content-Type-Options: "nosniff"
    
    #
    # Setting this header will prevent other sites from embedding pages from this
    # site as frames. This defends against clickjacking attacks.
    # Requires mod_headers to be enabled.
    #
    Header always set X-Frame-Options: "sameorigin"
    Header always set X-Content-Type-Options nosniff
    Header always set X-XSS-Protection "1; mode=block"
    Header always set X-Permitted-Cross-Domain-Policies "master-only"
    Header always set Cache-Control "no-cache, no-store, must-revalidate"
    Header always set Pragma "no-cache"
    Header always set Expires "-1"
    Header always set Content-Security-Policy: "default-src 'none';"
    Header always set Content-Security-Policy: "script-src 'self' www.google-analytics.com adserver.example.com www.example.com;"
    Header always set Content-Security-Policy: "style-src 'self' www.example.com;"
    
    注意:这是文件的底部。只有最后三个条目是CSP
    # First enable headers module for Apache 2,
    # and then restart the Apache2 service
    a2enmod headers
    apache2 -k graceful
    
    #
    # Setting this header will prevent MSIE from interpreting files as something
    # else than declared by the content type in the HTTP headers.
    # Requires mod_headers to be enabled.
    #
    #Header set X-Content-Type-Options: "nosniff"
    
    #
    # Setting this header will prevent other sites from embedding pages from this
    # site as frames. This defends against clickjacking attacks.
    # Requires mod_headers to be enabled.
    #
    Header always set X-Frame-Options: "sameorigin"
    Header always set X-Content-Type-Options nosniff
    Header always set X-XSS-Protection "1; mode=block"
    Header always set X-Permitted-Cross-Domain-Policies "master-only"
    Header always set Cache-Control "no-cache, no-store, must-revalidate"
    Header always set Pragma "no-cache"
    Header always set Expires "-1"
    Header always set Content-Security-Policy: "default-src 'none';"
    Header always set Content-Security-Policy: "script-src 'self' www.google-analytics.com adserver.example.com www.example.com;"
    Header always set Content-Security-Policy: "style-src 'self' www.example.com;"