發佈自 Kindem的博客,歡迎你們轉載,可是要注意註明出處。另外,該文章收納在 Kindem的我的的 IT 知識整理倉庫,歡迎 Star、Fork、投稿
這一點可能都被說爛了,只要是動態網站,能夠說基本上第一個必須考慮的點就是SQL注入。javascript
那什麼是SQL注入呢,先舉一個例子吧:php
這是一個典型的登陸場景:html
-------------------------------- | Username: | -------------------------------- | Password: | --------------------------------
網站要求用戶輸入用戶名和密碼以登陸,這時候一般後端的SQL語句是:前端
select * from user_t where user_t.username = '...' and user_t.password = '...';
看起來好像沒有什麼問題,當獲取到匹配用戶名和密碼的表項時,判斷結果集的數量是否爲1,再進行一些其餘的邏輯判斷,便可斷定用戶成功登錄,可是吧,這樣會有一個問題,若是後端代碼採用了字符串拼接,這裏將出現一個致命的問題:java
好比我按照以下方式輸入:git
-------------------------------- | Username: John Kindem'; -- | -------------------------------- | Password: mypassword | --------------------------------
此時SQL語句就會變成:github
select * from user_t where user_t.username = 'John Kindem'; --' and user_t.password = '...';
整理一下,就會變成這樣:數據庫
select * from user_t where user_t.username = 'John Kindem'; --' and user_t.password = '...';
可見本來密碼這一條件,直接被註釋掉了,而原來的SQL語句被提早結束了,這樣你隨意使用一個密碼就能登陸爲站點任意一個用戶,是否是很恐怖,設想一下,假如這個框中包含有管理員用戶的登陸功能,這一條語句將毀掉多少數據......後端
因此這就是SQL注入,這一點每每是Web開發中最危險的一個點,因爲其每每與權限有關,一旦被攻破就會致使數據庫遭到破壞或者是站點控制權的丟失。跨域
SQL注入每每經過構建特殊的輸入來進行,這些特殊的輸入每每有如下的想法:
SQL的防範其實也很好作,在現代的Web開發中,每每遵循如下幾條規則開發就能很好地避免被SQL注入:
對於後者,基本上全部的語言都支持這一點,拿JavaScript來講:
// Nodejs 鏈接 MySQL 進行查詢 connection.query('select * from student where id = ?', 5, () => { ... });
這樣能夠查詢到 student 表中 id = 5 的表項的全部信息,但同時可以防範SQL注入,由於這樣的語句在使用以前就會被預編譯,你沒法再隨意改變SQL語句的構成。
XSS的全稱是 Cross Site Scripting,意爲跨站腳本攻擊,爲了區別於 CSS (Cascading Style Sheets) 而特地寫成 XSS。這一攻擊方法也是很常見的Web攻擊之一,並且因爲須要在寫 JavaScript 的時候特別注意,這一攻擊每每容易被忽略。
固然隨着前端的發展,如今這一攻擊的防範方法每每都會被集成在框架中,好比 React、Vue 中,不少地方就集成了 XSS 防範,你在使用框架的時候,不少地方每每都不須要注意這一點,框架每每幫你作了防禦。
這裏簡單介紹一下 XSS,先舉一個例子:
如今有這樣一個博客網站:
那麼,假如用戶在富文本編輯器上寫:
hello world <script>alert(0);</script>
富文本編輯器的原理每每是將用戶輸入的內容轉義成帶有格式的html文本而且輸出,頗有可能它的輸出結果是這樣的:
<div class="post-editor"> hello world <script>alert(0);</script> </div>
想一想看,若是這樣的一段文本,若是原封不動地被顯示在看博客的頁面,會致使什麼?
很顯然,其中的 script 標籤中的內容,將會直接被當成腳本執行,想一想這會有很危險,有心的攻擊者能夠利用這一漏洞,爲所欲爲地寫本身的攻擊腳本,好比獲取用戶的 cookie、進行惡意請求、監聽用戶輸入等......
這就是 XSS,在平日寫 JavaScript 的過程當中很容易就會產生這一的漏洞,XSS 的生效每每有兩個條件:
最簡單的例子,就是網站直接將用戶的輸入做爲輸出顯示在頁面上,再或者,站點中有一些 eval() 之類的函數,可以直接執行用戶輸入......
固然 XSS 的防範也不是不無方法可循,最重要的一點是:
轉義這一點,講的是針對那些可以影響到原有代碼的特殊符號,好比 <、> 等,這裏給出一些經常使用的轉義規則:
--------------------- | < | < | --------------------- | > | > | --------------------- | ' | & | --------------------- | " | " | ---------------------
進行完轉義以後,這些字符會被當成普通顯示的字符,而不是具備特殊意義的字符
CSRF 全稱爲 Cross Site Request Forgery,即跨域請求僞造。這一點攻擊每每容易被人一樓,在一些老一些的網站,基本上都沒有考慮到這一點,就連百度、亞馬遜這一些大型網站,在 CSRF 被人大規模利用進行攻擊以前甚至都沒有作這一方面的防範。隱蔽性高是這一攻擊最大的特色。
這一攻擊主要利用的是網站對用戶身份的絕對信任,CSRF 有一些難以理解,這裏用一個例子簡單地說清楚:
舉一個例子,如今這裏有一個網購網站,通常來講,每每當用戶登陸以後,驗證了身份後,站點在一次會話結束前,都是信任用戶的,也就是說,站點相信用戶是本人,可是吧,如今有這樣一次操做:
如今想想,會出現什麼問題?因爲用戶沒有關閉網購網站的標籤頁,上一次會話並無結束,惡意網站發送的請求的 cookie 中將會帶有與上一次會話相同的 sessionId,也就是說在網購網站的那一端將會認爲這一次請求任然是用戶的請求,因此會欣然接受。
是否是很可怕?你明明沒有作任何操做,你的一切卻已經屬於了別人。不少時候,被 CSRF 攻擊以後,用戶每每都不知道發生了什麼,本身的錢包就空了。CSRF 最可怕的地方就在於這裏,它的攻擊目標每每不是站點,而是站點的用戶,再者,它的隱蔽性也讓人忌憚。
CSRF 的防範,也是有規律可循的,最重要的一點是,站點永遠不要信任任何一個用戶,須要對用戶進行時刻驗證,通常來講如今都是這樣操做的:
在平時咱們的開發中,每每靜態資源的命名都是有規律的,好比吧,一些同一頁面引用的js腳本,會被咱們如此命名:
一樣的,圖片、CSS 文件都會像這樣命名,有心人就能夠寫一個腳本,遍歷整個站點目錄,獲取一些文件。固然,這些靜態文件給他也無妨,畢竟你摁 F12 也是同樣的效果......
可是設想一下,假如站點文件服務器上有一些特殊的文件,好比哪個傻傻的開發者使用 bak 格式備份了某一個後端文件,可是忘了刪除而後一直存在了服務器上,好比:
這些文件要是給弄到了,至關於網站的後端邏輯直接暴露在了用戶面前,有心人就能夠經過這些文件來分析獲取該站點的一些漏洞。
總的來講危害仍是不大,可是平日裏必定要注意:
跨域問題,自如其名,就是在站點域外獲取站點的服務,這樣的危害其實不是很大,由於站點通常都有訪問控制,每個身份都有本身能作的事情和不能作的事情,並且通常來講,瀏覽器和框架對這一攻擊都有着嚴格的防範,基本上來講,非本域下的請求基本上不可能成功。
可是吧這裏仍是提一句吧,仍是以一個例子來講明:
雖然通常是不太可能成功的......可是咱們仍是假設站點真的傻到這種地步
跨域問題通常經過使用 http response header 中的 Access-Control-Allow-Origin 來防範,這一字段能夠聲明該 response 容許的域,好比:
Access-Control-Allow-Origin: www.kindemh.cn
那麼非本域的全部請求,就算你請求了,你也沒法獲取到 response
這裏值得一提的是,在現代開發中,咱們每每會使用 Ajax 技術來發送異步請求,可是實際上,若是你使用 Ajax 技術,十有八九都會由於跨域限制被攔截,這時候你就須要使用上述字段來容許你本身的服務。因此說這一點其實原本沒多大危害,要說真正的危害,仍是對你的開發效率會形成必定的影響。