只看: sql
(來源: https : //xkcd.com/327/ ) 數據庫
此SQL的做用是: spa
Robert'); DROP TABLE STUDENTS; --
我知道'
和--
都是註釋,可是DROP
這個詞不是同一行的一部分嗎? 翻譯
它是這樣工做的:假設管理員正在尋找學生的記錄 code
Robert'); DROP TABLE STUDENTS; --
因爲管理員賬戶具備較高的特權,所以能夠從該賬戶刪除表。 ip
從請求中檢索用戶名的代碼是 element
如今查詢將是這樣的(以搜索student表) 字符串
String query="Select * from student where username='"+student_name+"'"; statement.executeQuery(query); //Rest of the code follows
結果查詢變爲 get
Select * from student where username='Robert'); DROP TABLE STUDENTS; --
因爲未清理用戶輸入,所以上述查詢已分爲兩部分 it
Select * from student where username='Robert'); DROP TABLE STUDENTS; --
雙破折號(-)只會註釋掉查詢的其他部分。
這很危險,由於它會使密碼驗證無效(若是存在)
第一個將進行常規搜索。
若是該賬戶具備足夠的特權,則第二個將刪除該表格的學生(一般,學校管理員賬戶將運行此類查詢,而且具備上述特權)。
它放下學生桌。
學校程序中的原始代碼可能看起來像
q = "INSERT INTO Students VALUES ('" + FNMName.Text + "', '" + LName.Text + "')";
如您所見,這是將文本輸入添加到查詢中的簡單方法,而且很是糟糕 。
在姓氏中的值以後,是中間名文本框FNMName.Text (這是Robert'); DROP TABLE STUDENTS; --
Robert'); DROP TABLE STUDENTS; --
Robert'); DROP TABLE STUDENTS; --
)和姓氏文本框LName.Text (稱爲Derper
)與其他查詢串聯在一塊兒,結果其實是兩個查詢,由語句終止符 (分號)分隔。 第二個查詢已注入到第一個查詢中。 當代碼對數據庫執行此查詢時,它將看起來像這樣
INSERT INTO Students VALUES ('Robert'); DROP TABLE Students; --', 'Derper')
用簡單的英語粗略地翻譯成兩個查詢:
向「學生」表中添加一個名稱爲「 Robert」的新記錄
和
刪除學生表
第二個查詢以後的全部內容都標記爲註釋 : --', 'Derper')
學生姓名中的'
不是註釋,是結束字符串定界符 。 因爲學生的名字是一個字符串,所以在語法上須要它來完成假設的查詢。 注入攻擊僅在其將有效查詢注入結果的SQL查詢時起做用。
根據dan04的敏銳評論從新編輯
');
結束查詢,它不會開始註釋。 而後,它刪除了students表並註釋了應該執行的其他查詢。
SQL中的'
字符用於字符串常量。 在這種狀況下,它用於結束字符串常量,而不用於註釋。
數據庫的做者可能作了一個
sql = "SELECT * FROM STUDENTS WHERE (STUDENT_NAME = '" + student_name + "') AND other stuff"; execute(sql);
若是student_name是給定的,則使用名稱「 Robert」進行選擇,而後刪除表。 「-」部分將給定查詢的其他部分更改成註釋。