2010-10-29 77 views
1

如何防止像Tomcat這樣的獨立Java webapp服務器發生盜鏈?如何防止獨立Java webapp服務器上的盜鏈?

+0

下面是一個例子,爲什麼和怎麼樣,在Apache,可以防止盜鏈:http://www.dagondesign.com/articles/hotlink-protection-with-htaccess/我的情況是不同的是,我在獨立模式下使用Tomcat。 – SyntaxT3rr0r 2010-10-29 11:08:14

+0

有這麼多好的和有益的答案我不知道哪一個接受。我給每個人+1,但我不知道哪一個應該選作*正確的那一個。這是有點怪異的SO methinks:我的意思是,你必須接受一個事實... – SyntaxT3rr0r 2010-10-29 18:58:19

回答

2

我不確定它是否已經存在,但您可以輕鬆編寫一個Filter,檢查是否存在與適當模式匹配的Referer標題(如您已發佈的鏈接中所述)。

編輯: 什麼the article you've linked to描述是一個基於Referer HTTP標頭的規則(這是由瀏覽器發送到指示從哪個頁面獲得的鏈接)。 以下規則在Apache Httpd上的.htaccessmod_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] 

過濾器是在web應用對於之前他們發送給servlet處理(他們可以選擇,如果需要不重定向到Servlet)攔截請求的標準機制。

你會覆蓋在你的過濾器的doFilter(ServletRequest request, ServletResponse response, FilterChain chain),測試是否request.getHeader("Referer")正確的模式相匹配,如果是的話,叫chain.doFilter(request, response),否則發送重定向響應一些其他的圖像(也可以說「熱鏈」或其他),可能與403狀態碼。

+0

我真的不明白這一點,你能告訴我更多嗎? :)你的意思是說,從我自己提供的頁面上提出的對照片的所有要求已經包含了我可以檢查的'Referer'?或者除了過濾器之外,我還需要添加特定的「Referer」? – SyntaxT3rr0r 2010-10-29 11:15:53

+0

HTTP指定一個'引用者'標題,其中包含客戶端獲取他當前請求的地址的位置。對於嵌入式圖像,它是瀏覽器當前正在加載的頁面的URL。 – 2010-10-29 11:55:38

+0

@Tassos Bassoukos確實如此,但HTTP規範很遺憾地將它描述爲'Referer'(單個「r」)。 – Bruno 2010-10-29 12:16:49

2

你可以像布魯諾說的那樣檢查一個合適的引用者。

每個HTTP請求都包含一個referer頭,該頭包含鏈接到請求的當前URL(或者對於圖像來說,引用該圖像的頁面)的URL。在你的情況下,它應該包含一個適當的引用URL,它應該屬於你自己的網站。

爲了檢測不允許的查閱者,我認爲你可以使用像http://www.tuckey.org/urlrewrite/這樣的過濾器。您可以配置一條簡單的規則,以匹配不是來自您自己的網站的所有圖片請求,並禁止訪問或將該網址重寫爲自定義的「不允許盜鏈」圖片。

+0

事實上,我提到的urlrewrite過濾器是Apache的mod_rewrite的Java等價物,在您引用的文章中使用了它,因此您應該很容易地模仿該文章中描述的行爲。 – jjmontes 2010-10-29 12:02:03

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> 
+0

你確定它是'hsr.getHeader(「HTTP_REFERER」)'而不是'hsr.getHeader(「Referer」)'?我認爲它應該是實際的標題名稱,而不是某個配置關鍵字。 – Bruno 2010-10-29 12:19:20

+0

我的不好。這是「Referer」。謝謝。 – 2010-10-29 12:21:53

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>