点击劫持: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头缺失(低)

漏洞情况:

漏洞危害:

点击劫持(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====================================

本来看文档就头疼,尼玛,看完还没处理掉。在心里画了一万个圈圈骂他们。报错

实在没招了。回过头来再看看加粗的那部分,原来就是 apache 的 HttpHeaderSecurityFilter类。经过反编译看了看源码

原来初始化 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

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
X-Frame-Options是一个HTTP响应,用于指示浏览器是否允许将页面嵌入到frame、iframe或object中展示。当一个页面设置了X-Frame-Options为deny时,浏览器会拒绝在frame中展示该页面,即使是在相同域名的页面中也不允许。\[2\] 这个设置可以用来防止点劫持,即将一个网站的内容嵌入到另一个恶意网站中,以欺骗用户进行操作。\[3\] 如果你遇到了"Refused to display xxx in a frame because it set X-Frame-Options to deny"的错误,说明该页面设置了X-Frame-Options为deny,所以无法在frame中展示。这是一种安全措施,以保护网站的内容不被恶意利用。\[1\] 在开发中,你可以通过设置响应X-Frame-Options值来解决这个问题。例如,可以将X-Frame-Options设置为SAMEORIGIN,这样页面就可以在同域名页面的frame中嵌套展示。\[2\] #### 引用[.reference_title] - *1* [Refused to display 'xxx' in a frame because it set 'X-Frame-Options' to 'deny'.](https://blog.csdn.net/Absorbed66c/article/details/100914969)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [解决 Refused to display in a frame because it set 'X-Frame-Options' to 'deny'.问题](https://blog.csdn.net/lizy928/article/details/82535089)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值