天天看點

點選劫持:X-Frame-Options頭缺失 in a frame because it set 'X-Frame-Options' to 'deny'終極解決方案

      最近在一個扯蛋的項目中遇到一堆滲透測試的問題。其中有一個“X-Frame-Options漏洞”問題。我抓耳撓腮的一度不知道怎麼解決,最後在我的不屑堅持下.......嘻嘻。願遇到該BUG的人都能處理掉。我們先看看滲透報告中的東西,以失敗而告終。

廣告:由于我的博文《docker實作離線地圖server》怎麼寫都搜不到,是以請原諒我這樣無恥的推廣~~:https://blog.csdn.net/u010403700/article/details/90678645

===================================滲透報告中的内容 START====================================

點 擊劫持:X-Frame-Options頭缺失(低)

漏洞情況:

點選劫持:X-Frame-Options頭缺失 in a frame because it set 'X-Frame-Options' to 'deny'終極解決方案

漏洞危害:

點選劫持(ClickJacking)是一種視覺上的欺騙手段。攻擊者使用一個透明的、不可見的iframe,覆寫在一個網頁上,然後誘使使用者在該網頁上進行操作,此時使用者将在不知情的情況下點選透明的iframe頁面。通過調整iframe頁面的位置,可以誘使使用者恰好點選在iframe頁面的一些功能性按鈕上。

解決方案(用不了):

Tomcat配置X-Frame-Options

2種方法:

第1種:将ClickjackFilter.jar添加到lib目錄下。

(可在OWASP的網站中找到)

<filter>

    <filter-name>ClickjackFilterDeny</filter-name>

    <filter-class>org.owasp.filters.ClickjackFilter</filter-class>

      <init-param>

        <param-name>mode</param-name>

          <param-value>SAMEORIGIN </param-value>

      </init-param>

  </filter>

  <filter-mapping>

    <filter-name>ClickjackFilterDeny</filter-name>

    <url-pattern>/*</url-pattern>

  </filter-mapping>

第2種:打開webapps\ROOT\WEB-INF\web.xml添加以下過濾器:

 <filter>

<filter-name>httpHeaderSecurity</filter-name>

<filter-class>

org.apache.catalina.filters.HttpHeaderSecurityFilter

</filter-class>

<antiClickJackingEnabled>true</antiClickJackingEnabled>

<antiClickJackingOption>SAMEORIGIN</antiClickJackingEnabled>

</filter>

<filter-mapping>

<filter-name>httpHeaderSecurity</filter-name>

<url-pattern>/*</url-pattern>

<dispatcher>REQUEST</dispatcher>

</filter-mapping>

===================================滲透報告中的内容 END====================================

本來看文檔就頭疼,尼瑪,看完還沒處理掉。在心裡畫了一萬個圈圈罵他們。報錯

點選劫持:X-Frame-Options頭缺失 in a frame because it set 'X-Frame-Options' to 'deny'終極解決方案

實在沒招了。回過頭來再看看加粗的那部分,原來就是 apache 的 HttpHeaderSecurityFilter類。經過反編譯看了看源碼

點選劫持:X-Frame-Options頭缺失 in a frame because it set 'X-Frame-Options' to 'deny'終極解決方案

原來初始化 antiClickJackingOption 的值是XFrameOption.DENY。我們希望的是antiClickJackingOption=XFrameOption.SAME_ORIGIN。于是就重新了一個類,将HttpHeaderSecurityFilter中的代碼複制進去。就好了

提示:XFrameOptionn 中有三中,DENY  不允許嵌入IFrame、SAME_ORIGIN  運作顯示同源iframe、ALLOW_FROM指定位址的iframe

終極解決方案

1.編寫CntenHttpHeaderSecurityFilter類

public class CntenHttpHeaderSecurityFilter extends FilterBase{

      private static final Log log = LogFactory.getLog(CntenHttpHeaderSecurityFilter.class);

      private static final String HSTS_HEADER_NAME = "Strict-Transport-Security";

      private boolean hstsEnabled;

      private int hstsMaxAgeSeconds;

      private boolean hstsIncludeSubDomains;

      private String hstsHeaderValue;

      private static final String ANTI_CLICK_JACKING_HEADER_NAME = "X-Frame-Options";

      private boolean antiClickJackingEnabled;

      private XFrameOption antiClickJackingOption;

      private URI antiClickJackingUri;

      private String antiClickJackingHeaderValue;

      private static final String BLOCK_CONTENT_TYPE_SNIFFING_HEADER_NAME = "X-Content-Type-Options";

      private static final String BLOCK_CONTENT_TYPE_SNIFFING_HEADER_VALUE = "nosniff";

      private boolean blockContentTypeSniffingEnabled;

      public CntenHttpHeaderSecurityFilter()

      {

        this.hstsEnabled = true;

        this.hstsMaxAgeSeconds = 0;

        this.hstsIncludeSubDomains = false;

        this.antiClickJackingEnabled = true;

        this.antiClickJackingOption = XFrameOption.ALLOW_FROM;

        this.blockContentTypeSniffingEnabled = true;

      }

      public void init(FilterConfig filterConfig) throws ServletException {

        super.init(filterConfig);

        StringBuilder hstsValue = new StringBuilder("max-age=");

        hstsValue.append(this.hstsMaxAgeSeconds);

        if (this.hstsIncludeSubDomains) {

          hstsValue.append(";includeSubDomains");

        }

        this.hstsHeaderValue = hstsValue.toString();

        StringBuilder cjValue = new StringBuilder(this.antiClickJackingOption.headerValue);

        if (this.antiClickJackingOption == XFrameOption.ALLOW_FROM) {

          cjValue.append(':');

          cjValue.append(this.antiClickJackingUri);

        }

        this.antiClickJackingHeaderValue = cjValue.toString();

      }

      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

        throws IOException, ServletException

      {

        if (response.isCommitted()) {

          throw new ServletException(sm.getString("httpHeaderSecurityFilter.committed"));

        }

        if ((this.hstsEnabled) && (request.isSecure()) && ((response instanceof HttpServletResponse))) {

          ((HttpServletResponse)response).setHeader("Strict-Transport-Security", this.hstsHeaderValue);

        }

        if ((this.antiClickJackingEnabled) && ((response instanceof HttpServletResponse))) {

          ((HttpServletResponse)response).setHeader("X-Frame-Options", this.antiClickJackingHeaderValue);

        }

        if ((this.blockContentTypeSniffingEnabled) && ((response instanceof HttpServletResponse))) {

          ((HttpServletResponse)response).setHeader("X-Content-Type-Options", "nosniff");

        }

        chain.doFilter(request, response);

      }

      protected Log getLogger()

      {

        return log;

      }

      protected boolean isConfigProblemFatal()

      {

        return true;

      }

      public boolean isHstsEnabled()

      {

        return this.hstsEnabled;

      }

      public void setHstsEnabled(boolean hstsEnabled)

      {

        this.hstsEnabled = hstsEnabled;

      }

      public int getHstsMaxAgeSeconds()

      {

        return this.hstsMaxAgeSeconds;

      }

      public void setHstsMaxAgeSeconds(int hstsMaxAgeSeconds)

      {

        if (hstsMaxAgeSeconds < 0)

          this.hstsMaxAgeSeconds = 0;

        else

          this.hstsMaxAgeSeconds = hstsMaxAgeSeconds;

      }

      public boolean isHstsIncludeSubDomains()

      {

        return this.hstsIncludeSubDomains;

      }

      public void setHstsIncludeSubDomains(boolean hstsIncludeSubDomains)

      {

        this.hstsIncludeSubDomains = hstsIncludeSubDomains;

      }

      public boolean isAntiClickJackingEnabled()

      {

        return this.antiClickJackingEnabled;

      }

      public void setAntiClickJackingEnabled(boolean antiClickJackingEnabled)

      {

        this.antiClickJackingEnabled = antiClickJackingEnabled;

      }

      public String getAntiClickJackingOption()

      {

        return this.antiClickJackingOption.toString();

      }

      public void setAntiClickJackingOption(String antiClickJackingOption)

      {

        for (XFrameOption option : XFrameOption.values()) {

          if (option.getHeaderValue().equalsIgnoreCase(antiClickJackingOption)) {

            this.antiClickJackingOption = option;

            return;

          }

        }

        throw new IllegalArgumentException(sm.getString("httpHeaderSecurityFilter.clickjack.invalid", new Object[] { antiClickJackingOption }));

      }

      public String getAntiClickJackingUri()

      {

        return this.antiClickJackingUri.toString();

      }

      public boolean isBlockContentTypeSniffingEnabled()

      {

        return this.blockContentTypeSniffingEnabled;

      }

      public void setBlockContentTypeSniffingEnabled(boolean blockContentTypeSniffingEnabled)

      {

        this.blockContentTypeSniffingEnabled = blockContentTypeSniffingEnabled;

      }

      public void setAntiClickJackingUri(String antiClickJackingUri)

      {

          URI uri;

        try

        {

          uri = new URI(antiClickJackingUri);

        }

        catch (URISyntaxException e)

        {

           uri = null;

          throw new IllegalArgumentException(e);

        }

        this.antiClickJackingUri = uri;

      }

      private static enum XFrameOption

      {

        DENY("DENY"), 

        SAME_ORIGIN("SAMEORIGIN"), 

        ALLOW_FROM("ALLOW-FROM");

        private final String headerValue;

        private XFrameOption(String headerValue) {

          this.headerValue = headerValue;

        }

        public String getHeaderValue() {

          return this.headerValue;

        }

      }

}

2.在項目中的web.xml檔案中添加自定義Filter

<filter> 

        <filter-name>httpHeaderSecurity</filter-name> 

        <filter-class>

            com.hd.platform.devlActions.CntenHttpHeaderSecurityFilter

        </filter-class> 

        <antiClickJackingEnabled>true</antiClickJackingEnabled> 

        <antiClickJackingOption>SAMEORIGIN</antiClickJackingOption> 

    </filter> 

    <filter-mapping>

        <filter-name>httpHeaderSecurity</filter-name>

        <url-pattern>/*</url-pattern>

        <dispatcher>REQUEST</dispatcher>

    </filter-mapping> 

至此問題處理完畢。

相關資源位址:https://download.csdn.net/download/u010403700/10629286

需要探讨微服務、微服務容器化、微服務編排、arcgis for javascript 的問題。可加qq:914423503