单点登录判断后乱码问题
2015-11-13 11:52
387 查看
刚才是 处理一个XSS漏洞问题:在提交表单的时候输入框中包含<script>alert("123")</script>等敏感高危字符串需要url转码。
这本是比较简单的事情,本来转码数据一样会存储到后台,只是显示数据的时候会出错,需要对<script>alert("123")</script>进行html转码再保存。
html 转码方式如下:
public static String HTMLEncode(String aTagFragment){
final StringBuffer result = new StringBuffer();
final StringCharacterIterator iterator = new StringCharacterIterator(aTagFragment);
char character = iterator.current();
while (character != StringCharacterIterator.DONE ){
if (character = = '<') {
result.append("<");
}
else if (character = = '>') {
result.append(">");
}
else if (character = = '\"') {
result.append(""");
}
else if (character = = '\") {
result.append("'");
}
else if (character = = '\\') {
result.append("\");
}
else if (character = = '&') {
result.append("&");
}
else {
//the char is not a special one
//add it to the result as is
result.append(character);
}
在修改前,我自己先测试以前的功能:结果发现输入中文会乱码。
难道项目以前都中文乱码?纠结郁闷开始测试调试开始了。
最后发现访问不要登录的地址,比如搜索模块,中文传输正常;需要登录的地址,比如保存纠错记录。
判定估计是登录拦截器有问题。
我们现在用的是单点登录。
过滤器中代码:
/**
* 从请求中获得参数值,而后去除掉一个参数后,组装成新的字符串返回。
*
* @param request
* 请求
* @param exceptParm
* 要去除掉的参数名。
* @return String 返回字符串
* */
public static String getParms(HttpServletRequest request) {
StringBuffer result = new StringBuffer();
Enumeration enumeration = request.getParameterNames();
String parmName = null;
while (enumeration.hasMoreElements()) {
parmName = enumeration.nextElement().toString();
if (!"sticket".equalsIgnoreCase(parmName)) {
result.append("&").append(parmName).append("=")
.append(request.getParameter(parmName));
}
}
if (request.getRequestURL().toString().indexOf("portaltype") == -1
&& result.toString().indexOf("portaltype") == -1) {
result.append("&").append("portaltype").append("=")
.append(request.getAttribute("portaltype"));
result.append("&").append("version").append("=")
.append(request.getAttribute("version"));
result.append("&").append("areacode").append("=")
.append(request.getAttribute("areacode"));
}
return result.toString();
}
public static String getDirectURL(String ssoserverURL,HttpServletRequest request) {
//ssoserverURL 为单点登录地址
String url = null;
if (ssoserverURL.indexOf('?') > 0) {
url = ssoserverURL + "backurl=" + request.getRequestURL()
+ getParms(request);
} else {
url = ssoserverURL + '?' + "backurl=" + request.getRequestURL()
+ getParms(request);
}
return url;
}
String redirectUrl = getDirectURL(ssomap.get("ssoserverURL"), request);
response.sendRedirect(redirectUrl);
从上面代码看出来,拦截器对request中参数都拼接成字符串传递给服务器。
如果单点服务器接收中文参数乱码或者登录回调后传递中文参数乱码;那么最终得到的结果肯定乱码。
得到结论:访问地址 需要单点登录判断的则不能传递中文参数。
最终解决方法:
页面form表单需要 uri编码:
orgstr=encodeURI(encodeURI(orgstr));
后台处理
orgstr=URLDecoder.decode(orgstr, "utf-8");
最后进行html编码:
orgstr=HTMLEncode(orgstr);
orgstr被保存到数据库。
测试:页面输入:<script>alert("你")</script>
保存数据的数据为:<script>alert("你")</script>
取出显示到页面显示为:<script>alert("你")</script>
输入和显示一致。perfect!
这本是比较简单的事情,本来转码数据一样会存储到后台,只是显示数据的时候会出错,需要对<script>alert("123")</script>进行html转码再保存。
html 转码方式如下:
public static String HTMLEncode(String aTagFragment){
final StringBuffer result = new StringBuffer();
final StringCharacterIterator iterator = new StringCharacterIterator(aTagFragment);
char character = iterator.current();
while (character != StringCharacterIterator.DONE ){
if (character = = '<') {
result.append("<");
}
else if (character = = '>') {
result.append(">");
}
else if (character = = '\"') {
result.append(""");
}
else if (character = = '\") {
result.append("'");
}
else if (character = = '\\') {
result.append("\");
}
else if (character = = '&') {
result.append("&");
}
else {
//the char is not a special one
//add it to the result as is
result.append(character);
}
在修改前,我自己先测试以前的功能:结果发现输入中文会乱码。
难道项目以前都中文乱码?纠结郁闷开始测试调试开始了。
最后发现访问不要登录的地址,比如搜索模块,中文传输正常;需要登录的地址,比如保存纠错记录。
判定估计是登录拦截器有问题。
我们现在用的是单点登录。
过滤器中代码:
/**
* 从请求中获得参数值,而后去除掉一个参数后,组装成新的字符串返回。
*
* @param request
* 请求
* @param exceptParm
* 要去除掉的参数名。
* @return String 返回字符串
* */
public static String getParms(HttpServletRequest request) {
StringBuffer result = new StringBuffer();
Enumeration enumeration = request.getParameterNames();
String parmName = null;
while (enumeration.hasMoreElements()) {
parmName = enumeration.nextElement().toString();
if (!"sticket".equalsIgnoreCase(parmName)) {
result.append("&").append(parmName).append("=")
.append(request.getParameter(parmName));
}
}
if (request.getRequestURL().toString().indexOf("portaltype") == -1
&& result.toString().indexOf("portaltype") == -1) {
result.append("&").append("portaltype").append("=")
.append(request.getAttribute("portaltype"));
result.append("&").append("version").append("=")
.append(request.getAttribute("version"));
result.append("&").append("areacode").append("=")
.append(request.getAttribute("areacode"));
}
return result.toString();
}
public static String getDirectURL(String ssoserverURL,HttpServletRequest request) {
//ssoserverURL 为单点登录地址
String url = null;
if (ssoserverURL.indexOf('?') > 0) {
url = ssoserverURL + "backurl=" + request.getRequestURL()
+ getParms(request);
} else {
url = ssoserverURL + '?' + "backurl=" + request.getRequestURL()
+ getParms(request);
}
return url;
}
String redirectUrl = getDirectURL(ssomap.get("ssoserverURL"), request);
response.sendRedirect(redirectUrl);
从上面代码看出来,拦截器对request中参数都拼接成字符串传递给服务器。
如果单点服务器接收中文参数乱码或者登录回调后传递中文参数乱码;那么最终得到的结果肯定乱码。
得到结论:访问地址 需要单点登录判断的则不能传递中文参数。
最终解决方法:
页面form表单需要 uri编码:
orgstr=encodeURI(encodeURI(orgstr));
后台处理
orgstr=URLDecoder.decode(orgstr, "utf-8");
最后进行html编码:
orgstr=HTMLEncode(orgstr);
orgstr被保存到数据库。
测试:页面输入:<script>alert("你")</script>
保存数据的数据为:<script>alert("你")</script>
取出显示到页面显示为:<script>alert("你")</script>
输入和显示一致。perfect!
相关文章推荐
- Maven创建web项目
- html常用标签
- java并发编程实战
- Objective-C基础语法快速入门
- 安装gcc及其依赖
- 倒计时恢复按钮点击
- oracle外键--详解
- w3wp占用CPU过高的解决过程(Dictionary和线程安全)
- Android安全专项测试之Dex2jar
- 第一章:Mysql负载均衡与主从复制实验
- java 集合的多线程
- IOS多线程之NSThread
- 单例:app activity 单例模式管理类
- Python中的None与 NULL(即空字符)的区别
- 防止表单重复提交 java
- 时间类初始的一些细节
- 在Eclipse添加Android兼容包( v4、v7 appcompat )
- Elements of Statistical Learning Ch.15 Random Forest 学习笔记
- linux运维30题
- iOS在支持arc的工程中,导入不支持arc的第三方的插件