-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path1-19-1.html
153 lines (152 loc) · 7.52 KB
/
1-19-1.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="./public/favicon.ico" />
<meta http-equiv="cache-control" content="no-cache" />
<title></title>
<link rel="stylesheet" href=" https://necolas.github.io/normalize.css/8.0.1/normalize.css" />
<link rel="stylesheet" href="./hightlight/default.min.css" />
<link rel="stylesheet" href="./css/main.css" />
<link rel="stylesheet" href="./css/copybutton.css" />
<link rel="stylesheet" href="./css/hightlight.css" />
<script src="./hightlight/hightlight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.11/clipboard.min.js"></script>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-BEVZJDBC7Z"></script>
<script src="./js/gtag.js"></script>
</head>
<body>
<header>
<nav>
<h1>
<span id="toggle-menu"></span>
<a href="index.html"></a>
</h1>
</nav>
</header>
<main>
<aside>
<nav></nav>
</aside>
<article>
<h2 id="1-19-1">1-19-1 資安實作建議</h2>
<p>
首先,要了解單頁應用驗證與傳統驗證方式的不同。
單頁應用採用前後端分離的設計方式,路由由前端管理,前後端遵循一定的標準(如
REST、GraphQL),透過 AJAX
進行通訊。在這種情況下,使用者請求頁面時,後端經常無法取得使用者身份資訊,更無法確定傳回的資料。
同時,在一次驗證完畢後,如何在單頁應用的體驗中保持這個驗證狀態也債得思考。一般來說,單頁應用驗證可以採用下面的步驟實現。
</p>
<ul>
<li>
第一步:前端根據使用者互動發送資料請求之前,需要準備使用者資訊,同資料請求一起發送給後端處理。
</li>
<li>
第二步:後端按照約定好的規則,根據請求中的使用者身份資訊進行驗證。如果驗證不通過,則傳回
403 或 401 相關狀態碼,或其他狀態,以表示驗證失敗。如果驗證成功,後端就會傳回相關資料。
</li>
<li>第三步:前端根據資料繪製視圖。</li>
</ul>
<p>單頁應用驗證過程非常簡單清晰,如圖1 所示。</p>
<p>圖1</p>
<img src="./assets/image/1-19-1/1.jpg" alt="" />
<h4>HTTPS</h4>
<p>
在驗證過程中,如果使用HTTP來傳輸敏感性資料(使用者暱稱、使用者密碼、token等),那麼很容易被中間人攔截取得。在現代通訊中,我們都使用HTTPS來對傳輸內容進行加密。關於HTTPS
的應用及其原理又是一個超級話題,這裡由於篇幅限制,不再過多說明,有興趣的讀者可以自學。
</p>
<h4>不要使用 URL query 傳遞敏感性資料</h4>
<p>
URL query 會透過伺服器端記錄檔、瀏覽器記錄檔、瀏覽器歷史記錄查到。 不要使用 URL query
傳遞敏感性資料,這是最基本的準則之一。如果敏感性資料在 URL
query中,就會給惡意使用者輕鬆取得資料的機會。同時,URL query
的長度也有限制,這也是其傳遞資料的弊端之一。
</p>
<h4>防止暴力攻擊的方法</h4>
<p>
攻擊者可以透過暴力方法,嘗試取得使用者的密碼等資訊。因此,後端服務要時刻注意加入頻率限制,限制一個使用者短時間內嘗試輸人密碼的次數:
</p>
<p>
也可以限制可疑使用者(舉例來說,觸發了過多伺服器端錯誤的使用者)的存取。另外,需要注意的是不要給任何人曝露伺服器端的技術細節資訊,舉例來說,要記得關閉
X-Powered-By(伺服器回應標頭隱藏)。在使用 express 的情況下,強烈建議 Node.js 端使用
helmet 來防止技術細節的曝露。
</p>
<p>
helmet 可以幫助 Node.js 開發者透過設定合理的 HTTP header,來預防一些常見的 web
漏洞,舉例來說,上面提到的關閉 X-Powered-By
。實際上:它就是一組靈活的中介軟體函數,可以增強以下 HTTP header 的安全性。
</p>
<ul>
<li>
Content-Security-Policy
回應標頭,它可以設定應用是否可以參考某些來源的內容,進而防止XSS。
</li>
<li>關閉 X-Powered-By 回應標頭,以避免曝露伺服器端資訊。</li>
<li>增加 Public Key Pinning 回應標頭,預防中間人偽造憑證。</li>
<li>
設定 Strict-Transport-Security 回應標頭,這樣瀏覽器就只能透過 HTTPS 存取目前資源。
</li>
<li>
為 IE8 及以上的版本設定 X-Download-Options
回應標頭,用來預防下載內容的安全隱憂,目前只有 IE8 及以上的版本支援這個 header。
</li>
<li>設定 Cache-Control 和 Pragma header 以關閉瀏覽器端快取。</li>
<li>設定 X-Content-Type-Options 回應標頭,以禁用瀏覽器內容偵測。</li>
<li>
設定 X-Frame-Options 回應標頭,以預防 clickjacking
漏洞,這個回應標頭可以告訴瀏覽器是否允許在 <frame> 或
<iframe>標籤中繪製某個頁面。
</li>
<li>
設定 X-XSS-Protection
回應標頭,當檢測到跨站指令稿攻擊(XSS)時,瀏覽器便會停止載入頁面。
</li>
</ul>
<p>helmet 的使用非常簡單,程式如下。</p>
<pre><code class="language-js">
const express = require('express')
const helmet = require('helmet')
const app = express()
app.use(helmet())
</code></pre>
<p>
基原始程式是典型的 express 中介軟體寫法,會依次載入相關中介軟體集。舉例來說:程式中會参考
X-Powered-By 中介軟體,如下。
</p>
<pre><code class="language-js">
module.exports = function hidePoweredBy (options) {
var setTo = (options || {}).setTo
if (setTo) {
return function hidePoweredBy(reg, res, next) {
res.setHeader('X-Powered-By', setIo)
next()
}
} else {
return function hidePoweredBy (reg, res, next) {
res.removeHeader('X-Powered-By')
next()
}
}
}
</code></pre>
<p>
透過 setHeader 和 removeHeader 方法,就可以完成對 X-Powered-By 回應標頭的增加和刪除了。
</p>
<h4>升級依賴確保安全</h4>
<p>
如今,我們的應用中大部分指令稿都來自協力廠商函數庫,協力廠商函數庫出現安全隱憂的新聞已經屢見不鮮。除了從源頭把控協力廠商函數庫的引用,適時合理地更新
npm 套件也是值得宣導的做法,因此 npm 在 6.0 後可以使用以下相關指令。
</p>
<pre><code class="language-bash">
npm audit
# npn 6.0 新增,掃描所有依賴,並把不安全的依賴套件升級到可相容的版本
npm audit fix
</code></pre>
</article>
</main>
</body>
<script type="module" src="./js/main.js"></script>
</html>