當項目的安全團隊找上門告訴您,您開發的項目存在 XSS 安全漏洞,作為一個開發人員,就問您慌不慌??
HTML 內容寫入的時候,如果稍不注意就會觸發隱藏 BOSS 漏洞 XSS。
XSS 漏洞原理就是利用了網站上內容輸入的地方,比如說常見的評論提交,老六
通過輸入評論的地方,提交一些 包含 JS 代碼的內容
到服務器,服務器沒做任何操作直接寫入到數據庫,最后在評論查詢的時候直接將數據庫的內容原樣返給前端,而前端拿到此內容的時候,也不做任何處理,直接將內容以 HTML 的形式渲染的頁面中,這時候 老六
輸入的非法內容就會被當做 JS 代碼執行,這就是典型的 XSS 注入攻擊。
要避免 XSS 漏洞,就需要對不可信的內容進行過濾;或者不要
把這部分內容當做 HTML 處理,直接當做文本
渲染也可以避免 XSS 注入。
DOM 屬性操作
在了解 DOM 內容操作之前,先學習幾個常用的 DOM 屬性操作方法,畢竟 JS 與 CSS 聯動一般都是通過 DOM 屬性進行關聯。
比如 JS 控制 class 屬性的變化,再在 CSS 中編寫不同的 class 樣式,就可以讓 HTML 元素渲染成不同的樣子。
element.getAttribute(name)
element.setAttribute(name, value)
element.removeAttribute(name)
element.classList.add(c1, c2, c3, ...)
element.classList.remove(c1, c2, c3, ...)
element.classList.toggle(className, force)
element.classList.contains(className)
element.id
element.className
element.style
img.src
通過 className
可直接設置元素的 class 屬性,這兒有一個問題,為什么不是直接使用 class
設置呢?
原因是:class 是 JS 中的關鍵字,為避免引起一些語法問題,所以就換了一個名字 className
。
通過 className
控制類名的增刪改雖然也不是不能做,但是始終有那么一點點麻煩,所以后來就引入了 classList
用來專門控制 class 屬性。
而 Attribute
相關的幾個方法,則是可以用來控制元素的所有屬性,包括自定義屬性和一些默認的屬性 id、style、className 等。所以記住 Attribute 幾個方法就已經可以打穿 DOM 屬性操作了。
示例:
<style>
.red {
color: red;
}
.blue {
color: blue;
}
[data-type="bold"] {
font-weight: bold;
}
[data-type="italic"] {
font-style: italic;
}
</style>
<div id="test">公眾號:前端路引</div>
<img id="img">
<script>
const test = document.getElementById('test');
const img = document.getElementById('img');
test.setAttribute('data-type', 'bold')
const type = test.getAttribute('data-type')
console.log('?? ~ type:', type);
test.removeAttribute('data-type')
test.setAttribute('data-type', 'italic')
const hasRed = test.classList.contains('red')
console.log('?? ~ hasRed:', hasRed);
test.classList.add('red')
test.classList.remove('red')
test.classList.toggle('blue')
img.src = 'https://developer.mozilla.org/static/media/firefox.1eabb4da07c095ca04fa.svg'
console.log('?? ~ img.src:', img.src);
img.id = 'img-1'
console.log('?? ~ img.id:', img.id);
img.className = 'img-1'
console.log('?? ~ img.className:', img.className);
img.style.border = '1px solid red'
img.style.borderWidth = '4px'
img.style['border-color'] = 'blue'
img.style.width = '100px'
console.log('?? ~ img.style:', img.style['border-width']);
</script>
在使用 style
屬性設置樣式的時候,如果使用的是 .
語法賦值,那么必須要改為 小駝峰命名
,原因是 JS 中的 .
語法不支持短橫線,比如 borderWidth
,不能使用 border-width
。
在使用數組取值語法的時候,可以直接使用 css 的屬性賦值,比如 img.style['border-color'] = 'blue'
。
運行結果:

DOM 內容操作
DOM 屬性操作一般不會觸發安全問題, XSS 注入都是發生在 DOM 內容操作的時候,所以在使用 JS 進行 DOM 內容操作時需特別小心。
常用的兩個個方法:
element.innerHTML = htmlString;
element.textContent = textString;
實例:
<div id="test1">公眾號:前端路引</div>
<div id="test2">公眾號:前端路引</div>
<script>
const test1 = document.getElementById('test1');
const test2 = document.getElementById('test2');
test1.innerHTML = '<strong>警告</strong>:用戶輸入內容';
test2.textContent = '<strong>安全文本</strong>';
console.log(test2.innerHTML);
console.log(test2.textContent);
</script>
運行結果:

XSS 注入
在使用 innerHTML 設置 HTML 內容時,如果用戶輸入的內容中包含 JS 腳本,那么就會導致 XSS 注入。
比如這樣:
<div id="test1">公眾號:前端路引</div>
<div id="test2">公眾號:前端路引</div>
<script>
const test1 = document.getElementById('test1');
const h1 = `<script>alert("XSS");<\/script>`;
test1.innerHTML = h1;
const test2 = document.getElementById('test2');
const h2 = `<img src=x onerror="alert('XSS')">`;
test2.innerHTML = h2;
</script>
HTML5 規范規定:通過 innerHTML 動態插入的 <script>
標簽不會執行其中的 JavaScript 代碼。
這是瀏覽器的一種安全機制,目的是防止開發者無意或惡意插入可執行腳本。
XSS 注入可能導致的問題:非法用戶直接在網站中運行 JS 代碼,可以獲取用戶信息,從而偽造一些請求,達到非法目的。
寫在最后
在使用 JS 操作 DOM 內容的時候,需特別防范 XSS 注入問題,尤其是用戶輸入的內容更加要加強防范,可以把任何用戶當做一個潛在的攻擊者,他們所有的輸入都是不可信的,這樣可以避免很多的安全問題。
轉自https://www.cnblogs.com/linx/p/18951405
該文章在 2025/7/4 9:36:57 編輯過