如何开始使用网站内容安全策略

  • A+
所属分类:服务器

如何开始使用网站内容安全策略

本文是与地面...感谢您支持使SitePoint成为可能的合作伙伴。

网络是基于“同一来源”的政策。只有代码在mysite.com可以在cookie、localStorage、Ajax请求等中访问mysite.com的数据。evilsite.com将被拒绝。

不幸的是,事情从来没有那么简单。现代网站是复杂的,并加载了各种第三方组件,风格和脚本.从另一个域加载的脚本在当前页面的上下文中运行,可以执行它喜欢的任何操作。社交网络按钮可以监视访问者,劫持登录cookie,更改页面内容等等。即使您信任第三方站点,您也可能成为中间人攻击在脚本到达您之前进行更改的位置。或者,它可以允许用户启动自己的跨站点脚本攻击(XXS).

默认情况下,浏览器实现任何事-去接近。幸运的是,可以使用防止意外安全问题的内容安全策略(ContentSecurityPolicy,CSP)应用限制。CSP告诉浏览器什么是允许的,例如在mysite.com上运行JavaScript,但只能从文件中运行,而不是内联的

1
<script>

标签。

测试你的网站

若要检查csp是否在您的站点上实现,请访问observatory.mozilla.org,输入页面URL并按下扫描我...那些没有CSP保护的人很可能F(虽然进行了其他各种检查)。

CSP对于银行、在线商店、社交网络和任何实现用户帐户的网站来说都是必不可少的。如果您的站点不使用第三方脚本、字体、媒体、小部件或分析工具,这就不那么必要了,但您能确定它永远不会使用吗?

实现内容安全策略

开发人员或Web主机必须向每个页面添加内容安全策略。它使用内容-安全-策略由服务器端语言设置的http头(PHP、Node.js、Ruby等)或在服务器配置(如Apache的

1
.htaccess

文件,例如:


1
2
3
4
# Apply a CSP to all HTML and PHP files
<FilesMatch ".(html|php)$">
Header set Content-Security-Policy "policy-definition"
</FilesMatch>

(我们将很快讨论“策略定义”值。)

服务器配置文件是实用的,因为它们将相同的头应用于子文件夹层次结构中的所有页面。但是,您也可以在HTML中定义策略

1
<head>

使用

1
meta

标签:


1
<meta http-equiv="Content-Security-Policy" content="policy-definition">

如果您没有配置服务器的权限,或者在每个页面上需要不同的策略,这可能是必要的。

内容安全策略定义

现在是复杂的部分。CSP为不同类型的内容定义了允许域和上下文的白名单。

假设您只希望允许从您的域加载脚本。您可以使用以下CSP(请不要真的这么做--这只是个例子!):


1
script-src 'self';

然后,您会意识到,您还将从cdn加载一个第三方库,该库可以出现在

1
mycdn.com

...域通配符添加到空格分隔列表中:


1
script-src 'self' *.mycdn.com;

然后,您会记住一些在页面上内联运行的脚本--我们也可以定义:


1
script-src 'self' *.mycdn.com 'unsafe-inline';

我们现在有了脚本策略。但是,我们还没有定义其他类型,所以所有样式表、图像、字体等等都无法加载。要解决这个问题,我们可以使用

1
default-src

作为任何未定义类型的后盾:


1
default-src 'self'; script-src 'self' *.mycdn.com 'unsafe-inline';

注意,每个内容类型定义都用分号(;)分隔。我们现在可以在我们的

1
.htaccess

档案:


1
Header set Content-Security-Policy "default-src 'self'; script-src 'self' *.mycdn.com 'unsafe-inline';"

或者页面元标签:


1
2
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self' *.mycdn.com 'unsafe-inline';">

CSP指令参考

整套CSP指令:

指令 描述
1
default-src
默认的后备策略。通常设置为

1
'self'

1
'none'

为了确保所有其他指令都必须声明

1
style-src
有效样式表源
1
script-src
有效JavaScript源
1
connect-src
用于JavaScript数据检索的有效Ajax、WebSocket或事件源源
1
form-action
有效来源

1
form

动作属性

1
img-src
有效图像源
1
font-src
有效字体源
1
media-src
有效HTML 5

1
audio

1
video

元素源

1
object-src
HTML的有效插件源

1
object

1
embed

1
applet

元素

1
plugin-types
调用的插件的有效MIME类型。

1
object

1
embed

,G.

1
application/pdf
1
frame-src
有效

1
frame

1
iframe

来源(现在已被废弃-使用)

1
child-src

)

1
child-src
有效

1
frame

1
iframe

来源

1
frame-ancestors
有效嵌入源

1
frame

1
iframe

1
object

1
embed

1
applet

元素

1
sandbox
以类似于HTML 5

1
iframe

沙箱属性...这有一些限制是本指令所特有的:

1
allow-forms

1
allow-same-origin

1
allow-scripts

1
allow-popups

1
allow-modals

1
allow-orientation-lock

1
allow-pointer-lock

1
allow-presentation

1
allow-popups-to-escape-sandbox

,和

1
allow-top-navigation
1
report-uri
浏览器可以发布策略失败报告的地址。

CSP源参考

终止的CSP源指令

1
-src

支持下列值。可以使用任意数量的空格分隔值:

来源 描述
1
'none'
防止从任何源加载,例如:

1
frame-ancestors 'none'

停止显示任何iframe或插件的页面。该值不能跟随其他源。

1
'self'
允许从同一来源的源(协议、域/ip和端口)加载
1
https:
只允许HTTPS连接上的源。
1
data:
许可证数据:来源,例如

1
style-src data:

允许样式表中使用Base 64编码的图像。

1
*
任何URL的通配符
1
*.domain.com
允许来自domain.com的任何子域的来源,即www.domain.com、cdn.domain.com等。
1
exact.domain.com
许可来源:eart.domain.com
1
https://exact.domain.com/
允许在给定域上使用https源。
1
'unsafe-inline'
允许内联CSS、脚本、

1
javascript:

和元素事件处理程序(如

1
onclick

在HTML中

1
'unsafe-eval'
允许使用JavaScript的不安全动态代码

1
eval()

功能

1
'nonce-id'
允许内联CSS或脚本运行,如果

1
id

匹配当前属性值,例如

1
script-src 'nonce-abc123'

1
<script nonce="abc123">...</script>

1
'sha256-hash'
如果文件内容与生成的sha-256散列值匹配,则允许样式或脚本。

CSP发展建议

从严格的默认策略开始是切实可行的

1
default-src 'none';

然后根据需要添加进一步的权限。对大多数网站来说,一个很好的起点可以是:


1
default-src 'none'; style-src 'self' data:; img-src 'self' data:; script-src 'self'; connect-src 'self';

这允许相同来源的样式、图像、脚本和Ajax请求。

在Web浏览器中打开页面,然后启动Developer工具控制台。将报告阻塞的资源警告。


1
Refused to load the script 'XXX' because it violates the following Content Security Policy directive: "YYY".

您可能需要浏览各种页面,以确保您已经考虑到所有的字体,图像,视频,脚本,插件和IFRAME您的网站所需。

谷歌服务

Google提供了范围广泛的服务,您可能正在使用分析、字体、地图等等。不幸的是,在一系列URI上启用了这些功能,这些URI需要进一步的Ajax调用、内联执行和数据方案。您可能最终会得到一个复杂的策略,例如:


1
2
3
4
5
6
default-src 'self';
style-src 'self' 'unsafe-inline' *.googleapis.com;
script-src 'self' *.google-analytics.com *.googleapis.com data:;
connect-src 'self' *.google-analytics.com *.googleapis.com *.gstatic.com data:;
font-src 'self' *.gstatic.com data:;
img-src * data:;

(为了清晰起见,添加了行符,但不能在实际代码中使用。)

在编写本报告时,这是无法避免的,其他第三方供应商也将面临类似的挑战。

avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: