如何实施安全的HTTP头以防止漏洞?
你知道大多数安全漏洞都可以通过在响应头中实施必要的头来修复吗?
安全与您网站的内容和SEO一样重要,数千个网站因配置错误或缺乏保护而遭受攻击。如果您是网站所有者或安全工程师,并希望保护您的网站免受点击劫持、代码注入、MIME类型、XSS等攻击,则本指南将对您有所帮助。
在本文中,我将介绍在多个Web服务器、网络边缘和CDN提供商中实施的各种HTTP头(recommended by OWASP),以用于better website protection。
注意:
- 在进行更改之前,建议您备份配置文件
- 某些头在所有浏览器上可能不受支持,因此在实施之前进行check out the compatibility。
- 在Apache中必须启用Mod_headers才能实施这些头。确保在
httpd.conf
文件中取消注释以下行。
LoadModule headers_module modules/mod_headers.so
- 实施后,您可以使用secure headers online tool验证结果。
使用WordPress?您可能希望尝试使用HTTP Headers plugin,它会处理这些头以及更多内容。
我们开始吧…👨💻
HTTP严格传输安全
HSTS(HTTP Strict Transport Security)头部可确保所有浏览器的通信均通过HTTPS(HTTP Secure)发送。这可以防止HTTPS点击穿越提示并将HTTP请求重定向到HTTPS。
在实施此头之前,您必须确保您的网站页面都可以通过HTTPS访问,否则它们将被阻止。
HSTS头在IE、Firefox、Opera、Safari和Chrome等主要最新版本的浏览器中都受支持。有三个参数配置。
参数值 | 含义 |
max-age | 以秒为单位的持续时间,告诉浏览器请求仅可通过HTTPS进行。 |
includeSubDomains | 配置也适用于子域。 |
preload | 如果您希望您的域名包含在HSTS preload list中,则使用。 |
所以让我们举一个例子,将HSTS配置为一年,包括域名和sub-domain的预加载。
Apache HTTP服务器
您可以通过在httpd.conf文件中添加以下条目来在Apache中实施HSTS
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
重新启动Apache以查看结果
Nginx
要在Nginx中配置HSTS,请在服务器(SSL)指令下的nginx.conf
中添加下一条目
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload';
像往常一样,您需要重新启动Nginx以进行验证
Cloudflare
如果您使用Cloudflare,则可以通过几个简单的步骤启用HSTS。
- 登录到Cloudflare并选择站点
- 转到“Crypto”选项卡,然后点击“启用HSTS”。
选择您需要的设置即可,更改将即时应用。
Microsoft IIS
启动IIS Manager,并在相应站点的“HTTP Response Headers”中添加头。
重新启动站点
X-Frame-Options
使用X-Frame-Options头部可以防止您的网站上的Clickjacking漏洞。通过实施此头部,您可以指示浏览器不要将您的网页嵌入框架/iframe中。这在浏览器支持上有一些限制,因此在实施之前要检查。
您可以配置以下三个参数。
参数值 | 意义 |
SAMEORIGIN | 仅允许来自同一网站源的内容嵌入到框架/iframe中。 |
DENY | 防止任何域名使用框架/iframe嵌入你的内容。 |
ALLOW-FROM | 仅允许在特定URI上创建内容的框架。 |
让我们看看如何实现“DENY”,以便没有域名嵌入到网页中。
Apache
在httpd.conf
中添加以下行,并重新启动Web服务器以验证结果。
Header always append X-Frame-Options DENY
Nginx
在server指令/块中的nginx.conf
中添加以下内容。
add_header X-Frame-Options “DENY”;
重新启动以验证结果
F5 LTM
创建一个包含以下内容的iRule,并与相应的虚拟服务器相关联。
when HTTP_RESPONSE { HTTP::header insert "X-FRAME-OPTIONS" "DENY" }
无需重新启动任何内容,更改会自动生效。
WordPress
你也可以通过WordPress实现此标头。在wp-config.php文件中添加以下内容
header('X-Frame-Options: DENY);
如果你不熟悉编辑文件,则可以使用上面提到的plugin as explained here或。
Microsoft IIS
通过转到相应站点的“HTTP响应标头”来添加标头。
重新启动站点以查看结果。
X-Content-Type-Options
通过将此标头添加到您的网页HTTP响应中,可以防止MIME类型的安全风险。使用此标头会指示浏览器将文件类型视为已定义并禁止内容嗅探。您只需要添加一个参数“nosniff”。
让我们看看如何使用此标头。
Apache
通过在httpd.conf文件中添加以下行来实现。
Header set X-Content-Type-Options nosniff
别忘了重新启动Apache Web服务器以激活配置。
Nginx
在server块中的nginx.conf
文件中添加以下行。
add_header X-Content-Type-Options nosniff;
像往常一样,您需要重新启动Nginx以检查结果。
Microsoft IIS
打开IIS并转到“HTTP响应标头”
点击添加并输入名称和值
点击确定并重新启动IIS以验证结果。
内容安全策略
通过在您的网页HTTP响应中实现内容安全策略(CSP)标头,可以防止XSS,点击劫持和代码注入攻击。 CSP指示浏览器加载允许在网站上加载的内容。
所有browsers don’t support CSP,因此在实施之前您需要进行验证。您可以通过三种方式实现CSP标头。
- Content-Security-Policy – Level 2/1.0
- X-Content-Security-Policy – 不推荐使用
- X-Webkit-CSP – 不推荐使用
如果您仍在使用不推荐使用的版本,那么您可能考虑升级到最新版本。
有多个可能实施CSP的参数,您可以参考OWASP了解更多。但是,让我们看看最常用的两个参数。
参数值 | 意义 |
default-src | 从定义的源加载所有内容 |
script-src | 仅从定义的源加载脚本 |
以下示例演示了如何在各种web服务器中从同一来源加载所有内容。
Apache
在httpd.conf
文件中添加以下行,并重新启动Web服务器以生效。
Header set Content-Security-Policy "default-src 'self';"
Nginx
在nginx.conf
文件的服务器块中添加以下内容
add_header Content-Security-Policy "default-src 'self';";
Microsoft IIS
在IIS管理器中,转到相应网站的HTTP响应标头,并添加以下内容
查看此链接以了解如何使用CSP。这是X-Frame-Options的高级版本。
X-Permitted-Cross-Domain-Policies
使用Adobe产品如PDF,Flash等吗?
您可以实现此标头,以指示浏览器如何处理跨域的请求。通过实现此标头,您可以限制从其他域加载您站点的资源,以避免资源滥用。
有几个可用的选项。
值 | 描述 |
none | 不允许任何策略 |
master-only | 仅允许主策略 |
all | 允许所有内容 |
by-content-only | 仅允许特定类型的内容。例如- XML |
by-ftp-only | 仅适用于FTP服务器 |
Apache
如果您不想允许任何策略。
Header set X-Permitted-Cross-Domain-Policies "none"
您应该看到以下类似的标头。
Nginx
假设您需要实现master-only,然后在nginx.conf
的server
块中添加以下内容。
add_header X-Permitted-Cross-Domain-Policies master-only;
结果如下。
Referrer-Policy
想要控制您站点的引荐策略吗?有一些隐私和安全的好处。但是,并非所有浏览器都支持所有选项,因此在实施之前请检查您的要求。
Referrer-Policy支持以下语法。
值 | 描述 |
no-referrer | 不发送引荐信息 |
no-referrer-when-downgrade | 默认设置,将引荐发送到与HTTP到HTTP,HTTPS到HTTPS相同的协议。 |
unsafe-url | 将发送完整URL。 |
same-origin | 仅为同源站点发送引荐。 |
strict-origin | 仅在协议为HTTPS时发送 |
strict-origin-when-cross-origin | 完整的URL将通过严格的协议(如HTTPS)发送 |
origin | 在所有请求中发送原始URL |
origin-when-cross-origin | 在同源情况下发送完整URL。但是,在其他情况下只发送原始URL。 |
Apache
如果要设置no-referrer,可以添加以下内容。
Header set Referrer-Policy "no-referrer"
重启后,您应该在响应标头中看到。
Nginx
假设您需要实现同源,则需要添加以下内容。
add_header Referrer-Policy same-origin;
配置完成后,您应该得到以下结果。
Expect-CT
Expect-CT是一个仍处于实验阶段的新头部,用于指示浏览器验证与Web服务器的连接是否符合证书透明性(CT)。这个由Google发起的项目旨在修复一些flaws in the SSL/TLS certificate系统。
Expect-CT头部有以下三个可用的变量。
Value | Description |
max-age | 在多长时间内浏览器应该缓存该策略(以秒为单位)。 |
enforce | 一个可选的指令,用于强制执行该策略。 |
report-uri | 当未接收到有效的证书透明性时,浏览器向指定的URL发送报告。 |
Apache
假设您希望强制执行此策略,并在12小时内进行报告和缓存,那么您需要添加以下内容。
Header set Expect-CT 'enforce, max-age=43200, report-uri="https://somedomain.com/report"'
这是结果。
Nginx
如果您想要进行报告并在1小时内进行缓存,该怎么办?
add_header Expect-CT 'max-age=60, report-uri="https://mydomain.com/report"';
输出结果如下。
Permissions-Policy
此前被称为Feature-Policy,现已更名为Permissions-Policy,并增加了一些功能。您可以查看this以了解Feature-Policy到Permissions-Policy之间的重大变化。
通过Permissions-Policy,您可以在Web应用程序中启用或禁用浏览器功能,例如地理位置、全屏、扬声器、USB、自动播放、麦克风、支付、电池状态等。通过实施此策略,您让服务器指示客户端(浏览器)遵守Web应用程序的功能。
Apache
假设您需要禁用全屏功能,您可以在httpd.conf
或apache2.conf
文件中添加以下内容,具体取决于您使用的Apache HTTP服务器的版本。
Header always set Permissions-Policy "fullscreen 'none' "
如何在一行中添加多个功能呢?
这也是可以的!
Header always set Permissions-Policy "fullscreen 'none'; microphone 'none'"
重新启动Apache HTTP以查看结果。
HTTP/1.1 200 OK
Date: Thu, 29 Apr 2021 06:40:43 GMT
Server: Apache/2.4.37 (centos)
Permissions-Policy: fullscreen 'none'; microphone 'none'
Last-Modified: Thu, 29 Apr 2021 06:40:41 GMT
ETag: "3-5c116c620a6f1"
Accept-Ranges: bytes
Content-Length: 3
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
上述代码将指示浏览器禁用全屏和麦克风。
您还可以通过将允许列表保持为空来完全禁用该功能。
例如,您可以添加以下内容以禁用地理位置功能。
Header always set Permissions-Policy "geolocation=()"
这将在浏览器上输出如下内容。
HTTP/1.1 200 OK
Date: Thu, 29 Apr 2021 06:44:19 GMT
Server: Apache/2.4.37 (centos)
Permissions-Policy: geolocation=()
Last-Modified: Thu, 29 Apr 2021 06:40:41 GMT
ETag: "3-5c116c620a6f1"
Accept-Ranges: bytes
Content-Length: 3
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
Nginx
让我们举一个例子,禁用振动功能。
add_header Permissions-Policy "vibrate 'none';";
或者,禁用地理位置、相机和扬声器。
add_header Permissions-Policy "geolocation 'none'; camera 'none'; speaker 'none';";
以下是重新启动Nginx后的输出。
HTTP/1.1 200 OK
Server: nginx/1.14.1
Date: Thu, 29 Apr 2021 06:48:35 GMT
Content-Type: text/html
Content-Length: 4057
Last-Modified: Mon, 07 Oct 2019 21:16:24 GMT
Connection: keep-alive
ETag: "5d9bab28-fd9"
Permissions-Policy: geolocation 'none'; camera 'none'; speaker 'none';
Accept-Ranges: bytes
整个Nginx配置都在nginx.conf
或任何您使用的自定义文件的http
块下面。
清除站点数据
正如您可能从名称中猜到的那样,实施清除站点数据头是告诉客户端清除浏览数据(如缓存、存储、Cookie或全部内容)的一种很好的方法。这使您可以更好地控制您希望如何在浏览器中存储网站数据。
Apache
假设您想要清除源缓存,您可以添加以下内容。
Header always set Clear-Site-Data "cache"
这将输出以下HTTP响应。
HTTP/1.1 200 OK
Date: Thu, 29 Apr 2021 07:52:14 GMT
Server: Apache/2.4.37 (centos)
Clear-Site-Data: cache
Last-Modified: Thu, 29 Apr 2021 06:40:41 GMT
ETag: "3-5c116c620a6f1"
Accept-Ranges: bytes
Content-Length: 3
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
或者,清除全部内容。
Header always set Clear-Site-Data "*"
Nginx
让我们设置Nginx清除Cookie。
add_header Clear-Site-Data "cookies";
然后,您将看到以下输出。
HTTP/1.1 200 OK
Server: nginx/1.14.1
Date: Thu, 29 Apr 2021 07:55:58 GMT
Content-Type: text/html
Content-Length: 4057
Last-Modified: Mon, 07 Oct 2019 21:16:24 GMT
Connection: keep-alive
ETag: "5d9bab28-fd9"
Clear-Site-Data: cookies
Accept-Ranges: bytes
结论
保护网站是具有挑战性的,我希望通过实施上述头部,您可以增加一层安全性。如果您经营的是商业网站,您还可以考虑使用类似于SUCURI的云端WAF来保护您的在线业务。关于SUCURI的好处在于它既提供安全性又提供性能。
如果您选择使用SUCURI WAF,您将在防火墙 >> 安全选项卡下找到附加头部部分。