這篇寫的東西年輕不懂事時其實有些曾踩到過,列在這提醒未來的自己不要再犯了
出於書本 Chapter 14. Web sites and Applications
類似於前一天講的,基於 input
的驗證缺陷,利用輸入參數或是 script 來進行攻擊。如果上網查的話,最常被拿出來講的範例是 php
,比如說想透過 eval
debug ,debug 完之後又忘記移除這一行... [1]
<?php eval ("echo ".$_REQUEST["user_name"].";"); ?>
就有可能被惡意使用者,透過輸入類似下面的 URL request,擷取出系統資訊
http://www.example.com/index.php?user_name=admin
http://www.example.com/index.php?user_name=admin;phpinfo();
http://www.example.com/index.php?user_name=admin;system('ls -l');
或是連帶被攻擊者透過這種方式實現 SQL injection。
透過清理輸入來防止這種攻擊,以 golang 來看的話,透過 ?
的方式引用 SQL Prepared Statement
的方式,先將參數在資料庫編譯完成後,再將其套用到 SQL 語句上執行。這是目前公定比較安全的處理方式,效能的表現也佔有優勢。
// 以下範例來自 golang 官方網站
// Correct format for executing an SQL statement with parameters.
rows, err := db.Query("SELECT * FROM user WHERE id = ?", id)
惡意攻擊者透過在 URL request 裡輸入 SQL 語法,如 CONNECT
、 SELECT
或是 UNION
等嘗試與程式後面的資料庫做連線以竊取資訊。從 OWASP 撈兩個常見的範例 [2]
假設有個簡單的 SQL 語法像是
select id, firstname, lastname from authors
如果有個惡意使用者嘗試在其中的 firstname
欄位裡多輸入一個單引號 '
,像是
select id, firstname, lastname from authors where firstname = 'malicious'ex' and lastname ='newman'
這樣就會造成預期外的執行結果。
假如有個程式碼要執行的 SQL 語法是使用串接字串的方式組合而成,像是下面的範例
string userName = getAuthenticatedUserName();
string query = "SELECT * FROM items WHERE owner = "'"
+ userName + "' AND itemname = '"
+ ItemName.Text + "'";
守規矩的情況不會發生什麼太大的問題
SELECT * FROM items WHERE owner = 'john' AND itemname = 'name';
但是如果在 WHERE
後面加上可以被執行的條件,效果就會等同於 SELECT * FROM items
SELECT * FROM items WHERE owner = 'john' AND itemname = 'name' OR 'a'='a';
而僅僅只是利用 itemname
後面加上 'name' OR 'a' = 'a'
更多 SQL injection 的範例可以參考 OWASP 的網站
註: Open Web Application Security Project (OWASP,開放網路應用程式安全計畫)
[1] What is Code Injection and How to avoid it?