常见WEB安全漏洞及整改建议.doc
《常见WEB安全漏洞及整改建议.doc》由会员分享,可在线阅读,更多相关《常见WEB安全漏洞及整改建议.doc(28页珍藏版)》请在冰豆网上搜索。
![常见WEB安全漏洞及整改建议.doc](https://file1.bdocx.com/fileroot1/2022-10/7/bdb4ebaa-89ee-4cbb-892a-e5527a04242a/bdb4ebaa-89ee-4cbb-892a-e5527a04242a1.gif)
常见WEB安全漏洞及整改建议
1.HTML表单没有CSRF保护
1.1问题描述:
CSRF(Cross-siterequestforgery),中文名称:
跨站请求伪造,也被称为:
oneclickattack/sessionriding,缩写为:
CSRF/XSRF。
CSRF攻击:
攻击者盗用了你的身份,以你的名义发送恶意请求。
CSRF能够做的事情包括:
以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账……造成的问题包括:
个人隐私泄露以及财产安全。
1.2整改建议:
CSRF的防御可以从服务端和客户端两方面着手,防御效果是从服务端着手效果比较好,现在一般的CSRF防御也都在服务端进行。
有以下三种方法:
(1).CookieHashing(所有表单都包含同一个伪随机值):
(2).验证码
(3).One-TimeTokens(不同的表单包含一个不同的伪随机值)
1.3案例:
1.服务端进行CSRF防御
服务端的CSRF方式方法很多样,但总的思想都是一致的,就是在客户端页面增加伪随机数。
1.3.1CookieHashing(所有表单都包含同一个伪随机值):
这可能是最简单的解决方案了,因为攻击者不能获得第三方的Cookie(理论上),所以表单中的数据也就构造失败.
//构造加密的Cookie信息
$value=“DefenseSCRF”;
setcookie(”cookie”,$value,time()+3600);
?
>
在表单里增加Hash值,以认证这确实是用户发送的请求。
$hash=md5($_COOKIE['cookie']);
?
>
”>
然后在服务器端进行Hash值验证
if(isset($_POST['check'])){
$hash=md5($_COOKIE['cookie']);
if($_POST['check']==$hash){
doJob();
}else{
//…
}
}else{
//…
}
?
>
这个方法已经可以杜绝99%的CSRF攻击了,那还有1%….由于用户的Cookie很容易由于网站的XSS漏洞而被盗取,这就另外的1%。
一般的攻击者看到有需要算Hash值,基本都会放弃了,某些除外,所以如果需要100%的杜绝,这个不是最好的方法。
1.3.2验证码
这个方案的思路是:
每次的用户提交都需要用户在表单中填写一个图片上的随机字符串,这个方案可以完全解决CSRF,但在易用性方面似乎不是太好,还有是验证码图片的使用涉及了一个被称为MHTML的Bug,可能在某些版本的微软IE中受影响。
1.3.3One-TimeTokens(不同的表单包含一个不同的伪随机值)
在实现One-TimeTokens时,需要注意一点:
就是“并行会话的兼容”。
如果用户在一个站点上同时打开了两个不同的表单,CSRF保护措施不应该影响到他对任何表单的提交。
考虑一下如果每次表单被装入时站点生成一个伪随机值来覆盖以前的伪随机值将会发生什么情况:
用户只能成功地提交他最后打开的表单,因为所有其他的表单都含有非法的伪随机值。
必须小心操作以确保CSRF保护措施不会影响选项卡式的浏览或者利用多个浏览器窗口浏览一个站点。
以下实现:
1).先是令牌生成函数(gen_token()):
functiongen_token(){
//这是贪方便,实际上单使用Rand()得出的随机数作为令牌,也是不安全的。
//这个可以参考写的Findbugs笔记中的《Randomobjectcreatedandusedonlyonce》
$token=md5(uniqid(rand(),true));
return$token;
}
2).然后是Session令牌生成函数(gen_stoken()):
functiongen_stoken(){
$pToken=“”;
if($_SESSION[STOKEN_NAME]==$pToken){
//没有值,赋新值
$_SESSION[STOKEN_NAME]=gen_token();
}
else{
//继续使用旧的值
}
}
?
>
3).WEB表单生成隐藏输入域的函数:
functiongen_input(){
gen_stoken();
echo“<=""p=""style="padding:
0px;margin:
0px;font-size:
12px;font-family:
宋体;">
value=\””.$_SESSION[STOKEN_NAME].“\”>“;
}
?
>
4).WEB表单结构:
session_start();
include(”functions.php”);
?
>
5).服务端核对令牌:
2.jQuery跨站脚本漏洞
2.1问题描述
jQuery是继prototype之后又一个优秀的Javascrīpt框架。
jQuery1.6.3之前版本中存在跨站脚本漏洞。
当使用location.hash选择元素时,通过特制的标签,远程攻击者利用该漏洞注入任意web脚本或HTML。
2.2整改方法
目前厂商已经发布了升级补丁以修复此安全问题,补丁获取链接:
2.3整改案例
升级jQuery版本。
3.跨站脚本编制
3.1问题描述:
跨站脚本攻击是通过在网页中加入恶意代码,当访问者浏览网页时恶意代码会被执行或者通过给管理员发信息的方式诱使管理员浏览,从而获得管理员权限,控制整个网站。
攻击者利用跨站请求伪造能够轻松地强迫用户的浏览器发出非故意的HTTP请求,如诈骗性的电汇请求、修改口令和下载非法的内容等请求。
风险等级:
高
风险范围:
任何存在输入/输出方法(包括GET与POST)的页面皆可能存在恶意符号输入缺陷,主要影响应用包括留言板、在线通讯信息、文章发布页面等。
3.2整改建议:
对用户输入的参数执行严格检测:
1、对产生漏洞模块的传入参数进行有效性检测。
int类型的只允许0-9的整型数字;string等字符类型的只允许(1-9,a-z,A-Z)的英文字母;
2、当客户端输入限定值意外的字符后,立即转向自定义的错误页,而不能使用服务器默认的错误输出方式;
3、对穿入参数进行危险字符过滤,禁止('、"、+、%、&、<>、()、;、,.等)特殊字符的传入。
3.3案例:
加固范例
(一):
/*将login.jsp中[Stringu=request.getParameter("u");]替换为如下内容:
*/
Stringu=request.getParameter("u");
u=u.replace('<','_');
u=u.replace('>','_');
u=u.replace('"','_');
u=u.replace('\'','_');
u=u.replace('%','_');
u=u.replace(';','_');
u=u.replace('(','_');
u=u.replace(')','_');
u=u.replace('&','_');
u=u.replace('+','_');
加固范例
(二):
/*更积极的方式是利用正则表达式只允许输入指定的字符:
*/
/*在[Stringu=request.getParameter("u");]后代入以下isValidInput函数作辨别*/
publicbooleanisValidInput(Stringstr)
{
if(str.matches("[a-z0-9]+"))returntrue;
elsereturnfalse;
}
4.URL重定向钓鱼
4.13.1问题描述:
通过构建URL,攻击者可以使用户重定向到任意URL,利用这个漏洞可以诱使用户访问某个页面,挂马、密码记录、下载任意文件等,常被用来钓鱼。
4.23.2整改建议:
对输入参数进行做处理,建议过滤出所有以下字符:
[1]|(竖线符号)
[2]&(&符号)
[3];(分号)
[4]$(美元符号)
[5]%(百分比符号)
[6]@(at符号)
[7]'(单引号)
[8]"(引号)
[9]\'(反斜杠转义单引号)
[10]\"(反斜杠转义引号)
[11]<>(尖括号)
[12]()(括号)
[13]+(加号)
[14]CR(回车符,ASCII0x0d)
[15]LF(换行,ASCII0x0a)
[16],(逗号)
[17]\(反斜杠)
4.33.3案例:
对输入参数进行做处理。
加固范例
(一):
/*将login.jsp中[Stringu=request.getParameter("u");]替换为如下内容:
*/
Stringu=request.getParameter("u");
u=u.replace('<','_');
u=u.replace('>','_');
u=u.replace('"','_');
u=u.replace('\'','_');
u=u.replace('%','_');
u=u.replace(';','_');
u=u.replace('(','_');
u=u.replace(')','_');
u=u.replace('&','_');
u=u.replace('+','_');
加固范例
(二):
/*更积极的方式是利用正则表达式只允许输入指定的字符:
*/
/*在[Stringu=request.getParameter("u");]后代入以下isValidInput函数作辨别*/
publicbooleanisValidInput(Stringstr)
{