如何为nginx(虚拟主机)确定合理的内容安全策略来源?

12

我目前正在尝试学习关于nginx作为web服务器的安全性。我的想象设置是使用nginx创建了3个虚拟主机,每个主机都运行着一个博客。

在针对nginx加固的一些教程中,看到了那些 http-headers 后,我发现自己陷入了困境... 如果我有多个虚拟主机,这些虚拟主机可能会依赖来自不同站点的内容,那么通过nginx强制执行内容安全策略是否是正确的方式还不确定。

然而,我现在的位置是要找出如何为每个*-src参数设置合理的内容安全策略白名单。

指令参考和源列表参考 以及 最新的内容安全策略第3级 都没有回答“最佳实践白名单”的问题。

假设我在这些参数的每个参数上都添加了'self':

  • default-src:

如果设置为'self',则只有这个参数是有意义的

  • script-src, style-src, img-src, connect-src, font-src, child-src:

其余的让我真头疼,我应该如何知道每个好的来源呢? 如果我将这些设置为'self',那么用户是否总是会收到400 HTTP错误?

就像我之前说的,我不确定通过nginx强制执行内容安全策略是否是正确的方式。如果我运行一个具有5个以上客户端的web服务器,则对于这些客户端的每个“良好”源,我将无法知道。再次强调,我只是在想这些源参数。其他HTTP头(不仅限于内容安全策略)对我来说都是有意义的,并且完全合理。

敬礼, Megajin

1个回答

36

更新:经过进一步的研究

我在Github上找到了一个非常有用的仓库,我会与大家分享。

简短描述: Nginx Server Configs是一个配置片段集合,可以帮助您的服务器提高网站的性能和安全性,同时确保资源以正确的内容类型提供,并且如果需要,即使跨域也可以访问。

Repo链接: https://github.com/h5bp/server-configs-nginx

然而,我建议您阅读并学习每个选项! 我仍然使用我在原始回答中展示的自己的CSP策略。我认为这些信息对于nginx领域的任何初学者都可能很有用。


我对我的问题进行了更多的研究。目前,我很满意自己的配置,并将在本帖底部分享。

这个Stackoverflow问题实际上是一个很好的起点:Content Security Policy如何工作?

我的最后一个关键点是保护所有内容,如果任何用户遇到CSP错误,他们必须告诉服务器管理员他们想要添加另一个来源到CSP中。如果该来源看起来可靠,则会被添加;否则将被拒绝(我可能会以某种方式自动化该过程)。

如果有人对进一步的SSL配置感兴趣,可以查看这个github页面:https://gist.github.com/plentz/6737338

这是我的nginx头文件配置(根据2019年7月22日的更新更新了头文件):

# don't send the nginx version number in error pages and Server header
  server_tokens off;

# config to don't allow the browser to render the page inside an frame or iframe
# and avoid clickjacking http://en.wikipedia.org/wiki/Clickjacking
# if you need to allow [i]frames, you can use SAMEORIGIN or even set an uri with ALLOW-FROM uri
# https://developer.mozilla.org/en-US/docs/HTTP/X-Frame-Options
add_header X-Frame-Options SAMEORIGIN always;

# when serving user-supplied content, include a X-Content-Type-Options: nosniff header along with the Content-Type: header,
# to disable content-type sniffing on some browsers.
# https://www.owasp.org/index.php/List_of_useful_HTTP_headers
# currently suppoorted in IE > 8 http://blogs.msdn.com/b/ie/archive/2008/09/02/ie8-security-part-vi-beta-2-update.aspx
# http://msdn.microsoft.com/en-us/library/ie/gg622941(v=vs.85).aspx
# 'soon' on Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=471020
add_header X-Content-Type-Options nosniff always;

# This header enables the Cross-site scripting (XSS) filter built into most recent web browsers.
# It's usually enabled by default anyway, so the role of this header is to re-enable the filter for
# this particular website if it was disabled by the user.
# https://www.owasp.org/index.php/List_of_useful_HTTP_headers
add_header X-XSS-Protection "1; mode=block" always;

# with Content Security Policy (CSP) enabled(and a browser that supports it(http://caniuse.com/#feat=contentsecuritypolicy),
# you can tell the browser that it can only download content from the domains you explicitly allow
# http://www.html5rocks.com/en/tutorials/security/content-security-policy/
# https://www.owasp.org/index.php/Content_Security_Policy
# I need to change our application code so we can increase security by disabling 'unsafe-inline' 'unsafe-eval'
# directives for css and js(if you have inline css or js, you will need to keep it too).
# more: http://www.html5rocks.com/en/tutorials/security/content-security-policy/#inline-code-considered-harmful
add_header Content-Security-Policy "default-src 'self' https://google.com https://youtube.com https://facebook.com https://fonts.google.com https://fonts.googleapis.com https://ajax.googleapis.com https://www.google-analytics.com https://cdnjs.cloudflare.com https://code.jquery.com https://connect.facebook.net https://s.imgur.com https://imgur.com https://i.imgur.com https://500px.com https://drscdn.500px.org https://www.reddit.com https://www.flickr.com https://c1.staticflickr.com https://maxcdn.bootstrapcdn.com http://code.ionicframework.com https://cdn.fontawesome.com/; script-src 'self' 'unsafe-inline'; style-src 'self'; img-src 'self' data:; connect-src 'self'; font-src 'self'; object-src 'none'; media-src 'self'; form-action 'self'; frame-ancestors 'self';" always;

在我的用户的帮助下,这将是一个漫长的学习过程。我希望这也能帮到其他人。


2019年7月22日更新

根据评论中的说明,在某些情况下,headers会被显示但在第一行后被忽略。请注意:

nginx将引号之间的空格视为文字,因此只要您在每个新行前使用一个空格或制表符,标头就仍然有效。

注意:

RFC 7230已不再支持分割标题行:

来自 RFC 7230 section 3.2.4

历史上,HTTP标头字段值可以通过在每个额外行之前至少使用一个空格或水平制表符(obs-fold)来扩展。除了message/http媒体类型外,该规范不再支持这种行折叠方式。

最安全的解决方案是接受您配置文件中的某些行可能比您所期望的长得多。

更新来源:https://dev59.com/zVUL5IYBdhLWcg3wqZab#50043114


嗨@Megajin, 感谢您的解决方案。但是,浏览器中显示标题,但它只考虑第一行并忽略其余行。 - harsh
@harsh 你尝试过像我这样在前面使用带有空格的多行吗?Nginx会将引号之间的空格视为字面量,因此只要您在每个新行的开头加上一个空格或制表符,标头就会保持有效。但是由于拆分标头已被弃用,我将编辑我的答案。感谢您的提示! - Megajin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接