前端安全性問題


1、xss跨站腳本攻擊(原理、如何進行的、防御手段是什么,要說清楚)

2、CSRF跨站請求偽造(如何偽造法?怎么防御?等等都要說清楚)

3、sql腳本注入(注入方式,防御方式)

4、上傳漏洞 (防御方式)

 

1.xss攻擊

xss攻擊又叫做跨站腳本攻擊,主要是用戶輸入或通過其他方式,向我們的代碼中注入了一下其他的js,而我們又沒有做任何防范,去執行了這段js。

可能用戶會寫一個死循環,將我們的頁面給弄崩了,但是也有可能通過這種方式,來獲取我們的cookie,從而回去登陸態等信息

xss攻擊從來源可分為反射型和存儲型

反射型:

將xss代碼通過url來注入

index.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>反射型</title> </head> <body> <div id="test"></div> <script> var $test = document.querySelector('#test');; $test.innerHTML = window.location.hash </script> </body> </html> 

在IE瀏覽器去訪問該頁面並在地址后面加上index.html#<img src="404.html" onerror="alert('xss')" />

這時頁面一打開就會有個xss的彈窗,這就是最簡單的反射型攻擊
當然可能會覺得這樣沒有任何作用,但是修改一下代碼

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>反射型</title> </head> <body> <div id="test"></div> <script> // 先向頁面的cookie存儲一個name=1的信息 document.cookie = "name=1" var $test = document.querySelector('#test');; $test.innerHTML = window.location.hash </script> </body> </html> 

此時打開的地址修改為index.html#<img src="404.html" onerror="alert(document.cookie)" />

這里就會發現彈窗內容為我們存取的cookie。

注意:1.這里必須用IE打開這個鏈接,因為chrome和safari等瀏覽器,會主動將url里的一下字符串進行encode,保證了一定的安全性。 2.為什么我們這里用img的onerror來注入腳本呢?而不是直接用script標簽來執行,我們修改一下訪問的地址index.html#<script>alert(document.cookie)</script>,這時會發現,頁面並沒有執行這段代碼,但是這段代碼已經注入到了#test標簽中了。所以,一般通過img的onerror來注入是最有效的方法

存儲型

將xss代碼發送到了服務器,在前端請求數據時,將xss代碼發送給了前端。

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>存儲型</title> </head> <body> <div id="test"></div> <script> // 先向頁面的cookie存儲一個name=1的信息 document.cookie = "name=1" // 這里假設是請求了后台的接口 response是我們請求回來的數據 var response = '<img src="404.html" onerror="alert(document.cookie)"' var $test = document.querySelector('#test');; $test.innerHTML = response </script> </body> </html> 

這里最常見的情況就是一個富文本編輯器下,由用戶輸入了一串xss代碼,存儲在了服務器中,我們在展示用戶輸入內容時,沒有做防范處理。

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>富文本</title> </head> <body> <div id="test"></div> <textarea name="" id="" cols="30" rows="10"></textarea> <button onclick="submit()">提交</button> </body> </html> <script> function submit() { var $test = document.querySelector('#test'); $test.innerHTML = document.querySelector('textarea').value } </script> 

xss的防范手段:

1.encode

encode也分為html的encode和js的encode

html的encode: 就是將一些有特殊意義的字符串進行替換,比如:

& => &amp;

" => &quot;

' => &#39;

< => &lt;

> => &gt;

通過這些字符的替換,之前我們輸入的<img src="null" onerror="alert()">就被encode成了&lt;img src=&quot;null&quot; onerror=&quot;alert()&quot;&gt;

js的encode: 使用“\”對特殊字符進行轉義,除數字字母之外,小於127的字符編碼使用16進制“\xHH”的方式進行編碼,大於用unicode(非常嚴格模式)

用“\”對特殊字符進行轉義,這個可能比較好理解,因為將一下,比如',"這些字符轉譯為',"就可以使得js變為一個字符串,而不是一個可執行的js代碼了,那為什么還需要進行16進制轉換和unicode轉換呢?這樣做是為了預防一下隱藏字符,比如換行符可能會對js代碼進行換行

//使用“\”對特殊字符進行轉義,除數字字母之外,小於127使用16進制“\xHH”的方式進行編碼,大於用unicode(非常嚴格模式)。 var JavaScriptEncode = function(str){ var hex=new Array('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'); function changeTo16Hex(charCode){ return "\\x" + charCode.charCodeAt(0).toString(16); } function encodeCharx(original) { var found = true; var thecharchar = original.charAt(0); var thechar = original.charCodeAt(0); switch(thecharchar) { case '\n': return "\\n"; break; //newline case '\r': return "\\r"; break; //Carriage return case '\'': return "\\'"; break; case '"': return "\\\""; break; case '\&': return "\\&"; break; case '\\': return "\\\\"; break; case '\t': return "\\t"; break; case '\b': return "\\b"; break; case '\f': return "\\f"; break; case '/': return "\\x2F"; break; case '<': return "\\x3C"; break; case '>': return "\\x3E"; break; default: found=false; break; } if(!found){ if(thechar > 47 && thechar < 58){ //數字 return original; } if(thechar > 64 && thechar < 91){ //大寫字母 return original; } if(thechar > 96 && thechar < 123){ //小寫字母 return original; } if(thechar>127) { //大於127用unicode var c = thechar; var a4 = c%16; c = Math.floor(c/16); var a3 = c%16; c = Math.floor(c/16); var a2 = c%16; c = Math.floor(c/16); var a1 = c%16; return "\\u"+hex[a1]+hex[a2]+hex[a3]+hex[a4]+""; } else { return changeTo16Hex(original); } } } var preescape = str; var escaped = ""; var i=0; for(i=0; i < preescape.length; i++){ escaped = escaped + encodeCharx(preescape.charAt(i)); } return escaped; } 

2.對於富文本的防范:filter

因為富文本是比較特殊的,在富文本中輸入標簽,我們需要展示出來,所以我們不能用之前的html的encode方法來執行。所以我們就得用一個叫白名單過濾的方式來防范。

原理就是:首先列舉一下比較合法的標簽,稱為白名單,這些標簽是不會對頁面進行攻擊的。之后對用戶輸入的內容進行白名單過濾。

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>富文本</title> </head> <body> <div id="test"></div> <textarea name="" id="" cols="30" rows="10"></textarea> <button onclick="submit()">提交</button> </body> </html> <!-- xss_filter.js是一個白名單過濾庫 --> <script src="./xss_filter.js"></script> <script> function submit() { var $test = document.querySelector('#test'); $test.innerHTML = filterXSS(document.querySelector('textarea').value) } </script> 

此時用戶如果提交<img src="null" onerror="alert()">就會被過濾成<img src="">

這樣就有效的防范了用戶輸入的xss代碼

注意: 當遇到想后台提交數據的情況,我們應該在用戶提交的時候就進行過濾和encode呢?還是展示的時候處理呢? 我們應當考慮到提交代碼后會有個多端展示的問題,可能我們web端需要進行這些處理,但是移動端展示的時候就不需要這些處理,所以我們應當在展示的時候進行處理,而不是錄入的時候處理

2.CSRF– 跨站偽造請求

CSRF就是利用你所在網站的登錄的狀態,悄悄提交各種信息, 是一種比xss還要惡劣很多的攻擊。因為CSRF可以在我們不知情的情況下,利用我們登陸的賬號信息,去模擬我們的行為,去執行一下操作,也就是所謂的釣魚。比如我們在登陸某個論壇,但這個網站是個釣魚網站,我們利用郵箱或者qq登陸后,它就可以拿到我們的登陸態,session和cookie信息。然后利用這些信息去模擬一個另外網站的請求,比如轉賬的請求。

 
836049-20160322214747901-1548153978.jpg

csrf.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>csrf</title> </head> <body> <iframe id="" name="csrf-form"></iframe> <form target="csrf-form" method="post" action="http://127.0.0.1:3001/csrf"> <input name="name" value="1111"> <input type="submit" value="提交"> </form> </body> </html> 

我們點擊進入了一個csrf這個頁面里,我們以為我們只是在csrf中點擊提交了1111這個信息,其實這個網站悄悄的把這些信息提交到了本地的csrf上了,而不是我們當前瀏覽的csrf.html中

server.js

const http = require('http'); const fs = require('fs'); const proxy = http.createServer((req, res) => { if(req.method == 'POST'){ req.on('data' , (data)=>{ console.log('referer :' , req.headers.referer); console.log('data :' , data.toString() , ' cookies:' , req.headers.cookie); }); req.on('end' , (data)=>{ res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(''); }) } else { res.setHeader('Set-Cookie', ['login=1']); res.end(''); } }).listen(3001); 

在命令行中輸入node server.js
這是一個簡單的服務,端口為3001,如果我們直接本地登陸localhost:3001會給我們本地注入一個cookie為login=1的登陸態
此時我們在訪問csrf.html,在點擊提交按鈕的時候,會發現會把這個登陸態也提交上去。這就是一個典型的釣魚網站,

防范措施

  1. 提交 method=Post 判斷referer
    HTTP請求中有一個referer的報文頭,用來指明當前流量的來源參考頁。如果我們用post就可以將頁面的referer帶入,從而進行判斷請求的來源是不是安全的網站。但是referer在本地起的服務中是沒有的,直接請求頁面也不會有。這就是為什么我們要用Post請求方式。直接請求頁面,因為post請求是肯定會帶入referer,但get有可能不會帶referer。

  2. 利用Token
    Token簡單來說就是由后端生成的一個唯一的登陸態,並傳給前端保存在前端,每次前端請求時都會攜帶着Token,后端會先去解析這個Token,看看是不是后台給我們的,已經是否登陸超時,如果校驗通過了,才會同意接口請求



作者:魚仔1234
鏈接:https://www.jianshu.com/p/a38e280ed48b
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
 

三:sql攻擊

定義:輸入參數未經過濾,然后直接拼接到sql語句當中,解析執行,達到預想之外的效果稱為sql攻擊

舉個栗子:下面這種情況:我在輸入用戶賬號的時候,在后面加入了一個#號

 
 

這樣如果后代的執行 的mysql語句就會是這樣:                                                                                                  select * from userdatabase where username=1550976562# and password=' ',使用過mysql的用戶都知道#號是mysql的注釋,這樣后面的 and password=' '就會被當做注釋,不會被執行,因此攻擊者就可以不用密碼登錄你的網站了。

對SQL注入的防御方法主要有:

1. 字符串長度驗證,僅接受指定長度范圍內的變量值。sql注入腳本必然會大大增加輸入變量的長度,通過長度限制,比如用戶名長度為 8 到 20 個字符之間,超過就判定為無效值。

2. 對單引號和雙"-"、下划線、百分號等sql注釋符號進行轉義

3. 對接收的參數進行類型格式化,如id參數值獲取后,進行int類型轉換

4. 永遠不要使用動態拼裝SQL,推薦使用參數化的SQL或者直接使用存儲過程進行數據查詢存取。sql注入最主要的攻擊對象就是動態拼裝的SQL,通過參數化查詢可以極大減少SQL注入的風險。

5. 永遠不要使用管理員權限的數據庫連接(sa、root、admin),為每個應用使用單獨的專用的低特權賬戶進行有限的數據庫連接。

6. 不要把機密信息明文存放,請加密或者hash掉密碼和敏感的信息。這樣對方就算獲取到整個表的數據內容,也沒什么價值。

7. 應用的異常信息應該給出盡可能少的提示,最好使用自定義的錯誤信息對原始錯誤信息進行包裝,把異常信息輸出到日志而不是在頁面中展示。

8. 做好XSS跨站攻擊的防護,防止攻擊者偽造管理員信息進入系統后台

9. 不管客戶端是否做過數據校驗,在服務端必須要有數據校驗(長度、格式、是否必填等等)



作者:15545985473
鏈接:https://www.jianshu.com/p/ee24eafe0e9e
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
 
四. 上傳漏洞
 

文件上傳漏洞是指用戶上傳了一個可執行的腳本文件,並通過此腳本文件獲得了執行服務器端命令的能力。文件上傳功能本身是一個正常的業務需求,對於網站來說,很多時候也確實需要用戶將文件上傳到服務器。所以文件上傳本身沒有問題,但又問題的是文件上傳后,服務器怎么處理、解釋文件。如果服務器的處理邏輯做得不夠安全,則會導致嚴重的后果。----摘自《白帽子講WEB安全》

一、漏洞成立的條件

1、上傳的文件能夠被WEB容器解釋執行。
2、用戶能夠從web上訪問這個文件。如果文件上傳了,但用戶無法通過web訪問,或者無法使得web容器解釋這個腳本,那么也不能稱之為漏洞。

二、常見防御措施及軟肋

1、在前端驗證文件擴展名

​ 通過這種方式的驗證,繞過方式有二:

(1)客戶端禁用JS腳本

​ 禁用JS腳本,這就使得驗證文件的功能失效,用戶可上傳任意的文件。

(2)通過抓包改包方式

​ 假如前端限制了只允許上傳png格式的文件。我們首先將一句話木馬文件后綴名更改為png后上傳。此時會繞過前端js的驗證,繞過驗證后,通過抓包,修改報文中文件名的后綴,使其還原。顯然,一句話木馬上傳成功。

2、在服務端驗證文件類型

​ 在服務端驗證文件類型,一般是校驗Content-type字段的值。同樣,通過抓包改包可成功繞過其驗證。

3、在服務端驗證文件后綴名

(1)黑名單校驗

​ 黑名單校驗方式極不靠譜,我們總會找到一些漏網之魚,也有可能存在一些大小寫繞過的方式。比如 aSp 和 pHp 之類的。

(2)白名單校驗

​ 白名單校驗,其防御能力相對於黑名單校驗,要更安全,增加了攻擊者的攻擊難度。但是白名單也有其軟肋之處:如果服務器存在解析漏洞或截斷,則會成功觸發漏洞。如:

A:0x00 截斷繞過

​ 用像test.asp%00.jpg的方式進行截斷,屬於白名單文件。由於存在0x00,服務器會認為是asp文件。

B:解析/包含漏洞繞過

​ 這類漏洞直接配合上傳一個代碼注入過的白名單文件即可,再利用解析,包含漏洞。

4、在服務端驗證文件內容

​ 驗證文件內容,加大了攻擊者的攻擊難度。但在一定條件下,也有繞過的可能。其繞過方式有二:

(1)制作圖片馬

(2)文件幻術頭繞過

三、總結

​ 以上這些防御措施,如果在一定的限制條件下,是“安全的”。如果超過了安全邊界,則會變得那么不安全。對於文件上傳漏洞,我們只要知道它成立的條件,則可在一定程度上進行防御。其總結如下:

1、上傳后的文件最好不可執行。

2、更改上傳后的文件名,不與上傳之前的文件名相同。

3、如非必要,不要暴漏文件的訪問路徑。



作者:無遠弗屆_90
鏈接:https://www.jianshu.com/p/6d16b6c622d6
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

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



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