最近在一個扯蛋的項目中遇到一堆滲透測試的問題。其中有一個“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