Atom
CWE-798 Use of Hard-coded Credentials

CWE-798 Use of Hard-coded Credentials

CWE-798:Use of Hard-coded Credentials(使用硬編碼憑證)

  • 在程式碼裡直接寫死帳號、密碼、金鑰或 Token,導致攻擊者可以透過反編譯或讀取原始碼取得敏感憑證。

常見風險包括:

  1. 密碼或 API Key 被寫死在前端
  2. 憑證以固定字串產生(predictable pattern)
  3. 預設密碼直接暴露在程式碼內
  4. 密碼構成方式固定,使用者資訊可預測

這類問題通常會被SAST標示為高風險或中風險。


舉例

大部分 SAST 工具(如 SonarQube、Checkmarx、SnykCode、GitLab SAST 等)採用以下邏輯:

偵測硬編碼字串是否類似憑證
像是包含以下關鍵字的變數:

  • password
  • token
  • secret
  • key
  • credential

例如:

1
const DEFAULT_PASSWORD = "MEMBER_PHONE_37XXXXXX";

即使不是字串,可預測密碼模式也會被當成風險

例如:

1
password = `${PWD_RANDOM}${values.phone}`;

雖然RANDOM來自環境變數,但SAST仍會偵測到:

密碼由固定前綴組成

密碼包含可推測的使用者資料(phone, email 等)

偵測密碼是否使用「使用者資料 + 固定字串」

因為攻擊者只要知道使用者資料,就能輕易猜出密碼。


常見誤解:使用 runtime 注入就沒事嗎?

不一定。

例如:

1
2
const PWD_PREFIX = process.env.PWD_PREFIX ?? "MEMBER_Intl_";
password: `${PWD}${values.phone}`;

問題不是是否寫死,而是整個密碼生成邏輯過於固定、可預測。


修補方式建議

1. 密碼不要在前端生成

前端不應該組合密碼,而應讓後端自行產生強隨機密碼:

  • 前端
    1
    2
    3
    4
    5
    6
    7
    8
    variables: {
    account: values.email,
    type: values.role,
    name: values.name,
    mobile: values.phone,
    department: values.department,
    // 不傳 password
    }
  • 後端

後端自動產生:

1
2
3
隨機 12–16 位元密碼
或寄發「設定密碼」的 Email / 簡訊
首次登入強制更改密碼

2. 改成不可預測的隨機密碼

如果一定要前端生成密碼:

1
2
3
import { randomUUID } from "crypto";

password: randomUUID().replace(/-/g, "").slice(0, 12);

這樣密碼:

無法被猜測
沒有固定模式
不包含使用者個資
不會被 SAST 報告


像是我的blog寫法就很NG
不過我東西不是放在我自己的server
而是全部用免費資源架起來。
我也想不會有人無聊在那邊慢慢爆破
自己寫爽的就隨便了

本文作者:Atom
本文鏈接:https://d0ngd.github.io/2025/12/02/CWE-798 Use of Hard-coded Credentials/
版權聲明:本文採用 CC BY-NC-SA 3.0 CN 協議進行許可