1.不安全的http请求
http请求除了常见的get post之外、还有put、delete、options、Head、trace等请求方法,这些请求方法是不安全的,所以需要禁用。Tomcat的禁用方式是在web.xml中加入:
<!--禁用不安全的http method-->
<security-constraint>
<web-resource-collection>
<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>
</auth-constraint>
</security-constraint>
2.xss注入
xss注入是当渲染在HTML中的内容含有类似<script>alert(3)</script>这样的js脚本时,脚本可能在浏览器中被执行。如果这些脚本是其他用户(比如在一个论坛中)添加的,那么可能执行操作。解决方法是在后台数据返回给前端时过滤掉这些脚本。如果是json,那么可以添加一个messageConverter,在Spring MVC的配置中加入
<!-- 这里配置spring的注解,使得@Controller @RequestMapping等注解可以被识别 -->
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<bean
class="com.zjepe.appdev.planprophase.utils.xss.XSSMappingJackson2HttpMessageConverter"/>
</list>
</property>
</bean>
关于XSSMappingJackson2HttpMessageConverter的实现:
package com.zjepe.appdev.planprophase.utils.xss;
import java.io.IOException;
import java.lang.reflect.Type;
import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import com.fasterxml.jackson.databind.JavaType;
public class XSSMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
@Override
public Object read(Type type, Class<?> contextClass,
HttpInputMessage inputMessage) throws IOException,
HttpMessageNotReadableException {
JavaType javaType = getJavaType(type, contextClass);
Object obj = readJavaType(javaType, inputMessage);
String json = super.getObjectMapper().writeValueAsString(obj);
String result = cleanXSS(json.toString());
Object resultObj = super.getObjectMapper().readValue(result, javaType);
return resultObj;
}
// 这个就是父类的readJavaType方法,由于父类该方法是private的,所以我们copy一个用
private Object readJavaType(JavaType javaType, HttpInputMessage inputMessage) {
try {
return super.getObjectMapper().readValue(inputMessage.getBody(),
javaType);
} catch (IOException ex) {
throw new HttpMessageNotReadableException("Could not read JSON: "
+ ex.getMessage(), ex);
}
}
// 重写writeInternal方法,在返回内容前首先进行加密
@Override
protected void writeInternal(Object object, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
// 使用Jackson的ObjectMapper将Java对象转换成Json String
String json = super.getObjectMapper().writeValueAsString(object);
String result = cleanXSS(json.toString());
// 输出
outputMessage.getBody().write(result.getBytes("utf-8"));
}
private String cleanXSS(String value) {
String res = Jsoup.clean(value.toString(), Whitelist.relaxed());
return res;
}
}
3.sql注入
sql注入是用户在表单中输入了包含SQL的内容,可能会在数据库中执行的问题。数据库支持参数化查询即可避免这个问题,一般的ORM框架都会使用参数化查询。如果使用字符串拼接SQL,那么需要对参数进行检查。
4.csrf跨站请求
出现这个问题的原因是浏览器不限制其他站点的表单跨域请求,而且这个请求会携带cookie。即使操作改为post也不能解决这个问题。有两种方式解决这个问题:一种是校验请求的referer,如果不是自己站点的则拒绝(需要排除一些例外,比如首页)。第二种是不用浏览器自动的cookie作为用户令牌(或者增加双重令牌),即在操作请求时手动设置令牌。
网友评论