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); 

<?php


echo '欢迎您成功进入到首页!';


?>
测试回显:

正确

错误

【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.cookielocation.hasheval())。

3)可以用工具扫描

相关推荐
2601_94980959几秒前
flutter_for_openharmony家庭相册app实战+我的Tab实现
java·javascript·flutter
Up九五小庞11 分钟前
开源埋点分析平台 ClkLog 本地部署 + Web JS 埋点测试实战--九五小庞
前端·javascript·开源
猷咪22 分钟前
C++基础
开发语言·c++
IT·小灰灰23 分钟前
30行PHP,利用硅基流动API,网页客服瞬间上线
开发语言·人工智能·aigc·php
快点好好学习吧25 分钟前
phpize 依赖 php-config 获取 PHP 信息的庖丁解牛
android·开发语言·php
秦老师Q26 分钟前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
烟锁池塘柳026 分钟前
解决Google Scholar “We‘re sorry... but your computer or network may be sending automated queries.”的问题
开发语言
是誰萆微了承諾26 分钟前
php 对接deepseek
android·开发语言·php
24zhgjx-lxq28 分钟前
华为ensp:MSTP
网络·安全·华为·hcip·ensp
2601_9498683630 分钟前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter