CSRF 漏洞一般通过三种方式解决。
第一种是表单提交的时候增加token验证,这种改动比较大,适合新系统开发时采用。或者根据bug报告,给指定的请求增加token验证。
第二种是采用jwt的认证方式,在每次提交请求的时候必须带上jwt的认证信息。此种方式天然的杜绝了CSRF漏洞。但也适合新系统开发时使用。jspxcms在下一个版本的后台管理中,将使用jwt的认证方式。
第三种。针对已经开发好的系统,整体增加token验证不仅工作量巨大,而且可能引入新的bug。此时可以对POST
请求统一增加Referer
验证。
在jspxcms中,可以修改WEB-INF/classes/conf/conf.perperties
文件。
修改csrf.domains
的值,如系统部署在www.mysite.com
,则修改该配置为:
csrf.domains=www.mysite.com
要注意域名必须完全匹配,如www.mysite.com
不能写mysite.com
,127.0.0.1
不能写localhost
,多个域名用英文逗号
分开。如:
csrf.domains=www.mysite.com,localhost,127.0.0.1
添加之后,登陆没反应
你用什么域名访问的?这里添加了什么域名,就必须用什么域名访问。可以添加多个域名,如需本地访问,需要把本地的域名也加上去,如localhost。
csrf.domains=bggweb.com,localhost ,在本地报:CSRF Protection: Referer Illegal 错误,在服务器上用域名,就点击登陆按钮没有反应
稍等,我测试一下
经过测试,功能是没有问题的。要注意必须使用英文逗号,另外不要多余的空格之类的。域名也必须是完全匹配的域名,比如www.mysite.com
不能写mysite.com
,多个域名写法如下:csrf.domains=www.mysite.com,localhost,127.0.0.1
csrf.domains=localhost,127.0.0.1 我这么加了,在本地还是无法登录,一直都是403 您没有权限访问该页面,信息:CSRF Protection: Referer Illegal,而且登录接口 login.do 也是403状态
我们在本地测试过,没有问题。你用的是什么版本?
有关CSRF验证的类是com.jspxcms.core.support.CsrfFilter
调试一下以下代码,看看是哪里的问题。
private boolean verifyDomains(HttpServletRequest request) {
// 从 HTTP 头中取得 Referer 值
String referer = request.getHeader("Referer");
// 判断 Referer 是否以 合法的域名 开头。
if (referer != null) {
// 如 http://mysite.com/abc.html https://www.mysite.com:8080/abc.html
if (referer.indexOf("://") > 0) referer = referer.substring(referer.indexOf("://") + 3);
// 如 mysite.com/abc.html
if (referer.indexOf("/") > 0) referer = referer.substring(0, referer.indexOf("/"));
// 如 mysite.com:8080
if (referer.indexOf(":") > 0) referer = referer.substring(0, referer.indexOf(":"));
// 如 mysite.com
for (String domain : domains) {
if (referer.endsWith(domain)) return true;
}
}
return false;
}
找到问题了,应该是我用的版本问题,我这里的代码是 referer.substring(referer.indexOf("://") + 3)
改成referer=referer.substring(referer.indexOf("://") + 3)
就可以了