SQL注入原理及产生过程
2019獨角獸企業重金招聘Python工程師標準>>>
最近在學習關于SQL注入方面的知識,想將一些相關的知識點做個匯總和筆記,方便日后的查閱也方便現在的學習。因為剛開始學習,涉獵還沒有很深入,本章將簡單的講講關于SQL注入的原理及其產生的過程和基本的一些加固方法。1.理解SQL注入
SQL注入是一種將SQL代碼插入或添加到應用(用戶)的輸入參數中的攻擊,之后再將這些參數傳遞給后臺的sql服務器加以解析和執行。由于sql語句本身的多樣性,以及可用于構造sql語句的編程方法很多,因此凡是構造sql語句的步驟均存在被攻擊的潛在風險。Sql注入的方式主要是直接將代碼插入參數中,這些參數會被置入sql命令中加以執行。間接的攻擊方式是將惡意代碼插入字符串中,之后將這些字符串保存到數據庫的數據表中或將其當成元數據。當將存儲的字符串置入動態sql命令中時,惡意代碼就將被執行。如果web應用未對動態構造的sql語句使用的參數進行正確性審查(即便使用了參數化技術),攻擊者就很可能會修改后臺sql語句的構造。如果攻擊者能夠修改sql語句,那么該語句將與應用的用戶具有相同的權限。當使用sql服務器執行與操作系統交互命令時,該進程將與執行命令的組件(如數據庫服務器、應用服務器或web服務器)擁有相同的權限,這種權限的級別通常很高。如果攻擊者執行以上惡意代碼的插入操作成功,那么用戶數據庫服務器或者整個應用會遭到破壞,甚至被控制。
2.sql注入的產生過程及常見原因
2.1產生過程
大多數的web應用都需要與數據庫進行交互,并且大多數web應用編程語言(如ASP、C##、.NET、Java和PHP)均提供了可編程的方法來與數據庫連接并進行交互。如果web應用開發人員無法確保在將從web表單,cookie及輸入參數等收到的值傳遞給sql查詢(該查詢在數據庫服務器上執行)之前已經對其進行過驗證,那么通常會出現sql注入漏洞,如果攻擊者能夠控制發送給sql查詢的輸入,并且能夠操縱該輸入將其解析為代碼而非數據,那么攻擊者就很有可能有能力在后臺數據庫執行該代碼。
2.2常見的sql注入產生原因
基于此,SQL注入的產生原因通常表現在以下幾方面:①轉義字符處理不合適;②不安全的數據庫配置;③不合理的查詢集處理;④不當的錯誤處理;⑤多個提交處理不當。
2.2.1不當的處理類型
Sql數據庫將單引號字符(’)解析成代碼與數據間的分界線:單引號外面的內容軍事需要運行的代碼,而用單引號引起來的內容均是數據。因為只需要簡單的在URL或WEB頁面的字段中輸入一個單引號,就能很快速的識別出web站點是否會受到sql注入攻擊。
2.2.2不安全的數據庫配置
數據庫帶有很多默認的用戶預安裝內容。SQL Server使用聲名狼藉的“sa”作為數據庫系統管理員賬戶,MySQL使用“root”和“anonymous”用戶賬戶,Oracle則在創建數據庫時通常會創建SYS、SYSTEM、DBSNMP和OUTLN賬戶。這些并非是全部的賬號,知識比較出名的賬戶中的一部分,還有很多其他的賬戶。其他賬戶同樣按默認方式進行預設,口令總所周知。這就帶來了很大的安全風險,攻擊者利用sql注入漏洞時,通常會常識訪問數據庫的元數據,比如內部的數據庫和表的名稱、列的數據類型和訪問權限,例如MySQL服務器的元數據位于information_schema虛擬數據庫中,可通過show databases;和show tables;命令訪問。所有的MySQL用戶均有權限訪問該數據庫中的表,但只能查看表中那些與該用戶訪問權限相對應的對象的行。
2.2.3不合理的查詢集處理
有時需要使用動態的sql語句對某些復雜的應用進行編碼,因為程序開發階段可能還不知道要查詢的表或字段(或者不存在)。比如與大型數據庫交互的應用,這些數據庫在定期創建的表中的數據由于應用已經產生了輸入,因而開發人員會信任該數據,攻擊者可以使用自己的表和字段數據來替換應用產生的值,從而影響系統的返回值。2.2.4不當的錯誤處理
錯誤處理不當會為web站點帶來很多安全方面的問題。最常見的問題是將詳細的內部錯誤消息(如錯誤代碼,數據庫轉存儲)顯示給用戶或攻擊。這些錯誤消息會泄露實現細節,為攻擊者提供與網站潛在缺陷相關的重要線索。2.2.5多個提交處理不當
大型的web開發項目會出現這樣的問題:有些開發人員會對輸入進行驗證,而一些開發人員則不以為然。對于開發人員,團隊,甚至公司來說,彼此獨立工作的情形并不少見,很難保證項目中每個人都遵循相同的標準。 應用打開發人員還傾向于圍繞用戶來設計應用,他們盡可能的使用預期的處理流程來引導用戶,認為用戶將遵循他們已經設計好的邏輯順序。 例如:當用戶已到達一系列表單中的第三個表單時,他們會期望用戶肯定已經完成第一個和第二個表達。但實際上,借助URL亂序來請求資源,能夠非常容易的避開預期的數據流程。 3.加固方法 最近學習的東西還不是很深入,以下歸納的一些關于針對sql注入的加固方法,是本人在學習中領悟和查閱資料總結的幾點,如果有一些不正確或者更好的建議,歡迎大家補充。1.(簡單又有效的方法)PreparedStatement
采用預編譯語句集,它內置了處理SQL注入的能力,只要使用它的setXXX方法傳值即可。
使用好處:
(1).代碼的可讀性和可維護性.
(2).PreparedStatement盡最大可能提高性能.
(3).最重要的一點是極大地提高了安全性.
原理:
sql注入只對sql語句的準備(編譯)過程有破壞作用
而PreparedStatement已經準備好了,執行階段只是把輸入串作為數據處理,
而不再對sql語句進行解析,準備,因此也就避免了sql注入問題.
2.使用正則表達式過濾傳入的參數
要引入的包:
import java.util.regex.*;
正則表達式:
private String CHECKSQL = “^(.+)\sand\s(.+)|(.+)\sor(.+)\s$”;
判斷是否匹配:
Pattern.matches(CHECKSQL,targerStr);
下面是具體的正則表達式:
檢測SQL meta-characters的正則表達式 :
/(%27)|(’)|(--)|(%23)|(#)/ix
修正檢測SQL meta-characters的正則表達式 :/((%3D)|(=))1*((%27)|(’)|(--)|(%3B)|(:))/i
典型的SQL 注入攻擊的正則表達式 :/w*((%27)|(’))((%6F)|o|(%4F))((%72)|r|(%52))/ix
檢測SQL注入,UNION查詢關鍵字的正則表達式 :/((%27)|(’))union/ix(%27)|(’)
檢測MS SQL Server SQL注入攻擊的正則表達式:
/exec(s|+)+(s|x)pw+/ix
等等…..
3.字符串過濾
比較通用的一個方法:
(||之間的參數可以根據自己程序的需要添加)
public static boolean sql_inj(String str)
{
String inj_str = "'|and|exec|insert|select|delete|update|
count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";
String inj_stra[] = split(inj_str,"|");
for (int i=0 ; i < inj_stra.length ; i++ )
{
if (str.indexOf(inj_stra[i])>=0)
{
return true;
}
}
return false;
}
4.jsp中調用該函數檢查是否包函非法字符
防止SQL從URL注入:
sql_inj.java代碼:
package sql_inj;
import java.net.*;
import java.io.*;
import java.sql.*;
import java.text.*;
import java.lang.String;
public class sql_inj{
public static boolean sql_inj(String str)
{
String inj_str = "'|and|exec|insert|select|delete|update|
count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";
//這里的東西還可以自己添加
>>>>閱讀全文
轉載于:https://my.oschina.net/u/3889140/blog/1836317
總結
以上是生活随笔為你收集整理的SQL注入原理及产生过程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux下MySQL 5.7 主从复制
- 下一篇: golang 面试