如何防止独立Java webapp服务器上的热链接?

时间:2010-10-29 11:08:02

标签: java tomcat hotlinking

如何防止像Tomcat这样的独立Java webapp服务器上的热链接?

4 个答案:

答案 0 :(得分:3)

使用Tuckey的URLRewriteFilter(正如其他人已经间接提到的那样)。来自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">^$</condition>
    <condition name="referer" operator="notequal">^http://www.quux-corp.de/~quux/.*$</condition>
    <from>.*\.gif$</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">^$</condition>
    <condition name="referer" operator="notequal">.*/foo-with-gif\.html$</condition>
    <from>^inlined-in-foo\.gif$</from>
    <set type="status">403</set>
    <to>null</to>
</rule>

答案 1 :(得分:2)

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

修改 the article you've linked to描述的是基于Referer HTTP标头的规则(由浏览器发送以指示从哪个页面获取链接)。 如果.htaccess标头与mod_rewrite模式不匹配,{Httpd Referer中的以下规则http://(www\\.)?yoursite\\.com或更少或更少,则重定向到{{1} }。

/images/hotlink.jpeg

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

您可以覆盖过滤器中的RewriteEngine on RewriteCond %{HTTP_REFERER} . RewriteCond %{HTTP_REFERER} !^http://(www\\.)?yoursite\\.com [NC] RewriteRule \\.(gif|jpe?g)$ /images/hotlink.$1 [L] ,测试doFilter(ServletRequest request, ServletResponse response, FilterChain chain)是否与正确的模式匹配,如果是,请调用request.getHeader("Referer"),否则将重定向响应发送到其他图像(即说“hotlink”或其他),可能带有403状态代码。

答案 2 :(得分:2)

布鲁诺说,你可以检查一个合适的引用者。

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

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

答案 3 :(得分:2)

以下是过滤器实现的示例:

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>