1

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

4

4 回答 4

3

使用 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">^$</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>
于 2010-10-29T12:29:06.573 回答
2

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

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

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

于 2010-10-29T12:00:23.357 回答
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>
于 2010-10-29T12:02:47.450 回答
2

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

编辑:链接到的文章描述的是基于RefererHTTP 标头的规则(由浏览器发送以指示从哪个页面获取链接)。.htaccessApache Httpd 上的以下规则mod_rewrite或多或少意味着,如果Referer标头与模式不匹配http://(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]

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

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

于 2010-10-29T11:10:02.490 回答