pytm是一个基于Python的威胁建模库,用于基于STRIDE方法论的程序化威胁分析。它使得安全工程师能够将系统架构定义为代码,自动生成数据流图(DFDs),识别跨信任边界的安全威胁,并生成全面的威胁报告。这种方法将威胁建模集成到CI/CD管道中,实现了左移安全和持续威胁分析。
快速开始 创建基本威胁模型:
#!/usr/bin/env python3
from pytm import TM, Server, Dataflow, Boundary, Actor
# 初始化威胁模型
tm = TM("Web Application Threat Model")
tm.description = "E-commerce web application"
# 定义信任边界
internet = Boundary("Internet")
dmz = Boundary("DMZ")
internal = Boundary("Internal Network")
# 定义参与者和组件
user = Actor("Customer")
user.inBoundary = internet
web = Server("Web Server")
web.inBoundary = dmz
db = Server("Database")
db.inBoundary = internal
# 定义数据流
user_to_web = Dataflow(user, web, "HTTPS Request")
user_to_web.protocol = "HTTPS"
user_to_web.data = "credentials, payment info"
user_to_web.isEncrypted = True
web_to_db = Dataflow(web, db, "Database Query")
web_to_db.protocol = "SQL/TLS"
web_to_db.data = "user data, transactions"
# 生成威胁报告和图表
tm.process()
安装pytm:
pip install pytm
# 还需要graphviz来生成图表
brew install graphviz # macOS
# 或者:apt-get install graphviz # Linux
核心工作流程
工作流程1:创建新的威胁模型
进度:
[ ] 1. 定义系统范围和信任边界
[ ] 2. 识别所有参与者(用户、管理员、外部系统)
[ ] 3. 映射系统组件(服务器、数据库、API、服务)
[ ] 4. 定义组件间的数据流及安全属性
[ ] 5. 运行tm.process()生成威胁和DFD
[ ] 6. 审查STRIDE威胁并添加缓解措施
[ ] 7. 使用scripts/generate_report.py生成威胁报告
系统地完成每个步骤。完成的项目打勾。
工作流程2:STRIDE威胁分析
pytm自动根据STRIDE类别识别威胁:
- 欺骗:身份伪装攻击
- 篡改:未经授权的数据修改
- 否认:没有可追溯性的行为否认
- 信息披露:未经授权访问敏感数据
- 拒绝服务:可用性攻击
- 权限提升:未经授权的访问升级
对于每个识别的威胁:
- 审查威胁描述和受影响的组件
- 评估可能性和影响(使用
references/risk_matrix.md) - 确定现有控制是否缓解了威胁
- 使用
threat.mitigation = "description"添加缓解措施 - 文档化剩余风险和接受标准
工作流程3:架构即代码
以编程方式定义系统架构:
from pytm import TM, Server, Datastore, Dataflow, Boundary, Actor, Lambda
tm = TM("Microservices Architecture")
# 云边界
internet = Boundary("Internet")
cloud_vpc = Boundary("Cloud VPC")
# API网关
api_gateway = Server("API Gateway")
api_gateway.inBoundary = cloud_vpc
api_gateway.implementsAuthentication = True
api_gateway.implementsAuthorization = True
# 微服务
auth_service = Lambda("Auth Service")
auth_service.inBoundary = cloud_vpc
order_service = Lambda("Order Service")
order_service.inBoundary = cloud_vpc
# 数据存储
user_db = Datastore("User Database")
user_db.inBoundary = cloud_vpc
user_db.isEncryptedAtRest = True
# 数据流及安全属性
client_to_api = Dataflow(Actor("Client"), api_gateway, "API Request")
client_to_api.protocol = "HTTPS"
client_to_api.isEncrypted = True
client_to_api.data = "user credentials, orders"
api_to_auth = Dataflow(api_gateway, auth_service, "Auth Check")
api_to_auth.protocol = "gRPC/TLS"
auth_to_db = Dataflow(auth_service, user_db, "User Lookup")
auth_to_db.protocol = "TLS"
tm.process()
工作流程4:CI/CD集成
在持续集成中自动化威胁建模:
# .github/workflows/threat-model.yml
name: Threat Model Analysis
on: [push, pull_request]
jobs:
threat-model:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install dependencies
run: |
pip install pytm
sudo apt-get install -y graphviz
- name: Generate threat model
run: python threat_model.py
- name: Upload DFD diagram
uses: actions/upload-artifact@v3
with:
name: threat-model-dfd
path: '*.png'
- name: Check for unmitigated threats
run: python scripts/check_mitigations.py threat_model.py
工作流程5:威胁报告生成
生成全面的威胁文档:
# 运行威胁模型并生成报告
python threat_model.py
# 生成markdown报告
./scripts/generate_report.py --model threat_model.py --output threat_report.md
# 生成JSON以集成工具
./scripts/generate_report.py --model threat_model.py --format json --output threats.json
报告包括:
- 系统架构概览
- 信任边界分析
- 完整的STRIDE威胁枚举
- 现有和推荐的缓解措施
- 风险优先级矩阵
安全考虑
敏感数据处理
- 威胁模型作为代码:存储在版本控制中,但审查敏感架构细节
- 凭证和秘密:永远不要在威胁模型中硬编码 - 使用占位符
- 数据分类:清晰地用敏感性级别标记数据流(PII、PCI、PHI)
- 报告分发:控制显示安全架构的威胁报告的访问
访问控制
- 威胁模型仓库:限制写入权限给安全团队和架构师
- CI/CD集成:保护威胁建模管道免受篡改
- 图表工件:控制显示系统架构的DFDs的分发
- 缓解跟踪:与安全问题跟踪系统集成
审计日志
记录以下内容以进行安全治理:
- 威胁模型的创建和修改历史
- 识别的威胁和严重性评估
- 缓解措施的实施和验证
- 风险接受决定与批准
- 威胁模型审查和更新周期
合规要求
- NIST 800-30:风险评估方法论对齐
- ISO 27001:A.14.1.2 - 在公共网络上保护应用程序服务
- OWASP SAMM:威胁评估实践成熟度
- PCI-DSS 6.3.1:在开发中识别安全威胁
- SOC2 CC9.1:系统变更的风险评估过程
捆绑资源
脚本(scripts/)
generate_report.py- 生成带有STRIDE分类的markdown/JSON威胁报告check_mitigations.py- 验证所有已识别的威胁都有记录的缓解措施threat_classifier.py- 使用DREAD或自定义风险矩阵对威胁进行分类template_generator.py- 为常见架构生成威胁模型模板
参考(references/)
stride_methodology.md- 完整的STRIDE方法论指南及威胁示例risk_matrix.md- 风险评估框架,包括可能性和影响评分component_library.md- 可重用的pytm组件,用于常见模式(APIs、数据库、云服务)mitigation_strategies.md- 常见的缓解模式,对应STRIDE类别和OWASP控制
资产(assets/)
templates/web_application.py- Web应用威胁模型模板templates/microservices.py- 微服务架构模板templates/mobile_app.py- 移动应用威胁模型模板templates/iot_system.py- IoT系统威胁模型模板dfd_styles.json- 自定义graphviz样式,用于专业图表
常见模式
模式1:Web应用三层架构
from pytm import TM, Server, Datastore, Dataflow, Boundary, Actor
tm = TM("Three-Tier Web Application")
# 边界
internet = Boundary("Internet")
dmz = Boundary("DMZ")
internal = Boundary("Internal Network")
# 组件
user = Actor("End User")
user.inBoundary = internet
lb = Server("Load Balancer")
lb.inBoundary = dmz
lb.implementsNonce = True
web = Server("Web Server")
web.inBoundary = dmz
web.implementsAuthentication = True
web.implementsAuthenticationOut = False
app = Server("Application Server")
app.inBoundary = internal
app.implementsAuthorization = True
db = Datastore("Database")
db.inBoundary = internal
db.isSQL = True
db.isEncryptedAtRest = True
# 数据流
Dataflow(user, lb, "HTTPS").isEncrypted = True
Dataflow(lb, web, "HTTPS").isEncrypted = True
Dataflow(web, app, "HTTP").data = "session token, requests"
Dataflow(app, db, "SQL/TLS").data = "user data, transactions"
tm.process()
模式2:云原生微服务
from pytm import TM, Lambda, Datastore, Dataflow, Boundary, Actor
tm = TM("Cloud Microservices")
cloud = Boundary("Cloud Provider VPC")
user = Actor("Mobile App")
# 无服务器函数
api_gateway = Lambda("API Gateway")
api_gateway.inBoundary = cloud
api_gateway.implementsAPI = True
auth_fn = Lambda("Auth Function")
auth_fn.inBoundary = cloud
# 托管服务
cache = Datastore("Redis Cache")
cache.inBoundary = cloud
cache.isEncrypted = True
db = Datastore("DynamoDB")
db.inBoundary = cloud
db.isEncryptedAtRest = True
# 数据流
Dataflow(user, api_gateway, "API Call").protocol = "HTTPS"
Dataflow(api_gateway, auth_fn, "Auth").protocol = "internal"
Dataflow(auth_fn, cache, "Session").isEncrypted = True
Dataflow(api_gateway, db, "Query").isEncrypted = True
tm.process()
模式3:添加自定义威胁
定义组织特定的威胁:
from pytm import TM, Threat
tm = TM("Custom Threat Model")
# 向组件添加自定义威胁
web_server = Server("Web Server")
custom_threat = Threat(
target=web_server,
id="CUSTOM-001",
description="API速率限制绕过使用分布式请求",
condition="web_server.implementsRateLimiting is False",
mitigation="使用Redis实现分布式速率限制",
references="OWASP API Security Top 10 - API4 Unrestricted Resource Consumption"
)
web_server.threats.append(custom_threat)
模式4:信任边界分析
关注跨边界威胁:
# 识别所有信任边界穿越
for flow in tm.dataflows:
if flow.source.inBoundary != flow.sink.inBoundary:
print(f"Cross-boundary flow: {flow.name}")
print(f" From: {flow.source.inBoundary.name}")
print(f" To: {flow.sink.inBoundary.name}")
print(f" Encrypted: {flow.isEncrypted}")
print(f" Authentication: {flow.implementsAuthentication}")
信任边界穿越需要额外审查:
- 认证和授权机制
- 在传输中的加密
- 输入验证和清理
- 日志记录和监控
集成点
SDLC集成
- 设计阶段:在架构审查期间创建初始威胁模型
- 开发:参考威胁模型以满足安全需求
- 代码审查:验证缓解措施是否正确实现
- 测试:从识别的威胁生成安全测试用例
- 部署:验证安全控制是否符合威胁模型假设
- 运维:针对基础设施变更更新威胁模型
安全工具生态系统
- 问题跟踪:将威胁导出为Jira/GitHub问题以跟踪缓解措施
- 文档:为安全文档生成威胁模型
- SIEM:将威胁映射到检测规则和监控警报
- 渗透测试:向渗透测试人员提供威胁模型以进行针对性评估
- 代码分析:将SAST/DAST发现链接到威胁模型威胁
云和DevOps
- 基础设施即代码:对Terraform/CloudFormation模板进行威胁建模
- 容器安全:对容器编排和服务网格建模
- API设计:对API网关和微服务通信建模
- 秘密管理:对密钥管理和秘密分发建模
故障排除
问题:输出中缺少威胁
症状:预期的STRIDE威胁没有出现在生成的报告中
解决方案:
- 验证组件属性是否设置正确(例如,数据库的
isSQL=True) - 检查数据流安全属性(
isEncrypted,protocol) - 确保组件被分配到边界
- 审查信任边界穿越
- 参考
references/stride_methodology.md了解威胁条件
问题:图表生成失败
症状:DFD未生成或graphviz错误
解决方案:
# 验证graphviz安装
dot -V
# 如果缺少graphviz,请安装
brew install graphviz # macOS
sudo apt-get install graphviz # Linux
# 测试pytm与简单模型
python -c "from pytm import TM; tm = TM('test'); tm.process()"
问题:太多误报威胁
症状:识别的威胁不适用于您的架构
解决方案:
- 设置准确的组件属性以抑制不相关的威胁
- 使用威胁条件进行过滤:
threat.condition = "..." - 文档化为什么威胁不适用:
threat.mitigation = "N/A - 使用托管服务" - 使用
references/component_library.md创建自定义威胁库
问题:威胁模型维护漂移
症状:威胁模型不反映当前架构
解决方案:
- 将威胁模型存储在版本控制中,与架构图一起
- 在架构变更时触发威胁模型再生
- 计划每季度审查威胁模型
- 将威胁模型更新与架构审查委员会批准链接
- 使用
scripts/check_mitigations.py验证完整性
高级配置
自定义威胁定义
创建组织特定的威胁库:
# custom_threats.py
from pytm import Threat
def add_custom_threats(tm):
"""向威胁模型添加组织特定的威胁"""
# 云特定威胁
cloud_misconfiguration = Threat(
id="CLOUD-001",
description="配置错误的云存储桶暴露敏感数据",
condition="datastore.inBoundary.name == 'Cloud' and not datastore.isEncrypted",
mitigation="启用静态加密和桶策略"
)
# API特定威胁
api_abuse = Threat(
id="API-001",
description="由于缺乏速率限制而滥用API端点",
condition="server.implementsAPI and not server.implementsRateLimiting",
mitigation="实施速率限制和API密钥轮换"
)
return [cloud_misconfiguration, api_abuse]
风险评分集成
向威胁添加DREAD评分:
class ScoredThreat(Threat):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.damage = 0 # 0-10
self.reproducibility = 0
self.exploitability = 0
self.affected_users = 0
self.discoverability = 0
def dread_score(self):
return (self.damage + self.reproducibility + self.exploitability +
self.affected_users + self.discoverability) / 5
# 使用
threat = ScoredThreat(
target=component,
description="SQL注入",
damage=9,
reproducibility=8,
exploitability=7,
affected_users=10,
discoverability=6
)
print(f"DREAD Score: {threat.dread_score()}/10")
图表定制
使用graphviz属性定制DFD输出:
# 为信任边界设置自定义颜色
internet.color = "red"
dmz.color = "orange"
internal.color = "green"
# 自定义图表输出
tm.graph_options = {
"rankdir": "LR", # 从左到右布局
"bgcolor": "white",
"fontname": "Arial",
"fontsize": "12"
}