雙引號
在js代碼中
在js中單、雙引號引起來的是字符串,如果我們要在字符串中使用單、雙引號,需要反斜杠進(jìn)行轉(zhuǎn)義
let str='user\'s name'; // or let str=" user's name"; // or let str="she said:\"...\".";
如果在字符串中輸出反斜杠,仍然是用反斜杠轉(zhuǎn)義,即2個反斜杠輸出1個反斜杠
在html代碼中
html標(biāo)簽中,屬性值通常用雙引號引起來,也可以使用單引號或不用引號。
<input name=user /> <input name="user" /> <input name='user' />
這3種寫法都正確,不過通常我們是選擇用雙引號引起來。
如果我們要在屬性值中使用單、雙綽號,我們不能直接寫成下面這樣
<input name=user'name /> <input name="user"name" /> <input name='user'name' />
這些全部是錯誤的。我們要像在js中對單、雙引號轉(zhuǎn)義一樣,對屬性中的單、雙引號轉(zhuǎn)義
在html中輸出預(yù)留符號,可以使用字符實(shí)體轉(zhuǎn)義的形式,這里有簡單介紹:http://www.w3school.com.cn/html/html_entities.asp。即想輸出一個雙引號可以使用"的形式,
<input name="user"name" />
除此之外,html還支持十進(jìn)制與十六進(jìn)制編碼的形式輸出字符,如我們知道字符a的ascii碼的十進(jìn)制是97 十六進(jìn)制是61
所以我們在頁面body中輸出一個字符a,有以下3種形式
<body> a<!--直接輸出--> a<!--十進(jìn)制輸出--> a<!--十六進(jìn)制輸出--> </body>
同樣,單雙引號也有十進(jìn)制(單:39,雙:34)與十六進(jìn)制(單:27,雙:22),所以我們在屬性中輸出一個單引號有2種選擇,十進(jìn)制與十六進(jìn)制
<input name='user'name' /><!--十進(jìn)制--> <input name='user'name' /><!--十六進(jìn)制-->
而輸出一個雙引號則有3種選擇
<input name="user"name" /><!--實(shí)體--> <input name="user"name" /><!--十進(jìn)制--> <input name="user"name" /><!--十六進(jìn)制-->
當(dāng)js代碼遇上實(shí)體編碼
我們可以通過dom節(jié)點(diǎn)提供的事件寫上調(diào)用js的代碼,如點(diǎn)擊body彈出hello這個字符串,我們可以寫成
<body onclick="alert('hello')"> click here </body>
如果我們的需求是就彈出一個雙引號呢?
根據(jù)前述規(guī)則,我們要寫成:
<body onclick="alert('"')"><!--這里用十進(jìn)制或十六進(jìn)制都可以--> click here </body>
當(dāng)然,alert里的單引號也可以使用十進(jìn)制或十六進(jìn)制編碼
<body onclick="alert("'")"><!--"單引號 '雙引號--> click here </body>
這樣也是可以的。
是不是有點(diǎn)xss的感覺?
如果我們把彈雙引號的需求改成單引號呢?
<body onclick="alert(''')"><!--這樣html中是合法的,但js中并不合法,因?yàn)樵趈s中,中間的單引號并沒有轉(zhuǎn)義--> click here </body>
如果我們用十進(jìn)制或十六進(jìn)制編碼呢?
<body onclick="alert('"')"><!--這樣可以嗎--> click here </body>
這樣仍然是不可以的
我們要對js字符串中的單引號進(jìn)行轉(zhuǎn)義,如
<body onclick="alert('\'')"><!--轉(zhuǎn)義后可正確彈出--> click here </body>
或
<body onclick="alert('\"')"><!--轉(zhuǎn)義后可正確彈出--> click here </body>
前面的onclick="alert('\'')"看起來還正常,后面的這個onclick="alert('\"')"就有點(diǎn)不直觀了。因?yàn)楹竺孢@個看上去反斜杠像在轉(zhuǎn)義&這1個字符,而&在js的字符串中并不需要轉(zhuǎn)義的。
動態(tài)輸出
如前述的alert彈出的消息,如果是一個變量控制,動態(tài)輸出呢?
<body onclick="alert('${msg}')"> click here </body>
那我們這個msg字符串就得注意了,從這個示例來看,這個動態(tài)的msg即出現(xiàn)在屬性onclick中,也出現(xiàn)在alert的單引號開始的字符串中。
我們要對msg中的雙引號轉(zhuǎn)成"或"或",并對msg中單引號的前面加上一個反斜杠\ ?
題外話:對msg中的反斜杠需要做double處理,因?yàn)榉葱备茉趆tml屬性中并不是特殊的,但在js的字符串中是特殊的。因此正確的做法是對反斜杠及單引號前面各加上一個反斜杠
然而,你并不能保證屬性是用雙引號,alert中的字符串用的是單引號,因?yàn)榭梢詫懗上旅孢@樣
<body onclick='alert("${msg}")'> click here </body>
?
這種情況我們要對msg中的單引號轉(zhuǎn)成'或',并對msg中雙引號前面加上一個反斜杠\
題外話:同上
看上去要根據(jù)不同的情況做不同的處理,其實(shí)也不需要
我們只需要對單、雙引號前面加上一個反斜杠\然后再對單、雙引號實(shí)體編碼即可。
在js中如果反斜杠后面跟的不需要反斜杠轉(zhuǎn)義的字符,那么這個反斜杠是被丟棄的,因此像
var str="user\'s name";
單引號前面多加一個反斜杠也不要緊的。
自動化處理與識別提醒
在magix項(xiàng)目中,由于magix-combine的支持,可識別出屬性中js代碼的部分,并自動化處理,如
<button mx-click="showName({name:'<%=name%>'})">click here</button>
name這個變量可包含任意的單、雙引號及反斜杠。工具自動識別并處理,開發(fā)者不需要做任何事情。
而對于這樣的寫法:
<button mx-click="showName({name:'"'})">click here</button> <!-- or--> <button mx-click="showName({name:'\"'})">click here</button>
第一種寫法其實(shí)并不正確,但第二種情況看上去又怪怪的。magix-combine工具能識別出來是否需要添加反斜杠,并自動添加處理。
第一種需要添加反斜杠,工具會自動加上,并提醒開發(fā)者這里的寫法是不正確的。
第二種說明開發(fā)者意識到了問題所在,自己處理了,工具就不再處理也不再提醒開發(fā)者。
eb安全是指保護(hù)Web應(yīng)用程序、Web服務(wù)器和Web瀏覽器免受各種網(wǎng)絡(luò)攻擊和惡意行為的方法和技術(shù)。隨著越來越多的業(yè)務(wù)和活動轉(zhuǎn)移到互聯(lián)網(wǎng)上,Web安全成為越來越重要的問題。
Web安全包括以下方面:
以下以編碼安全、邏輯安全、數(shù)據(jù)安全展開說明。
本文介紹編碼安全,邏輯安全、數(shù)據(jù)安全在下一篇文章中介紹。
1. 什么是編碼安全?
安全編碼規(guī)范是一種定義編碼要求的標(biāo)準(zhǔn)化方法。它確保代碼是高質(zhì)量、可重用和安全的。安全編碼規(guī)范應(yīng)該適用于代碼開發(fā)、測試和維護(hù)的所有階段。
安全編碼規(guī)范應(yīng)該涵蓋以下方面:身份驗(yàn)證、授權(quán)、輸入驗(yàn)證、輸出編碼、錯誤處理和安全配置管理等。
2. 編碼安全-輸入驗(yàn)證
任何來自客戶端的數(shù)據(jù),如 URL 和參數(shù)、HTTP 頭部、Javascript 或其他嵌入代碼提交的信息,都屬于不可信數(shù)據(jù)。在應(yīng)用外部邊界或內(nèi)部每個組件或功能邊界,都將其當(dāng)做潛在的惡意輸入來校驗(yàn)。
輸入驗(yàn)證通常采用以下幾點(diǎn):
a. 白名單
不可信數(shù)據(jù)可以設(shè)定白名單校驗(yàn)的,應(yīng)接受所有和白名單匹配的數(shù)據(jù),并阻止其他數(shù)據(jù)。
b. 黑名單
不可信數(shù)據(jù)中包含不良輸入字符時,如空字節(jié)(%00)、換行符(%0d,%0a)、路徑字符(../或..)等,建議直接阻止該數(shù)據(jù),若需要接受該數(shù)據(jù),則應(yīng)做不同方式的凈化處理。
c. 規(guī)范化/合法性校正
不可信數(shù)據(jù)需實(shí)施各種凈化處理時,應(yīng)徹底刪除惡意字符,只留下已知安全的字符,或者在處理前對它們進(jìn)行適當(dāng)編碼或“轉(zhuǎn)義”,如數(shù)據(jù)輸出到應(yīng)用頁面時對其進(jìn)行HTML編碼可防止腳本攻擊、不可信數(shù)據(jù)的合法性校驗(yàn)包括:數(shù)據(jù)類型如字符。數(shù)字、日期等特征;數(shù)據(jù)長度等。
d. 防范SQL注入
不可信數(shù)據(jù)進(jìn)入后端數(shù)據(jù)庫揉作前,建議使用正確的參數(shù)化查詢來處理,禁止拼接 SQL 語句,避免出現(xiàn) SQL 注入。
e. 訪問控制
不可信數(shù)據(jù)通過上述校驗(yàn)后,還應(yīng)確認(rèn)所提交的內(nèi)容是否與用戶的身份匹配,避免越權(quán)訪問。
3. 編碼安全-輸出驗(yàn)證:
考慮目標(biāo)編譯器的安全性,對所有輸出字符進(jìn)行正確編碼。
輸入驗(yàn)證通常采用以下幾點(diǎn)
a. 編碼輸出
不可信數(shù)據(jù)輸出到前后端頁面時,根據(jù)輸出場景對其進(jìn)行相關(guān)編碼,如 HTML 實(shí)體編碼、UR 編碼。
b. 凈化輸出
針對操作系統(tǒng)命令、SQL 和 LDAP查詢,凈化所有輸出的敏感信息,如銀行卡、手機(jī)號、系統(tǒng)信息等
c. 規(guī)范輸出
可以采用JSON 格式作為統(tǒng)一的返回值格式這樣方便客戶端和服務(wù)器端進(jìn)行數(shù)據(jù)交換(包括返回的狀態(tài)碼、消息、數(shù)據(jù)等信息)
4. Sql注入
SQL注入就是在Web表單提交數(shù)據(jù)/傳輸數(shù)據(jù)時,將預(yù)先準(zhǔn)備好的SQL語句添加進(jìn)去,達(dá)到欺騙服務(wù)器、修改SQL語句執(zhí)行結(jié)果,非法獲取服務(wù)器端數(shù)據(jù)的目的。
4.1 Sql注入原理
攻擊者猜測Web系統(tǒng)的數(shù)據(jù)驗(yàn)證過程,在輸入數(shù)據(jù)的最后加上一段SQL語句,讓服務(wù)器端的SQL執(zhí)行出現(xiàn)偏差,從而欺騙服務(wù)器,甚至可獲取數(shù)據(jù)庫的管理權(quán)限,然后將數(shù)據(jù)庫管理用戶權(quán)限提升至操作系統(tǒng)管理用戶權(quán)限,控制服務(wù)器操作系統(tǒng),獲取重要信息及機(jī)密文件
4.2 SQL注入流程
?判斷是否存在注入,注入是字符型還是數(shù)字型
?猜解SQL查詢語句中的字段數(shù)
?確定顯示位置
?獲取當(dāng)前數(shù)據(jù)庫
?獲取數(shù)據(jù)庫中的表
?獲取表中的字段名
?下載數(shù)據(jù)
4.3 尋找SQL注入點(diǎn)
SQL注入可以出現(xiàn)在任何從系統(tǒng)或用戶接收數(shù)據(jù)輸入的前端應(yīng)用程序中,這些應(yīng)用程序之后被用于訪問數(shù)據(jù)庫服務(wù)器。如果要對一個網(wǎng)站進(jìn)行SQL注入攻擊,首先就需要找到存在SQL注入漏洞的地方,也就是尋找所謂的注入點(diǎn)。可能的SQL注入點(diǎn)一般存在于登錄頁面、查找頁面或添加頁面等用戶可以查找或修改數(shù)據(jù)的地方。最常用的尋找SQL注入點(diǎn)的方法,是在網(wǎng)站中尋找如下形式的頁面鏈接:http://www.abc.com/xyz.xxx?id=yy,其中“yy”可能是數(shù)字,也有可能是字符串,分別被稱為整數(shù)類型數(shù)據(jù)或者字符型數(shù)據(jù)。
4.4 Sql注入判斷
a.整型參數(shù)的判斷
當(dāng)輸入的參數(shù)YY為整型時,通常xyz.asp中SQL語句原貌大致如下:
select * from表名where字段=YY,所以可以用以下步驟測試SQL注入是否存在。
http://www.abc.com/xyz.xx?p=YY’(附加一個單引號),此時xyz.asp中的SQL語句變成了select * from表名where字段=YY’,xyz.asp運(yùn)行異常;
http://www.abc.com/xyz.xx?p=YYand 1=1,xyz.asp運(yùn)行正常,而且與http://www.abc.com/xyz.xxp?p=YY運(yùn)行結(jié)果相同;
http://www.abc.com/xyz.xx?p=YYand1=2,xyz.asp運(yùn)行異常;
如果以上三步全面滿足,xyz.asp中一定存在SQL注入漏洞。
b.字符串型參數(shù)的判斷
當(dāng)輸入的參數(shù)YY為字符串時,通常xyz.asp中SQL語句原貌大致如下:
select * from表名where字段='YY',所以可以用以下步驟測試SQL注入是否存在。
http://www.abc.com/xyz.xx?p=YY’(附加一個單引號),此時xyz.asp中的SQL語句變成了select * from表名where字段=YY’,xyz.asp運(yùn)行異常;
http://www.abc.com/xyz.xx?p=YY&nb...39;1'='1',xyz.asp運(yùn)行正常,而且與http://www.abc.com/xyz.xx?p=YY運(yùn)行結(jié)果相同;
http://www.abc.com/xyz.xx?p=YY&nb...39;1'='2',xyz.asp運(yùn)行異常;
如果以上三步全面滿足,xyz.asp中一定存在SQL注入漏洞
c.特殊情況的處理
有時程序員會在程序員過濾掉單引號等字符,以防止SQL注入。此時可以用以下幾種方法試一試。
大小寫混合法:某些語言并不區(qū)分大小寫(如asp),此時可將SQL語句中的命令字進(jìn)行大小寫混合來規(guī)避過濾技術(shù),如用wHeRe代替where等。
ASCII碼法:將輸入內(nèi)容的部分或全部字符使用ASCII碼來代替,這樣也有可能規(guī)避過濾技術(shù),如A=chr(65),a=chr(97)等
d.Sql注入示例
5. XSS攻擊
5.1 什么是XSS攻擊
XSS攻擊又稱為跨站腳本,XSS的重點(diǎn)不在于跨站點(diǎn),而是在于腳本的執(zhí)行。XSS是一種經(jīng)常出現(xiàn)在Web應(yīng)用程序中的計(jì)算機(jī)安全漏洞,是由于Web應(yīng)用程序?qū)τ脩舻妮斎脒^濾不足而產(chǎn)生的,它允許惡意web用戶將代碼植入到提供給其它用戶使用的頁面中。
5.2 XSS漏洞的危害
a.竊取管理員帳號或Cookie。入侵者可以冒充管理員的身份登錄后臺,使得入侵者具有惡意操縱后臺數(shù)據(jù)的能力,包括讀取、更改、添加、刪除一些信息。
b.竊取用戶的個人信息或者登錄帳號。對網(wǎng)站的用戶安全產(chǎn)生巨大的威脅。例如冒充用戶身份進(jìn)行各種操作。
c.網(wǎng)站掛馬。先將惡意攻擊代碼嵌入到Web應(yīng)用程序之中。當(dāng)用戶瀏覽該掛馬頁面時,用戶的計(jì)算機(jī)會被植入木馬。
d.發(fā)送廣告或者垃圾信息。攻擊者可以利用XSS漏洞植入廣告,或者發(fā)送垃圾信息,嚴(yán)重影響到用戶的正常使用。
5.3 Xss漏洞分類
a.反射型XSS
反射型XSS,也稱為非持久性XSS,是最常見的一種XSS。
XSS代碼常常出現(xiàn)在URL請求中,當(dāng)用戶訪問帶有XSS代碼的URL請求時,服務(wù)器端接收請求并處理,然后將帶有XSS代碼的數(shù)據(jù)返回給瀏覽器,瀏覽器解析該段帶有XSS代碼的數(shù)據(jù)并執(zhí)行,整個過程就像一次反射,故稱為反射型XSS。
該類攻擊的主要特點(diǎn)是它的及時性和一次性,即用戶提交請求后,響應(yīng)信息會立即反饋給用戶。該類攻擊常發(fā)生在搜索引擎、錯誤提示頁面等對用戶的輸入做出直接反應(yīng)的場景中。
b.存儲型XSS
存儲型XSS,也稱為持久性XSS。
在存儲型XSS中,XSS代碼被存儲到服務(wù)器端,因此允許用戶存儲數(shù)據(jù)到服務(wù)器端的Web應(yīng)用程序可能存在該類型XSS漏洞。攻擊者提交一段XSS代碼后,服務(wù)器接收并存儲,當(dāng)其他用戶訪問包含該XSS代碼的頁面時,XSS代碼被瀏覽器解析并執(zhí)行。
存儲型XSS攻擊的特點(diǎn)之一是提交的惡意內(nèi)容會被永久存儲,因而一個單獨(dú)的惡意代碼就會使多個用戶受害,故被稱為持久性XSS,它也是跨站腳本攻擊中最危險(xiǎn)的一類。二是被存儲的用戶提交的惡意內(nèi)容不一定被頁面使用,因此存在危險(xiǎn)的響應(yīng)信息不一定被立即返回,也許在訪問那些在時間上和空間上沒有直接關(guān)聯(lián)的頁面時才會引發(fā)攻擊,因此存在不確定性和更好的隱蔽性。
這類攻擊的一個典型場景是留言板、博客和論壇等,當(dāng)惡意用戶在某論壇頁面發(fā)布含有惡意的Javascript代碼的留言時,論壇會將該用戶的留言內(nèi)容保存在數(shù)據(jù)庫或文件中并作為頁面內(nèi)容的一部分顯示出來。當(dāng)其他用戶查看該惡意用戶的留言時,惡意用戶提交的惡意代碼就會在用戶瀏覽器中解析并執(zhí)行。
c.DOM型XSS
DOM (Document Objet Model)指文檔對象模型。
DOM常用來表示在HTML和XML中的對象。DOM可以允許程序動態(tài)的訪問和更新文檔的內(nèi)容、結(jié)構(gòu)等。客戶端JavaScript可以訪問瀏覽器的文檔對象模型。也就是說,通過JavaScript代碼控制DOM節(jié)點(diǎn)就可以不經(jīng)過服務(wù)器端的參與重構(gòu)HTML頁面。
該類攻擊是反射型XSS的變種。它通常是由于客戶端接收到的腳本代碼存在邏輯錯誤或者使用不當(dāng)導(dǎo)致的。比如Javascript代碼不正確地使用各種DOM方法(如document.write)和Javascript內(nèi)部函數(shù)(如eval函數(shù)),動態(tài)拼接HTML代碼和腳本代碼就容易引發(fā)DOM型的跨站腳本攻擊。
因此,DOM型XSS與前面兩種XSS的區(qū)別就在于DOM型XSS攻擊的代碼不需要與服務(wù)器端進(jìn)行交互,DOM型XSS的觸發(fā)基于瀏覽器端對DOM數(shù)據(jù)的解析來完成,也就是完全是客戶端的事情。
5.4 Xss漏洞分類判斷
如何判斷是哪一種XSS, 發(fā)送一次帶XSS代碼的請求,若只能在當(dāng)前返回的數(shù)據(jù)包里發(fā)現(xiàn)XSS代碼,則是反射型;若以后這個頁面的返回包里都會有XSS代碼,則是存儲型;若在返回包里找不到XSS代碼,則是DOM型。
5.5 XSS漏洞的檢測與防御
a.手工檢測
手工檢測重點(diǎn)要考慮數(shù)據(jù)輸入的地方,且需要清楚輸入的數(shù)據(jù)輸出到什么地方。
在檢測的開始,可以輸入一些敏感字符,比如“<、>、()”等,提交后查看網(wǎng)頁源代碼的變化以發(fā)現(xiàn)輸入被輸出到什么地方,且可以發(fā)現(xiàn)相關(guān)敏感字符是否被過濾。
手工檢測結(jié)果相對準(zhǔn)確,但效率較低。
b.工具檢測
常用工具有AVWS(Acunetix Web Vulnerability Scanner)、BurpSuite等。還有一些專門針對XSS漏洞的檢測工具,如:XSSer、XSSF(跨站腳本攻擊框架)、BeEF(The Browser Exploitation Framework)等
c.防御
使用黑名單進(jìn)行:
●對HTML標(biāo)簽或特殊字符進(jìn)行過濾
●使用內(nèi)容安全的CSP
●使用設(shè)計(jì)上就會自動編碼的框架,如:OWASP ESAPI、React JS、JSOUP等,對于JAVA而言,可以使用ESAPI.encoder().encodeForHTML()對字符串進(jìn)行HTML編碼。
●對于反射型和存儲型XSS,可以在數(shù)據(jù)返回給客戶端瀏覽器時,將敏感字符進(jìn)行轉(zhuǎn)義,如:將單引號進(jìn)行編碼替換(十進(jìn)制編碼'、十六進(jìn)制編碼'、HTML編碼&apos、Unicode編碼\u0027等)。
●對于DOM型XSS,可以使用上下文敏感數(shù)據(jù)編碼。如:在PHP中的htmlspecialchars()、htmlentities()函 數(shù)可以將一些預(yù)定義的字符轉(zhuǎn)換為HTML實(shí)體,如:小于轉(zhuǎn)化為<、大于轉(zhuǎn)化為>、雙引號轉(zhuǎn)化為"、單引號轉(zhuǎn)化為&apos、轉(zhuǎn)化為&等。
●啟用瀏覽器的HttpOnly特性可以組織客戶端腳本訪問cookie。如:在PHP中可以通過下面的代碼設(shè)置cookie并啟用HttpOnly。
案例1:某app搜索接口越權(quán)獲取敏感信息
cloud/search/group/userstaff_id 可枚舉,通過遍歷將任意的用戶拉入群聊,直接獲取大量員工的個人敏感信息,涉及組織機(jī)構(gòu)、手機(jī)號
案例2:“某某查”付費(fèi)資源泄露
5. 文件管理-上傳/下載
5.1 文件上傳
a. 身份校驗(yàn)
進(jìn)行文件上傳時,在服務(wù)端對用戶的身份進(jìn)行合法性校驗(yàn)。
b. 文件類型限制
須在服務(wù)器端采用白名單方式對上傳或下載的文件類型、大小進(jìn)行嚴(yán)格的限制。僅允許業(yè)務(wù)所需文件類型上傳,避免上傳.jsp、.jspx、.class、.java 等可執(zhí)行文件
c.禁止外部文件存儲于可執(zhí)行目錄
禁止外部文件存儲于 WEB 容器的可執(zhí)行目錄。建議保存在專門的文件服務(wù)器中。
d.隱藏文件路徑
進(jìn)行文件保存時,成功上傳的文件需要進(jìn)行隨機(jī)化重命名,禁止給客戶端返回保存的路徑信息。
5.2 文件下載
a.身份校驗(yàn)
進(jìn)行文件下載時,在服務(wù)端對用戶的身份進(jìn)行合法性校驗(yàn)。
b.文件訪問設(shè)置
進(jìn)行文件下載時,應(yīng)以二進(jìn)制形式下載,建議不提供直接訪問(防止木馬文件)。
c.目錄跳轉(zhuǎn)
禁止客戶端自定義文件下載路徑(如:使用../../../../../或..%2F..%2F..%2F..%2F 進(jìn)行跳轉(zhuǎn))
下一篇更新邏輯安全和數(shù)據(jù)安全,敬請期待!
參考答案:
TCP 協(xié)議通過三次握手建立可靠的點(diǎn)對點(diǎn)連接,具體過程是:
首先服務(wù)器進(jìn)入監(jiān)聽狀態(tài),然后即可處理連接
第一次握手:建立連接時,客戶端發(fā)送 syn 包到服務(wù)器,并進(jìn)入 SYN_SENT 狀態(tài),等待服務(wù)器確認(rèn)。在發(fā)送的包中還會包含一個初始序列號 seq。此次握手的含義是客戶端希望與服務(wù)器建立連接。
第二次握手:服務(wù)器收到 syn 包,然后回應(yīng)給客戶端一個 SYN+ACK 包,此時服務(wù)器進(jìn)入 SYN_RCVD 狀態(tài)。此次握手的含義是服務(wù)端回應(yīng)客戶端,表示已收到并同意客戶端的連接請求。
第三次握手:客戶端收到服務(wù)器的 SYN 包后,向服務(wù)器再次發(fā)送 ACK 包,并進(jìn)入 ESTAB_LISHED 狀態(tài)。
最后,服務(wù)端收到客戶端的 ACK 包,于是也進(jìn)入 ESTAB_LISHED 狀態(tài),至此,連接建立完成
參考答案:
針對 HTTPS 攻擊主要有 SSL 劫持攻擊和 SSL 剝離攻擊兩種。
SSL 劫持攻擊是指攻擊者劫持了客戶端和服務(wù)器之間的連接,將服務(wù)器的合法證書替換為偽造的證書,從而獲取客戶端和服務(wù)器之間傳遞的信息。這種方式一般容易被用戶發(fā)現(xiàn),瀏覽器會明確的提示證書錯誤,但某些用戶安全意識不強(qiáng),可能會點(diǎn)擊繼續(xù)瀏覽,從而達(dá)到攻擊目的。
SSL 剝離攻擊是指攻擊者劫持了客戶端和服務(wù)器之間的連接,攻擊者保持自己和服務(wù)器之間的 HTTPS 連接,但發(fā)送給客戶端普通的 HTTP 連接,由于 HTTP 連接是明文傳輸?shù)模纯色@取客戶端傳輸?shù)乃忻魑臄?shù)據(jù)。
參考答案:
首先說 http1.0
它的特點(diǎn)是每次請求和響應(yīng)完畢后都會銷毀 TCP 連接,同時規(guī)定前一個響應(yīng)完成后才能發(fā)送下一個請求。這樣做有兩個問題:
無法復(fù)用連接
每次請求都要創(chuàng)建新的 TCP 連接,完成三次握手和四次揮手,網(wǎng)絡(luò)利用率低
隊(duì)頭阻塞
如果前一個請求被某種原因阻塞了,會導(dǎo)致后續(xù)請求無法發(fā)送。
然后是 http1.1
http1.1 是 http1.0 的改進(jìn)版,它做出了以下改進(jìn):
長連接
http1.1 允許在請求時增加請求頭connection:keep-alive,這樣便允許后續(xù)的客戶端請求在一段時間內(nèi)復(fù)用之前的 TCP 連接
管道化
基于長連接的基礎(chǔ),管道化可以不等第一個請求響應(yīng)繼續(xù)發(fā)送后面的請求,但響應(yīng)的順序還是按照請求的順序返回。
緩存處理
新增響應(yīng)頭 cache-control,用于實(shí)現(xiàn)客戶端緩存。
斷點(diǎn)傳輸
在上傳/下載資源時,如果資源過大,將其分割為多個部分,分別上傳/下載,如果遇到網(wǎng)絡(luò)故障,可以從已經(jīng)上傳/下載好的地方繼續(xù)請求,不用從頭開始,提高效率
最后是 http2.0
http2.0 進(jìn)一步優(yōu)化了傳輸效率,它主要有以下改進(jìn):
二進(jìn)制分幀
將傳輸?shù)南⒎譃楦〉亩M(jìn)制幀,每幀有自己的標(biāo)識序號,即便被隨意打亂也能在另一端正確組裝
多路復(fù)用
基于二進(jìn)制分幀,在同一域名下所有訪問都是從同一個 tcp 連接中走,并且不再有隊(duì)頭阻塞問題,也無須遵守響應(yīng)順序
頭部壓縮
http2.0 通過字典的形式,將頭部中的常見信息替換為更少的字符,極大的減少了頭部的數(shù)據(jù)量,從而實(shí)現(xiàn)更小的傳輸量
服務(wù)器推
http2.0 允許服務(wù)器直接推送消息給客戶端,無須客戶端明確的請求
參考答案:
HTTP/1.1 不是二進(jìn)制傳輸,而是通過文本進(jìn)行傳輸。由于沒有流的概念,在使用并行傳輸(多路復(fù)用)傳遞數(shù)據(jù)時,接收端在接收到響應(yīng)后,并不能區(qū)分多個響應(yīng)分別對應(yīng)的請求,所以無法將多個響應(yīng)的結(jié)果重新進(jìn)行組裝,也就實(shí)現(xiàn)不了多路復(fù)用。
參考答案:
在 HTTP/2 中,有兩個非常重要的概念,分別是幀(frame)和流(stream)。 幀代表著最小的數(shù)據(jù)單位,每個幀會標(biāo)識出該幀屬于哪個流,流也就是多個幀組成的數(shù)據(jù)流。 多路復(fù)用,就是在一個 TCP 連接中可以存在多條流。換句話說,也就是可以發(fā)送多個請求,對端可以通過幀中的標(biāo)識知道屬于哪個請求。通過這個技術(shù),可以避免 HTTP 舊版本中的隊(duì)頭阻塞問題,極大的提高傳輸性能。
TCP 協(xié)議通過三次握手建立可靠的點(diǎn)對點(diǎn)連接,具體過程是:
首先服務(wù)器進(jìn)入監(jiān)聽狀態(tài),然后即可處理連接
第一次握手:建立連接時,客戶端發(fā)送 syn 包到服務(wù)器,并進(jìn)入 SYN_SENT 狀態(tài),等待服務(wù)器確認(rèn)。在發(fā)送的包中還會包含一個初始序列號 seq。此次握手的含義是客戶端希望與服務(wù)器建立連接。
第二次握手:服務(wù)器收到 syn 包,然后回應(yīng)給客戶端一個 SYN+ACK 包,此時服務(wù)器進(jìn)入 SYN_RCVD 狀態(tài)。此次握手的含義是服務(wù)端回應(yīng)客戶端,表示已收到并同意客戶端的連接請求。
第三次握手:客戶端收到服務(wù)器的 SYN 包后,向服務(wù)器再次發(fā)送 ACK 包,并進(jìn)入 ESTAB_LISHED 狀態(tài)。
最后,服務(wù)端收到客戶端的 ACK 包,于是也進(jìn)入 ESTAB_LISHED 狀態(tài),至此,連接建立完成
當(dāng)需要關(guān)閉連接時,需要進(jìn)行四次揮手才能關(guān)閉
Client 向 Server 發(fā)送 FIN 包,表示 Client 主動要關(guān)閉連接,然后進(jìn)入 FIN_WAIT_1 狀態(tài),等待 Server 返回 ACK 包。此后 Client 不能再向 Server 發(fā)送數(shù)據(jù),但能讀取數(shù)據(jù)。 Server 收到 FIN 包后向 Client 發(fā)送 ACK 包,然后進(jìn)入 CLOSE_WAIT 狀態(tài),此后 Server 不能再讀取數(shù)據(jù),但可以繼續(xù)向 Client 發(fā)送數(shù)據(jù)。 Client 收到 Server 返回的 ACK 包后進(jìn)入 FIN_WAIT_2 狀態(tài),等待 Server 發(fā)送 FIN 包。 Server 完成數(shù)據(jù)的發(fā)送后,將 FIN 包發(fā)送給 Client,然后進(jìn)入 LAST_ACK 狀態(tài),等待 Client 返回 ACK 包,此后 Server 既不能讀取數(shù)據(jù),也不能發(fā)送數(shù)據(jù)。 Client 收到 FIN 包后向 Server 發(fā)送 ACK 包,然后進(jìn)入 TIME_WAIT 狀態(tài),接著等待足夠長的時間(2MSL)以確保 Server 接收到 ACK 包,最后回到 CLOSED 狀態(tài),釋放網(wǎng)絡(luò)資源。 Server 收到 Client 返回的 ACK 包后便回到 CLOSED 狀態(tài),釋放網(wǎng)絡(luò)資源。
參考答案:
客戶端請求服務(wù)器,并告訴服務(wù)器自身支持的加密算法以及密鑰長度等信息 服務(wù)器響應(yīng)公鑰和服務(wù)器證書 客戶端驗(yàn)證證書是否合法,然后生成一個會話密鑰,并用服務(wù)器的公鑰加密密鑰,把加密的結(jié)果通過請求發(fā)送給服務(wù)器 服務(wù)器使用私鑰解密被加密的會話密鑰并保存起來,然后使用會話密鑰加密消息響應(yīng)給客戶端,表示自己已經(jīng)準(zhǔn)備就緒 客戶端使用會話密鑰解密消息,知道了服務(wù)器已經(jīng)準(zhǔn)備就緒。 后續(xù)客戶端和服務(wù)器使用會話密鑰加密信息傳遞消息
參考答案:
校驗(yàn)證書的頒發(fā)機(jī)構(gòu)是否受客戶端信任。 通過 CRL 或 OCSP 的方式校驗(yàn)證書是否被吊銷。 對比系統(tǒng)時間,校驗(yàn)證書是否在有效期內(nèi)。 通過校驗(yàn)對方是否存在證書的私鑰,判斷證書的網(wǎng)站域名是否與證書頒發(fā)的域名一致。
參考答案:
301 表示永久重定向,302 表示臨時重定向。
如果瀏覽器收到的是 301,則會緩存重定向的地址,之后不會再重新請求服務(wù)器,直接使用緩存的地址請求,這樣可以減少請求次數(shù)。但如果瀏覽器收到的是 302,則不會緩存重定向地址,瀏覽器將來會繼續(xù)以原有地址請求。
因此,301 適合地址永久轉(zhuǎn)移的場景,比如域名變更;而 302 適合臨時轉(zhuǎn)移的場景,比如首頁臨時跳轉(zhuǎn)到活動頁
參考答案:
由于瀏覽器會自動發(fā)送 cookie 到服務(wù)器,因此攻擊者可以利用這種特點(diǎn)進(jìn)行 csrf 攻擊。
而通常 token 是不放到 cookie 中的,需要瀏覽器端使用 JS 自行保存到 localstorage 中,在請求時也需要手動的加入到請求頭中,因此不容易引發(fā) csrf 攻擊。
參考答案:
以最常見的 token 格式 jwt 為例, token 分為三段,分別是 header、payload、signature。 其中,header 標(biāo)識簽名算法和令牌類型;payload 標(biāo)識主體信息,包含令牌過期時間、發(fā)布時間、發(fā)行者、主體內(nèi)容等;signature 是使用特定的算法對前面兩部分進(jìn)行加密,得到的加密結(jié)果。
token 有防篡改的特點(diǎn),如果攻擊者改動了前面兩個部分,就會導(dǎo)致和第三部分對應(yīng)不上,使得 token 失效。而攻擊者不知道加密秘鑰,因此又無法修改第三部分的值。
所以,在秘鑰不被泄露的前提下,一個驗(yàn)證通過的 token 是值得被信任的。
參考答案:
SSO 一般都需要一個獨(dú)立的認(rèn)證中心(passport),子系統(tǒng)的登錄均得通過 passport,子系統(tǒng)本身將不參與登錄操作,當(dāng)一個系統(tǒng)成功登錄以后,passport 將會頒發(fā)一個令牌給各個子系統(tǒng),子系統(tǒng)可以拿著令牌會獲取各自的受保護(hù)資源,為了減少頻繁認(rèn)證,各個子系統(tǒng)在被 passport 授權(quán)以后,會建立一個局部會話,在一定時間內(nèi)可以無需再次向 passport 發(fā)起認(rèn)證。
具體流程是:
用戶訪問系統(tǒng) 1 的受保護(hù)資源,系統(tǒng) 1 發(fā)現(xiàn)用戶未登錄,跳轉(zhuǎn)至 sso 認(rèn)證中心,并將自己的地址作為參數(shù) sso 認(rèn)證中心發(fā)現(xiàn)用戶未登錄,將用戶引導(dǎo)至登錄頁面 用戶輸入用戶名密碼提交登錄申請 sso 認(rèn)證中心校驗(yàn)用戶信息,創(chuàng)建用戶與 sso 認(rèn)證中心之間的會話,稱為全局會話,同時創(chuàng)建授權(quán)令牌 sso 認(rèn)證中心帶著令牌跳轉(zhuǎn)會最初的請求地址(系統(tǒng) 1) 系統(tǒng) 1 拿到令牌,去 sso 認(rèn)證中心校驗(yàn)令牌是否有效 sso 認(rèn)證中心校驗(yàn)令牌,返回有效,注冊系統(tǒng) 1 系統(tǒng) 1 使用該令牌創(chuàng)建與用戶的會話,稱為局部會話,返回受保護(hù)資源 用戶訪問系統(tǒng) 2 的受保護(hù)資源 系統(tǒng) 2 發(fā)現(xiàn)用戶未登錄,跳轉(zhuǎn)至 sso 認(rèn)證中心,并將自己的地址作為參數(shù) sso 認(rèn)證中心發(fā)現(xiàn)用戶已登錄,跳轉(zhuǎn)回系統(tǒng) 2 的地址,并附上令牌 系統(tǒng) 2 拿到令牌,去 sso 認(rèn)證中心校驗(yàn)令牌是否有效 sso 認(rèn)證中心校驗(yàn)令牌,返回有效,注冊系統(tǒng) 2 系統(tǒng) 2 使用該令牌創(chuàng)建與用戶的局部會話,返回受保護(hù)資源
參考答案:
客戶端請求服務(wù)器時,通過請求行告訴服務(wù)器使用的協(xié)議是 http1.1,同時在請求頭中附帶connection:keep-alive(為保持兼容),告訴服務(wù)器這是一個長連接,后續(xù)請求可以重復(fù)使用這一次的 TCP 連接。
這樣做的好處是減少了三次握手和四次揮手的次數(shù),一定程度上提升了網(wǎng)絡(luò)利用率。但由于 http1.1 不支持多路復(fù)用,響應(yīng)順序必須按照請求順序抵達(dá)客戶端,不能真正實(shí)現(xiàn)并行傳輸,因此在 http2.0 出現(xiàn)之前,實(shí)際項(xiàng)目中往往把靜態(tài)資源,比如圖片,分發(fā)到不同域名下的資源服務(wù)器,以便實(shí)現(xiàn)真正的并行傳輸。
參考答案:
客戶端將文件的二進(jìn)制內(nèi)容進(jìn)行分片,每片數(shù)據(jù)按順序進(jìn)行序號標(biāo)識,上傳每片數(shù)據(jù)時同時附帶其序號。服務(wù)器接收到每片數(shù)據(jù)時,將其保存成一個臨時文件,并記錄每個文件的 hash 和序號。
若上傳中止,將來再次上傳時,可以向服務(wù)器索要已上傳的分片序號,客戶端僅需上傳剩余分片即可。
當(dāng)全部分片上傳完成后,服務(wù)器按照分片的順序組裝成完整的文件,并刪除分片文件。
參考答案:
它們都是用于保證傳輸安全的協(xié)議,介于傳輸層和應(yīng)用層之間,TLS 是 SSL 的升級版。
它們的基本流程一致:
客戶端向服務(wù)器端索要公鑰,并使用數(shù)字證書驗(yàn)證公鑰。 客戶端使用公鑰加密會話密鑰,服務(wù)端用私鑰解密會話密鑰,于是得到一個雙方都認(rèn)可的會話密鑰 傳輸?shù)臄?shù)據(jù)使用會話密鑰加密,然后再傳輸,接收消息方使用會話密鑰解密得到原始數(shù)據(jù)
參考答案:
從上到下分別為:應(yīng)用層、傳輸層、網(wǎng)絡(luò)層、數(shù)據(jù)鏈路層、物理層。在發(fā)送消息時,消息從上到下進(jìn)行打包,每一層會在上一層基礎(chǔ)上加包,而接受消息時,從下到上進(jìn)行解包,最終得到原始信息。
其中:
應(yīng)用層主要面向互聯(lián)網(wǎng)中的應(yīng)用場景,比如網(wǎng)頁、郵件、文件中心等等,它的代表協(xié)議有 http、smtp、pop3、ftp、DNS 等等
傳輸層主要面向傳輸過程,比如 TCP 協(xié)議是為了保證可靠的傳輸,而 UDP 協(xié)議則是一種無連接的廣播,它們提供了不同的傳輸方式
網(wǎng)絡(luò)層主要解決如何定位目標(biāo)的問題,比如 IP、ICMP、ARP 等等
數(shù)據(jù)鏈路層的作用是將數(shù)據(jù)可靠的傳輸?shù)侥繕?biāo),比如常見的以太網(wǎng)協(xié)議、P2P 協(xié)議
物理層是要規(guī)范網(wǎng)絡(luò)兩端使用的物理設(shè)備,比如藍(lán)牙、wifi、光纖、網(wǎng)線接頭等等
參考答案:
從 http 協(xié)議的角度來說,GET 和 POST 它們都只是請求行中的第一個單詞,除了語義不同,其實(shí)沒有本質(zhì)的區(qū)別。
之所以在實(shí)際開發(fā)中會產(chǎn)生各種區(qū)別,主要是因?yàn)闉g覽器的默認(rèn)行為造成的。
受瀏覽器的影響,在實(shí)際開發(fā)中,GET 和 POST 有以下區(qū)別:
瀏覽器在發(fā)送 GET 請求時,不會附帶請求體 GET 請求的傳遞信息量有限,適合傳遞少量數(shù)據(jù);POST 請求的傳遞信息量是沒有限制的,適合傳輸大量數(shù)據(jù)。 GET 請求只能傳遞 ASCII 數(shù)據(jù),遇到非 ASCII 數(shù)據(jù)需要進(jìn)行編碼;POST 請求沒有限制 大部分 GET 請求傳遞的數(shù)據(jù)都附帶在 path 參數(shù)中,能夠通過分享地址完整的重現(xiàn)頁面,但同時也暴露了數(shù)據(jù),若有敏感數(shù)據(jù)傳遞,不應(yīng)該使用 GET 請求,至少不應(yīng)該放到 path 中 刷新頁面時,若當(dāng)前的頁面是通過 POST 請求得到的,則瀏覽器會提示用戶是否重新提交。若是 GET 請求得到的頁面則沒有提示。 GET 請求的地址可以被保存為瀏覽器書簽,POST 不可以
參考答案:
是指攻擊者在客戶端和服務(wù)器之間同時建立了連接通道,通過某種方式,讓客戶端請求發(fā)送到自己的服務(wù)器,然后自己就擁有了控制響應(yīng)內(nèi)容的能力,從而給客戶端展示錯誤的信息。
參考答案:
http 劫持是指攻擊者在客戶端和服務(wù)器之間同時建立了連接通道,通過某種方式,讓客戶端請求發(fā)送到自己的服務(wù)器,然后自己就擁有了控制響應(yīng)內(nèi)容的能力,從而給客戶端展示錯誤的信息,比如在頁面中加入一些廣告內(nèi)容。
DNS 劫持是指攻擊者劫持了 DNS 服務(wù)器,獲得了修改 DNS 解析記錄的權(quán)限,從而導(dǎo)致客戶端請求的域名被解析到了錯誤的 IP 地址,攻擊者通過這種方式竊取用戶資料或破壞原有正常服務(wù)。
XSS 是指跨站腳本攻擊。攻擊者利用站點(diǎn)的漏洞,在表單提交時,在表單內(nèi)容中加入一些惡意腳本,當(dāng)其他正常用戶瀏覽頁面,而頁面中剛好出現(xiàn)攻擊者的惡意腳本時,腳本被執(zhí)行,從而使得頁面遭到破壞,或者用戶信息被竊取。
要防范 XSS 攻擊,需要在服務(wù)器端過濾腳本代碼,將一些危險(xiǎn)的元素和屬性去掉或?qū)υ剡M(jìn)行HTML實(shí)體編碼。
參考答案:
XSS:
XSS 是指跨站腳本攻擊。攻擊者利用站點(diǎn)的漏洞,在表單提交時,在表單內(nèi)容中加入一些惡意腳本,當(dāng)其他正常用戶瀏覽頁面,而頁面中剛好出現(xiàn)攻擊者的惡意腳本時,腳本被執(zhí)行,從而使得頁面遭到破壞,或者用戶信息被竊取。
要防范 XSS 攻擊,需要在服務(wù)器端過濾腳本代碼,將一些危險(xiǎn)的元素和屬性去掉或?qū)υ剡M(jìn)行HTML實(shí)體編碼。
CSRF:
CSRF 是跨站請求偽造,是一種挾制用戶在當(dāng)前已登錄的Web應(yīng)用上執(zhí)行非本意的操作的攻擊方法
它首先引導(dǎo)用戶訪問一個危險(xiǎn)網(wǎng)站,當(dāng)用戶訪問網(wǎng)站后,網(wǎng)站會發(fā)送請求到被攻擊的站點(diǎn),這次請求會攜帶用戶的cookie發(fā)送,因此就利用了用戶的身份信息完成攻擊。
防御 CSRF 攻擊有多種手段:
不使用cookie 為表單添加校驗(yàn)的 token 校驗(yàn) cookie中使用sameSite字段 服務(wù)器檢查 referer 字段
參考答案:
客戶端請求服務(wù)器,并告訴服務(wù)器自身支持的加密算法以及密鑰長度等信息 服務(wù)器響應(yīng)公鑰和服務(wù)器證書 客戶端驗(yàn)證證書是否合法,然后生成一個會話密鑰,并用服務(wù)器的公鑰加密密鑰,把加密的結(jié)果通過請求發(fā)送給服務(wù)器 服務(wù)器使用私鑰解密被加密的會話密鑰并保存起來,然后使用會話密鑰加密消息響應(yīng)給客戶端,表示自己已經(jīng)準(zhǔn)備就緒 客戶端使用會話密鑰解密消息,知道了服務(wù)器已經(jīng)準(zhǔn)備就緒。 后續(xù)客戶端和服務(wù)器使用會話密鑰加密信息傳遞消息
參考答案:
主要是為了解決證書的可信問題。如果沒有權(quán)威機(jī)構(gòu)對證書進(jìn)行簽名,客戶端就無法知曉證書是否是偽造的,從而增加了中間人攻擊的風(fēng)險(xiǎn),https 就變得毫無意義。
參考答案:
密鑰
密鑰是一種參數(shù),它是在明文轉(zhuǎn)換為密文或?qū)⒚芪霓D(zhuǎn)換為明文的算法中輸入的參數(shù)。密鑰分為對稱密鑰與非對稱密鑰,分別應(yīng)用在對稱加密和非對稱加密上。
對稱加密
對稱加密又叫做私鑰加密,即信息的發(fā)送方和接收方使用同一個密鑰去加密和解密數(shù)據(jù)。對稱加密的特點(diǎn)是算法公開、加密和解密速度快,適合于對大數(shù)據(jù)量進(jìn)行加密,常見的對稱加密算法有 DES、3DES、TDEA、Blowfish、RC5 和 IDEA。
非對稱加密
非對稱加密也叫做公鑰加密。非對稱加密與對稱加密相比,其安全性更好。對稱加密的通信雙方使用相同的密鑰,如果一方的密鑰遭泄露,那么整個通信就會被破解。而非對稱加密使用一對密鑰,即公鑰和私鑰,且二者成對出現(xiàn)。私鑰被自己保存,不能對外泄露。公鑰指的是公共的密鑰,任何人都可以獲得該密鑰。用公鑰或私鑰中的任何一個進(jìn)行加密,用另一個進(jìn)行解密。
摘要
摘要算法又稱哈希/散列算法。它通過一個函數(shù),把任意長度的數(shù)據(jù)轉(zhuǎn)換為一個長度固定的數(shù)據(jù)串(通常用 16 進(jìn)制的字符串表示)。算法不可逆。
參考答案:
websocket 協(xié)議 HTML5 帶來的新協(xié)議,相對于 http,它是一個持久連接的協(xié)議,它利用 http 協(xié)議完成握手,然后通過 TCP 連接通道發(fā)送消息,使用 websocket 協(xié)議可以實(shí)現(xiàn)服務(wù)器主動推送消息。
首先,客戶端若要發(fā)起 websocket 連接,首先必須向服務(wù)器發(fā)送 http 請求以完成握手,請求行中的 path 需要使用ws:開頭的地址,請求頭中要分別加入upgrade、connection、Sec-WebSocket-Key、Sec-WebSocket-Version標(biāo)記
然后,服務(wù)器收到請求后,發(fā)現(xiàn)這是一個 websocket 協(xié)議的握手請求,于是響應(yīng)行中包含Switching Protocols,同時響應(yīng)頭中包含upgrade、connection、Sec-WebSocket-Accept標(biāo)記
當(dāng)客戶端收到響應(yīng)后即可完成握手,隨后使用建立的 TCP 連接直接發(fā)送和接收消息。
參考答案:
當(dāng)頁面中需要觀察實(shí)時數(shù)據(jù)的變化(比如聊天、k 線圖)時,過去我們往往使用兩種方式完成:
第一種是短輪詢,即客戶端每隔一段時間就向服務(wù)器發(fā)送消息,詢問有沒有新的數(shù)據(jù)
第二種是長輪詢,發(fā)起一次請求詢問服務(wù)器,服務(wù)器可以將該請求掛起,等到有新消息時再進(jìn)行響應(yīng)。響應(yīng)后,客戶端立即又發(fā)起一次請求,重復(fù)整個流程。
無論是哪一種方式,都暴露了 http 協(xié)議的弱點(diǎn),即響應(yīng)必須在請求之后發(fā)生,服務(wù)器是被動的,無法主動推送消息。而讓客戶端不斷的發(fā)起請求又白白的占用了資源。
websocket 的出現(xiàn)就是為了解決這個問題,它利用 http 協(xié)議完成握手之后,就可以與服務(wù)器建立持久的連接,服務(wù)器可以在任何需要的時候,主動推送消息給客戶端,這樣占用的資源最少,同時實(shí)時性也最高。
參考答案:
https 有防篡改的特點(diǎn),只要瀏覽器證書驗(yàn)證過程是正確的,很難在用戶不察覺的情況下進(jìn)行攻擊。但若能夠更改瀏覽器的證書驗(yàn)證過程,便有機(jī)會實(shí)現(xiàn) https 中間人攻擊。
所以,要劫持 https,首先要偽造一個證書,并且要想辦法讓用戶信任這個證書,可以有多種方式,比如病毒、惡意軟件、誘導(dǎo)等。一旦證書被信任后,就可以利用普通中間人攻擊的方式,使用偽造的證書進(jìn)行攻擊。
參考答案:
使用 JSONP
這是一種古老的解決跨域問題的思路。在需要跨域請求時,事先準(zhǔn)備好一個處理服務(wù)器數(shù)據(jù)的函數(shù),然后生成一個script元素,src指向跨域站點(diǎn),同時把準(zhǔn)備好的函數(shù)名通過地址參數(shù)傳遞到服務(wù)器。
跨域站點(diǎn)返回一段調(diào)用該函數(shù)的腳本,當(dāng)客戶端接收到腳本后就會運(yùn)行事先準(zhǔn)備的函數(shù),從而實(shí)現(xiàn)跨域獲取數(shù)據(jù)。
JSONP 實(shí)現(xiàn)簡單、兼容性好,但缺點(diǎn)也很明顯,它只支持 get 請求,同時也有安全性問題,并且對服務(wù)器端代碼侵入性比較強(qiáng)。
使用 cors
在請求時,客戶端使用一些特殊的請求頭向服務(wù)器申請跨域訪問,并通過這些請求頭告訴服務(wù)器自己的行為。服務(wù)器根據(jù)自身的規(guī)則決定是否允許跨域,如果允許,則通過響應(yīng)頭告訴客戶端可以發(fā)送跨域請求。
cors 協(xié)議已被各種主流瀏覽器支持,它安全性高,同時也不會侵入服務(wù)器代碼,是目前最主流的跨域方式
除此之外,遠(yuǎn)古時期的跨域處理還包括 iframe、form 等,由于它們?nèi)毕莘浅C黠@,故很少使用了。
參考答案:
短輪詢。即客戶端每隔一段時間就向服務(wù)器發(fā)送消息,詢問有沒有新的數(shù)據(jù) 長輪詢,發(fā)起一次請求詢問服務(wù)器,服務(wù)器可以將該請求掛起,等到有新消息時再進(jìn)行響應(yīng)。響應(yīng)后,客戶端立即又發(fā)起一次請求,重復(fù)整個流程。 websocket,握手完畢后會建立持久性的連接通道,隨后服務(wù)器可以在任何時候推送新消息給客戶端
參考答案:
301 永久重定向,瀏覽器會把重定向后的地址緩存起來,將來用戶再次訪問原始地址時,直接引導(dǎo)用戶訪問新地址
302 臨時重定向,瀏覽器會引導(dǎo)用戶進(jìn)入新地址,但不會緩存原始地址,下一次用戶訪問源地址時,瀏覽器仍然要請求原地址的服務(wù)器
304 資源未修改,服務(wù)器通過該狀態(tài)碼告訴客戶端,請求的資源和過去一樣,并沒有任何變化,建議自行使用過去的緩存。通常,304 狀態(tài)碼的響應(yīng)中,服務(wù)器不會附帶任何的響應(yīng)體。
403 不允許訪問。服務(wù)器通過該狀態(tài)碼告訴客戶端,這個資源目前不允許訪問。這種狀態(tài)碼通常出現(xiàn)在權(quán)限不足的情況下。
參考答案:
瀏覽器自動補(bǔ)全協(xié)議、端口 瀏覽器自動完成url編碼 瀏覽器根據(jù)url地址查找本地緩存,根據(jù)緩存規(guī)則看是否命中緩存,若命中緩存則直接使用緩存,不再發(fā)出請求 通過DNS解析找到服務(wù)器的IP地址 瀏覽器向服務(wù)器發(fā)出建立TCP連接的申請,完成三次握手后,連接通道建立 若使用了HTTPS協(xié)議,則還會進(jìn)行SSL握手,建立加密信道。使用SSL握手時,會確定是否使用HTTP2 瀏覽器決定要附帶哪些cookie到請求頭中 瀏覽器自動設(shè)置好請求頭、協(xié)議版本、cookie,發(fā)出GET請求 服務(wù)器處理請求,進(jìn)入后端處理流程。完成處理后,服務(wù)器響應(yīng)一個HTTP報(bào)文給瀏覽器。 瀏覽器根據(jù)使用的協(xié)議版本,以及Connection字段的約定,決定是否要保留TCP連接。 瀏覽器根據(jù)響應(yīng)狀態(tài)碼決定如何處理這一次響應(yīng) 瀏覽器根據(jù)響應(yīng)頭中的Content-Type字段識別響應(yīng)類型,如果是text/html,則對響應(yīng)體的內(nèi)容進(jìn)行HTML解析,否則做其他處理 瀏覽器根據(jù)響應(yīng)頭的其他內(nèi)容完成緩存、cookie的設(shè)置 瀏覽器開始從上到下解析HTML,若遇到外部資源鏈接,則進(jìn)一步請求資源 解析過程中生成DOM樹、CSSOM樹,然后一邊生成,一邊把二者合并為渲染樹(rendering tree),隨后對渲染樹中的每個節(jié)點(diǎn)計(jì)算位置和大小(reflow),最后把每個節(jié)點(diǎn)利用GPU繪制到屏幕(repaint) 在解析過程中還會觸發(fā)一系列的事件,當(dāng)DOM樹完成后會觸發(fā)DOMContentLoaded事件,當(dāng)所有資源加載完畢后會觸發(fā)load事件
參考答案:
客戶端請求服務(wù)器,并告訴服務(wù)器自身支持的加密算法以及密鑰長度等信息 服務(wù)器響應(yīng)公鑰和服務(wù)器證書 客戶端驗(yàn)證證書是否合法,然后生成一個會話密鑰,并用服務(wù)器的公鑰加密密鑰,把加密的結(jié)果通過請求發(fā)送給服務(wù)器 服務(wù)器使用私鑰解密被加密的會話密鑰并保存起來,然后使用會話密鑰加密消息響應(yīng)給客戶端,表示自己已經(jīng)準(zhǔn)備就緒 客戶端使用會話密鑰解密消息,知道了服務(wù)器已經(jīng)準(zhǔn)備就緒。 后續(xù)客戶端和服務(wù)器使用會話密鑰加密信息傳遞消息
參考答案:
驗(yàn)證碼主要用于讓服務(wù)器區(qū)分請求是人還是機(jī)器發(fā)送的。這樣做是為了避免某些程序惡意的提交大量信息到服務(wù)器,進(jìn)而導(dǎo)致服務(wù)器產(chǎn)生大量的垃圾數(shù)據(jù)。有時,驗(yàn)證碼也可以防止機(jī)器暴力破解用戶密碼,它通過在短時間內(nèi)不斷提交登錄信息,嘗試各種密碼組合來達(dá)到破解的目的。
參考答案:
http1.0
每次請求和響應(yīng)完畢后都會銷毀 TCP 連接,同時規(guī)定前一個響應(yīng)完成后才能發(fā)送下一個請求。這樣做有兩個問題:
無法復(fù)用連接
每次請求都要創(chuàng)建新的 TCP 連接,完成三次握手和四次揮手,網(wǎng)絡(luò)利用率低
隊(duì)頭阻塞
如果前一個請求被某種原因阻塞了,會導(dǎo)致后續(xù)請求無法發(fā)送。
http2.0
http2.0 優(yōu)化了傳輸效率,它主要有以下改進(jìn):
二進(jìn)制分幀
將傳輸?shù)南⒎譃楦〉亩M(jìn)制幀,每幀有自己的標(biāo)識序號,即便被隨意打亂也能在另一端正確組裝
多路復(fù)用
基于二進(jìn)制分幀,在同一域名下所有訪問都是從同一個 tcp 連接中走,并且不再有隊(duì)頭阻塞問題,也無須遵守響應(yīng)順序
頭部壓縮
http2.0 通過字典的形式,將頭部中的常見信息替換為更少的字符,極大的減少了頭部的數(shù)據(jù)量,從而實(shí)現(xiàn)更小的傳輸量
服務(wù)器推
http2.0 允許服務(wù)器直接推送消息給客戶端,無須客戶端明確的請求
http3.0
http3.0 它完全拋棄了 TCP 協(xié)議,轉(zhuǎn)而使用 UDP 協(xié)議,是為了進(jìn)一步提升性能。 雖然 http2.0 進(jìn)行了大量的優(yōu)化,但它無法擺脫 TCP 協(xié)議本身的問題,比如建立連接時間長、對頭阻塞問題等等。為了保證傳輸?shù)目煽啃裕琱ttp3.0 使用了 QUIC 協(xié)議。
參考答案:
cookie、sessionStorage、localStorage 都是保存本地?cái)?shù)據(jù)的方式
其中,cookie 兼容性較好,所有瀏覽器均支持。瀏覽器針對 cookie 會有一些默認(rèn)行為,比如當(dāng)響應(yīng)頭中出現(xiàn)set-cookie字段時,瀏覽器會自動保存 cookie 的值;再比如,瀏覽器發(fā)送請求時,會附帶匹配的 cookie 到請求頭中。這些默認(rèn)行為,使得 cookie 長期以來擔(dān)任著維持登錄狀態(tài)的責(zé)任。與此同時,也正是因?yàn)闉g覽器的默認(rèn)行為,給了惡意攻擊者可乘之機(jī),CSRF 攻擊就是一個典型的利用 cookie 的攻擊方式。雖然 cookie 不斷的改進(jìn),但前端仍然需要另一種更加安全的保存數(shù)據(jù)的方式。
HTML5 新增了 sessionStorage 和 localStorage,前者用于保存會話級別的數(shù)據(jù),后者用于更持久的保存數(shù)據(jù)。瀏覽器針對它們沒有任何默認(rèn)行為,這樣一來,就把保存數(shù)據(jù)、讀取數(shù)據(jù)的工作交給了前端開發(fā)者,這就讓惡意攻擊者難以針對登錄狀態(tài)進(jìn)行攻擊。
cookie 的大小是有限制的,一般瀏覽器會限制同一個域下的 cookie 總量為 4M,而 sessionStorage 和 localStorage 則沒有限制
cookie 會與 domain、path 關(guān)聯(lián),而 sessionStorage 和 localStorage 只與 domain 關(guān)聯(lián)
參考答案:
form data 適合傳遞簡單的鍵值對信息,由于傳遞的信息比較扁平,難以傳遞深層次嵌套的數(shù)據(jù)
request payload 適合傳遞任意格式的數(shù)據(jù),包括單個數(shù)字、布爾、深層次嵌套的對象、數(shù)組等,但 request payload 不適合傳遞文件數(shù)據(jù)
在前后端分離的項(xiàng)目中,對于非文件數(shù)據(jù)的傳遞,都推薦使用 request payload 的形式,以傳遞最明確的數(shù)據(jù)類型和數(shù)據(jù)結(jié)構(gòu),而對于文件上傳,則推薦使用傳統(tǒng)的 form data
參考答案:
GET,表示向服務(wù)器獲取資源 POST,表示向服務(wù)器提交信息,通常用于產(chǎn)生新的數(shù)據(jù),比如注冊 PUT,表示希望修改服務(wù)器的數(shù)據(jù),通常用于修改 DELETE,表示希望刪除服務(wù)器的數(shù)據(jù) OPTIONS,發(fā)生在跨域的預(yù)檢請求中,表示客戶端向服務(wù)器申請跨域提交 TRACE,回顯服務(wù)器收到的請求,主要用于測試和診斷 CONNECT,用于建立連接管道,通常在代理場景中使用,網(wǎng)頁中很少用到
參考答案:
優(yōu)化打包體積
利用一些工具壓縮、混淆最終打包代碼,減少包體積
多目標(biāo)打包
利用一些打包插件,針對不同的瀏覽器打包出不同的兼容性版本,這樣一來,每個版本中的兼容性代碼就會大大減少,從而減少包體積
壓縮
現(xiàn)代瀏覽器普遍支持壓縮格式,因此服務(wù)端的各種文件可以壓縮后再響應(yīng)給客戶端,只要解壓時間小于優(yōu)化的傳輸時間,壓縮就是可行的
CDN
利用 CDN 可以大幅縮減靜態(tài)資源的訪問時間,特別是對于公共庫的訪問,可以使用知名的 CDN 資源,這樣可以實(shí)現(xiàn)跨越站點(diǎn)的緩存
緩存
對于除 HTML 外的所有靜態(tài)資源均可以開啟協(xié)商緩存,利用構(gòu)建工具打包產(chǎn)生的文件 hash 值來置換緩存
http2
開啟 http2 后,利用其多路復(fù)用、頭部壓縮等特點(diǎn),充分利用帶寬傳遞大量的文件數(shù)據(jù)
雪碧圖
對于不使用 HTTP2 的場景,可以將多個圖片合并為雪碧圖,以達(dá)到減少文件的目的
defer、async
通過 defer 和 async 屬性,可以讓頁面盡早加載 js 文件
prefetch、preload
通過 prefetch 屬性,可以讓頁面在空閑時預(yù)先下載其他頁面可能要用到的資源
通過 preload 屬性,可以讓頁面預(yù)先下載本頁面可能要用到的資源
多個靜態(tài)資源域
對于不使用 HTTP2 的場景,將相對獨(dú)立的靜態(tài)資源分到多個域中保存,可以讓瀏覽器同時開啟多個 TCP 連接,并行下載
參考答案:
過期時間
當(dāng)客戶端長時間沒有傳遞 sessionid 過來時,服務(wù)器可以在過期時間之后自動清除 session
客戶端主動通知
可以使用 JS 監(jiān)聽客戶端頁面關(guān)閉或其他退出操作,然后通知服務(wù)器清除 session
參考答案:
DNS 域名解析是指把域名解析成 IP 地址的過程。
在具體的實(shí)現(xiàn)上,域名解析是由多個層級的服務(wù)器共同完成的。在查詢域名時,客戶端會先檢查自身的 DNS 映射表,若找不到解析記錄,則使用用戶配置的 DNS 服務(wù)器,若目標(biāo) DNS 服務(wù)器中找不到記錄,則繼續(xù)往上一個層級尋找,直到到達(dá)根域名服務(wù)器,根域名服務(wù)器會根據(jù)域名的類型,將解析任務(wù)分發(fā)到對應(yīng)的子域名服務(wù)器依次查找,直到找到解析記錄為止。
注: 至此,網(wǎng)絡(luò)篇內(nèi)容就整理完了,目前正在整理關(guān)于vue方面的,大家可以期待一下。歡大家迎關(guān)注我哈,點(diǎn)擊鏈接即可關(guān)注 法醫(yī),大家認(rèn)真看哦,奧利給!
作者:法醫(yī)
鏈接:https://juejin.cn/post/7197070078360322109
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。