Vulnerability Detail Report
Vulnerability Overview
- ZDID: ZD-2026-00728
- Vendor: 狄卡科技股份有限公司
- Title: Dcard 密碼重設 token 透過第三方廣告/追蹤請求外洩
- Introduction: 密碼重設頁會將 reset token 帶入第三方 DoubleClick / Google Ads 請求 URL,可能導致帳號復原 token 在使用者送出新密碼前外洩。
處理狀態
目前狀態
-
新提交
-
已審核
-
已通報
-
已修補
-
未複測
-
公開
處理歷程
- 2026/05/21 16:12:35 : 新提交 (由 monkey47 更新此狀態)
- 2026/05/25 15:52:19 : 審核中 (由 HITCON ZeroDay 服務團隊 更新此狀態)
- 2026/06/12 14:33:40 : 複測申請中 (由 組織帳號 更新此狀態)
- 2026/06/30 03:00:06 : 公開 (由 HITCON ZeroDay 平台自動更新)
詳細資料
- ZDID:ZD-2026-00728
- 通報者:davidyen1124 (monkey47)
- 風險:中
- 類型:資訊洩漏 (Information Leakage)
參考資料
OWASP 漏洞說明 (Top 10 2017 - A3 Sensitive Data Exposure)
https://www.owasp.org/index.php/Top_10-2017_A3-Sensitive_Data_Exposure
CWE-200 漏洞說明
https://cwe.mitre.org/data/definitions/200.html
相關網址
https://www.dcard.tw/passwords/reset/DUMMY_RESET_TOKEN_NOT_REAL_20260521
敘述
摘要
Dcard 的密碼重設頁會將 reset token 放在 URL path 中,並在頁面初始化時載入第三方廣告 / 追蹤資源。實測使用假 token 時,完整 token URL 會出現在頁面 metadata、__NEXT_DATA__,以及第三方 DoubleClick iframe 的 url= 參數中。
本測試僅使用假 token,未使用真實 reset token,也未送出密碼重設表單。
重現步驟
- 開啟以下使用假 token 的 PoC URL:
https://www.dcard.tw/passwords/reset/DUMMY_RESET_TOKEN_NOT_REAL_20260521
- 不輸入密碼,也不送出表單,只觀察頁面載入後的 DOM / metadata / 第三方 iframe。
- 可觀察到頁面正常顯示 Reset password 表單,且 token 被寫入頁面資料與第三方請求 URL。
實際結果
__NEXT_DATA__ 中包含 reset token:
{
"page": "/passwords/reset/[token]",
"query": {
"token": "DUMMY_RESET_TOKEN_NOT_REAL_20260521"
},
"props": {
"pageProps": {
"componentInitialProps": {
"token": "DUMMY_RESET_TOKEN_NOT_REAL_20260521"
}
}
}
}
頁面 metadata 也包含完整 token URL:
<meta property="og:url" content="https://www.dcard.tw/passwords/reset/DUMMY_RESET_TOKEN_NOT_REAL_20260521">
<meta name="url" itemprop="url" content="https://www.dcard.tw/passwords/reset/DUMMY_RESET_TOKEN_NOT_REAL_20260521">
同一次載入中,第三方 DoubleClick iframe 收到完整 token URL:
https://cm.g.doubleclick.net/partnerpixels?gdpr=0&us_privacy=1YNN&gpp=DBABL~BVQqAAAAAg&gpp_sid=7&url=https%3A%2F%2Fwww.dcard.tw%2Fpasswords%2Freset%2FDUMMY_RESET_TOKEN_NOT_REAL_20260521
先前同一路徑測試也觀察到 Google Ads conversion request 的 url= 參數包含完整 token URL:
https://www.googleadservices.com/pagead/viewthroughconversion/771926312/?...&url=https%3A%2F%2Fwww.dcard.tw%2Fpasswords%2Freset%2FDUMMY_RESET_TOKEN_NOT_REAL_20260521...
靜態程式碼佐證
前端頁面會從 route query 讀取 token 並提供給 reset flow:
R.getInitialProps = async e => {
let { query: t } = e;
return { token: t.token };
};
送出表單時,該 token 會被用於 password reset API:
confirmEmailPasswordReset({
password: e.password,
clearTokens: e.clearTokens,
token: s
});
影響說明
Password reset token 通常可直接代表帳號復原授權。若 token 尚未過期且尚未被使用,第三方接收到該 token-bearing URL 後,理論上可能造成未授權重設密碼或帳號接管風險。實際影響會依 Dcard 的 token TTL、是否 single-use、是否綁定 session / device,以及第三方請求是否在 token server-side 驗證前就送出而定。
即使全程使用 HTTPS,這裡的問題仍然存在,因為完整 token URL 是被主動放入第三方請求參數並傳送給第三方網域,而不是單純的傳輸中竊聽問題。
修補建議
建議在 /passwords/reset/* 等含有 secret 的頁面停用第三方廣告、追蹤 pixel、partner iframe。
建議對密碼重設頁設定 Referrer-Policy: no-referrer,並避免將 reset token 寫入 og:url、itemprop=url、analytics page URL 或其他 metadata。
也可以在頁面初始化前先完成 same-origin token exchange,將 token 綁定為短效 same-origin reset session 後,以 history.replaceState 將網址改為 /passwords/reset。
建議在所有 analytics / ads 初始化前,統一移除 URL 中的敏感參數或敏感 path segment,例如 token、code、secret、password、reset 等。