Security headers (such as 'X-Frame-Options', 'X-XSS-Protection', etc.)
Overview of Security Headers
Security headers are part of HTTP response headers used to control browser behavior and enhance web application security. They effectively defend against common attacks such as clickjacking, XSS, and MIME type confusion. In modern web development, properly configuring security headers has become a fundamental security practice.
X-Frame-Options
X-Frame-Options
controls whether a page can be embedded in <frame>
, <iframe>
, or <object>
, primarily defending against clickjacking attacks. It has three possible values:
DENY
: Completely prohibits embeddingSAMEORIGIN
: Allows embedding only by same-origin pagesALLOW-FROM uri
: Allows embedding from a specified source (deprecated)
# Nginx configuration example
add_header X-Frame-Options "SAMEORIGIN";
// Express middleware example
app.use((req, res, next) => {
res.setHeader('X-Frame-Options', 'DENY');
next();
});
Real-world example: Banking websites often use DENY
to prevent malicious sites from embedding their login pages in iframes for phishing attacks.
X-XSS-Protection
X-XSS-Protection
controls the browser's built-in XSS filter. Although modern browsers are gradually phasing out this header, it still holds value in older browsers:
0
: Disables filtering1
: Enables filtering1; mode=block
: Enables filtering and blocks rendering1; report=<uri>
: Enables filtering and reports (Chrome only)
# Apache configuration
Header set X-XSS-Protection "1; mode=block"
Note: Modern applications should primarily rely on Content Security Policy (CSP) for XSS defense, with this header serving as a supplement.
Content-Security-Policy
CSP is one of the most powerful security headers, using a whitelist mechanism to control resource loading:
Content-Security-Policy: default-src 'self'; script-src 'self' https://apis.example.com; style-src 'self' 'unsafe-inline'; img-src *; media-src media.example.com; child-src 'none'
Key directives include:
default-src
: Default resource loading policyscript-src
: Controls JavaScript executionstyle-src
: Controls CSS loadingconnect-src
: Restricts connections like XMLHttpRequestreport-uri
: Violation reporting address
<!-- Example: Only allows loading same-origin resources -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">
Advanced usage: Nonces or hashes can allow specific inline scripts:
<script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">
// Only scripts with matching nonces will execute
</script>
Strict-Transport-Security
HSTS forces browsers to use HTTPS connections:
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
max-age
: Validity period (seconds)includeSubDomains
: Includes all subdomainspreload
: Requests inclusion in browser preload lists
// Node.js implementation
app.use((req, res, next) => {
if(req.secure) {
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
}
next();
});
X-Content-Type-Options
The nosniff
option prevents browser MIME type sniffing:
X-Content-Type-Options: nosniff
This prevents browsers from executing non-JavaScript files as JS, defending against MIME type confusion attacks.
# Enable for all static resources
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
add_header X-Content-Type-Options nosniff;
}
Referrer-Policy
Controls Referer header information leakage:
Referrer-Policy: strict-origin-when-cross-origin
Common values:
no-referrer
: Completely disablessame-origin
: Sends only for same-origin requestsstrict-origin
: Sends only the origin (excluding path)strict-origin-when-cross-origin
: Sends only the origin for cross-origin requests
<!-- Set via meta tag -->
<meta name="referrer" content="strict-origin-when-cross-origin">
Feature-Policy/Permissions-Policy
Controls browser feature access permissions (renamed to Permissions-Policy in newer versions):
Permissions-Policy: geolocation=(), camera=(), microphone=(), payment=()
// Disable unnecessary features
app.use((req, res, next) => {
res.setHeader('Permissions-Policy', 'accelerometer=(), camera=(), geolocation=()');
next();
});
Security Header Best Practices
-
Combination: Single headers cannot provide comprehensive protection. A typical combination:
add_header X-Frame-Options "DENY"; add_header X-Content-Type-Options "nosniff"; add_header X-XSS-Protection "1; mode=block"; add_header Content-Security-Policy "default-src 'self'"; add_header Referrer-Policy "strict-origin-when-cross-origin";
-
Testing: Use security header scanning tools to verify configurations:
curl -I https://example.com | grep -iE '(xss|frame|csp)'
-
Gradual Deployment: CSP can first use report-only mode:
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report
-
Performance Considerations: Excessive security headers increase HTTP header size; balance security and performance.
Common Issues and Solutions
CSP blocking third-party resources:
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com
HSTS causing development environment issues:
- Avoid long
max-age
in local development - Clear HSTS settings via browser
iframe integration conflicts with X-Frame-Options:
Content-Security-Policy: frame-ancestors https://partner.example.com
CSP and nonce management: Build tools can automatically generate nonces:
// Webpack plugin example
const crypto = require('crypto');
const HtmlWebpackPlugin = require('html-webpack-plugin');
class NoncePlugin {
apply(compiler) {
compiler.hooks.compilation.tap('NoncePlugin', (compilation) => {
HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync(
'NoncePlugin',
(data, cb) => {
const nonce = crypto.randomBytes(16).toString('base64');
data.html = data.html.replace(/<script/g, `<script nonce="${nonce}"`);
cb(null, data);
}
);
});
}
}
Modern Browser Security Evolution
As browser security models evolve, some header behaviors have changed:
- CSP Level 3: New directives like
worker-src
,prefetch-src
- Reporting API: Unified violation reporting mechanism
Reporting-Endpoints: default="https://example.com/reports" Content-Security-Policy: default-src 'self'; report-to default
- Trusted Types: DOM XSS defense
Content-Security-Policy: require-trusted-types-for 'script'
Server Configuration Examples
Complete Apache Configuration:
<IfModule mod_headers.c>
Header set X-Frame-Options "DENY"
Header set X-Content-Type-Options "nosniff"
Header set X-XSS-Protection "1; mode=block"
Header set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://*.example.com; font-src 'self'; connect-src 'self' https://api.example.com; frame-src 'none'; object-src 'none';"
Header set Referrer-Policy "strict-origin-when-cross-origin"
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header set Permissions-Policy "geolocation=(), camera=()"
</IfModule>
CloudFront Lambda@Edge:
exports.handler = (event, context, callback) => {
const response = event.Records[0].cf.response;
response.headers['x-frame-options'] = [{ key: 'X-Frame-Options', value: 'DENY' }];
response.headers['content-security-policy'] = [{
key: 'Content-Security-Policy',
value: "default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self'; base-uri 'self'; form-action 'self'"
}];
callback(null, response);
};
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:同源策略与跨域安全
下一篇:HTTPS与混合内容问题