如何防止伪造Referer Header非法访问API,仅允许指定域名调用
Great question—validating the Referer header is a common way to block unauthorized cross-site calls to your API, though it’s important to note its limitations upfront. Clients can spoof this header relatively easily, so always pair this check with other security measures (like API keys, strict CORS policies, or OAuth) for robust protection. That said, here’s how to implement it for common setups:
1. Nginx Reverse Proxy (If Your API Uses One)
If your API sits behind Nginx, you can add a validation rule directly in your server block to filter requests by Referer:
server { listen 80; server_name your-api-domain.com; # Define allowed referer domain valid_referers www.abcd.ef; # Block requests with invalid/missing Referer if ($invalid_referer) { return 403 Forbidden; } # Proxy to your API backend location /api { proxy_pass http://your-api-backend; } }
The valid_referers directive lists trusted domains, and $invalid_referer triggers a 403 response if the incoming Referer doesn’t match or is missing.
2. Backend Code Implementation
If you prefer handling validation directly in your API’s backend, here are examples for popular frameworks:
Node.js/Express
app.use((req, res, next) => { const allowedReferer = 'https://www.abcd.ef'; const incomingReferer = req.get('Referer'); // Check if Referer exists and starts with the allowed domain (handles trailing path variations) if (!incomingReferer || !incomingReferer.startsWith(allowedReferer)) { return res.status(403).send('Forbidden: Invalid request origin'); } next(); });
Python/Flask
from flask import request, abort @app.before_request def validate_referer(): allowed_referer = "https://www.abcd.ef" incoming_referer = request.headers.get('Referer') if not incoming_referer or not incoming_referer.startswith(allowed_referer): abort(403, description="Forbidden: Invalid request origin")
Java/Spring Boot
import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class RefererValidationFilter implements Filter { private static final String ALLOWED_REFERER = "https://www.abcd.ef"; @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; String incomingReferer = req.getHeader("Referer"); if (incomingReferer == null || !incomingReferer.startsWith(ALLOWED_REFERER)) { res.sendError(HttpServletResponse.SC_FORBIDDEN, "Forbidden: Invalid request origin"); return; } chain.doFilter(request, response); } }
Critical Things to Keep in Mind
- Referer Spoofing: Malicious users can modify the Referer header with tools like curl or Postman. Never rely on this check alone for sensitive APIs.
- Missing Referer: Some browsers or privacy-focused extensions strip the Referer header entirely. Decide if you want to block these requests or add exceptions (e.g., allow internal service calls without a Referer).
- Subdomain Flexibility: If you need to allow subdomains (like
app.abcd.ef), adjust your validation logic to check if the Referer ends with.abcd.efinstead of an exact match. - CORS Synergy: Pair this with a strict CORS policy that only allows
www.abcd.efas an allowed origin—this adds an extra layer of protection for browser-based requests.
内容的提问来源于stack exchange,提问作者Lululu

