W3Cschool
恭喜您成為首批注冊用戶
獲得88經驗值獎勵
所謂 SQL 注入,就是通過把 SQL 命令插入到 Web 表單提交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執(zhí)行惡意的 SQL 命令。具體來說,它是利用現(xiàn)有應用程序,將(惡意)的 SQL 命令注入到后臺數(shù)據庫引擎執(zhí)行的能力,它可以通過在 Web 表單中輸入(惡意)SQL 語句得到一個存在安全漏洞的網站上的數(shù)據庫,而不是按照設計者意圖去執(zhí)行 SQL 語句。比如先前的很多影視網站泄露 VIP 會員密碼大多就是通過 Web 表單遞交查詢字符暴出的,這類表單特別容易受到 SQL 注入式攻擊。
下面給了一個完整的可復現(xiàn)的 SQL 注入例子,實際上注入的 SQL 語句寫法有很多,下例是比較簡單的。
location /test {
content_by_lua_block {
local mysql = require "resty.mysql"
local db, err = mysql:new()
if not db then
ngx.say("failed to instantiate mysql: ", err)
return
end
db:set_timeout(1000) -- 1 sec
local ok, err, errno, sqlstate = db:connect{
host = "127.0.0.1",
port = 3306,
database = "ngx_test",
user = "ngx_test",
password = "ngx_test",
max_packet_size = 1024 * 1024 }
if not ok then
ngx.say("failed to connect: ", err, ": ", errno, " ", sqlstate)
return
end
ngx.say("connected to mysql.")
local res, err, errno, sqlstate =
db:query("drop table if exists cats")
if not res then
ngx.say("bad result: ", err, ": ", errno, ": ", sqlstate, ".")
return
end
res, err, errno, sqlstate =
db:query("create table cats "
.. "(id serial primary key, "
.. "name varchar(5))")
if not res then
ngx.say("bad result: ", err, ": ", errno, ": ", sqlstate, ".")
return
end
ngx.say("table cats created.")
res, err, errno, sqlstate =
db:query("insert into cats (name) "
.. "values (\'Bob\'),(\'\'),(null)")
if not res then
ngx.say("bad result: ", err, ": ", errno, ": ", sqlstate, ".")
return
end
ngx.say(res.affected_rows, " rows inserted into table cats ",
"(last insert id: ", res.insert_id, ")")
-- 這里有 SQL 注入(后面的 drop 操作)
local req_id = [[1'; drop table cats;--]]
res, err, errno, sqlstate =
db:query(string.format([[select * from cats where id = '%s']], req_id))
if not res then
ngx.say("bad result: ", err, ": ", errno, ": ", sqlstate, ".")
return
end
local cjson = require "cjson"
ngx.say("result: ", cjson.encode(res))
-- 再次查詢,table 被刪
res, err, errno, sqlstate =
db:query([[select * from cats where id = 1]])
if not res then
ngx.say("bad result: ", err, ": ", errno, ": ", sqlstate, ".")
return
end
db:set_keepalive(10000, 100)
}
}
其他變種,大家可以自行爬行搜索引擎了解。
其實大家可以大概網絡爬行一下看看如何解決 SQL 注入,可以發(fā)現(xiàn)實現(xiàn)方法很多,比如替換各種關鍵字等。在 OpenResty 中,其實就簡單很多了,只需要對輸入參數(shù)進行一層過濾即可。
對于 MySQL ,可以調用 ?ndk.set_var.set_quote_sql_str
? ,進行一次過濾即可。
-- for MySQL
local req_id = [[1'; drop table cats;--]]
res, err, errno, sqlstate =
db:query(string.format([[select * from cats where id = %s]],
ndk.set_var.set_quote_sql_str(req_id)))
if not res then
ngx.say("bad result: ", err, ": ", errno, ": ", sqlstate, ".")
return
end
如果恰巧你使用的是 PostgreSQL ,調用 ?ndk.set_var.set_quote_pgsql_str
? 過濾輸入變量。讀者這時候可以再次把這段代碼放到剛剛的示例代碼中,如果您可以得到下面的錯誤,恭喜您,以正確的姿勢防止 SQL 注入。
bad result: You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near
'1\'; drop table cats;--''' at line 1: 1064: 42000.
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: