Java 中 SQL 注入問題剖析?

一、引言?

在當今數字化時代,數據是企業和組織的核心資產之一。許多應用程序都依賴于數據庫來存儲和管理數據,而 Java 作為一種廣泛使用的編程語言,常被用于開發與數據庫交互的應用程序。然而,SQL 注入這一安全漏洞卻如同隱藏在暗處的炸彈,時刻威脅著這些應用程序的數據安全。?

二、SQL 注入的原因?

2.1 拼接 SQL 語句?

在 Java 應用程序中,當開發人員直接將用戶輸入的數據拼接到 SQL 語句中時,就為 SQL 注入攻擊埋下了隱患。以下是一個簡單的示例代碼:?

import java.sql.Connection;?

import java.sql.DriverManager;?

import java.sql.ResultSet;?

import java.sql.Statement;?

import java.util.Scanner;?

?

public class SQLInjectionExample {?

public static void main(String[] args) {?

try {?

Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testdb", "root", "password");?

Scanner scanner = new Scanner(System.in);?

System.out.println("請輸入用戶名:");?

String username = scanner.nextLine();?

System.out.println("請輸入密碼:");?

String password = scanner.nextLine();?

String sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";?

Statement stmt = conn.createStatement();?

ResultSet rs = stmt.executeQuery(sql);?

if (rs.next()) {?

System.out.println("登錄成功");?

} else {?

System.out.println("登錄失敗");?

}?

rs.close();?

stmt.close();?

conn.close();?

} catch (Exception e) {?

e.printStackTrace();?

}?

}?

}?

?

在上述代碼中,用戶輸入的用戶名和密碼直接被拼接到 SQL 語句中。如果攻擊者輸入惡意的 SQL 代碼,就可能改變原 SQL 語句的語義。?

2.2 缺乏輸入驗證?

當應用程序沒有對用戶輸入進行嚴格的驗證和過濾時,攻擊者可以輕松地輸入惡意的 SQL 代碼。例如,在上述登錄示例中,如果用戶輸入的密碼為' OR '1'='1,那么最終生成的 SQL 語句將變為:?

SELECT * FROM users WHERE username = 'xxx' AND password = '' OR '1'='1'?

?

由于'1'='1'始終為真,這個 SQL 語句將返回users表中的所有記錄,攻擊者就可以繞過正常的身份驗證機制登錄系統。?

三、SQL 注入的種類?

3.1 基于字符串的注入?

這是最常見的 SQL 注入類型之一。在這種注入方式中,攻擊者利用應用程序對字符串輸入處理不當的漏洞。例如,在前面提到的 Java 登錄示例中,如果輸入的用戶名或密碼字段沒有正確處理,攻擊者輸入類似' OR '1'='1 --的字符串。其中,OR '1'='1用于改變 SQL 語句的邏輯,使其永遠為真,而--是 SQL 中的注釋符號,用于注釋掉后面可能存在的 SQL 語句部分,從而達到繞過驗證或獲取非法數據的目的。?

3.2 數字型注入?

當應用程序期望用戶輸入數字,并將其直接用于 SQL 查詢時,容易發生數字型注入。例如,SQL 語句可能是SELECT * FROM products WHERE product_id = + userInput。如果攻擊者輸入1 OR 1=1,則最終的 SQL 語句變為SELECT * FROM products WHERE product_id = 1 OR 1=1。由于1=1恒為真,該查詢將返回products表中的所有記錄。?

3.3 布爾盲注?

布爾盲注發生在應用程序對 SQL 查詢結果的反饋只有兩種狀態(通常是真或假,比如頁面顯示正常或錯誤)的情況下。攻擊者通過構造不同的 SQL 注入語句,根據應用程序返回的不同狀態來推斷數據庫中的信息。例如,攻擊者可以構造這樣的注入語句' AND (SELECT COUNT(*) FROM users WHERE username = 'admin') > 0 --,如果返回的頁面狀態表示條件為真,那么就可以推斷出數據庫中存在名為admin的用戶。攻擊者不斷改變注入語句中的條件,通過多次嘗試來逐步獲取數據庫中的數據。?

3.4 時間盲注?

時間盲注利用了數據庫執行特定操作時的時間延遲來推斷信息。當應用程序對 SQL 查詢結果沒有直接的反饋信息時,攻擊者可以通過讓數據庫執行一些耗時操作,根據操作執行的時間來判斷注入語句是否成功。例如,在 MySQL 數據庫中,攻擊者可以使用' AND SLEEP(5) --這樣的注入語句,如果數據庫執行該語句后頁面延遲了 5 秒加載,就說明該注入語句可能被成功執行,攻擊者可以通過類似的方式逐步推斷數據庫中的數據。?

3.5 聯合查詢注入?

聯合查詢注入允許攻擊者在原有的 SQL 查詢基礎上添加額外的查詢語句。例如,假設原 SQL 語句是SELECT name, age FROM users WHERE user_id = + userInput。攻擊者輸入1 UNION SELECT database(), version() --,那么最終的 SQL 查詢將變成SELECT name, age FROM users WHERE user_id = 1 UNION SELECT database(), version()。這樣攻擊者就可以獲取數據庫的名稱和版本等信息。?

四、相關SQL注入的事件?

4.1 美國零售商塔吉特(Target)數據泄露事件?

2013 年,美國零售商塔吉特遭遇了嚴重的 SQL 注入攻擊。攻擊者通過入侵塔吉特的支付系統,獲取了約 4000 萬張信用卡信息和 7000 萬客戶的個人信息。此次攻擊導致塔吉特公司遭受了巨大的經濟損失,包括賠償客戶、修復系統漏洞等費用,同時也嚴重損害了公司的聲譽。?

4.2 索尼 PlayStation Network 數據泄露事件?

2011 年,索尼的 PlayStation Network 遭受了 SQL 注入攻擊,導致約 7700 萬用戶的個人信息泄露,包括姓名、地址、出生日期、電子郵件地址等。此次攻擊導致 PlayStation Network 服務中斷數周,給索尼公司帶來了巨大的經濟損失和聲譽損害。?

五、SQL 注入導致的問題?

4.1 數據泄露?

攻擊者可以通過 SQL 注入漏洞獲取數據庫中的敏感信息,如用戶的賬號密碼、信用卡號、個人身份信息等。這些信息一旦泄露,可能會給用戶和企業帶來巨大的損失。?

4.2 數據篡改?

攻擊者可以利用 SQL 注入漏洞修改數據庫中的數據,例如修改用戶的賬戶余額、訂單狀態等。這不僅會影響企業的正常運營,還可能導致法律糾紛。?

4.3 數據庫損壞?

在某些情況下,攻擊者可以通過 SQL 注入執行刪除數據庫表、刪除數據庫等操作,導致數據庫無法正常使用,給企業帶來嚴重的經濟損失。?

六、預防 SQL 注入的方法?

6.1 使用預編譯語句(PreparedStatement)?

預編譯語句是預防 SQL 注入的最有效方法之一。在 Java 中,PreparedStatement接口會對 SQL 語句進行預編譯,將用戶輸入的數據作為參數進行處理,而不是直接拼接到 SQL 語句中。以下是使用PreparedStatement改寫后的登錄示例代碼:?

?

TypeScript

取消自動換行復制

import java.sql.Connection;?

import java.sql.DriverManager;?

import java.sql.PreparedStatement;?

import java.sql.ResultSet;?

import java.util.Scanner;?

?

public class SecureLoginExample {?

public static void main(String[] args) {?

try {?

Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testdb", "root", "password");?

Scanner scanner = new Scanner(System.in);?

System.out.println("請輸入用戶名:");?

String username = scanner.nextLine();?

System.out.println("請輸入密碼:");?

String password = scanner.nextLine();?

String sql = "SELECT * FROM users WHERE username =? AND password =?";?

PreparedStatement pstmt = conn.prepareStatement(sql);?

pstmt.setString(1, username);?

pstmt.setString(2, password);?

ResultSet rs = pstmt.executeQuery();?

if (rs.next()) {?

System.out.println("登錄成功");?

} else {?

System.out.println("登錄失敗");?

}?

rs.close();?

pstmt.close();?

conn.close();?

} catch (Exception e) {?

e.printStackTrace();?

}?

}?

}?

?

在這個代碼中,?是占位符,用戶輸入的數據會被安全地設置到占位符位置,數據庫驅動會自動處理數據的轉義等操作,從而有效防止 SQL 注入。?

6.2 輸入驗證與過濾?

除了使用預編譯語句,對用戶輸入進行嚴格的驗證和過濾也是必不可少的。可以使用正則表達式等方式驗證用戶輸入是否符合預期的格式。例如,對于用戶名,可以限制只能包含字母和數字:?

?取消自動換行復制

import java.util.regex.Pattern;?

?

public class InputValidation {?

public static boolean isValidUsername(String username) {?

String pattern = "^[A-Za-z0-9]+$";?

return Pattern.matches(pattern, username);?

}?

}?

?對于密碼等敏感信息,也可以設置強度要求,并進行驗證。同時,要過濾掉用戶輸入中的特殊字符,如單引號、雙引號、分號等可能用于 SQL 注入的字符。但需要注意的是,輸入驗證和過濾不能完全替代預編譯語句,它只是作為一種額外的安全措施。?

6.3 最小權限原則?

在數據庫中,為應用程序使用的數據庫用戶分配最小的權限。例如,如果應用程序只需要讀取某些表的數據,那么就只賦予該用戶對這些表的SELECT權限,而不給予INSERT、UPDATE、DELETE等其他不必要的權限。這樣即使發生 SQL 注入攻擊,攻擊者也無法執行修改或刪除數據等危險操作。?

6.4 安全框架與工具的使用?

利用成熟的安全框架,如 Spring Security 等,這些框架提供了一系列的安全功能,包括防止 SQL 注入的機制。同時,使用靜態代碼分析工具,如庫博靜態代碼分析工具等,它們可以在開發過程中檢測代碼中潛在的 SQL 注入風險,幫助開發人員及時發現和修復問題。?

七、結論?

SQL 注入是一種嚴重的安全漏洞,它可能會給企業和用戶帶來巨大的損失。在 Java 開發中,開發人員應該避免直接拼接 SQL 語句,而是使用預編譯語句(PreparedStatement)來防止 SQL 注入。同時,要對用戶輸入進行嚴格的驗證和過濾,遵循最小權限原則,并合理使用安全框架與工具。通過采取這些措施,可以有效降低 SQL 注入攻擊的風險,保護企業和用戶的數據安全。為了更好地發現軟件代碼中SQL注入的問題,可以采用靜態代碼審計提前發現問題,及時解決,防止軟件上線后被不法分子攻擊。由北京北大軟件工程股份有限公司自主研制開發的庫博靜態代碼分析工具可以在不運行軟件代碼的情況下,對代碼中各類SQL注入問題進行自動化檢測,發現問題,并提供解決方案,進一步保障企業和用戶的數據安全。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/900776.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/900776.shtml
英文地址,請注明出處:http://en.pswp.cn/news/900776.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

安全理念和安全產品發展史

從安全理念的發展歷史來看,技術與產品的演進始終圍繞 “威脅對抗” 與 “業務適配” 兩大核心展開。以下從七個關鍵階段解析安全技術與產品的發展脈絡,并結合最新實踐與未來趨勢提供深度洞察: 一、密碼學奠基階段(1970s 前) 安全理念:以 “信息保密” 為核心,防御手段…

【Ansible自動化運維】二、Playbook 深入探究:構建復雜自動化流程

? 在 Ansible 自動化運維體系中,Playbook 是極為關鍵的部分。它允許我們以一種結構化、可重復的方式定義和執行一系列復雜的任務,從而構建高效的自動化流程。本篇文章將深入探究 Ansible Playbook 的各個方面,助您掌握構建復雜自動化…

springboot項目中常用的工具類和api

在Spring Boot項目中,開發者通常會依賴一些工具類和API來簡化開發、提高效率。以下是一些常用的工具類及其典型應用場景,涵蓋 Spring 原生工具、第三方庫(如Hutool、Guava) 和 Java 自帶工具。 1. Spring Framework 自帶工具類 (…

23種設計模式-行為型模式-模板方法

文章目錄 簡介場景解決代碼關鍵優化點 總結 簡介 模板方法是一種行為設計模式,它在超類中定義了一個算法的框架,允許子類在不修改結構的情況下重寫算法的特定步驟。 場景 假如你正在開發一款分析文檔的數據挖掘程序。用戶需要向程序輸入各種格式&…

解決Long類型前端精度丟失和正常傳回后端問題

在 Java 后端開發中,可能會遇到前后端交互過程中 Long 類型精度丟失的問題。尤其是在 JavaScript 中,由于其 Number 類型是雙精度浮點數,超過 16 位的 Long 類型值就會發生精度丟失。 問題背景 假設有如下實體類: public class…

PowerPhotos:拯救你的Mac照片庫,告別蘋果原生應用的局限

如果你用Mac管理照片,大概率被蘋果原生「照片」應用折磨過——無法真正并行操作多個圖庫。每次切換圖庫都要關閉重啟,想合并照片得手動導出導入,重復文件更是無處可逃…… 直到我發現了 PowerPhotos,這款專為Mac設計的照片庫管理…

android 14.0 工廠模式 測試音頻的一些問題(高通)

1之前用tinycap,現在得用agmcap 執行----agmcap /data/test.wav -D 100 -d 101 -i CODEC_DMA-LPAIF_RXTX-TX-3 -T 3 報錯1 agmcap data/test.wav -D 100 -d 101 -i CODEC_DMA-LPAIF_RXTX-TX-3 -T 3 Failed to open xml file name /vendor/etc/backend_co…

以庫存系統為核心的ERP底層架構設計

在企業資源計劃(ERP)系統中,庫存系統常被視為基礎模塊。但在現代企業的數字化進程中,庫存系統不僅僅是一個模塊,它已經逐步演化為驅動整個ERP生態的核心引擎。本文從架構設計的角度,探討為何庫存系統應被置…

辛格迪客戶案例 | 北京舒曼德醫藥實施電子合約系統(eSign)

01 北京舒曼德醫藥科技開發有限公司:醫藥科技的數字化先鋒 北京舒曼德醫藥科技開發有限公司(以下簡稱“舒曼德醫藥”)作為國內醫藥科技領域的領軍企業,致力于創新藥物的研發、臨床試驗和市場推廣。公司以“科技興藥、質量為先、服…

【UE5】RTS游戲的框選功能+行軍線效果實現

目錄 效果 步驟 一、項目準備 二、框選NPC并移動到指定地點 三、框選效果 效果 步驟 一、項目準備 1. 新建一個俯視角游戲工程 2. 新建一個pawn、玩家控制器和游戲模式,這里分別命名為“MyPawn”、“MyController”和“MyGameMode” 3. 打開“MyGameMode”,設置玩家…

vim定位有問題的腳本/插件的一般方法

在使用vim的過程中可能會遇到一些報錯或其他不符合預期的情況,本文介紹一些我自己常用的定位有問題腳本/插件的方法(以下方法同樣適用于neovim) 執行了某些命令的情況 這種情況最簡單,使用:h 命令,如果插件有文檔的話…

智能驅動教育變革:人工智能在高中教育中的實踐路徑與創新策略

一、引言 隨著信息技術的飛速發展,人工智能(Artificial Intelligence, AI)已成為推動社會進步的重要力量。在教育領域,人工智能的應用正逐漸改變著傳統的教學模式和方法,為教育現代化注入了新的活力。高中教育作為教育…

VLAN(虛擬局域網)

一、vlan概述 VLAN(virtual local area network)是一種通過邏輯方式劃分網絡的技術,允許將一個物理網絡劃分為多個獨立的虛擬網絡。每一個vlan是一個廣播域,不同vlan之間的通信需要通過路由器或三層交換機 [!注意] vlan是交換機獨有的技術,P…

spring-cloud-starter-alibaba-seata使用說明

Spring Cloud Alibaba Seata 使用說明 spring-cloud-starter-alibaba-seata 是 Spring Cloud Alibaba 生態中用于集成分布式事務框架 Seata 的核心組件,支持 AT(自動補償)、TCC(手動補償) 等模式。 一、依賴配置 添加…

每日一題(小白)暴力娛樂篇23

由題意得知給我們一串數字,我們每次交換兩位,最少交換多少次成功得到有順序的數組。我們以平常的思維去思考,加入給你一串數字獲得最少的交換次數,意味著你的交換后續基本不會變,比如說2 1 3 5 4 中1與2交換后不變&…

Python基礎——Pandas庫

對象的創建 導入 Pandas 時,通常給其一個別名“pd”,即 import pandas as pd。作為標簽庫,Pandas 對象在 NumPy 數組基礎上給予其行列標簽。可以說,列表之于字典,就如 NumPy 之于 Pandas。Pandas 中,所有數…

Spring入門概念 以及入門案例

Spring入門案例 Springspring是什么spring的狹義與廣義spring的兩個核心模塊IoCAOP Spring framework特點spring入門案例不用new方法,如何使用返回創建的對象 容器:IoC控制反轉依賴注入 Spring spring是什么 spring是一款主流的Java EE輕量級開源框架 …

The packaging for this project did not assign a file to the build artifact

問題: maven install報錯:The packaging for this project did not assign a file to the build artifact 解決方案: 方案1: 使用mvn clean install 就可以解決問題, 方案2: 找到lifecycle點clean再點…

C++入門一:C++ 編程概述

一、C 語言與 C 的關系:從 “帶類的 C” 到獨立王國 1.1 血緣關系:C 是 C 的 “超級進化版” 起源:C 由 Bjarne Stroustrup 在 1980 年代開發,最初名為 “C with Classes”(帶類的 C),旨在為 …

LLM生成文本的 束搜索參數是什么(Beam Search)

LLM生成文本的 束搜索參數是什么(Beam Search) 束搜索(Beam Search)是一種在序列生成任務(如機器翻譯、文本生成等)中常用的啟發式搜索算法,用于在搜索空間中尋找最優的生成序列。 束搜索的基本概念 在序列生成過程中,每一步都會有多個可能的選擇(即候選標記)。 …