返回
Featured image of post NodeJS - 通訊安全

NodeJS - 通訊安全

各種網路連線中,chrome開發工具中Network,可以發現通訊Header中所有的資訊


web server 框架 使用 Express 網址封包傳送,很多資料會透露在客端瀏覽器,可以從Header的地方去更改資訊。


轉貼:
Express - 正式作業最佳作法:安全


Tools - npm - Helmet

npm i helmet --save 

Helmet - 9 中介軟體函數組成:

  • csp 會設定 Content-Security-Policy 標頭,以防範跨網站 Scripting 攻擊和其他跨網站注入。
  • hidePoweredBy 會移除 X-Powered-By 標頭。
  • hsts 會設定 Strict-Transport-Security 標頭,以施行安全的 (HTTP over SSL/TLS) 伺服器連線。
  • ieNoOpen 會設定 X-Download-Options(適用於 IE8+)。
  • noCache 會設定 Cache-Control 和 Pragma 標頭,以停用用戶端快取。
  • noSniff 會設定 X-Content-Type-Options,以阻止瀏覽器對脫離所宣告內容類型的回應進行 MIME 探查。
  • frameguard 會設定 X-Frame-Options 標頭,以提供 clickjacking 保護。
  • xssFilter 會設定 X-XSS-Protection,以便在最新的 Web 瀏覽器中啟用跨網站 Scripting (XSS) 過濾器。

停用 X-Powered-By 標頭

app.disable('x-powered-by');

攻擊者可能使用這個標頭(依預設,會啟用),來偵測執行 Express 的應用程式,然後啟動特定目標的攻擊。


npm i cookie-session

設定 Cookie 選項來加強安全:

  • secure - 確保瀏覽器只透過 HTTPS 傳送 Cookie。
  • httpOnly - 確保只透過 HTTP(S) 傳送 Cookie,而不透過用戶端 JavaScript 傳送,如此有助於防範跨網站 Scripting 攻擊。
  • domain - 指出 Cookie 的網域;用來與發出 URL 要求之伺服器的網域相互比較。如果相符,接著會檢查路徑屬性。
  • path - 指出 Cookie 的路徑;用來與要求路徑相互比較。如果此項與網域相符,則會傳送要求中的 Cookie。
  • expires - 用來設定持續性 Cookie 的到期日。
var session = require('cookie-session');
var express = require('express');
var app = express();

var expiryDate = new Date( Date.now() + 60 * 60 * 1000 ); // 1 hour
app.use(session({
  name: 'session',
  keys: ['key1', 'key2'],
  cookie: { secure: true,
            httpOnly: true,
            domain: 'example.com',
            path: 'foo/bar',
            expires: expiryDate
          }
  })
);

csrf 使用

一種資料儲存在session使用 對於csrf token的看法,使用cookie去驗證這筆資料的確定性。

  • server side 儲存 cookie 驗證
  • client side SPA 使用 Double Submit Cookie 核心概念是:「攻擊者的沒辦法讀寫目標網站的 cookie,所以 request 的 csrf token 會跟 cookie 內的不一樣」

分享文章: TechBridge 技術共筆部落格 - 讓我們來談談 CSRF

JWT 使用

JWT - JSON Web Token,來驗證身份的一種方式與習慣。
由三段加密組成

Header.Payload.Signature
  • Header:含 Token 的種類及產生簽章(signature)要使用的雜湊演算法
  • Payload:帶有欲存放的資訊(例如用戶資訊)
  • Signature:編譯後的 Header、Payload 與密鑰透過雜湊演算法所產生

Header 定義 Token 種類(typ)及雜湊演算法(alg)資訊的 JSON。

{
  "alg": "HS256", 
  "typ": "JWT"
}

經過 Bash64 編譯

DQp7DQogICJhbGciOiAiSFMyNTYiLCANCiAgInR5cCI6ICJKV1QiDQp9

Payload

Payload 定義使用者和相關的資訊。exp 設定 Token 到期的時間、iat 設定 Token 簽發時間。

{
  "_id": "01", 
  "name": "Hifounder",
  "exp": 1300819380
}

經過 Bash64 編譯

ew0KICAiX2lkIjogIjAxIiwgDQogICJuYW1lIjogIkhpZm91bmRlciIsDQogICJleHAiOiAxMzAwODE5MzgwDQp9

不要將隱私資訊存放在 Payload 中,被轉換成 Base64 編碼後,能夠被輕易的轉換回來 ,不應該把用戶密碼等重要資料存在 Payload 中

Signature

Signature 將編碼過的 HeaderPayload自定義密鑰,透過設定的雜湊演算法方式所產生的。 由於密鑰並非公開,因此伺服器端在拿到 Token 後,能透過解碼,驗證對方身份。 secret 是在 伺服器端才擁有的,所以無人得知,

// SHA-256
sha256(base64(header) + "." + base64(payload), "secret")

經過 SHA-256 編譯

b423b2e0eddb4f993b1b764d793ae47eee62762bd3f9d951262ffa0fa766b2b9

完整的JWT

DQp7DQogICJhbGciOiAiSFMyNTYiLCANCiAgInR5cCI6ICJKV1QiDQp9.ew0KICAiX2lkIjogIjAxIiwgDQogICJuYW1lIjogIkhpZm91bmRlciIsDQogICJleHAiOiAxMzAwODE5MzgwDQp9.b423b2e0eddb4f993b1b764d793ae47eee62762bd3f9d951262ffa0fa766b2b9

傳送給客端瀏覽器存放在,可存放在localStorage中,客戶端發送Request放在Header當中傳遞,Authorization

// JWT 是一種 Bearer Token (客端)
Authorization: 'Bearer ' + token

// Node Express (伺服器端)
const token = req.header('Authorization').replace('Bearer ', '')
console.log(token)
Licensed under CC BY-NC-SA 4.0
comments powered by Disqus