更新密码--二阶注入攻击的原理

1.原理知识:

二阶SQL注入攻击(Second-Order SQL Injection)原理详解

一、基本概念

二阶注入是一种"存储型"SQL注入,攻击流程分为两个阶段:

  1. ​首次输入​​:攻击者将恶意SQL片段存入数据库
  2. ​二次调用​​:当应用程序使用存储的数据构造SQL查询时触发攻击
二、典型攻击场景(以密码更新为例)

三、具体攻击步骤分解
  1. ​初始注入阶段​

    -- 攻击者注册特殊用户名
    INSERT INTO users(username) VALUES ('admin''-- ')

    存储结果

    idusername
    1admin'--
  2. ​触发阶段(密码更新操作)​

    // 应用代码示例(存在漏洞)
    $newPassword = $_POST['password'];
    $username = $_SESSION['username']; // 从会话获取"admin'--"$sql = "UPDATE users SET password='$newPassword' WHERE username='$username'";

    实际执行SQL

    UPDATE users SET password='hacked' 
    WHERE username='admin'-- '

    ​效果​​:

    • --注释掉了后续条件
    • 所有用户的密码被更新为hacked
四、与普通注入的关键区别
特性普通SQL注入二阶注入
触发时机即时执行延迟执行(数据被使用时)
输入点直接拼接的输入参数存储在数据库中的数据
防御难度较易检测更难发现
五、防御方案
1. 数据存储阶段
// 存入前转义+类型检查
$username = $pdo->quote($_POST['username']); 
// 或使用预处理
$stmt = $pdo->prepare("INSERT INTO users(username) VALUES (?)");
$stmt->execute([$_POST['username']]);
2. 数据使用阶段
// 永远使用参数化查询(即使数据来自数据库)
$stmt = $pdo->prepare("UPDATE users SET password=? WHERE username=?");
$stmt->execute([$newPassword, $dbStoredUsername]);
3. 深度防御措施
  • ​数据净化​​:在读取数据库后仍进行过滤
    function sanitizeDbValue($value) {return preg_replace('/[^\w@.-]/', '', $value); 
    }
  • ​权限分离​​:
    CREATE USER 'app_update'@'localhost' IDENTIFIED BY 'pass';
    GRANT UPDATE(password) ON db.users TO 'app_update'@'localhost';
    -- 无权限修改其他字段
4. 安全审计建议
-- 监控非常规模式
CREATE TRIGGER audit_password_changes 
AFTER UPDATE ON users
FOR EACH ROW
INSERT INTO audit_log VALUES(NEW.id, '密码变更', NOW());
六、实际案例检测

检测代码是否脆弱:

// 危险代码模式(可被二阶注入利用)
function updatePassword($conn, $newPass){$user = getUserFromDB(); // 从数据库获取用户名$conn->query("UPDATE users SET pass='$newPass' WHERE user='{$user['name']}'");
}// 安全版本
function safeUpdatePassword($pdo, $newPass){$user = getUserFromDB();$stmt = $pdo->prepare("UPDATE users SET pass=? WHERE user=?");$stmt->execute([$newPass, $user['name']]);
}
七、进阶防护:ORM层防护
// 使用Laravel Eloquent示例
User::where('name', $request->username)->update(['password' => bcrypt($request->password)]); 
// 自动参数化,无需手动处理

关键原则:​​所有来自外部和内部的数据在拼接SQL时都应视为不可信的​​,必须通过参数化查询处理。

2.更新密码的二阶注入攻击关系解释

用户注册的特殊账号会再更新密码的过程中引起二阶注入攻击。

更新密码场景下的二阶SQL注入攻击原理详解

一、攻击流程全貌(以密码更新为例)

二、关键漏洞形成原理
  1. ​第一次存储时的"无害"数据​

    -- 注册时(使用了参数化查询,此时安全)
    INSERT INTO users(username) VALUES('admin''--')

    数据库实际存储:

    idusername
    1admin'--
  2. ​密码更新时的危险拼接​

    // 漏洞代码示例
    $username = getUsernameFromDB(); // 获取存储的"admin'--"
    $newPass = $_POST['password'];// 直接拼接SQL(未使用参数化)
    $sql = "UPDATE users SET password='$newPass' WHERE username='$username'";

    生成的恶意SQL:

    UPDATE users SET password='hacked' 
    WHERE username='admin'-- '
  3. ​注入效果​

    • --注释掉了原SQL的条件部分
    • 语句等效于:
      UPDATE users SET password='hacked'
    • ​所有用户的密码被修改​
三、与传统注入的核心区别
特性传统注入二阶注入
输入点直接来自HTTP请求来自数据库存储的数据
触发条件立即执行需要特定业务逻辑触发
防御盲区输入过滤即可防御需要全程参数化
检测难度容易被扫描器发现需要业务流分析
四、完整攻击实例分析
  1. ​攻击准备阶段​

    POST /register HTTP/1.1
    username=admin'--&password=123
    • 后端安全地存储了该用户名(此时无风险)
  2. ​触发攻击阶段​

    POST /update-password HTTP/1.1
    new_password=hacked
    • 后端操作流程:
      // 从数据库获取当前用户名
      $user = $db->query("SELECT username FROM users WHERE id = {$_SESSION['id']}")->fetch();// 危险操作:拼接SQL
      $db->exec("UPDATE users SET password='hacked' WHERE username='{$user['username']}'");
  3. ​实际执行的恶意SQL​

    UPDATE users SET password='hacked' 
    WHERE username='admin'-- '
五、针对性防御方案
1. 存储阶段防御
// 注册时严格过滤
function validateUsername($name) {return preg_match('/^[a-z0-9_]{3,20}$/i', $name);
}// 使用预处理语句存储
$stmt = $pdo->prepare("INSERT INTO users(username) VALUES(?)");
$stmt->execute([$_POST['username']]);
2. 使用阶段防御
// 密码更新操作(安全版本)
function updatePassword($userId, $newPass) {$pdo = new PDO(...);// 步骤1:获取用户名(使用参数化)$stmt = $pdo->prepare("SELECT username FROM users WHERE id = ?");$stmt->execute([$userId]);$user = $stmt->fetch();// 步骤2:更新密码(再次参数化)$stmt = $pdo->prepare("UPDATE users SET password = ? WHERE username = ?");$stmt->execute([password_hash($newPass, PASSWORD_BCRYPT), $user['username']]);
}
3. 深度防御措施
  • ​数据库权限隔离​

    CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'pass';
    GRANT SELECT, UPDATE(password) ON db.users TO 'app_user'@'localhost';
    -- 禁止修改username等其他字段
  • ​审计日志​

    CREATE TRIGGER password_change_audit
    AFTER UPDATE ON users
    FOR EACH ROW
    INSERT INTO security_log VALUES(USER(), CONCAT('Password changed for ', OLD.username),NOW()
    );
六、漏洞检测方法
  1. ​代码审计关键点​

    • 查找所有从数据库读取数据后直接拼接SQL的地方
    • 特别关注:用户资料更新、密码重置、权限变更等敏感操作
  2. ​自动化测试脚本​

# 二阶注入测试脚本示例
def test_second_order_injection():# 注册测试账号register("test'--", "123456")# 修改密码resp = update_password("new_password")# 验证是否所有用户密码被修改admin_pass = get_password("admin")assert admin_pass == "new_password"  # 如果成立说明漏洞存在
七、现代框架的最佳实践
// Laravel示例(自动防护二阶注入)
User::where('username', $request->username)->update(['password' => bcrypt($request->new_password)]);
// Eloquent ORM自动使用参数化查询// 即使这样也是安全的:
$user = User::find($id);
DB::update("UPDATE users SET password = ? WHERE username = ?", [$newPass, $user->username]);

关键安全原则:​​无论数据来自HTTP请求还是数据库,在拼接SQL时永远使用参数化查询​​。这种防御方式能同时防护一阶和二阶SQL注入攻击。

3.建立具有密码更新功能的网站

前端html页面+后端php页面

3.1用户注册页面(html)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Register</title>
<style>#a{ width: 300px; text-align: right; }.b{width: 150px;height:20px;}
</style>
</head>
<body><div id=a><form name="form_register" method="post" action="check_register.php">Username: <input type="text" class=b name="username" /> <br>Psssword: <input type="password"  class=b name="passwd" /> <br><input type="submit" name="Submit" value="Submit" /> <input type="reset" name="Reset" value="Reset" /></form></div>
</body>
</html>

3.1实现注册功能(php)

<?php
//包含数据库连接
include('con_database.php');//获取输入的信息
$username = isset($_POST['username']) ? mysqli_escape_string($con,$_POST['username']) : '';
$passwd = isset($_POST['passwd']) ? mysqli_escape_string($con, $_POST['passwd']) : '';
if($username == '' || $passwd == '' ) 
{ echo "<script>alert('信息不完整!'); history.go(-1);</script>"; exit;
}
//执行数据库查询,判断用户是否已经存在
$sql="select * from users where username = '$username' ";$query = mysqli_query($con,$sql)
or die('SQL语句执行失败, : '.mysqli_error($con));$num = mysqli_fetch_array($query); //统计执行结果影响的行数 
if($num)    //如果已经存在该用户 
{ echo "<script>alert('用户名已存在!'); history.go(-1);</script>"; exit;
}  $sql = "insert into users (username,passcode) values('$username','$passwd')"; mysqli_query($con, $sql)
or die('注册失败,  : '.mysqli_error($con));echo "注册成功,请<a href='login.html'>登录</a>";mysqli_close($con);
?>

3.3登录验证(php)

<?php
//包含数据库连接
include('con_database.php');
//获取输入的信息
$username = isset($_POST['username']) ? mysqli_escape_string($con,$_POST['username']) : '';
$passwd = isset($_POST['passwd']) ? mysqli_escape_string($con, $_POST['passwd']) : '';
if($username == '' || $passwd == '' ) 
{ echo "<script>alert('请输入用户名和密码!'); history.go(-1);</script>"; exit;
}//从数据库查询
$sql = "select * from users where username = '$username' and passcode = '$passwd' ";
$res = mysqli_query($con,$sql) or die('SQL语句执行失败, : '.mysqli_error($con));
$row = mysqli_fetch_row($res);if ($row[0]) 
{session_start();$_SESSION['username'] = $row[1];echo $row[1].'欢迎访问!';echo "<br>";echo "<a href='updatepasswd.html'>修改密码</a>";
}
else
{echo "<script>alert('用户名或密码错误!'); history.go(-1);</script>"; 
}
mysqli_close($con);
?>

3.4更新密码 (html)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>UpdatePassword</title>
<style>#a{ width: 300px; text-align: right; }.b{width: 150px;height:20px;}
</style>
</head>
<body><div id=a><form name="form_register" method="post" action="updatepasswd_mysqli.php">当前密码: <input type="text" class=b name="current_passwd" /> <br>新密码: <input type="password"  class=b name="passwd" /> <br><input type="submit" name="Submit" value="Submit" /> <input type="reset" name="Reset" value="Reset" /></form></div>
</body>
</html>

3.5更新密码功能(php)

<?php
session_start();
if(!isset($_SESSION['username']))
{//重新定位到注册页面header('Location: register.html');	
}
if (isset($_POST['Submit'])){//包含数据库连接include("con_database.php");//	$username = $_SESSION['username'];$username = mysqli_real_escape_string($con,$_SESSION['username']);$curr_pass= mysqli_real_escape_string($con,$_POST['current_passwd']);$pass= mysqli_real_escape_string($con,$_POST['passwd']);$sql = "UPDATE users SET passcode = '$pass' WHERE username = '$username' and passcode = '$curr_pass' ";$res = mysqli_query($con,$sql) or die('SQL执行失败 :'.mysqli_error($con));$row = mysqli_affected_rows($con);if($row != 0){echo "<script>alert('密码更改成功!'); history.go(-1);</script>"; 	}else{echo "<script>alert('当前密码错误!'); history.go(-1);</script>"; 	}
}
mysqli_close($con);
?>

4.用户使用功能测试

检查apache打开

报错,原因是我是双击打开的html,应该用http协议打开

注册之后需要用到登录页面

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Login</title>
<style>#a{ width: 300px; text-align: right;}.b{width: 150px;height:20px;}
</style>
</head>
<body><div id=a><form name="form_login" method="post" action="check_login.php">Username: <input type="text" class=b name="username" /> <br>Psssword: <input type="password"  class=b name="passwd" /> <br><input type="submit" name="Submit" value="Submit" /> <input type="reset" name="Reset" value="Reset" /></form></div>
</body>
</html>

修改密码,用到updatepasword

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/83075.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在 WSL Ubuntu-24.04 上安装 Nacos 2.5.1 并使用 MySQL 数据库

在微服务架构中&#xff0c;Nacos 是一个非常重要的服务发现和配置管理工具。本文将详细介绍如何在 WSL&#xff08;Windows Subsystem for Linux&#xff09;中的 Ubuntu-24.04 系统上安装 Nacos 2.5.1&#xff0c;并将其配置为使用 MySQL 数据库进行数据存储。我们将使用 roo…

2.qml使用c++

目录 1.概述2.注册方式3. 分类①枚举类②工具类③数据类④资源类②视图类 1.概述 qml是用来干嘛的&#xff1f; 当然是提高UI开发效率的 为什么要混合C&#xff1f; 因为qml无法处理密集型数据逻辑 而加入c则兼顾了性能 达到11>2 总结就是 qml 开发UI, C 实现逻辑 而js的用…

位置规划模式和周期同步位置模式区别

专业方向&#xff1a; 伺服电机位置控制模式&#xff08;电气自动化&#xff09; 标题解释 位置规划模式&#xff08;Profile Position Mode&#xff0c;PP&#xff09;和周期同步位置模式&#xff08;Cyclic Synchronous Position Mode&#xff0c;CSP&#xff09;区别。 常规…

C# ToString格式说明符

货币 "C"或"c" //C Console.WriteLine(666.ToString("C"));//&#xffe5;666.00//C数字 表示保留几位小数精度 Console.WriteLine(666.ToString("C1"));//&#xffe5;666.0 Console.WriteLine(666.ToString("C3"));//&…

基本数据指针的解读-C++

1、引言 笔者认为对于学习指针要弄清楚如下问题基本可以应付大部分的场景&#xff1a; ① 指针是什么&#xff1f; ② 指针的类型是什么&#xff1f; ③ 指针指向的类型是什么&#xff1f; ④ 指针指向了哪里&#xff1f; 2、如何使用指针 使用时的步骤如下&#xff1a; ① …

【Elasticsearch】suggest_mode

suggest_mode 是 Elasticsearch 中 term suggester 和 phrase suggester 的一个参数&#xff0c;用于控制建议的生成方式。它有以下三种模式&#xff1a; 1. missing&#xff1a;默认值。仅对索引中不存在的词项提供建议。如果输入的词已经在索引中存在&#xff0c;则不会生成建…

九、【前后端联调篇】Vue3 + Axios 异步通信实战

九、【前后端联调篇】Vue3 Axios 异步通信实战 前言准备工作第一步&#xff1a;安装 Axios第二步&#xff1a;封装 Axios 实例第三步&#xff1a;创建 API 服务模块第四步&#xff1a;在组件中调用 API第五步&#xff1a;测试前后端联调 总结 前言 在 Web 开发中&#xff0c;…

【计算机网络】传输层TCP协议——协议段格式、三次握手四次挥手、超时重传、滑动窗口、流量控制、

&#x1f525;个人主页&#x1f525;&#xff1a;孤寂大仙V &#x1f308;收录专栏&#x1f308;&#xff1a;计算机网络 &#x1f339;往期回顾&#x1f339;&#xff1a; 【计算机网络】传输层UDP协议 &#x1f516;流水不争&#xff0c;争的是滔滔不息 一、TCP协议 UDP&…

php:5.6-apache Docker镜像中安装 gd mysqli 库 【亲测可用】

Dockerfile 代码如下&#xff1a; FROM php:5.6-apache# 使用Debian归档源 RUN echo "deb http://archive.debian.org/debian stretch main contrib non-free" > /etc/apt/sources.list && \echo "deb http://archive.debian.org/debian-security s…

动态设置微信小程序页面标题(navigationBarTitleText属性)

前言&#xff1a; 最近在公司进行小程序研发的时候&#xff0c;产品给出了一个动态加载页面标题的需求&#xff0c;经过调研之后将结果在这里与各位伙伴进行分享。 代码展示&#xff1a; 在.json文件中进行初始配置&#xff1a; { "usingComponents": {}, &q…

从0开始学习R语言--Day12--泊松分布

今天我们来看一个很经典的回归模型&#xff1a;泊松分布。 泊松分布 我们一般会把泊松分布用于预测问题&#xff0c;比如想知道成年人每天接到的骚扰电话次数&#xff0c;医院每天的急诊病人等。但在一些方面&#xff0c;跟我们想的会有出入。例如你不能将其应用在预测下周你的…

k8s中kubeSphere的安装使用+阿里云私有镜像仓库配置完整步骤

一、实验目的 1、掌握kubeSphere 的安装部署 2、掌握kubesphere 使用外部镜像仓库&#xff1b; 2、熟悉图像化部署任务&#xff1a;产生pod---定义服务--验证访问 本次实验旨在通过 KubeSphere 平台部署基于自定义镜像&#xff08;nginx:1.26.0 &#xff09;的有状态副本集…

STM32单片机简介

1.基本情况 STM32单片机正如其名是32位微控制器&#xff0c;相较于51单片机的8位微控制器&#xff0c;性能会更好&#xff0c;但学习难度也会提高。 在stm32单片机中内核时核心部分&#xff0c;是ARM公司设计的&#xff0c;其在stm32单片机中占据极为重要的地位。(程序指令的…

GESP】C++一级考试大纲知识点梳理(1)

计算机基础和操作系统 GESP C++一级官方考试大纲中,除可通过编码掌握的Dev C++开发工具的使用和C++编程基础语法知识外(考纲2-13),还涉及计算机基础知识的要求(考纲1): (1)了解计算机的基本构成(CPU,内存,I/O 设备等) ,了解 Windows、Linux等操作系统基本概念和常…

浅谈 JavaScript 性能优化

文章目录 概要一、代码执行优化1. 减少全局变量访问2. 避免不必要的计算3. 优化循环操作 二、内存管理优化1. 减少内存泄漏2. 对象池与内存复用 三、渲染性能优化1. 避免强制同步布局2. 减少 DOM 操作3. 优化动画与合成 四、网络加载优化1. 代码压缩与 Tree Shaking2. 按需加载…

mongodb nosql数据库笔记

MongoDB 简介 MongoDB 是一个开源的 NoSQL 数据库&#xff0c;采用文档存储模型&#xff08;BSON 格式&#xff0c;类似 JSON&#xff09;&#xff0c;支持高灵活性、水平扩展和高性能的数据操作。与传统关系型数据库&#xff08;如 MySQL&#xff09;不同&#xff0c;MongoDB…

Flutter实现不规则瀑布流布局拖拽重排序

因为业务&#xff0c;所以需要用flutter去实现一种不规则图形的瀑布流&#xff0c;但是同时需要支持拖拽并重新排序。效果类似如下。 查询过现有的插件&#xff0c;要么是仅支持同样大小的组件进行排序&#xff0c;要么就是动画效果不是很满意&#xff0c;有点死板&#xff0c;…

微信小程序(uniapp)实现腾讯云 IM 消息撤回

uniapp 实现腾讯云 IM 消息撤回功能实战指南 一、功能实现原理 腾讯云 IM 的消息撤回功能通过 消息修订&#xff08;Message Revision&#xff09; 机制实现&#xff0c;核心流程如下&#xff1a; 发送方调用撤回 API 删除指定消息云端生成撤回通知消息&#xff08;类型为 T…

AI入门示例

市面上有很多AI大模型&#xff0c;这里以 智谱的大模型 为示例 1.先要注册智谱AI开放平台 2.注册成功后&#xff0c;会赠送3个月的免费额度&#xff0c;如下 3.然后去控制台&#xff0c;创建一个API KEY 4.接着就可以开始写代码了 提前导入包&#xff1a; openai 示例1&…

【数据结构】单链表练习

1.链表的中间节点 https://leetcode.cn/problems/middle-of-the-linked-list/description/ 用快慢指针来解决 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* middleNode(struct ListNode* he…