この記事はまだ日本語に翻訳されていません。英語版を表示しています。
Six HTTP security headers to enable on your website
A few lines of server configuration are enough to block many common attacks. Here are the ones that matter, and how to add them without breaking anything.
Codanalyst チーム
3分で読めます
目次
Every time a browser loads a page, the server sends a series of HTTP headers before the content. Some of them serve only one purpose: telling the browser how to protect itself. They cost nothing and don't slow the site down, yet a large share of the sites we analyze don't enable a single one.
Here are the six that matter, with a ready-to-copy configuration for Nginx. The Apache equivalents follow the same principle with the Header always set directive.
Strict-Transport-Security (HSTS)
Your site runs on HTTPS, great. But on a very first visit, or when someone types the address without https://, the connection sometimes starts over plain HTTP. HSTS tells the browser to never use anything but HTTPS for your domain.
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Content-Security-Policy (CSP)
This is the most powerful header, and the most delicate. The CSP lists the allowed sources for scripts, styles, images and fonts. If an attacker manages to inject a script into your page (an XSS vulnerability), the browser will refuse to run it because it doesn't come from an allowed source.
A reasonable starting policy:
add_header Content-Security-Policy "default-src 'self'; img-src 'self' data: https:; script-src 'self'; style-src 'self' 'unsafe-inline'; frame-ancestors 'self'" always;
The right approach is to start in observation mode with the Content-Security-Policy-Report-Only header. The browser then reports what it would have blocked, without blocking anything. You adjust the list, then switch to enforcing mode.
X-Content-Type-Options
Some browsers try to guess a file's type from its content, even when the server declares something else. A text file uploaded by a user could then be interpreted as a script. There's only one value, and it solves the problem:
add_header X-Content-Type-Options "nosniff" always;
Protection against iframe embedding
Without protection, any site can display yours inside an invisible frame and trick your visitors into clicking without knowing it ("clickjacking"). The CSP frame-ancestors directive shown above handles it. For older browsers, add:
add_header X-Frame-Options "SAMEORIGIN" always;
Referrer-Policy
When a visitor clicks an outbound link, their browser sends the address of the page they came from by default. If that address contains an identifier, a token or search parameters, they go along with it. This value only sends the domain name to external sites:
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Permissions-Policy
Camera, microphone, geolocation: most sites don't need any of them. Disabling them prevents a compromised third-party script from accessing them.
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
How to check that everything is in place
Open your browser's developer tools, go to the Network tab, reload the page and click the first request: the response headers appear. Remember the always keyword in Nginx, without which the headers disappear from error pages.
Codanalyst checks these six headers on every page it analyzes and flags the missing ones, with the configuration line to add for your server. Test your site: the result comes back in under a minute.