如何防范HTTP请求头内容注入攻击?(Node.js+Requestly场景)
Great question—this is such a common pain point when building Node.js apps, especially since tools like Requestly make it so easy for attackers (or even curious users) to tweak HTTP headers like Referer. Let’s walk through practical, actionable ways to harden your app against this kind of tampering:
Core Rule: Never Trust Client-Side Data
First things first: any header, parameter, or data sent from the client can be modified. Treat all incoming requests as untrusted until you’ve validated them. This is the foundation of all the defenses below.
1. Validate and Sanitize Incoming Headers
If your app relies on headers like Referer, create a strict validation layer to ensure they match expected values. For example, if you only expect requests from your own domain, whitelist those domains and reject anything outside:
// Express example: Middleware to validate Referer header const allowedReferrers = ['https://your-app.com', 'https://admin.your-app.com']; app.use((req, res, next) => { const referer = req.get('Referer'); // Only validate if Referer exists (some browsers don't send it) if (referer) { const isAllowed = allowedReferrers.some(domain => referer.startsWith(domain)); if (!isAllowed) { return res.status(403).send('Invalid request origin'); } } next(); });
If you ever need to display content from headers (like showing the referrer in a dashboard), sanitize it first to prevent XSS attacks. Use libraries like DOMPurify or manually escape special characters:
const sanitizedReferer = DOMPurify.sanitize(req.get('Referer') || '');
2. Use CSRF Tokens for State-Changing Requests
Tampering with Referer is often tied to CSRF attacks, where an attacker tricks a user into sending a request to your app. CSRF tokens solve this by tying each request to the user’s active session. Here’s how to implement this in Express:
const csurf = require('csurf'); const cookieParser = require('cookie-parser'); // Initialize middleware app.use(cookieParser()); app.use(csurf({ cookie: { secure: true, httpOnly: true } })); // Pass the token to your templates (for form submissions) app.get('/checkout', (req, res) => { res.render('checkout', { csrfToken: req.csrfToken() }); }); // In your form, include the token as a hidden input // <input type="hidden" name="_csrf" value="<%= csrfToken %>"> // The middleware automatically validates the token on POST/PUT/DELETE requests app.post('/submit-order', (req, res) => { // If the token is invalid, csurf will send a 403 response automatically res.send('Order submitted successfully'); });
3. Enforce Strict CSP (Content Security Policy)
While CSP doesn’t directly prevent header tampering, it limits the damage if an attacker injects malicious links via a modified Referer. Set a CSP header to restrict which resources your app can load:
app.use((req, res, next) => { res.setHeader( 'Content-Security-Policy', "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:;" ); next(); });
This blocks any external scripts, styles, or images that aren’t explicitly allowed, stopping malicious links from executing code in your app.
4. Force HTTPS and Secure Cookies
Use HSTS (HTTP Strict Transport Security) to ensure all requests are sent over HTTPS, which prevents man-in-the-middle attacks that could modify headers. Also, mark your session cookies as Secure and HttpOnly:
// Enable HSTS app.use((req, res, next) => { res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains'); next(); }); // Set secure cookies res.cookie('session_id', userSession.id, { secure: true, // Only sent over HTTPS httpOnly: true, // Not accessible via client-side JS sameSite: 'Strict' // Prevents cross-site cookie access });
5. Avoid Using Headers for Critical Logic
Don’t rely on headers like Referer for access control or sensitive operations. Instead, use more secure methods:
- API Keys: For server-to-server requests, use secret API keys sent in headers (but keep them secure, don’t expose them to clients).
- OAuth2/JWT Tokens: For authenticated users, use tokens that include user permissions and are signed with a secret key.
- IP Whitelisting: For internal services, restrict requests to trusted IP ranges (though this isn’t ideal for public apps).
内容的提问来源于stack exchange,提问作者Klark

