安全漏洞解决方案

 

XSS跨站漏洞

现象:表单输入框输入<svg/onload=alert(2)>,点击保存后进行查看。如果出现弹窗,存在XSS漏洞。

解决方案:

  1. 应用添加过滤器。将常见的关键字进行转义;,',",<>,(),,,\,script,svg,alert,confirm,prompt,onload,onmouseover,onfocus,onerror,xss.还要注意大小写的问题。这里直接使用org.springframework.web.util.HtmlUtils.htmlEscape()进行转义。

  2. 在HTTP Header 头中添加 X-XSS-Protection,Content-Security-Policy.这部分spring seurity 帮忙做了。

CSRF跨站请求伪造

现象:非本站发起的请求。外站访问本站的链接,借助于本站存在的cookie发起请求。

解决方案:

  1. 验证referer字段 安全性低,改造简单,容易误伤自己
  2. token验证 全部改造困难,安全性高
  3. HTTP 头中自定义属性并验证 不适用同步请求

最终使用了验证referer字段进行保护。对应用的影响是无法在新标签页打开页面。

明文传输

https

Host主机头攻击

现象:curl --header "Host: www.baidu.com" http://132.91.153.197:8085/login.sp -v 返回报文将请求重定向到百度。

nginx解决方案

nginx 存在default_server。配置default_server.并且将业务server 的server_name 修改为指定的对外ip。


server {
    listen       8085;
    server_name  132.91.153.197 132.91.153.11 127.0.0.1;
    ...
}
server {
  listen 8085 default_server;
  server_name _;
  return 403; # 403 forbidden
}

2019年7月15日更新

当server配置使用https时,配置 default_server 会导致网站不可访问。此时可使用以下的方式避免host主机头攻击,具体为啥不生效还不清楚。

if ($host != 'baidu.com'){
    return 403;
}

tomcat解决方案

<!-- 修改name为真实的域名 -->
<Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true">

Apache Tomcat示例目录漏洞

删除tomcat webapps 目录下示例程序,只留下业务应用。

Snoop Servlet信息披露

删除tomcat webapps 目录下示例程序,只留下业务应用

不安全的crossdomain.xml文件

目前业务上没有使用到cors访问。直接禁掉

location /crossdomain.xml {
    return 403;
}

Apache Tomcat示例文件

删除tomcat webapps 目录下示例程序,只留下业务应用

启用了不安全的options方法

  1. servlet直接对外
<security-constraint>
    <web-resource-collection>
        <web-resource-name>onlyGetAndPost</web-resource-name>
        <url-pattern>/*</url-pattern>
        <http-method>PUT</http-method>
        <http-method>DELETE</http-method>
        <http-method>HEAD</http-method>
        <http-method>OPTIONS</http-method>
        <http-method>TRACE</http-method>
    </web-resource-collection>
    <auth-constraint/>
</security-constraint>

  1. nginx对外
if ($request_method !~* GET|POST) {
    return 403;
}

中间件程序版本信息泄露

nginx配置:

server_tokens off;

启用自动完成的密码类型输入

<input type="password" autocomplete="new-password" />

会话标识未更新

<http>
    <custom-filter position="FORM_LOGIN_FILTER" ref="myAuthFilter" />
    <session-management session-authentication-strategy-ref="sas"/>
</http>

<beans:bean id="myAuthFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
	<beans:property name="sessionAuthenticationStrategy" ref="sas" />
</beans:bean>

<beans:bean id="sas" class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy" />

点击劫持:X-Frame-Options未配置(登录页)

js解决

if(window.top !== window.self){ window.top.location = window.location;}

jsp

<%
    //禁止页面被iframe嵌套,这是服务端的做法,上面那句是客户端的做法 登录页不允许嵌套
    response.addHeader("X-Frame-Options","DENY");
%>

spring security

<http>
<headers >
    <!--iframe 允许同源嵌套-->
    <frame-options policy="SAMEORIGIN"/>
</headers>
<intercept-url pattern="/**" access="authenticated()"/>
</http>