Day28 -js开发01 -JS三个实例:文件上传 登录验证 购物商城 ---逻辑漏洞复现 及 判断js的payload思路
本篇利用3个实例 来引出前端验证的逻辑漏洞
一、文件上传
实例:利用JS实现
【1】代码实现
js:文件后缀筛选
php:文件保存
00x1 先利用js文件上传
就利用之前php原生写的upload.html的模板,再加上script的后缀过滤。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>文件上传页面</title><style>body {font-family: Arial, sans-serif;background-color: #f2f2f2;padding: 20px;}h1 {text-align: center;margin-top: 50px;}form {background-color: #fff;border-radius: 10px;padding: 20px;margin-top: 30px;max-width: 600px;margin: 0 auto;}input[type="file"] {margin-top: 20px;margin-bottom: 20px;}button {background-color: #4CAF50;color: #fff;padding: 10px 20px;border: none;border-radius: 5px;cursor: pointer;}button:hover {background-color: #3e8e41;}</style>
</head>
<body>
<h1>文件上传</h1>
<form action="upload.php" method="POST" enctype="multipart/form-data"><label for="file">选择文件:</label><br><!-- CheckFileExt当用户选择文件时触发验证函数 this.value获取完整文件名--><input type="file" id="file" name="f" onchange="CheckFileExt(this.value)"><br><button type="submit">上传文件</button>
</form><script>function CheckFileExt(filename){var flag=false;//规定白名单上传后缀var exts=['png','gif','jpg'];//1.php 1.php.jpg 接受传递的后缀名var index=filename.lastIndexOf("."); <!-- 查找最后一个点号位置 取.及后面为后缀-->var ext = filename.substr(index+1); <!-- index+1是把点号去除掉-->//进行后缀检测for(i=0;i<exts.length;i++){if(ext==exts[i]){var flag=true;alert('文件后缀正确!');break;}}if(!flag){alert('文件后缀错误!')location.reload(true);}}</script></body>
</html>
00x2 php实现文件存储
之前写原生php文件上传时候的代码拿来复用。
创建一个upload文件夹
<?php// 从前端表单提取出来的信息,利用全局变量进行提出
$name=$_FILES['f']['name'];
$type=$_FILES['f']['type'];
$size=$_FILES['f']['size'];
$tmp_name=$_FILES['f']['tmp_name'];
$error=$_FILES['f']['error'];if(move_uploaded_file($tmp_name, 'upload/' . $name)){echo '<script>alert("上传成功!")</script>';
}
查看结果,也是将上传内容成功实现存储。
【2】利用JS前端验证衍生的安全问题
1)过滤代码能被看到 进行代码审计白盒绕过
js属于前端语言,意味着我们刚刚做的过滤限制是可以在前端被看到的,更进一步说明了用户可以白盒我们的页面,去进行过滤绕过。
2)可通过禁用JS / 删除过滤代码绕过
法1: 禁用JS
浏览器中可以直接禁止js
怎么把网页的js关闭 | PingCode智库
【后续也要讲js的调试,很重要】
法2: 删除过滤代码
CSRF漏洞原理攻击与防御(非常细)-CSDN博客
漏洞复现:
step1、将前端源码复制到本地
step2、将源码中与过滤相关的函数 / 操作删除
step3、将新构建的前端页面的路径替换成实际可以上传到的路径
step4、验证
保存后将新构建的前端直接拖入浏览器,进行上传,上传在白名单之外的文件类型,查看是否成功(有js框提示上传成功 & upload文件夹里确实传入了非白名单类型的文件)
二、登录页面
实例1:利用JS实现登录页面
【1】代码实现
逻辑:首先借用之前我们原生php开发时候的优雅的html前端页面 ---> 然后进行js的代码编写,利用ajax将用户输入数据传递给后端进行验证的php文件 ---> 后端php写一个从数据库里提取用户信息并与接收到的进行对比的逻辑 (若有信息,则跳转index首页 ;若无信息,无操作)
00x1 先利用js实现前端页面
00x2 php进行用户信息后端验证
实际情况应该是连接数据库,在库中存储的数据与用户提交的数据进行对比,我这里写死给了一个用户信息。再简单的给一个首页文件
<?php
header('Content-Type: application/json'); // 明确声明返回JSON$user=$_POST['myuser'];
$pass=$_POST['mypass'];
//真实情况需要在数据库获取
$success=array('msg'=>'ok');
if($user=='xiaodi' && $pass=='123456'){$success['infoCode']=1;
}else{$success['infoCode']=0;
}
echo json_encode($success);
<?phpecho '欢迎您成功进入到首页!';?>
测试回显:
正确
错误
【2】写法中的安全问题 ---存在逻辑漏洞
漏洞原理:我们刚刚是将跳转写在了前端,意思是我们可以在前端获取到由后端php验证返回的json数据包,是这样的结构:{msg: 'ok', infoCode: 1 / 0},所以我们可以先输入正确的一个账密(字典爆破 / 暴力破解 ),拿到了账密正确返回的json数据包,bp抓一个任意用户的包,将json包改为可以正确登录的包,就可以实现任意用户登录。
00x1 输入正确的账密 拿到正确登录的json包
{msg: 'ok', infoCode: 1}
00x2 输入错误的登录信息
00x3 进行bp抓包拦截
抓到有响应包,将正确的替换错误json包
{msg: 'ok', infoCode: 1}
放行,看login.html的回显
【3】如何防止这种安全问题
我们刚刚在前端js中,确认code值为1后直接进行了跳转首页的操作,这个就是我们刚刚复现逻辑漏洞的主要原因,那么我们将跳转放到后端php文件中(服务器中),就算被替换了json数据包的值,但是真正的验证跳转是在服务器中,前端code为1没用只提示登陆成功但是没有任何操作,得是服务器中code值为1才会跳转。
没有跳转,也就不会触发任意用户登录。
三、购物商城
1、代码实现
思路:先构建一个前端页面,ajax去后端php文件进行逻辑判断,但是还是在前端按照infocode值去决定购买成功(1)与失败(0)
前端:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>商品购买</title>
</head>
<body>
<img src="iphone.png" width="300" height="300" alt=""><br>
金钱:10000<br>
商品价格:8888<br>
数量:<input type="text" name="number" class="number">
<button>购买</button>
</body>
</html><script src="js/jquery-1.12.4.js"></script>
<script>$("button").click(function (){$.ajax({type: 'POST',url: 'shop.php',data: {num:$('.number').val(),},success: function (res){console.log(res);if(res['infoCode']==1){alert('购买成功');//购买成功的流程}else{alert('购买失败');}},dataType: 'json',});});
</script>
后端:
<?php$num = $_POST['num']; // 将前端的num以遍历num接收//真实情况需要在数据库获取
$success = array('msg' => 'ok');
if (10000>=($num*8888)) { // 进行总价与1w对比$success['infoCode'] = 1;
} else {$success['infoCode'] = 0;
}
echo json_encode($success);
验证:
2、逻辑漏洞利用
{msg: 'ok', infoCode: 1}
四、总结
1、如何判断js是否存在
F12 看网页文件 / 右击检查 看源码 里面有无js代码
2、如何敏锐察觉js可能存在安全隐患
1)如果在js代码中写了判断逻辑(有注释 / 很多代码)就引起重视【前端验证】
2)优先关注高敏感代码:任何涉及用户输入,URL参数,Cookie,LocalStorage的代码(如 document.cookie
、location.hash
、eval()
)。
3)可以用工具扫描