天天看點

防止 SQL 注入 · OpenResty防止 SQL 注入

防止 SQL 注入

所謂 SQL 注入,就是通過把 SQL 指令插入到 Web 表單送出或輸入域名或頁面請求的查詢字元串,最終達到欺騙伺服器執行惡意的 SQL 指令。具體來說,它是利用現有應用程式,将(惡意)的 SQL 指令注入到背景資料庫引擎執行的能力,它可以通過在 Web 表單中輸入(惡意)SQL 語句得到一個存在安全漏洞的網站上的資料庫,而不是按照設計者意圖去執行 SQL 語句。比如先前的很多影視網站洩露 VIP 會員密碼大多就是通過 Web 表單遞交查詢字元暴出的,這類表單特别容易受到 SQL 注入式攻擊。

+

SQL 注入例子

下面給了一個完整的可複現的 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)

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, ".")

res, err, errno, sqlstate =

db:query("create table cats "

.. "(id serial primary key, "

.. "name varchar(5))")

ngx.say("table cats created.")

db:query("insert into cats (name) "

.. "values (\'Bob\'),(\'\'),(null)")

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;--]]

db:query(string.format([[select * from cats where id = '%s']], req_id))

local cjson = require "cjson"

ngx.say("result: ", cjson.encode(res))

-- 再次查詢,table 被删

db:query([[select * from cats where id = 1]])

db:set_keepalive(10000, 100)

}

其他變種,大家可以自行爬行搜尋引擎了解。

OpenResty 中如何規避

其實大家可以大概網絡爬行一下看看如何解決 SQL 注入,可以發現實作方法很多,比如替換各種關鍵字等。在 OpenResty 中,其實就簡單很多了,隻需要對輸入參數進行一層過濾即可。

對于 MySQL ,可以調用  ndk.set_var.set_quote_sql_str  ,進行一次過濾即可。

 -- for MySQL

db:query(string.format([[select * from cats where id = %s]],

ndk.set_var.set_quote_sql_str(req_id)))

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.