国产精品美女久久久浪潮AV,国产精品三级一二三区,久久精品国产一区二区小说 ,依依成人影视国产精品,全部无卡免费的毛片在线看,日本一区二区三深夜不卡,国产精品女同一区二区久久,国产精品夜色一区二区三区

        web安全之XSS實(shí)例解析

        2020-5-20    seo達(dá)人

        XSS

        跨站腳本攻擊(Cross Site Script),本來縮寫是 CSS, 但是為了和層疊樣式表(Cascading Style Sheet, CSS)有所區(qū)分,所以安全領(lǐng)域叫做 “XSS”;


        XSS攻擊,通常是指攻擊者通過 “HTML注入”篡改了網(wǎng)頁,插入了惡意的腳本,從而在用戶瀏覽網(wǎng)頁時(shí),對用戶的瀏覽器進(jìn)行控制或者獲取用戶的敏感信息(Cookie, SessionID等)的一種攻擊方式。


        頁面被注入了惡意JavaScript腳本,瀏覽器無法判斷區(qū)分這些腳本是被惡意注入的,還是正常的頁面內(nèi)容,所以惡意注入Javascript腳本也擁有了所有的腳本權(quán)限。如果頁面被注入了惡意 JavaScript腳本,它可以做哪些事情呢?


        可以竊取 cookie信息。惡意 JavaScript可以通過 ”doccument.cookie“獲取cookie信息,然后通過 XMLHttpRequest或者Fetch加上CORS功能將數(shù)據(jù)發(fā)送給惡意服務(wù)器;惡意服務(wù)器拿到用戶的cookie信息之后,就可以在其他電腦上模擬用戶的登陸,然后進(jìn)行轉(zhuǎn)賬操作。

        可以監(jiān)聽用戶行為。惡意JavaScript可以使用 "addEventListener"接口來監(jiān)聽鍵盤事件,比如可以獲取用戶輸入的銀行卡等信息,又可以做很多違法的事情。

        可以修改DOM 偽造假的登陸窗口,用來欺騙用戶輸入用戶名和密碼等信息。

        還可以在頁面內(nèi)生成浮窗廣告,這些廣告會(huì)嚴(yán)重影響用戶體驗(yàn)。

        XSS攻擊可以分為三類:反射型,存儲(chǔ)型,基于DOM型(DOM based XSS)


        反射型

        惡意腳本作為網(wǎng)絡(luò)請求的一部分。


        const Koa = require("koa");

        const app = new Koa();


        app.use(async ctx => {

           // ctx.body 即服務(wù)端響應(yīng)的數(shù)據(jù)

           ctx.body = '<script>alert("反射型 XSS 攻擊")</script>';

        })


        app.listen(3000, () => {

           console.log('啟動(dòng)成功');

        });

        訪問 http://127.0.0.1:3000/ 可以看到 alert執(zhí)行


        反射型XSS1


        舉一個(gè)常見的場景,我們通過頁面的url的一個(gè)參數(shù)來控制頁面的展示內(nèi)容,比如我們把上面的一部分代碼改成下面這樣


        app.use(async ctx => {

           // ctx.body 即服務(wù)端響應(yīng)的數(shù)據(jù)

           ctx.body = ctx.query.userName;

        })

        此時(shí)訪問 http://127.0.0.1:3000?userName=xiaoming 可以看到頁面上展示了xiaoming,此時(shí)我們訪問 http://127.0.0.1:3000?userName=<script>alert("反射型 XSS 攻擊")</script>, 可以看到頁面彈出 alert。


        反射型XSS2


        通過這個(gè)操作,我們會(huì)發(fā)現(xiàn)用戶將一段含有惡意代碼的請求提交給服務(wù)器,服務(wù)器在接收到請求時(shí),又將惡意代碼反射給瀏覽器端,這就是反射型XSS攻擊。另外一點(diǎn)需要注意的是,Web 服務(wù)器不會(huì)存儲(chǔ)反射型 XSS 攻擊的惡意腳本,這是和存儲(chǔ)型 XSS 攻擊不同的地方。


        在實(shí)際的開發(fā)過程中,我們會(huì)碰到這樣的場景,在頁面A中點(diǎn)擊某個(gè)操作,這個(gè)按鈕操作是需要登錄權(quán)限的,所以需要跳轉(zhuǎn)到登錄頁面,登錄完成之后再跳轉(zhuǎn)會(huì)A頁面,我們是這么處理的,跳轉(zhuǎn)登錄頁面的時(shí)候,會(huì)加一個(gè)參數(shù) returnUrl,表示登錄完成之后需要跳轉(zhuǎn)到哪個(gè)頁面,即這個(gè)地址是這樣的 http://xxx.com/login?returnUrl=http://xxx.com/A,假如這個(gè)時(shí)候把returnUrl改成一個(gè)script腳本,而你在登錄完成之后,如果沒有對returnUrl進(jìn)行合法性判斷,而直接通過window.location.href=returnUrl,這個(gè)時(shí)候這個(gè)惡意腳本就會(huì)執(zhí)行。


        存儲(chǔ)型

        存儲(chǔ)型會(huì)把用戶輸入的數(shù)據(jù)“存儲(chǔ)”在服務(wù)器。


        比較常見的一個(gè)場景就是,攻擊者在社區(qū)或論壇寫下一篇包含惡意 JavaScript代碼的博客文章或評論,文章或評論發(fā)表后,所有訪問該博客文章或評論的用戶,都會(huì)在他們的瀏覽器中執(zhí)行這段惡意的JavaScript代碼。


        存儲(chǔ)型攻擊大致需要經(jīng)歷以下幾個(gè)步驟


        首先攻擊者利用站點(diǎn)漏洞將一段惡意JavaScript代碼提交到網(wǎng)站數(shù)據(jù)庫中

        然后用戶向網(wǎng)站請求包含了惡意 JavaScript腳本的頁面

        當(dāng)用戶瀏覽該頁面的時(shí)候,惡意腳本就會(huì)將用戶的cookie信息等數(shù)據(jù)上傳到服務(wù)器

        存儲(chǔ)型XSS


        舉一個(gè)簡單的例子,一個(gè)登陸頁面,點(diǎn)擊登陸的時(shí)候,把數(shù)據(jù)存儲(chǔ)在后端,登陸完成之后跳轉(zhuǎn)到首頁,首頁請求一個(gè)接口將當(dāng)前的用戶名顯示到頁面


        客戶端代碼


        <!DOCTYPE html>

        <html lang="en">


        <head>

           <meta charset="UTF-8">

           <meta name="viewport" content="width=device-width, initial-scale=1.0">

           <meta http-equiv="X-UA-Compatible" content="ie=edge">

           <title>XSS-demo</title>

           <style>

               .login-wrap {

                   height: 180px;

                   width: 300px;

                   border: 1px solid #ccc;

                   padding: 20px;

                   margin-bottom: 20px;

               }

               input {

                   width: 300px;

               }

           </style>

        </head>


        <body>

           <div class="login-wrap">

               <input type="text" placeholder="用戶名" class="userName">

               <br>

               <input type="password" placeholder="密碼" class="password">

               <br>

               <br>

               <button class="btn">登陸</button>

           </div>

        </body>

        <script>

           var btn = document.querySelector('.btn');

           

           btn.onclick = function () {

               var userName = document.querySelector('.userName').value;

               var password = document.querySelector('.password').value;

               

               fetch('http://localhost:3200/login', {

                   method: 'POST',

                   body: JSON.stringify({

                       userName,

                       password

                   }),

                   headers:{

                       'Content-Type': 'application/json'

                   },

                   mode: 'cors'

               })

                   .then(function (response) {

                       return response.json();

                   })

                   .then(function (res) {

                       alert(res.msg);

                       window.location.href= "http://localhost:3200/home";

                   })

                   .catch(err => {

                       message.error(`本地測試錯(cuò)誤 ${err.message}`);

                       console.error('本地測試錯(cuò)誤', err);

                   });

           }

        </script>


        </html>

        服務(wù)端代碼


        const Koa = require("koa");

        const app = new Koa();

        const route = require('koa-route');

        var bodyParser = require('koa-bodyparser');

        const cors = require('@koa/cors');


        // 臨時(shí)用一個(gè)變量來存儲(chǔ),實(shí)際應(yīng)該存在數(shù)據(jù)庫中

        let currentUserName = '';


        app.use(bodyParser()); // 處理post請求的參數(shù)


        const login = ctx => {

           const req = ctx.request.body;

           const userName = req.userName;

           currentUserName = userName;


           ctx.response.body = {

               msg: '登陸成功'

           };

        }


        const home = ctx => {

           ctx.body = currentUserName;

        }

        app.use(cors());

        app.use(route.post('/login', login));

        app.use(route.get('/home', home));

        app.listen(3200, () => {

           console.log('啟動(dòng)成功');

        });

        點(diǎn)擊登陸將輸入信息提交大服務(wù)端,服務(wù)端使用變量 currentUserName來存儲(chǔ)當(dāng)前的輸入內(nèi)容,登陸成功后,跳轉(zhuǎn)到 首頁, 服務(wù)端會(huì)返回當(dāng)前的用戶名。如果用戶輸入了惡意腳本內(nèi)容,則惡意腳本就會(huì)在瀏覽器端執(zhí)行。


        在用戶名的輸入框輸入 <script>alert('存儲(chǔ)型 XSS 攻擊')</script>,執(zhí)行結(jié)果如下


        存儲(chǔ)型XSS


        基于DOM(DOM based XSS)

        通過惡意腳本修改頁面的DOM節(jié)點(diǎn),是發(fā)生在前端的攻擊


        基于DOM攻擊大致需要經(jīng)歷以下幾個(gè)步驟


        攻擊者構(gòu)造出特殊的URL,其中包含惡意代碼

        用戶打開帶有惡意代碼的URL

        用戶瀏覽器接受到響應(yīng)后執(zhí)行解析,前端JavaScript取出URL中的惡意代碼并執(zhí)行

        惡意代碼竊取用戶數(shù)據(jù)并發(fā)送到攻擊者的網(wǎng)站,冒充用戶行為,調(diào)用目標(biāo)網(wǎng)站接口執(zhí)行攻擊者指定的操作。

        舉個(gè)例子:


        <body>

           <div class="login-wrap">

               <input type="text" placeholder="輸入url" class="url">

               <br>

               <br>

               <button class="btn">提交</button>

               <div class="content"></div>

           </div>

        </body>

        <script>

           var btn = document.querySelector('.btn');

           var content = document.querySelector('.content');

           

           btn.onclick = function () {

               var url = document.querySelector('.url').value;

               content.innerHTML = `<a href=${url}>跳轉(zhuǎn)到輸入的url</a>`

           }

        </script>

        點(diǎn)擊提交按鈕,會(huì)在當(dāng)前頁面插入一個(gè)超鏈接,其地址為文本框的內(nèi)容。


        在輸入框輸入 如下內(nèi)容


        '' onclick=alert('哈哈,你被攻擊了')

        執(zhí)行結(jié)果如下


        基于DOM型XSS


        首先用兩個(gè)單引號閉合調(diào) href屬性,然后插入一個(gè)onclick事件。點(diǎn)擊這個(gè)新生成的鏈接,腳本將被執(zhí)行。


        上面的代碼是通過執(zhí)行 執(zhí)行 alert來演示的攻擊類型,同樣你可以把上面的腳本代碼修改為任何你想執(zhí)行的代碼,比如獲取 用戶的 cookie等信息,<script>alert(document.cookie)</script>,同樣也是可以的.

        防御XSS

        HttpOnly

        由于很多XSS攻擊都是來盜用Cookie的,因此可以通過 使用HttpOnly屬性來防止直接通過 document.cookie 來獲取 cookie。


        一個(gè)Cookie的使用過程如下


        瀏覽器向服務(wù)器發(fā)起請求,這時(shí)候沒有 Cookie

        服務(wù)器返回時(shí)設(shè)置 Set-Cookie 頭,向客戶端瀏覽器寫入Cookie

        在該 Cookie 到期前,瀏覽器訪問該域下的所有頁面,都將發(fā)送該Cookie

        HttpOnly是在 Set-Cookie時(shí)標(biāo)記的:


        通常服務(wù)器可以將某些 Cookie 設(shè)置為 HttpOnly 標(biāo)志,HttpOnly 是服務(wù)器通過 HTTP 響應(yīng)頭來設(shè)置的。


        const login = ctx => {

           // 簡單設(shè)置一個(gè)cookie

           ctx.cookies.set(

               'cid',

               'hello world',

               {

                 domain: 'localhost',  // 寫cookie所在的域名

                 path: '/home',       // 寫cookie所在的路徑

                 maxAge: 10 * 60 * 1000, // cookie有效時(shí)長

                 expires: new Date('2021-02-15'),  // cookie失效時(shí)間

                 httpOnly: true,  // 是否只用于http請求中獲取

                 overwrite: false  // 是否允許重寫

               }

             )

        }

        HttpOnly


        需要注意的一點(diǎn)是:HttpOnly 并非阻止 XSS 攻擊,而是能阻止 XSS 攻擊后的 Cookie 劫持攻擊。


        輸入和輸出的檢查

        永遠(yuǎn)不要相信用戶的輸入。


        輸入檢查一般是檢查用戶輸入的數(shù)據(jù)是都包含一些特殊字符,如 <、>, '及"等。如果發(fā)現(xiàn)特殊字符,則將這些字符過濾或編碼。這種可以稱為 “XSS Filter”。


        安全的編碼函數(shù)


        針對HTML代碼的編碼方式是 HtmlEncode(是一種函數(shù)實(shí)現(xiàn),將字符串轉(zhuǎn)成 HTMLEntrities)


        & --> &amp;

        < --> &lt;

        > --> &gt;

        " --> &quot;

        相應(yīng)的, JavaScript的編碼方式可以使用 JavascriptEncode。


        假如說用戶輸入了 <script>alert("你被攻擊了")</script>,我們要對用戶輸入的內(nèi)容進(jìn)行過濾(如果包含了 <script> 等敏感字符,就過濾掉)或者對其編碼,如果是惡意的腳本,則會(huì)變成下面這樣


        &lt;script&gt;alert("你被攻擊了");&lt;/script&gt;

        經(jīng)過轉(zhuǎn)碼之后的內(nèi)容,如 <script>標(biāo)簽被轉(zhuǎn)換為 &lt;script&gt;,即使這段腳本返回給頁面,頁面也不會(huì)指向這段代碼。


        防御 DOM Based XSS

        我們可以回看一下上面的例子


        btn.onclick = function () {

           var url = document.querySelector('.url').value;

           content.innerHTML = `<a href=${url}>跳轉(zhuǎn)到輸入的url</a>`

        }

        事實(shí)上,DOM Based XSS 是從 JavaScript中輸出數(shù)據(jù)到HTML頁面里。


        用戶輸入 '' onclick=alert('哈哈,你被攻擊了'),然后通過 innerHTML 修改DOM的內(nèi)容,就變成了 <a href='' onclick=alert('哈哈,你被攻擊了')>跳轉(zhuǎn)到輸入的url</a>, XSS因此產(chǎn)生。


        那么正確的防御方法是什么呢?

        從JavaScript輸出到HTML頁面,相當(dāng)于一次 XSS輸出的過程,需要根據(jù)不同場景進(jìn)行不同的編碼處理


        變量輸出到 <script>,執(zhí)行一次 JavascriptEncode

        通過JS輸出到HTML頁面


        輸出事件或者腳本,做 JavascriptEncode 處理

        輸出 HTML內(nèi)容或者屬性,做 HtmlEncode 處理

        會(huì)觸發(fā) DOM Based XSS的地方有很多,比如


        xxx.interHTML

        xxx.outerHTML

        document.write

        頁面中所有的inputs框

        XMLHttpRequest返回的數(shù)據(jù)

        ...


        項(xiàng)目中如果用到,一定要避免在字符串中拼接不可信的數(shù)據(jù)。


        利用CSP

        CSP (Content Security Policy) 即內(nèi)容安全策略,是一種可信白名單機(jī)制,可以在服務(wù)端配置瀏覽器哪些外部資源可以加載和執(zhí)行。我們只需要配置規(guī)則,如何攔截是由瀏覽器自己實(shí)現(xiàn)的。我們可以通過這種方式來盡量減少 XSS 攻擊。


        通常可以通過兩種方式來開啟 CSP:


        設(shè)置 HTTP Header 的 Content-Security-Policy

        Content-Security-Policy: default-src 'self'; // 只允許加載本站資源

        Content-Security-Policy: img-src https://*  // 只允許加載 HTTPS 協(xié)議圖片

        Content-Security-Policy: child-src 'none'    // 允許加載任何來源框架

        設(shè)置 meta 標(biāo)簽的方式

        <meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">

        日歷

        鏈接

        個(gè)人資料

        存檔

        主站蜘蛛池模板: 欧美videosdesexo| 在线观看日本高清=区| 美女脱了内裤打开腿让人的桶| 成人毛片一区二区| 国产日韩欧美一区在线| 性人久久久久| 人妻放荡乱h文| 真人高清实拍女处被破的视频| 亚洲精品国产av天美传媒| 亚洲毛片无码专区亚洲乱| 欧美熟妇喷潮xxxx| 亚洲人成自拍网站在线观看| 碌曲县| 日本熟妇色一本在线观看| 国产精品亚洲精品日韩已满| 无码国产成人午夜电影在线观看| 精品人妻一区二区三区丽| 成全电影大全在线观看第二季| 伊在人间香蕉最新视频| 国产免费av片无码永久免费| 亚洲国产日韩a在线播放| mm131美女图片尤物写真丝袜| 三年片在线观看免费观看大全+下载| 中文字幕日韩一区二区不卡| 久久亚洲av午夜福利精品一区| 国产内射在线激情一区| 成全电影在线观看免费| 久久久婷婷五月亚洲97色| 麻豆剧果冻传媒在线播放下载| 亚洲av无码国产在丝袜app| 和林格尔县| 人人玩人人添人人澡超碰| www.色.com| 国产av熟女一区二区三区| 磐安县| 国产手机在线αⅴ片无码观看| 俺去啦网站| 国产精品无码一本二本三本色| 国产亚洲欧洲aⅴ综合一区| 亚洲av日韩综合一区久热| 无码av波多野结衣久久|