摘要:前端如何防范跨站腳本攻擊是一種攻擊者向用戶的瀏覽器注入惡意代碼腳本的攻擊。調用該方法后,該節點上處理該事件的處理程序將被調用,事件不再被分派到其他節點。不論鼠標指針穿過被選元素或其子元素,都會觸發事件。
前端如何防范XSS
跨站腳本攻擊, 是一種攻擊者向用戶的瀏覽器注入惡意代碼腳本的攻擊。
XSS攻擊的種類:
持續型XSS攻擊
攻擊者輸入惡意代碼并通過評論或表單提交等方式將其提交到網站, 而網站的后端卻對用戶的數據不做任何處理進而直接存入數據庫, 當其他用戶訪問該網站并且需要請求網站的評論數據時網站后端直接從數據庫中取出帶有惡意代碼的數據返回給用戶頁面此時用戶就會遭受到攻擊, 比如while { alert( "Attack!" ) } 這樣的惡意腳本。
反射型XSS攻擊
用戶向網站發送get請求某個網頁的url, 但用戶點開的是帶攻擊的url類似于:
/* http://xxx?name= <-- evil url ctx.render("index.html", { name:name }); --index.html--${name}*/
基于DOM的XSS攻擊
它是反射型攻擊的一種, 此時服務器返回的頁面是正常的, 只是頁面在執行JS時會將惡意腳本一并執行。
/* http://xxx?name= <-- evil url --index.js-- var name = getparm("name"); document.querySelector("div").innerHTML = name; */
防止XSS注入的一些方法:
function htmlEncode(html) { var sub = document.createElement("div"); sub.textContent != null ? sub.textContent = html : sub.innerText = html; var output = sub.innerHTML; sub = null; return output; }
//既然有轉義當然也有反轉義的方法 function htmlDecode(text) { var sub = document.createElement("div"); sub.innerHTML = text; var output = sub.textContent || sub.innerText; sub = null; return output; }
/* @ escape() @ encodeURI() @ encodeURIComponent() -- 對應的解碼方法 -- @ unescape() @ unencodeURI() @ unencodeURIComponent() */
CSP的實質就是白名單制度, 開發者明確告訴客戶端, 哪些外部資源可以加載和執行, 等同于提供白名單。它的實現和執行全部由瀏覽器完成, 開發者只需提供配置, CSP大大增強了網頁的安全性。
有兩種方法可以啟用CSP, 一種是通過設置HTTP頭信息的Content-Security-Policy 字段, 另外一種是通過網頁中的 標簽。
CSP通過設置限制選項來提供我們所需的白名單:
/* @ script-src: 外部腳本 @ style-src: 樣式表 @ img-src: 圖像 @ media-src: 媒體文件 ( 音頻和視頻 ) @ font-src: 字體文件 @ object-src: 插件 ( 比如Flash ) @ child-src: 框架 @ connect-src: HTTP 連接 ( 通過 XHR、WebSockets、EventSource等 ) ...... */
default-src 用來設置上面每個選項的默認值:
Content-Security-Policy: default-src "self" // 限制所有的外部資源, 只能從當前域名加載
其他的一些限制:
/* @ block-all-mixed-content:HTTPS 網頁不得加載 HTTP 資源(瀏覽器已經默認開啟) @ upgrade-insecure-requests:自動將網頁上所有加載外部資源的 HTTP 鏈接換成 HTTPS 協議 @ sandbox:瀏覽器行為的限制,比如不能有彈出窗口等 */
使用report-uri 還可以記錄XSS注入的行為并報告給指定的url:
Content-Security-Policy: default-src "self"; ...; report-uri https://retroastro.com;
設置多個值, 用空格分隔:
Content-Security-Policy: script-src "self" https://host1.com https://host2.com
script-src 中的一些特殊值:
/* @ nonce: 每次HTTP回應給出一個授權token,頁面內嵌腳本必須有這個token,才會執行。 @ hash: 列出允許執行的腳本代碼的Hash值,頁面內嵌腳本的哈希值只有吻合的情況下,才能執行。 */ /* nonce值的例子: Content-Security-Policy: script-src "nonce-EDNnf03nceIOfn39fn3e9h3sdfa" 設置的nonce值要與內嵌腳本中的nonce相等才會執行代碼 */ /* hash值的例子: Content-Security-Policy: script-src "sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng=" 服務器給出一個允許執行代碼片段的hash值, 對應的代碼才會執行, 因為hash值相等。 */
JavaScript的各種寬高屬性
網上看到有一篇博客講的挺好挺全面的, 有需要的可以去看看:
戳這里看JS中的各種寬高圖解
場景:實現bilibili右側導航欄的切換導航效果。
// HTML LiveComicsDramaNativeMusicDanceGameScienceLifeKichikuAdvertiseEntertainFashionTVshowsFilmMovies
// CSS .elevator-module{ position:fixed; top:20px; left:50%; margin-left:590px; transition:all .4s ease; z-index:10; } .elevator-module .nav-list{ position:relative; background-color:#f6f9fa; border:1px solid #e5e9ef; overflow:hidden; border-radius:4px; } .elevator-module .nav-list .item{ width:48px; height:32px; line-height:32px; text-align:center; transition:all .3s; cursor:pointer; } .elevator-module .nav-list .item.on, .elevator-module .nav-list .item:hover{ background-color:#00a1d6; color:#fff; } .nav-list .item.active{ color:#fff; background:#00a1d6; } .elevator-module .s-line{ position:relative; border-left:1px solid #ffffd; border-right:1px solid #ffffd; height:9px; width:30px; margin:0 auto; } .elevator-module .back-top:hover{ background-color:#00a1d6; border-color:#00a1d6; } .elevator-module .back-top{ position:relative; display:block; cursor:pointer; height:50px; background-color:#f6f9fa; overflow:hidden; border: 1px solid #e5e9ef; border-radius:4px; text-align: center; } .circle{ display:inline-block; width:30px; height:30px; margin-top:10px; border-radius:50%; background:#ffafc9; } .part{ width:800px; height:600px; margin:20px auto; background:#00a1d6; text-align:center; line-height:600px; font-size:13em; font-family:Comic Sans MS; color:#fff; font-weight:700; border-radius:4px; } .container{ width:1160px; margin:0 auto; position:relative; }
// JavaScript var ElevatorModule = { init() { this.scrollEvent(); }, scrollEvent() { var elevator = document.querySelector(".elevator-module"); var navList = document.querySelector(".nav-list"); var items = document.querySelectorAll(".nav-list .item"); var modules = document.querySelectorAll(".part"); var backtop = document.querySelector(".back-top"); window.addEventListener("scroll", slipper); navList.addEventListener("click", moveTo); backtop.addEventListener("click", fly); function slipper() { for ( var item of items ) { var rect = item.getBoundingClientRect(); var scrollTop = document.documentElement.scrollTop; var item_top = rect.top + scrollTop; //獲取右側導航每個分區上方到頁面最頂部的距離 var fetch = getLocation(); var id = item.getAttribute("data-id"); if ( item_top >= fetch[id] - 100 ) { //移到哪個分區右側的hover就停留在哪 items.forEach((el) => { el.classList.remove("active"); }) item.classList.add("active"); } } } var flag = true; //定位到指定分區 function moveTo() { var e = window.event; items.forEach((item) => { item.classList.remove("active"); }) if ( e.target && e.target.nodeName == "DIV" ) { var id = e.target.getAttribute("data-id"); e.target.classList.add("active"); var fetch = getLocation(); if ( flag ) { AnimationFrame(fetch[id]); id ? flag = false : flag = true; //設置節流效果, 即在運動的過程中不允許再次觸發AnimationFrame函數 } } } //scrollTop過渡 function AnimationFrame(future_top) { let current_top = document.documentElement.scrollTop; var timer = setInterval( () => { if ( current_top > future_top ) { current_top -= 60; document.documentElement.scrollTop = current_top; } else if ( current_top < future_top ) { current_top += 60; document.documentElement.scrollTop = current_top; } if ( current_top >= future_top - 30 && current_top <= future_top + 30 ) { //當移動到指定的范圍內時直接定位到對應的位置 document.documentElement.scrollTop = future_top; clearInterval(timer); flag = true; } },10) } //獲取pageY function getLocation() { var arr = []; modules.forEach((module) => { var thing = pageY(module); arr.push(thing); }) return arr; } //獲取頁面中間每個分塊上方到頁面最頂部的距離 function pageY(el) { if ( el.offsetParent ) { return el.offsetTop + pageY(el.offsetParent); } else { return el.offsetTop; } } //平滑返回頁面頂部 function fly() { cancelAnimationFrame(timer); var timer = requestAnimationFrame( function fn() { var top = window.pageYOffset; if ( top > 0 ) { document.documentElement.scrollTop = top - 80; timer = requestAnimationFrame(fn); } else { cancelAnimationFrame(timer); } }) } } } ElevatorModule.init();
PS:
一些需要注意的常見js事件屬性:
event.stopPropagation()
終止事件在傳播過程的捕獲、目標處理或起泡階段進一步傳播。調用該方法后,該節點上處理該事件的處理程序將被調用,事件不再被分派到其他節點。
event.preventDefault()
該方法將通知 Web 瀏覽器不要執行與事件關聯的默認動作(如果存在這樣的動作)。
不論鼠標指針穿過被選元素或其子元素,都會觸發 mouseover 事件。對應mouseout
只有在鼠標指針穿過被選元素時,才會觸發 mouseenter 事件。對應mouseleave
參考文章:
https://www.cnblogs.com/caizh... XSS
https://www.cnblogs.com/zzgbl... 轉義方法
http://www.ruanyifeng.com/blo... CSP
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/107658.html
摘要:禁止內聯腳本執行規則較嚴格,目前發現使用。合理使用上報可以及時發現,利于盡快修復問題。因為事件會從目標元素一層層冒泡至對象。允許給一個事件注冊多個監聽。表示在捕獲階段觸發,表示在冒泡階段觸發。 關于【Step-By-Step】 Step-By-Step (點擊進入項目) 是我于 2019-05-20 開始的一個項目,每個工作日發布一道面試題。每個周末我會仔細閱讀大家的答案,整理最一份...
摘要:要錢的簡單理解百度的廣告就是不用錢的自己配置提高搜索引擎的權重是一種技術,主要是用于提高網站瀏覽量而做的優化手段為什么需要我們搜一下微信公眾號發現排名是有先后的,博客園都是靠前的。 CDN 什么是CDN 初學Web開發的時候,多多少少都會聽過這個名詞->CDN。 CDN在我沒接觸之前,它給我的印象是用來優化網絡請求的,我第一次用到CDN的時候是在找JS文件時。當時找不到相對應的JS文件...
摘要:要錢的簡單理解百度的廣告就是不用錢的自己配置提高搜索引擎的權重是一種技術,主要是用于提高網站瀏覽量而做的優化手段為什么需要我們搜一下微信公眾號發現排名是有先后的,博客園都是靠前的。 CDN 什么是CDN 初學Web開發的時候,多多少少都會聽過這個名詞->CDN。 CDN在我沒接觸之前,它給我的印象是用來優化網絡請求的,我第一次用到CDN的時候是在找JS文件時。當時找不到相對應的JS文件...
摘要:禁止內聯腳本執行規則較嚴格,目前發現使用。典型的攻擊流程受害者登錄站點,并保留了登錄憑證。站點接收到請求后,對請求進行驗證,并確認是受害者的憑證,誤以為是無辜的受害者發送的請求。攻擊完成,攻擊者在受害者不知情的情況下,冒充受害者完成了攻擊。 隨著互聯網的發展,各種Web應用變得越來越復雜,滿足了用戶的各種需求的同時,各種網絡安全問題也接踵而至。作為前端工程師的我們也逃不開這個問題,今天一起...
閱讀 633·2021-11-24 09:39
閱讀 3478·2019-08-30 15:53
閱讀 2509·2019-08-30 15:44
閱讀 3237·2019-08-30 12:54
閱讀 2206·2019-08-29 12:23
閱讀 3304·2019-08-26 14:05
閱讀 2101·2019-08-26 13:36
閱讀 3429·2019-08-26 13:33