跨站指令碼 (XSS) 是一種攻擊類型,惡意人士藉此將用戶端 JavaScript 注入您的網站,使其在您使用者瀏覽器的信任環境中執行。
防止 XSS 攻擊最乾淨俐落的方式,是在注入點逸出不受信任的資料。這表示在資料實際注入 HTML 的那個點上進行逸出。
使用 <%= %>
來 HTML 編碼資料
<h3 is="welcome-msg">Hello <%= me.username %>!</h3>
<h4><%= owner.username %>'s projects:</h4>
<ul><% _.each(projects, function (project) { %>
<li>
<a href="/<%= owner.username %>/<%= project.slug %>"><%= project.friendlyName %></a>
</li>
<% }); %></ul>
使用 exposeLocalsToBrowser
partial 來安全地將部分或全部視圖本地變數暴露給用戶端 JavaScript
<%- exposeLocalsToBrowser(); %>
<script>
console.log(window.SAILS_LOCALS);
// {
// me: {
// username: 'eleven',
// memberSince: '1982-08-01T05:00:00.000Z'
// },
// owner: {
// username: 'joyce',
// memberSince: '1987-11-03T05:00:00.000Z'
// },
// projects: [
// {
// slug: 'my-neat-stuff-n-things',
// friendlyName: 'My neat stuff & things',
// description: 'Yet another project.'
// },
// {
// slug: 'kind-of-neat-stuff-but-not-that-great',
// friendlyName: 'Kind of neat stuff, but not that great...',
// description: 'I am so sick and tired of these project. <script>alert(\'attack\');</script>'
// }
// ],
// _csrf: 'oon95Uac-wKfWQKC5pHx1rP3HsiN9tjqGMyE'
// }
</script>
請注意,當您使用此策略時,您的視圖本地變數中的字串在暴露給用戶端 JavaScript 後,將不再是 HTML 解逸出狀態。這是因為當您將它們放入 DOM 時,您會想要再次逸出它們。如果您始終在注入點逸出,那麼追蹤這些東西會容易得多。這樣一來,您就知道您可以安全地逸出任何從用戶端 JavaScript 注入到 DOM 中的字串。(詳情如下。)
許多 XSS 防禦措施都與您在用戶端程式碼中所做的事情有關。以下是一些範例
使用 <%- %>
來 HTML 編碼資料
<div data-template-id="welcome-box">
<h3 is="welcome-msg">Hello <%- me.username %>!</h3>
</div>
使用類似 $(...).text()
的方法來 HTML 編碼資料
var $welcomeMsg = $('#signup').find('[is="welcome-msg"]');
welcomeMsg.text('Hello, '+window.SAILS_LOCALS.me.username+'!');
// Avoid using `$(...).html()` to inject untrusted data.
// Even if you know an XSS is not possible under particular circumstances,
// accidental escaping issues can cause really, really annoying client-side bugs.
您可能已經發現,上面的範例假設您正在使用 jQuery,但相同的概念適用於您正在使用的任何前端函式庫。
- 上面的範例假設您正在使用預設視圖引擎 (EJS) 和來自預設資源管線的用戶端 JST/Lodash 模板。