大家都知道shiro方法级,请求级保障是不错的,但是对于对于具体的行级数据安全控制是比较无力的,但是我们总是需要用一些手段来保证数据级的安全,举个比较简单的说明,
有合法登录A和B用户,A用户通过方法findById=A可以加载出自己的信息并修改密码,这个时候用户B可以通过findById=A也可以加载出A的信息,这样简单的入侵方式比较简单,
只要使用编辑器改动下表单的提交值即可,如果严谨是没事的,但是总有那么一些人不会那么严谨,所以经常都是通过id直出直入查询到数据,导致用户资料泄漏被修改,
那么问题来了,我们该如何防止这样的低级攻击呢?
下面我提供一个比较简单的方案,希望抛砖引玉,如果有更好的方案请分享出来,互相学习
一般来说,我们更新,删除或者查询单个记录都是需要一个唯一键,例如id?别人可以编辑这个id的值获取其他记录的信息,这个时候我们可以加一个认证值给请求路径,防止只修改了id
即可认为是合法请求
下面上些代码
- <a href="#" onclick="removeById('/cms/user/removeById.do?id=${v.id}&rsv_=<@key id="${v.id}" />');return false;" style="cursor: pointer;">删除</a>
看到后面删除的参数有一个rsv_,这个是认证值,如果单独修改id的值,但是没有修改出相应的rsv_值那是认为是非法请求,因为id和rsv_是配套,通过一定算法出来的关联
而这里我的<@key id="${v.id}" /> 这个是我自定义的freemarker标签,相信看过前面的文章也知道该如何配置使用,下面我展示下生成的rsv_标签类
- package com.silvery.core.freemarker;
-
- import java.io.IOException;
- import java.util.Map;
-
- import com.silvery.utils.ShortLinkUtils;
-
- import freemarker.core.Environment;
- import freemarker.template.TemplateDirectiveBody;
- import freemarker.template.TemplateDirectiveModel;
- import freemarker.template.TemplateException;
- import freemarker.template.TemplateModel;
-
- /**
- *
- * FreeMarker自定义标签,生成编号认证
- *
- * @author shadow
- *
- */
- public class KeyTag implements TemplateDirectiveModel {
-
- @SuppressWarnings("unchecked")
- public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody directiveBody)
- throws TemplateException, IOException {
-
- Object id = params.get("id");
- validate(id, null);
-
- env.getOut().write(ShortLinkUtils.getSingleLink(id.toString()));
-
- }
-
- private void validate(Object id, Object body) throws TemplateException {
- if (id == null || id.toString().trim().equals("")) {
- throw new TemplateException("参数[id]不能为空", null);
- }
- }
-
- }
然后看我们的请求拦截器,如何判断是否合法请求
- package com.silvery.core.spring.handler;
-
- import java.text.SimpleDateFormat;
- import java.util.Date;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.web.servlet.HandlerInterceptor;
- import org.springframework.web.servlet.ModelAndView;
-
- import com.silvery.utils.ShortLinkUtils;
-
- public class SystemHandler implements HandlerInterceptor {
-
- private final static Logger log = LoggerFactory.getLogger(SystemHandler.class);
-
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object obj, Exception e)
- throws Exception {
- }
-
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object obj, ModelAndView view)
- throws Exception {
- }
-
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws Exception {
- return validateSafeRequest(request, response, obj);
- }
-
- /** 防止擅改数据提交 */
- private boolean validateSafeRequest(HttpServletRequest request, HttpServletResponse response, Object obj) {
- String newObj = request.getParameter("id");
- if (!isNull(newObj)) {
- String newToken = request.getParameter("rsv_");
- if (!isNull(newToken)) {
- if (ShortLinkUtils.getSingleLink(newObj).equals(newToken)) {
- return true;
- }
- }
- log.error(new StringBuffer().append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())).append(
- " [").append(obj).append("] ").append(" appear insecure request ").toString());
- return false;
- }
- return true;
- }
-
- private boolean isNull(String s) {
- if (s == null || s.length() <= 0) {
- return true;
- }
- return false;
- }
-
- }
这是spring-mvc的拦截器,当然你也可以用普通的filter,原理是一样
大概流程就是这样,相信大家都能理解,比较简单,比较实用,请随意喷,最多我去蓝翔再深造下回来咯...
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。