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)可以用工具扫描

相关推荐
用户962377954484 小时前
DVWA 靶场实验报告 (High Level)
安全
炫饭第一名4 小时前
速通Canvas指北🦮——基础入门篇
前端·javascript·程序员
进击的尘埃6 小时前
Vue3 响应式原理:从 Proxy 到依赖收集,手撸一个迷你 reactivity
javascript
willow6 小时前
JavaScript数据类型整理1
javascript
LeeYaMaster6 小时前
20个例子掌握RxJS——第十一章实现 WebSocket 消息节流
javascript·angular.js
UIUV7 小时前
RAG技术学习笔记(含实操解析)
javascript·langchain·llm
数据智能老司机7 小时前
用于进攻性网络安全的智能体 AI——在 n8n 中构建你的第一个 AI 工作流
人工智能·安全·agent
数据智能老司机7 小时前
用于进攻性网络安全的智能体 AI——智能体 AI 入门
人工智能·安全·agent
颜酱8 小时前
理解二叉树最近公共祖先(LCA):从基础到变种解析
javascript·后端·算法
用户962377954489 小时前
DVWA 靶场实验报告 (Medium Level)
安全