Kamixitong/scripts/verify_csrf_fix.py
2025-12-12 11:35:14 +08:00

194 lines
5.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
CSRF问题修复验证脚本
验证API和Web表单的CSRF配置是否正确
"""
import requests
import sys
from urllib.parse import urljoin
def test_api_without_csrf():
"""测试API是否豁免CSRF"""
print("=" * 60)
print("🔍 测试API CSRF豁免")
print("=" * 60)
base_url = "http://localhost:5000"
# 测试健康检查端点
print("\n1. 测试健康检查端点...")
try:
response = requests.get(f"{base_url}/api/v1/health", timeout=5)
if response.status_code == 200:
print(" ✅ 健康检查端点正常")
print(f" 响应: {response.json()}")
else:
print(f" ⚠️ 健康检查返回状态码: {response.status_code}")
except Exception as e:
print(f" ❌ 健康检查失败: {str(e)}")
return False
# 测试需要认证的API应该返回401而不是400
print("\n2. 测试需要认证的API...")
test_endpoints = [
"/api/v1/licenses",
"/api/v1/products"
]
for endpoint in test_endpoints:
try:
# GET请求不应该需要CSRF
response = requests.get(urljoin(base_url, endpoint), timeout=5)
if response.status_code == 400:
print(f"{endpoint} 返回400 - 可能是CSRF错误")
return False
elif response.status_code == 401:
print(f"{endpoint} 返回401 - 未认证(正确)")
elif response.status_code == 200:
print(f"{endpoint} 返回200 - 成功")
else:
print(f" ⚠️ {endpoint} 返回状态码: {response.status_code}")
except Exception as e:
print(f"{endpoint} 请求失败: {str(e)}")
return False
return True
def check_csrf_configuration():
"""检查CSRF配置"""
print("\n" + "=" * 60)
print("🔧 检查CSRF配置")
print("=" * 60)
try:
# 检查app/__init__.py中的CSRF配置
with open('app/__init__.py', 'r', encoding='utf-8') as f:
content = f.read()
if 'csrf.exempt(api_bp)' in content:
print(" ✅ 已配置API CSRF豁免")
else:
print(" ❌ 未找到API CSRF豁免配置")
return False
if 'csrf.init_app(app)' in content:
print(" ✅ CSRF已初始化")
else:
print(" ❌ CSRF未初始化")
return False
return True
except Exception as e:
print(f" ❌ 检查配置文件失败: {str(e)}")
return False
def test_web_form_csrf():
"""测试Web表单CSRF保护"""
print("\n" + "=" * 60)
print("🔐 测试Web表单CSRF保护")
print("=" * 60)
base_url = "http://localhost:5000"
try:
# 获取登录页面
response = requests.get(f"{base_url}/login", timeout=5)
if response.status_code == 200:
print(" ✅ 登录页面可访问")
# 检查是否包含CSRF token
if 'csrf_token' in response.text or 'name="csrf_token"' in response.text:
print(" ✅ 登录页面包含CSRF token")
else:
print(" ⚠️ 登录页面未找到CSRF token")
else:
print(f" ⚠️ 登录页面返回状态码: {response.status_code}")
except Exception as e:
print(f" ❌ 测试Web表单失败: {str(e)}")
return False
return True
def generate_report():
"""生成检查报告"""
print("\n" + "=" * 60)
print("📊 CSRF问题修复验证报告")
print("=" * 60)
checks = [
("API CSRF豁免配置", check_csrf_configuration),
("API豁免CSRF测试", test_api_without_csrf),
("Web表单CSRF保护", test_web_form_csrf)
]
results = []
for name, check_func in checks:
try:
result = check_func()
results.append((name, result))
except Exception as e:
print(f"{name}检查失败: {str(e)}")
results.append((name, False))
# 总结
print("\n" + "=" * 60)
print("📋 检查结果汇总")
print("=" * 60)
all_passed = True
for name, passed in results:
status = "✅ 通过" if passed else "❌ 失败"
print(f"{name:25s}: {status}")
if not passed:
all_passed = False
print("\n" + "=" * 60)
if all_passed:
print("✅ 所有检查通过CSRF问题已修复")
print("\n💡 后续建议:")
print(" 1. 重启应用以应用修复")
print(" 2. 测试所有API端点")
print(" 3. 确认Web表单仍受CSRF保护")
else:
print("⚠️ 发现问题,请检查上述详细信息")
print("=" * 60)
return all_passed
def main():
"""主函数"""
print("🔧 KaMiXiTong CSRF问题修复验证工具")
print("检查API和Web表单的CSRF配置是否正确")
# 检查应用是否运行
try:
response = requests.get("http://localhost:5000/api/v1/health", timeout=3)
if response.status_code != 200:
print("\n⚠️ 应用似乎未运行或无法访问")
print("请先启动应用: flask run --host=0.0.0.0 --port=5000")
print("然后重新运行此脚本")
sys.exit(1)
except Exception as e:
print("\n⚠️ 无法连接到应用")
print(f"错误: {str(e)}")
print("请先启动应用: flask run --host=0.0.0.0 --port=5000")
print("然后重新运行此脚本")
sys.exit(1)
passed = generate_report()
sys.exit(0 if passed else 1)
if __name__ == '__main__':
main()