简介
威胁建模是一种在系统遭受攻击前思考「可能出现什么问题」的实用方法。与其直接使用工具,不如先识别出需要保护的对象、数据跨越信任边界的位置、攻击者如何在系统中移动,以及哪些控制措施可以降低风险。
在本实验中,你将检查一个小型本地登录服务,并在 security-model.json 中完成一个结构化的威胁模型。该模型并非自由格式的报告:每一步都会添加特定的 JSON 条目,并可通过验证脚本进行检查。
检查登录服务
在这一步中,你将检查即将进行建模的小型服务。威胁模型始于可观察的系统行为:应用程序的功能、它使用的文件,以及哪些信息对攻击者至关重要。
首先,进入项目目录:
cd /home/labex/project
列出准备好的文件:
ls -l
你应该能看到 app.py、users.json、sessions.json、security-model.json 以及 uploads 目录等文件。
现在,让演示应用程序显示其路由。路由是应用程序接收某种请求的入口点:
python3 app.py routes
输出应显示四条路由:
/login - 接收用户名和密码,然后创建会话令牌
/files - 列出属于已登录用户的文件
/download - 从 uploads 目录读取请求的文件名
/admin - 仅向管理员显示账户记录
最后,运行当前的模型检查器。由于模型目前是空的,它会报告缺失的部分:
python3 model-check.py all
你应该会看到每部分都缺少必要条目的提示。这就是本实验后续步骤的起点。
识别资产
在这一步中,你将向模型添加资产。在威胁建模中,资产是指系统必须保护的任何事物。对于这个登录服务,重要的资产不仅是文件,还包括身份验证数据和会话状态。
使用 cat 检查用户数据库:
cat users.json
该文件包含用户名、密码和角色。因此,user_credentials(用户凭据)和 admin_records(管理员记录)是重要的资产。
检查会话文件和 uploads 目录:
cat sessions.json
ls -l uploads
会话文件可能包含登录令牌,而 uploads 目录包含用户的私有内容。这些对应于 session_tokens(会话令牌)和 private_uploads(私有上传文件)。
现在更新 security-model.json 中的 assets 数组。下面的命令使用了 Python 的 here-document(即时文档)。它将 PY 标记之间的行作为简短脚本发送给 python3:
python3 - <<'PY'
import json
from pathlib import Path
path = Path("security-model.json")
model = json.loads(path.read_text())
model["assets"] = [
"user_credentials",
"session_tokens",
"private_uploads",
"admin_records",
]
path.write_text(json.dumps(model, indent=2) + "\n")
PY
仅检查资产部分:
python3 model-check.py assets
预期结果为:
assets: complete
映射信任边界
在这一步中,你将添加信任边界。信任边界是指数据在具有不同控制或信任级别的区域之间移动的位置。边界非常有用,因为许多攻击发生在不受信任的输入进入受信任的代码、文件或特权函数时。
再次查看路由列表:
python3 app.py routes
/login、/files 和 /download 路由接收来自用户侧的输入,并将其传递给服务器逻辑。在这个小型模型中,这就是 browser_to_server(浏览器到服务器)边界。
/download 路由从请求中读取文件名,然后访问 uploads 目录。这创建了一个 server_to_filesystem(服务器到文件系统)边界。/admin 路由将普通用户与仅限管理员的数据隔离开来,因此它创建了一个 user_to_admin_area(用户到管理区域)边界。
将这些边界添加到模型中:
python3 - <<'PY'
import json
from pathlib import Path
path = Path("security-model.json")
model = json.loads(path.read_text())
model["trust_boundaries"] = [
"browser_to_server",
"server_to_filesystem",
"user_to_admin_area",
]
path.write_text(json.dumps(model, indent=2) + "\n")
PY
检查信任边界部分:
python3 model-check.py trust_boundaries
预期结果为:
trust_boundaries: complete
添加攻击路径
在这一步中,你将添加攻击路径。攻击路径是攻击者从入口点向资产移动的具体方式。这是威胁建模的核心:将资产和边界与现实的攻击者行为联系起来。
使用演示凭据尝试一次登录:
python3 app.py login alice wonderland
输出是一个会话令牌:
session-alice-demo
这种行为展示了为什么密码和会话令牌很重要。弱密码可能导致 credential_guessing(凭据猜测),而窃取的令牌可能导致 session_token_theft(会话令牌窃取)。
/download 路由接受请求的文件名,因此粗心的实现可能导致 path_traversal(路径遍历)。/admin 路由保护管理员记录,因此缺失角色检查可能导致 admin_area_abuse(管理区域滥用)。
将这些攻击路径添加到模型中:
python3 - <<'PY'
import json
from pathlib import Path
path = Path("security-model.json")
model = json.loads(path.read_text())
model["attack_paths"] = [
"credential_guessing",
"session_token_theft",
"path_traversal",
"admin_area_abuse",
]
path.write_text(json.dumps(model, indent=2) + "\n")
PY
检查攻击路径部分:
python3 model-check.py attack_paths
预期结果为:
attack_paths: complete
选择缓解措施
在这一步中,你将通过添加缓解措施来完成模型。缓解措施是一种降低攻击路径发生概率或影响的控制手段。优秀的威胁模型会将每个重要的攻击路径与至少一个实用的控制措施配对。
为该小型登录服务使用以下配对:
credential_guessing可以通过rate_limit_login(限制登录频率)来降低。session_token_theft可以通过protect_session_tokens(保护会话令牌)来降低。path_traversal可以通过validate_download_paths(验证下载路径)来降低。admin_area_abuse可以通过enforce_admin_authorization(强制执行管理员授权)来降低。
将缓解措施添加到模型中:
python3 - <<'PY'
import json
from pathlib import Path
path = Path("security-model.json")
model = json.loads(path.read_text())
model["mitigations"] = [
"rate_limit_login",
"protect_session_tokens",
"validate_download_paths",
"enforce_admin_authorization",
]
path.write_text(json.dumps(model, indent=2) + "\n")
PY
现在运行完整的模型检查:
python3 model-check.py all
每一部分都应该是完整的:
assets: complete
trust_boundaries: complete
attack_paths: complete
mitigations: complete
你也可以查看最终的结构化模型:
cat security-model.json
重要的结果是,该模型现在将同一个小型服务中受保护的资产、信任边界、攻击路径和缓解措施连接了起来。
总结
你针对一个小型登录服务练习了实用的威胁建模工作流。你检查了服务、识别了资产、映射了信任边界、添加了攻击路径,并在结构化的 JSON 模型中将这些路径与缓解措施进行了配对。
这种工作流有助于将安全思考与可观察的系统行为联系起来,而不是将威胁建模视为一份单独的书面报告。



