iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 9
0
Software Development

今晚我想來點 Express 佐 MVC 分層架構系列 第 9

[今晚我想來點 Express 佐 MVC 分層架構] DAY 09 - Express 安全防護

  • 分享至 

  • xImage
  •  

只要有應用必定有黑帽駭客的出現,要做好防範黑客的機制在現今已經是標配,雖然不見得是資安大師,但至少要把最基本的防禦做好,善盡工程師的責任!Express 官方在安全最佳作法中有提及到應該使用 helmet 套件來防範應用程式出現已知的漏洞,那 helmet 到底能做到什麼事情呢?

helmet

helmet 是由多個中介軟體所構成,它做的事情很簡單,就是 修改 header 中的資訊 ,來做到一些基本的防護,降低被黑客攻擊的風險。安裝方式一樣透過 npm 進行:

npm install helmet

要使用的話也是很簡單,並且 helmet 很自由,可以使用 我全都要 模式,來打開所有 helmet 中介軟體的功能:

import helmet from 'helmet';
app.use(helmet());

這樣就可以把所有配置都打開了,但根本不知道它做了啥呀!也不確定是不是每項都是需要的,還有就是能否只使用某幾個或是哪些不使用呢?下方會進行個別說明。

本篇章的重點為如何使用 helmet 套件,但內容涉及眾多 header 知識,為了不失焦,所以僅會說明該功能的用處並附上相關知識連結,敬請見諒!

降低跨網域腳本攻擊

透過設置 Content-Security-Policy 來降低跨網域腳本攻擊,可以參考 MDN 的說明文件 來了解有哪些參數可以設置。下方為使用 helmet 提供的方法來設置的範例:

app.use(
  helmet.contentSecurityPolicy({
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", "example.com"],
      objectSrc: ["'none'"],
      upgradeInsecureRequests: [],
    },
  })
);

當然,也可以不設置任何參數直接使用 helmet.contentSecurityPolicy() ,那就會採用下方預設值:

default-src 'self';
base-uri 'self';
block-all-mixed-content;
font-src 'self' https: data:;
frame-ancestors 'self';
img-src 'self' data:;
object-src 'none';
script-src 'self';
script-src-attr 'none';
style-src 'self' https: 'unsafe-inline';
upgrade-insecure-requests

降低憑證發行錯誤

透過設置 Expect-CT 來降低憑證發行錯誤,可以參考 MDN 的說明文件 來了解各個參數的意義。下方為使用 helmet 提供的方法來設置的範例:

app.use(
  helmet.expectCt({
    maxAge: 86400,
    enforce: true,
    reportUri: "https://example.com/report",
  })
);

參數預設值:

  • maxAge:預設為 0
  • enforce:預設為 false
  • reportUri:無預設配置

控管 Referrer

透過設置 Referrer-Policy 來控管 Referrer 的資訊,可以參考 MDN 的說明文件 來了解各參數的意義。下方為使用 helmet 提供的方法來設置的範例:

app.use(
  helmet.referrerPolicy({
    policy: ["origin", "unsafe-url"],
  })
);

policy 參數預設值為 no-referrer

強制 HTTPS

透過設置 Strict-Transport-Security 來告訴瀏覽器強制使用 HTTPS 進行連線。可以參考 MDN 的說明文件 來了解各參數的意義。下方為使用 helmet 提供的方法來設置的範例:

app.use(
  helmet.strictTransportSecurity({
    maxAge: 123456,
  })
);

參數預設值:

  • maxAge:為 180 天
  • includeSubDomains: 預設為 true
  • preload:預設為 false

阻止 MIME 探查

透過設置 X-Content-Type-Optionsnosniff 來阻止瀏覽器對 Content-Type 不明的內容進行探查,以防止惡意程式碼的注入。可以參考 MDN 的說明文件。下方為使用 helmet 提供的方法來設置的範例:

app.use(helmet.noSniff());

DNS 預讀取

透過設置 X-DNS-Prefetch-Control 來控制 DNS 的預讀取,以決定是否要用性能換取一些使用者的隱私。可以參考 MDN 的說明文件 。下方為使用 helmet 提供的方法來設置的範例:

app.use(
  helmet.dnsPrefetchControl({
    allow: true,
  })
);

allow 預設為 false

IE8 以上的下載配置

透過設置 X-Download-Optionsnoopen 來指定 IE8 以上不要在下載框顯示「打開」選項。可以參考 微軟的說明文件。下方為使用 helmet 提供的方法來設置的範例:

app.use(helmet.ieNoOpen());

減緩點擊劫持攻擊

透過設置 X-Frame-Options 決定是否在瀏覽器中顯示 frame 或 iframe 指定的頁面,以減緩點擊劫持攻擊。可以參考 MDN 的說明文件。下方為使用 helmet 提供的方法來設置的範例:

  helmet.frameguard({
    action: "deny",
  })

action 可填入的參數有:denysameorigin,的預設值為 sameorigin

允許跨域政策

透過設置 X-Permitted-Cross-Domain-Policies 來決定你的網域政策加載跨域內容。可以參考 OWASP 的說明文件。下方為使用 helmet 提供的方法來設置的範例:

app.use(
  helmet.permittedCrossDomainPolicies({
    permittedPolicies: "by-content-type",
  })
);

permittedPolicies 可填入的參數有:nonemaster-onlyby-content-typeall ,預設值為 none

移除 X-Powered-By

X-Powered-By 從 header 中移除,可以使攻擊者無法得知使用的工具為何,是 非常重要的配置 。下方為使用 helmet 提供的方法來設置的範例:

app.use(helmet.hidePoweredBy());

XSS 過濾器

通過將 X-XSS-Protection 設為 0,來關閉瀏覽器 XSS 過濾器。下方為使用 helmet 提供的方法來設置的範例:

app.use(helmet.xssFilter());

小結

今天的內容有些艱澀,不過還是要大致了解 helmet 這個套件能夠做哪些事?又做了哪些事?才不會用了這個工具卻不知道這個工具是幹嘛的,另外,就算真的不想用它,也一定要將 X-Powered-By 移除!至少可以讓攻擊者不知道使用的框架、技術為何,增加攻擊的困難度。
由於本系列文的最終目標是用 MVC 架構來寫 Express,其中會使用到資料庫,所以下一篇會稍微介紹時下最夯的 NoSQL - MongoDB,好讓往後的文章有資料庫能完善應用。

參考資料

helmet 官方文檔


上一篇
[今晚我想來點 Express 佐 MVC 分層架構] DAY 08 - Express CORS
下一篇
[今晚我想來點 Express 佐 MVC 分層架構] DAY 10 - 設置 MongoDB
系列文
今晚我想來點 Express 佐 MVC 分層架構30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言