替代HTTP_REFERER:基于MITRE实现反向代理的PNG防盗链技术问询
Hey there! Let's break down how to handle hotlink protection for your MITRE-based reverse proxy—since you’re already modifying the execute method, we can build right on that. Here’s a practical, step-by-step approach to implement this and troubleshoot common issues:
Core Logic for Hotlink Prevention
The foundation of hotlink protection lies in verifying where the image request is coming from. We’ll use the Referer HTTP header to check if the request originates from your authorized website. Keep in mind:
- The
Refererheader can be empty (e.g., direct browser access) or spoofed, so we’ll add fallback checks for edge cases. - We only want to block requests for PNG files—other traffic should pass through normally.
Step-by-Step Implementation in the execute Method
Below is a concrete example (assuming Java, common for MITRE proxy implementations) of how to modify your execute method to enforce hotlink protection:
@Override public void execute(HttpServletRequest request, HttpServletResponse response) throws IOException { // Define your authorized website domain(s) Set<String> allowedOrigins = new HashSet<>(Arrays.asList( "https://your-main-site.com", "https://subdomain.your-main-site.com" )); String requestURI = request.getRequestURI(); String referer = request.getHeader("Referer"); boolean isHotlinkAttempt = false; // Only check PNG requests if (requestURI.toLowerCase().endsWith(".png")) { // Case 1: No Referer = direct browser access (block by default) if (referer == null) { isHotlinkAttempt = true; } // Case 2: Referer exists but isn't from an allowed domain else { boolean originAllowed = allowedOrigins.stream() .anyMatch(origin -> referer.startsWith(origin)); isHotlinkAttempt = !originAllowed; } } // Handle hotlink attempts if (isHotlinkAttempt) { // Option 1: Return 403 Forbidden response.sendError(HttpServletResponse.SC_FORBIDDEN, "Hotlinking not permitted"); // Option 2: Return a custom placeholder image instead // response.setContentType("image/png"); // try (InputStream placeholder = getClass().getResourceAsStream("/hotlink-blocked.png")) { // IOUtils.copy(placeholder, response.getOutputStream()); // } return; } // If valid, forward the request to the internal server as usual super.execute(request, response); }
Common Issues & Fixes
Problem: Legitimate requests get blocked because the
Refererheader is empty
Fix: Add a signature-based validation layer. When generating image URLs on your website, append a time-sensitive signature (e.g.,?sig=abc123&exp=1699999999). In the proxy’sexecutemethod, verify the signature before allowing access—this bypasses reliance on theRefererheader entirely.Problem: Subdomains aren’t recognized as valid origins
Fix: Replace thestartsWithcheck with a regex that matches any subdomain of your main site:Pattern allowedOriginPattern = Pattern.compile("^https?://([a-z0-9-]+\\.)?your-main-site.com/"); boolean originAllowed = allowedOriginPattern.matcher(referer).find();Problem:
Refererisn’t sent when your site uses HTTPS and the proxy uses HTTP
Fix: Add aReferrer-Policyheader to your website’s responses:<meta name="referrer" content="strict-origin-when-cross-origin">This tells browsers to send the
Refererheader even when moving between HTTPS and HTTP (if origins match).Problem: Testing the setup is tricky
Fix: Usecurlto simulate different request scenarios:# Simulate a hotlink from an external site curl -H "Referer: https://random-site.com" https://your-proxy-domain/image.png # Simulate a valid request from your site curl -H "Referer: https://your-main-site.com/page.html" https://your-proxy-domain/image.png
Additional Optimization Tips
- Cache validation results for frequently requested images to reduce overhead (use a short TTL to avoid stale permissions).
- Extend the file type check to cover other image formats (JPG, WebP) if needed.
- Log hotlink attempts to monitor abuse patterns.
内容的提问来源于stack exchange,提问作者hublo

