Preface
For security reasons, we need the pictures returned by the backend to be only allowed to be displayed on a certain website, and we do not want to be downloaded after the crawler gets the image address. Or, don't want the browser to access the image link directly.
For performance reasons, I don’t want other people’s websites, so I use our image links to display them, and consume my own server resources in vain.
Therefore, simple picture anti-theft chain rules can be used in springboot. Intercept some processing.
1. Code implementation
This practical code is a simple version, and the code is written in a dead configuration
1-1. Create an interceptor class
import ; import ; import import ; public class ImageProtectionInterceptor implements HandlerInterceptor { private static final String ALLOWED_DOMAIN = ""; // Allowed domain name @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // Get the requested URL String requestUrl = ().toString(); // Determine whether the request ends with an image suffix if ((".jpg") || (".png") || (".jpeg")) { // Get the source domain name of the request String referer = ("Referer"); // Check whether the source domain name meets expectations if (referer != null && (ALLOWED_DOMAIN)) { return true; // Comply with the anti-theft link requirements and release the request } else { (HttpServletResponse.SC_FORBIDDEN); // Return to 403 Forbidden return false; // Intercept request } } return true; // Release requests for non-image resources } }
2. Code implementation (flexible configuration)
2-1. Configure information in
# Image anti-theft chain configuration img-protect:# Picture anti-theft chain protection switchenabled: true # Whether to allow direct access by browserallowBrowser: false # Whitelist of picture anti-theft chains, separated by commas by multiple [if not fill in, all websites will be blocked]allowReferer:
2-2. Create a configuration file mapping class
import ; import ; @Component@ConfigurationProperties("img-protect") public class ImgProtectConfig { private boolean enabled; private boolean allowBrowser; private String allowReferer; public boolean getEnabled() { return enabled; } public void setEnabled(boolean enabled) { = enabled; } public boolean getAllowBrowser() { return allowBrowser; } public void setAllowBrowser(boolean allowBrowser) { = allowBrowser; } public String getAllowReferer() { return allowReferer; } public void setAllowReferer(String allowReferer) { = allowReferer; } }
2-3. Create an interceptor class
import Above2-2The created classpath.ImgProtectConfig; import ; import ; import ; import ; import ; import ; import ; import ; @Componentpublic class ImageProtectionInterceptor implements HandlerInterceptor { @Autowired private ImgProtectConfig imgProtectConfig; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // Determine whether the picture anti-theft link function is enabled if (!()){ return true; } // Get the requested URL String requestUrl = ().toString(); // Determine whether the request ends with an image suffix if ((".jpg") || (".png") || (".jpeg")) { // Get the source domain name of the request String referer = ("Referer"); // Check whether the source domain name meets expectations. If referer is null, it means that it is accessed directly by the browser. if (referer == null && ()){ return true; // Comply with the anti-theft link requirements and release the request }else if (referer != null && isAllowedDomain(referer)) { return true; // Comply with the anti-theft link requirements and release the request } else { (HttpServletResponse.SC_FORBIDDEN); // Return to 403 Forbidden return false; // Intercept request } } return true; // Release requests for non-image resources } // Check if it comes from the allowed domain name private boolean isAllowedDomain(String referer) { // Get the allowed domain name String allowedReferers = (); // If the allowed domain name is not empty if (() != null && !"".equals(())) { // Split the allowed domain names into string arrays Set<String> allowedDomains = new HashSet<>(((","))); // traverse the allowed domain names for (String allowedDomain : allowedDomains) { // Return true if the requested domain name contains the allowed domain name if ((())) { return true; } } } // Otherwise return false return false; } }
2-4. Register an interceptor
import ; import ; import ;@Configuration public class WebConfig implements WebMvcConfigurer { // You can no longer use the new method to create objects!!! @Autowired private ImageProtectionInterceptor imageProtectionInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { // Register an interceptor to intercept all requests (imageProtectionInterceptor) .addPathPatterns("/**"); // Intercept all requests } }
Conclusion
The above anti-theft chain interceptor can basically deal with image chain theft in general, but it cannot guarantee absolute security.
The following situations may occur:
Referer forgery:Malicious clients can forge referer headers. An attacker can forge an effective referer to bypass protection.
Missed reports:An attacker may find ways to bypass referer checks (such as images encoded with data URIs or base64).
False alarm:Legal users may be blocked because referer mismatch (such as a private browser or proxy server).
Reverse proxy:The attacker can add a domain name whitelist as a reverse proxy path in the url path, and bypass the code's contain method check.
The above is the detailed content of SpringBoot's image anti-theft chain function. For more information about SpringBoot's image anti-theft chain, please follow my other related articles!