如何防止独立 Java Web 应用程序服务器上的热链接?

发布于 2024-09-29 13:19:54 字数 45 浏览 7 评论 0原文

如何防止 Tomcat 等独立 Java Web 应用程序服务器上的热链接?

How do you prevent hotlinking on a standalone Java webapp server like Tomcat?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

回忆躺在深渊里 2024-10-06 13:19:54

使用 Tuckey 的 URLRewriteFilter (正如其他人已经间接提到的那样)。来自文档

<rule>
    <name>Blocked Inline-Images</name>
    <note>
        Assume we have under http://www.quux-corp.de/~quux/ some pages with inlined GIF graphics. These graphics are
        nice, so others directly incorporate them via hyperlinks to their pages. We don't like this practice because
        it adds useless traffic to our server.

        While we cannot 100% protect the images from inclusion, we can at least restrict the cases where the browser
        sends a HTTP Referer header.

        RewriteCond %{HTTP_REFERER} !^$
        RewriteCond %{HTTP_REFERER} !^http://www.quux-corp.de/~quux/.*$ [NC]
        RewriteRule .*\.gif$ - [F]
    </note>
    <condition name="referer" operator="notequal">^
lt;/condition>
    <condition name="referer" operator="notequal">^http://www.quux-corp.de/~quux/.*
lt;/condition>
    <from>.*\.gif
lt;/from>
    <set type="status">403</set>
    <to>null</to>
</rule>

<rule>
    <name>Blocked Inline-Images example 2</name>
    <note>
        RewriteCond %{HTTP_REFERER} !^$
        RewriteCond %{HTTP_REFERER} !.*/foo-with-gif\.html$
        RewriteRule ^inlined-in-foo\.gif$ - [F]
    </note>
    <condition name="referer" operator="notequal">^
lt;/condition>
    <condition name="referer" operator="notequal">.*/foo-with-gif\.html
lt;/condition>
    <from>^inlined-in-foo\.gif
lt;/from>
    <set type="status">403</set>
    <to>null</to>
</rule>

Use Tuckey's URLRewriteFilter (as mentioned by others already indirectly). From the documentation:

<rule>
    <name>Blocked Inline-Images</name>
    <note>
        Assume we have under http://www.quux-corp.de/~quux/ some pages with inlined GIF graphics. These graphics are
        nice, so others directly incorporate them via hyperlinks to their pages. We don't like this practice because
        it adds useless traffic to our server.

        While we cannot 100% protect the images from inclusion, we can at least restrict the cases where the browser
        sends a HTTP Referer header.

        RewriteCond %{HTTP_REFERER} !^$
        RewriteCond %{HTTP_REFERER} !^http://www.quux-corp.de/~quux/.*$ [NC]
        RewriteRule .*\.gif$ - [F]
    </note>
    <condition name="referer" operator="notequal">^
lt;/condition>
    <condition name="referer" operator="notequal">^http://www.quux-corp.de/~quux/.*
lt;/condition>
    <from>.*\.gif
lt;/from>
    <set type="status">403</set>
    <to>null</to>
</rule>

<rule>
    <name>Blocked Inline-Images example 2</name>
    <note>
        RewriteCond %{HTTP_REFERER} !^$
        RewriteCond %{HTTP_REFERER} !.*/foo-with-gif\.html$
        RewriteRule ^inlined-in-foo\.gif$ - [F]
    </note>
    <condition name="referer" operator="notequal">^
lt;/condition>
    <condition name="referer" operator="notequal">.*/foo-with-gif\.html
lt;/condition>
    <from>^inlined-in-foo\.gif
lt;/from>
    <set type="status">403</set>
    <to>null</to>
</rule>
拒绝两难 2024-10-06 13:19:54

正如布鲁诺所说,您可以检查合适的推荐人。

每个 HTTP 请求都包含一个引用标头,其中包含链接到当前请求的 URL 的 URL(或者,对于图像,链接到引用该图像的页面)。对于您的情况,它应该包含一个适当的引用 URL,该 URL 应该属于您自己的站点。

为了检测不允许的引用者,我认为您可以使用像 http://www.tuckey.org/urlrewrite 这样的过滤器/ 。您可以配置一个简单的规则来匹配不是来自您自己站点的每个图像请求,并禁止访问或将该 URL 重写为自定义“不允许热链接”图像。

You can check for an appropriate referer as Bruno said.

Every HTTP request contains a referer header that contains the URL that linked to the current URL being requested (or, for images, the page that referenced the image). In your case, it should contain an appropriate referer URL, which should belong to your own site.

In order to detect disallowed referers, I think you could use a filter like http://www.tuckey.org/urlrewrite/ . You can configure a simple rule that matches every image request not coming from your own site, and forbid the access or rewrite that URL to a custom 'Hotlinking not allowed' image.

星星的轨迹 2024-10-06 13:19:54

我不确定它是否已经存在,但是您可以轻松编写 Filter 检查是否存在与适当模式匹配的 Referer 标头(如您发布的链接中所述)。

编辑:
您链接到的文章描述的规则基于Referer HTTP 标头(由浏览器发送以指示从哪个页面获取链接)。
如果 Referer 标头与 http 不匹配,则 Apache Httpd 上的 .htaccess 中的以下规则与 mod_rewrite 或多或少意味着什么://(www\\.)?yoursite\\.com 模式,然后重定向到 /images/hotlink.jpeg

RewriteEngine on 
RewriteCond %{HTTP_REFERER} . 
RewriteCond %{HTTP_REFERER} !^http://(www\\.)?yoursite\\.com [NC] 
RewriteRule \\.(gif|jpe?g)$ /images/hotlink.$1 [L]

过滤器是 web 应用程序中的一种标准机制,用于在请求发送到 servlet 进行处理之前拦截请求(如果需要,它们可以选择不重定向到 servlet)。

您将覆盖过滤器中的 doFilter(ServletRequest request, ServletResponse response, FilterChain chain) ,测试 request.getHeader("Referer") 是否匹配正确的模式(如果是) ,调用 chain.doFilter(request, response),否则发送重定向响应到其他某个图像(即“热链接”或其他内容),可能带有 403 状态代码。

I'm not sure whether it already exists, but you could easily write a Filter that checks whether there's a Referer header that matches the appropriate pattern (as described in the link you've posted).

EDIT:
What the article you've linked to describes is a rule based on the Referer HTTP header (which is sent by browsers to indicate from which page the link was obtained).
The following rules in .htaccess on Apache Httpd with mod_rewrite more or less mean, if the Referer header doesn't match the http://(www\\.)?yoursite\\.com pattern, then redirect to /images/hotlink.jpeg.

RewriteEngine on 
RewriteCond %{HTTP_REFERER} . 
RewriteCond %{HTTP_REFERER} !^http://(www\\.)?yoursite\\.com [NC] 
RewriteRule \\.(gif|jpe?g)$ /images/hotlink.$1 [L]

Filters are a standard mechanism in webapps for intercepting requests before they're sent to the servlet for processing (and they can chose not to redirect to the servlet if needed).

You would override the doFilter(ServletRequest request, ServletResponse response, FilterChain chain) in your Filter, test whether request.getHeader("Referer") matches the right pattern, if so, call chain.doFilter(request, response), otherwise send a redirection response to some other image (that would say "hotlink" or whatever), possibly with a 403 status code.

九公里浅绿 2024-10-06 13:19:54

下面是一个过滤器实现示例:

public class HotLinkFilter implements Filter{

    private final Map<Pattern, Pattern> PATTERNS =
        new ConcurrentHashMap<Pattern, Pattern>();

    private void addPatterns(final String targetPattern,
        final String referrerPattern){
        PATTERNS.put(Pattern.compile(targetPattern),
            Pattern.compile(referrerPattern));
    }

    @Override
    public void init(final FilterConfig config) throws ServletException{
        @SuppressWarnings("unchecked")
        final Enumeration<String> parameterNames =
            config.getInitParameterNames();
        while(parameterNames.hasMoreElements()){
            final String nextParam = parameterNames.nextElement();
            if(nextParam.startsWith("pattern")){
                final String[] patterns =
                    config.getInitParameter(nextParam).split("\\s+");
                if(patterns.length == 2){
                    addPatterns(patterns[0], patterns[1]);
                }
            }
        }
    }

    @Override
    public void doFilter(final ServletRequest request,
        final ServletResponse response,
        final FilterChain chain) throws IOException, ServletException{

        if(request instanceof HttpServletRequest){
            final HttpServletRequest hsr = (HttpServletRequest) request;
            final String referrer = hsr.getHeader("Referer");
            boolean valid = true;
            if(referrer != null){
                final String requestUrl = hsr.getRequestURL().toString();
                for(final Entry<Pattern, Pattern> entry : PATTERNS.entrySet()){
                    if(entry.getKey().matcher(requestUrl).matches()
                        && !entry.getValue().matcher(referrer).matches()){
                        valid = false;
                        break;
                    }
                }
            }
            if(valid){
                chain.doFilter(request, response);
            } else{
                // this is probably not the correct thing to do
                throw new ServletException("Hotlinking not allowed");
            }

        }

    }

    @Override
    public void destroy(){
    }

}

它使用正则表达式模式的映射。如果请求与左侧的模式匹配并且存在引用者,则我们检查引用者是否与右侧的模式匹配。您可以在 web.xml 中进行配置:

<filter>
    <filter-name>Hotlink-Filter</filter-name>
    <filter-class>com.yourcompany.HotLinkFilter</filter-class>
    <init-param>
        <param-name>pattern1</param-name>
        <param-value>http://.*\.mysite.com/.*\.(jpe?g|gif|png) 
        http://.*\.mysite.com/.*</param-value>
    </init-param>
</filter>

Here's an example filter implementation:

public class HotLinkFilter implements Filter{

    private final Map<Pattern, Pattern> PATTERNS =
        new ConcurrentHashMap<Pattern, Pattern>();

    private void addPatterns(final String targetPattern,
        final String referrerPattern){
        PATTERNS.put(Pattern.compile(targetPattern),
            Pattern.compile(referrerPattern));
    }

    @Override
    public void init(final FilterConfig config) throws ServletException{
        @SuppressWarnings("unchecked")
        final Enumeration<String> parameterNames =
            config.getInitParameterNames();
        while(parameterNames.hasMoreElements()){
            final String nextParam = parameterNames.nextElement();
            if(nextParam.startsWith("pattern")){
                final String[] patterns =
                    config.getInitParameter(nextParam).split("\\s+");
                if(patterns.length == 2){
                    addPatterns(patterns[0], patterns[1]);
                }
            }
        }
    }

    @Override
    public void doFilter(final ServletRequest request,
        final ServletResponse response,
        final FilterChain chain) throws IOException, ServletException{

        if(request instanceof HttpServletRequest){
            final HttpServletRequest hsr = (HttpServletRequest) request;
            final String referrer = hsr.getHeader("Referer");
            boolean valid = true;
            if(referrer != null){
                final String requestUrl = hsr.getRequestURL().toString();
                for(final Entry<Pattern, Pattern> entry : PATTERNS.entrySet()){
                    if(entry.getKey().matcher(requestUrl).matches()
                        && !entry.getValue().matcher(referrer).matches()){
                        valid = false;
                        break;
                    }
                }
            }
            if(valid){
                chain.doFilter(request, response);
            } else{
                // this is probably not the correct thing to do
                throw new ServletException("Hotlinking not allowed");
            }

        }

    }

    @Override
    public void destroy(){
    }

}

It uses a map of Regex patterns. If a request matches the pattern on the left side and a referrer is present, then we check if the referrer matches the pattern on the right side. You can configure this in the web.xml:

<filter>
    <filter-name>Hotlink-Filter</filter-name>
    <filter-class>com.yourcompany.HotLinkFilter</filter-class>
    <init-param>
        <param-name>pattern1</param-name>
        <param-value>http://.*\.mysite.com/.*\.(jpe?g|gif|png) 
        http://.*\.mysite.com/.*</param-value>
    </init-param>
</filter>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文