TC39JavaScript新語法ES Modules資安

TC39 新語法深度解析(十):Import Attributes — 更安全、更明確的模組導入語法

整理 ES2024 Import Attributes(Stage 4,已所有主流瀏覽器支援):import with { type: 'json' } 的安全價值、動態 import 屬性、CSS Module Scripts、Vite/webpack 支援。

· 2 分鐘閱讀

這是 TC39 新語法深度解析系列的第十篇。Import Attributes(以前叫做 Import Assertions)解決了一個長期被忽視的安全問題:MIME-type confusion 攻擊。這個語法現在已進入 ES2024,所有主流瀏覽器都已支援。


Import Attributes 是什麼?

// 過去:不知道這個 JSON 是真的 JSON
import data from './data.json';  // 只知道副檔名是 .json

// 現在:明確宣告類型,讓瀏覽器驗證
import data from './data.json' with { type: 'json' };

with { type: 'json' } 告訴瀏覽器:「我預期這個模組的 MIME type 是 application/json」。如果伺服器返回的 Content-Type 不匹配,JavaScript 引擎會拒絕執行,而不是可能執行攻擊者構造的惡意內容。


為什麼這件事重要:MIME-type Confusion 攻擊

攻擊情境:
1. 攻擊者上傳一個看起來像 JSON 的恶意檔案(副檔名 .json)
2. 伺服器錯誤地將其 Content-Type 設為 application/javascript
3. 瀏覽器執行了惡意代碼,因為只看 Content-Type

Import Attributes 的防範:
import malicious from './data.json' with { type: 'json' };
瀏覽器會檢查 Content-Type 是否為 application/json,如果不是就拒絕執行

動態 import 的屬性語法

// 動態 import 也可以加屬性
const data = await import('./data.json', {
  with: { type: 'json' }
});

// 或
const css = await import('./theme.css', {
  with: { type: 'css' }
});

CSS Module Scripts:瀏覽器原生 CSS import

<!-- 在 HTML 中直接使用 CSS import -->
<script type="module">
  const sheet = await import('./theme.css', {
    with: { type: 'css' }
  });

  // sheet.default 是 CSSStyleSheet 物件
  document.adoptedStyleSheets = [sheet.default];
</script>

Vite 與 webpack 的支援

// Vite 4.6+ 原生支援
import data from './data.json' with { type: 'json' };

// webpack 5+ 原生支援
import data from './data.json' with { type: 'json' };

Bundler 在打包時會幫你處理屬性驗證,讓這個語法在 development 和 production 都安全。


未來:更多類型

// 未來可能支援的類型
import wasm from './module.wasm' with { type: 'webassembly' };
import html from './widget.html' with { type: 'html' };

總結

Import Attributes 是那種「看起來很小的語法,但其實解決了一個重要安全問題」的功能:

  • 所有瀏覽器現在都支援(ES2024)
  • 開發體驗不變:Bundler 讓語法在 development 和 production 都安全
  • 讓模組來源更明確:不再只依賴副檔名

這是 TC39 新語法深度解析系列的第十篇。


延伸閱讀


本文基於 ES2024 Import Attributes(Stage 4)整理。