更新密碼--二階注入攻擊的原理

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
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/83075.shtml
英文地址,請注明出處:http://en.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…