跨站脚本(Cross Site Scripting)漏洞一般称为XSS漏洞。通过在URL中传入参数或篡改http请求等手段插入一段javascript代码,这些内容输出到客户端后可以执行的话就是一个XSS漏洞。XSS漏洞是WEB应用最常见最容易出现的安全漏洞之一,其危害也是很大的,直接损失了访问应用的客户的信息,可能包括用户名/密码,信用卡之类的信息。幸好,这个漏洞相对来说是比较容易发现并且修正的。
归根结底,造成该漏洞的原因就是对外部输入的内容没有做任何处理就将内容再输出到了客户端。页面上的内容输出一般是在html元素属性,html内容和js代码片段中,因此该漏洞一般也是出现在这几个地方。
存在漏洞的代码示例
如前所述造成xss漏洞的原因就是将外部输入不加任何处理就直接输出到了客户端而导致脚本的执行,因此防范该漏洞的主要方法就是对用户输入进行过滤和验证并在输出时进行转义处理。而脚本要得到执行,主要是依靠标签,因此转义输出的处理核心是对标签进行处理,简单来说就是对尖括号(<>)进行转义。另外,一些表示结束的分隔符也需要注意转义,如单双引号,换车,回行等制表符。需要注意的是由于内容输出的位置不同,转义的内容也是略有区别的。
CMyString.filterForHTMLValue方法:
public static String filterForHTMLValue(String _sContent) {
if (_sContent == null) return "";
char[] srcBuff = _sContent.toCharArray();
int nLen = srcBuff.length;
if (nLen == 0) return "";
StringBuffer retBuff = new StringBuffer((int) (nLen * 1.8));
for (int i = 0; i < nLen; i++) {
char cTemp = srcBuff[i];
switch (cTemp) {
case '&': // 转化:& --> &
if ((i + 1) < nLen) {//&#nnnn;的形式不处理
cTemp = srcBuff[i + 1];
if (cTemp == '#'){
retBuff.append("&");
}else{
retBuff.append("&");
}
} else{
retBuff.append("&");
}
break;
case '<': // 转化:< --> <
retBuff.append("<");
break;
case '>': // 转化:> --> >
retBuff.append(">");
break;
case '\"': // 转化:" --> "
retBuff.append(""");
break;
default:
retBuff.append(cTemp);
}
}
return retBuff.toString();
}
CMyString.transDisplay方法:
public static String transDisplay(String _sContent, boolean _bChangeBlank) {
if (_sContent == null) return "";
char[] srcBuff = _sContent.toCharArray();
int nSrcLen = srcBuff.length;
StringBuffer retBuff = new StringBuffer(nSrcLen * 2);
for (int i = 0; i < nSrcLen; i++) {
char cTemp = srcBuff[i];
switch (cTemp) {
case ' ':
retBuff.append(_bChangeBlank ? " " : " ");
break;
case '<':
retBuff.append("<");
break;
case '>':
retBuff.append(">");
break;
case '\n':
if (_bChangeBlank){
retBuff.append("<br/>");
}else{
retBuff.append(cTemp);
}
break;
case '"':
retBuff.append(""");
break;
case '&':
retBuff.append("&");
break;
case 9: // Tab
retBuff.append(_bChangeBlank ? " "
: " ");
break;
default:
retBuff.append(cTemp);
}
}
if (_bChangeBlank) return retBuff.toString();
return replaceParasStartEndSpaces(retBuff.toString());
}
CMyString.filterForJs方法:
public static String filterForJs(String _sContent) {
if (_sContent == null) return "";
char[] srcBuff = _sContent.toCharArray();
int nLen = srcBuff.length;
if (nLen == 0) return "";
StringBuffer retBuff = new StringBuffer((int) (nLen * 1.8));
for (int i = 0; i < nLen; i++) {
char cTemp = srcBuff[i];
switch (cTemp) {
case '"': // 转化:" --> \"
retBuff.append("\\\"");
break;
case '\'': // 转化:' --> \'
retBuff.append("\\\'");
break;
case '\\': // 转化:\ --> \\
retBuff.append("\\\\");
break;
case '\n':
retBuff.append("\\n");
break;
case '\r':
retBuff.append("\\r");
break;
case '\f':
retBuff.append("\\f");
break;
case '\t':
retBuff.append("\\t");
break;
case '/':
retBuff.append("\\/");
break;
default:
retBuff.append(cTemp);
}
}
return retBuff.toString();
}