SeifMoussa/securebank-web-security-lab
GitHub: SeifMoussa/securebank-web-security-lab
一个基于 FastAPI 的虚构银行 Web 安全实验室,通过可运行的代码和测试演示 OWASP Top 10 安全控制措施的工程实践。
Stars: 0 | Forks: 0
# SecureBank Web 安全实验室
[](https://github.com/SeifMoussa/securebank-web-security-lab/actions/workflows/ci.yml)
[](https://github.com/SeifMoussa/securebank-web-security-lab/actions/workflows/codeql.yml)
[](https://github.com/SeifMoussa/securebank-web-security-lab/actions/workflows/zap-baseline.yml)
[](LICENSE)
**仅供实验室使用的虚构项目。** 这不是一家真实的银行,不会转移真实资金,不连接任何支付系统,且绝不能包含真实的客户数据或真实的金融标识符。
SecureBank Web Security Lab 是一个刻意保持小型的服务端渲染 FastAPI 应用程序,用于在安全工程实验室中演示安全的软件工程实践。它仅使用虚构的用户、虚构的账户以及整数形式的“实验室积分”。
## 为什么开发这个项目
我想要一个小型应用程序,其中的安全决策能在代码和测试套件中清晰可见,而不仅仅是列在一份检查清单上。虚构的银行业务流程为我设定了有用的工作边界:身份验证、授权、转账、审计事件以及恶意输入都至关重要,同时又无需涉及任何真实的金融数据或支付渠道。我使用 OWASP Top 10 作为覆盖范围图,然后通过侧重于安全的测试和 ZAP baseline 来支撑这些控制措施,而不是仅仅将这种映射关系本身作为证明。
## 比预期更困难的部分
身份验证的安全性是边界情况最多的部分。添加 Argon2id 哈希非常简单。但要让登录失败提示变得通用、对未知用户进行虚拟验证、处理签名会话以及测试被篡改的 cookie,则需要更加谨慎。虚构的转账路径还需要精心设计的事务边界,以确保写入失败时不会导致实验室积分余额只更新了一半。让 ZAP baseline 保持实用性,又不把每个扫描器警告都当作可利用的漏洞,则是另一个需要权衡的决策,这就是为什么它的工作流会保留一份报告供审查。
## 它所展示的内容
- 采用 Argon2id 密码哈希的防御性身份验证设计。
- 针对服务端渲染表单的签名会话 cookie 和 CSRF 防护。
- 通过 SQLAlchemy 表达式 API 和静态检查防止 SQL 注入。
- 通过全局 Jinja2 自动转义、CSP 和模板扫描防止 XSS。
- 针对已认证的银行风格页面的访问控制。
- 在持久化失败时支持回滚的原子级虚构转账行为。
- 不包含明文密码或会话密钥的安全审计日志。
- 针对 OWASP Top 10 控制措施的实用 pytest 覆盖。
- 用于后续运行时验证的 Docker Compose 文件和冒烟测试脚本。
- GitHub Actions CI、CodeQL 以及可选的 ZAP baseline 工作流配置。
## 当前功能
- 注册、登录、登出以及已认证的着陆页。
- 演示用户 `alice`、`bob` 和 `carol`,拥有虚构的实验室积分账户。
- 显示当前用户实验室积分余额和最近交易的仪表板。
- 演示用户之间的虚构转账流程。
- 交易历史页面。
- 健康检查端点:`/healthz` 和 `/health`。
- 纯 CSS、服务端渲染模板,且不使用 React。
## 技术栈
- FastAPI
- Jinja2 服务端渲染模板
- SQLAlchemy 2
- SQLite
- Pydantic v2 和 pydantic-settings
- 通过 `argon2-cffi` 实现的 Argon2id
- `itsdangerous` 签名 token
- 纯 CSS
- pytest
- ruff
- Docker Compose
在 GitHub 上验证过:GitHub Actions CI、CodeQL、Docker 冒烟测试以及 OWASP ZAP baseline 工作流。
## 安全控制
- Argon2id 密码哈希。
- 通用的登录失败提示信息。
- 对缺失用户进行虚拟密码验证,以降低用户名枚举风险。
- 签名的 HttpOnly SameSite=Strict 会话 cookie。
- 可配置的 Secure cookie 和 HSTS 设置。
- 针对会改变状态表单的 CSRF token。
- 包含 CSP `default-src 'self'` 的安全响应头。
- 全局启用 Jinja2 自动转义。
- 不使用模板的 `|safe`。
- SQLAlchemy 参数化查询风格。
- 基于已认证会话的服务端授权。
- 针对虚构转账的原子级扣款、入账和交易创建。
- 针对身份验证、授权和转账结果的审计事件。
- 针对原始 SQL 模式、不安全的模板过滤器、真实金融标识符以及已提交密钥材料的静态安全扫描。
## OWASP Top 10 摘要
- A01 失效的访问控制:受保护的路由、基于会话派生的发送者、IDOR 测试。
- A02 加密失败:Argon2id 密码和签名的会话 token。
- A03 注入:SQLAlchemy 查询和类恶意输入测试。
- A04 不安全的设计:虚构的实验室范围、整数实验室积分、原子级转账。
- A05 安全配置错误:安全响应头、CSP、HSTS 门控、自动转义。
- A06 易受攻击和过时的组件:已声明依赖项;自动化扫描待定。
- A07 身份识别和身份验证失败:验证、通用失败提示、虚拟验证、登出、会话篡改测试。
- A08 软件和数据完整性失败:签名会话/CSRF token;CI 完整性检查待定。
- A09 安全日志记录和监控失败:审计事件和敏感数据排除测试。
- A10 SSRF:由于应用程序不执行任何出站 HTTP 请求,因此被记录为超出范围。
参见 [docs/owasp-top-10-mapping.md](docs/owasp-top-10-mapping.md)。
## 不使用 Docker 的快速开始
```
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
python -m uvicorn securebank.main:app --reload
```
打开:
- `http://localhost:8000/healthz`
- `http://localhost:8000/login`
- `http://localhost:8000/register`
预设用户的演示密码:
```
LabDemo123!
```
## Docker 快速开始
Docker 文件和冒烟测试脚本已实现,但由于当前环境中未安装 Docker 或 Docker 不在 PATH 中,因此尚未在本地进行 Docker 运行时验证。
在支持 Docker 的机器上:
```
docker compose build
docker compose up -d
curl http://localhost:8000/healthz
docker compose down
```
冒烟测试脚本:
```
scripts/verify-docker.sh
```
```
.\scripts\smoke-test.ps1
```
## 测试命令
```
python -m pytest
python -m ruff check .
python -m ruff format --check .
```
Make 目标也可用:
```
make test
make lint
make format-check
```
## 项目结构
```
src/securebank/
auth/ authentication routes and services
audit/ audit event helper
banking/ fictional lab-credit pages and transfer service
security/ password, session, CSRF, and header helpers
templates/ server-rendered Jinja2 templates
static/ plain CSS
tests/ unit, route, security, static safety, and Docker artifact tests
docs/ threat model, controls, OWASP mapping, testing, and safety docs
scripts/ Docker smoke verification scripts
```
## 截图
截图待定。不包含任何虚假截图。
计划中的真实截图:
- 登录页面
- 仪表板
- 转账表单
- 交易历史
## 当前验证状态
- pytest:70 个通过
- coverage:96.02%
- ruff check:通过
- ruff format check:通过
- docs check:通过
- Docker 文件和冒烟测试脚本:已实现
- Docker 运行时:已通过 GitHub Actions Docker 冒烟测试验证
- GitHub Actions CI:已在 GitHub 上验证
- CodeQL:已在 GitHub 上验证
- ZAP baseline 工作流:已在 GitHub 上验证
## 已知限制
- 这是一个虚构的银行安全实验室,而不是生产级别的银行系统。
- 它没有真实的支付渠道、银行集成、客户数据或金融标识符;预设的用户和实验室积分余额仅作为演示数据。
- 部署加固受到限制。该仓库演示了可配置的安全 cookie 和 HSTS,但不提供生产环境下的密钥管理、基础设施隔离、监控、备份或容灾恢复。
- OWASP Top 10 映射、安全测试和 ZAP baseline 提供了有用的覆盖范围,但它们不能替代威胁模型审查、手动渗透测试或生产风险评估。
- 在用于编写本地项目笔记的机器上无法使用 Docker 运行时;Docker 冒烟测试和 ZAP baseline 路径是通过 GitHub Actions 执行的。
## 接下来我会改进的地方
我的下一步将是添加一个可重复的、经过加固的部署示例,其中包含外部密钥注入、TLS 终止、持久化数据库备份以及可观察的审计事件处理。我还会添加明确的登录限流和会话撤销机制,然后围绕这些控制措施扩展安全测试。对于扫描器覆盖范围,我将随着时间的推移审查并记录 ZAP baseline 的变化,而不是让该工作流变成一个无人阅读的徽章。
## 如何验证其有效性
安装开发依赖项,然后运行该仓库使用的相同本地检查:
```
python -m pip install -e ".[dev]"
python -m pytest
python -m ruff check .
python -m ruff format --check .
python scripts/check-docs.py
```
要在具有 Docker 的机器上进行运行时检查,请使用该仓库的 Compose 配置并验证健康检查端点:
```
docker compose build
docker compose up -d
curl http://localhost:8000/healthz
docker compose down
```
ZAP baseline 定义在 `.github/workflows/zap-baseline.yml` 中,并在 GitHub Actions 中针对本地实验室应用程序运行。请审查该工作流上传的报告及其状态;绿色的 baseline 并不代表该应用程序已准备好投入生产环境。
## 许可证
MIT。参见 [LICENSE](LICENSE)。
标签:AV绕过, FastAPI, OPA, OWASP Top 10, Web安全, Web应用开发, 安全工程, 安全规则引擎, 版权保护, 蓝队分析, 逆向工具, 靶场