關於「AND 1=1 UNION ALL SELECT 1,NULL,'<script>alert(\"XSS\")</script>',table_name FROM information_schema.tables WHERE 2>1--/**/; EXEC xp_cmdshell('cat ../../../etc/passwd')#」
有時會在 access log 裡面看到這樣的東西
/some/path?blah=1%20AND%201%3D1%20UNION%20ALL%20SELECT%201%2CNULL%2C%27%3Cscript%3Ealert%28%5C%22XSS%5C%22%29%3C%2Fscript%3E%27%2Ctable_name%20FROM%20information_schema.tables%20WHERE%202%3E1--%2F%2A%2A%2F%3B%20EXEC%20xp_cmdshell%28%27cat%20..%2F..%2F..%2Fetc%2Fpasswd%27%29%23
url decode 之後會看到
/some/path?blah=1 AND 1=1 UNION ALL SELECT 1,NULL,'<script>alert(\"XSS\")</script>',table_name FROM information_schema.tables WHERE 2>1--/**/; EXEC xp_cmdshell('cat ../../../etc/passwd')#
這個字串出自於 sqlmap 用來偵測 WAF 的查詢。
如果在 access log 中看到,表示有人拿程式自動掃你的網站/API。相對的對方在那當下不是手動測打,有比較高的機率掃完沒看到問題就去打下一個網站。
你不應該針對這個字串特別做處理,如果針對特定掃站工具做處理,表示有洞沒補完,多的是被其他手法打穿的機會。
應對的方式倒是殊途同歸:
- 不可在程式邏輯一開頭預先做資料跳脫,資料應該盡量保留原貌,直到必須送出到外部(例如組成 SQL,組成 HTML,組成 JavaScript...)的那一行才做跳脫。
- 不同的地方要做的跳脫不同,不可混成處理。
- SQL escape 跟 HTML escape 跟 JavaScript escape 要做的事情不同,看到字串就加斜線無用處。
- 最好是不要自己組 SQL / HTML / JavaScript
- SQL 用 prepared statement,那不是組合 SQL 而是設定 SQL 中的變數
- Server side 組網頁內容,透過樣版引擎的 escape function 處理,而且 HTML 跟 JavaScript 要套用不同的 escape。
- 不過 URL(例如
<a href="{{link}}">link</a>
)很難完整 escape...除 HTML 跳脫以外最好也驗證開頭是否為「https://
」 - JavaScript 組網頁內容,要用瀏覽器提供的 DOM api,不可以自己
document.write
修改 HTML - 要餵資料給 JavaScript,可考慮用個語言的 json 轉換機制(Python 的
json.dump
,PHP 的json_encode
...)來處理
而且寫程式的時候,要把所有使用者輸入的參數(例如整份 query string)都視為內容有毒。