100 lines
3.3 KiB
Python
100 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
路徑遍歷防護測試腳本
|
|
測試 app.py 中的 safe_join 函數
|
|
"""
|
|
|
|
import sys
|
|
import os
|
|
|
|
# 確保可以導入專案模組
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
from app import safe_join
|
|
from pathlib import Path
|
|
|
|
def test_safe_join():
|
|
"""測試 safe_join 函數"""
|
|
print("="*60)
|
|
print("MOMO 監控系統 - 路徑遍歷防護測試")
|
|
print("="*60)
|
|
|
|
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
BACKUP_DIR = os.path.join(BASE_DIR, 'backups')
|
|
|
|
test_cases = [
|
|
# (基礎路徑, 子路徑, 是否應該通過, 描述)
|
|
(BACKUP_DIR, 'backup.zip', True, '正常檔案名'),
|
|
(BACKUP_DIR, 'subfolder/backup.zip', True, '子目錄中的檔案'),
|
|
(BACKUP_DIR, 'backup_20260112.zip', True, '帶日期的檔案名'),
|
|
(BACKUP_DIR, '../../../etc/passwd', False, '路徑遍歷攻擊 (../)'),
|
|
(BACKUP_DIR, '..\\..\\..\\windows\\system32\\config\\sam', False, 'Windows 路徑遍歷'),
|
|
(BACKUP_DIR, '/etc/passwd', False, '絕對路徑攻擊'),
|
|
(BACKUP_DIR, 'backup/../../../etc/passwd', False, '混合路徑遍歷'),
|
|
(BACKUP_DIR, '....//....//etc/passwd', False, '變種路徑遍歷'),
|
|
(BACKUP_DIR, 'backup/./../../../config.py', False, '多層目錄遍歷'),
|
|
(BASE_DIR, '.env', True, '根目錄檔案'),
|
|
(BASE_DIR, '../momo_pro_system/.env', False, '繞過根目錄'),
|
|
]
|
|
|
|
passed = 0
|
|
failed = 0
|
|
|
|
print("\n測試 safe_join() 函數:")
|
|
print("-"*60)
|
|
|
|
for base, path, should_pass, description in test_cases:
|
|
try:
|
|
result = safe_join(base, path)
|
|
|
|
if should_pass:
|
|
print(f"✅ 通過: {description}")
|
|
print(f" 基礎: {base}")
|
|
print(f" 路徑: {path}")
|
|
print(f" 結果: {result}")
|
|
passed += 1
|
|
else:
|
|
print(f"❌ 失敗: {description}")
|
|
print(f" 基礎: {base}")
|
|
print(f" 路徑: {path}")
|
|
print(f" 錯誤: 應該被阻擋但通過了")
|
|
print(f" 結果: {result}")
|
|
failed += 1
|
|
except ValueError as e:
|
|
if not should_pass:
|
|
print(f"✅ 通過: {description}")
|
|
print(f" 基礎: {base}")
|
|
print(f" 路徑: {path}")
|
|
print(f" 結果: 成功阻擋 - {str(e)[:60]}")
|
|
passed += 1
|
|
else:
|
|
print(f"❌ 失敗: {description}")
|
|
print(f" 基礎: {base}")
|
|
print(f" 路徑: {path}")
|
|
print(f" 錯誤: 不應該被阻擋 - {e}")
|
|
failed += 1
|
|
except Exception as e:
|
|
print(f"❌ 失敗: {description}")
|
|
print(f" 基礎: {base}")
|
|
print(f" 路徑: {path}")
|
|
print(f" 錯誤: 未預期的異常 - {e}")
|
|
failed += 1
|
|
|
|
print()
|
|
|
|
# 顯示總結
|
|
print("="*60)
|
|
print("測試結果摘要")
|
|
print("="*60)
|
|
print(f"✅ 通過: {passed}")
|
|
print(f"❌ 失敗: {failed}")
|
|
print(f"總計: {passed + failed}")
|
|
|
|
assert failed == 0
|
|
|
|
print("\n🎉 所有路徑遍歷防護測試通過!")
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(test_safe_join())
|