name: threat-modeling description: 威胁建模方法论(STRIDE、DREAD)、攻击树、威胁建模为代码,以及与SDLC集成以进行主动安全设计 argument-hint: “<组件或功能描述>” allowed-tools: Read, Grep, Glob, Write, Edit, Task, mcp__perplexity__, mcp__context7__, mcp__microsoft-learn__*
威胁建模
系统性的方法,用于识别、量化和解决软件系统中的安全威胁。
何时使用此技能
关键词: 威胁建模,STRIDE,DREAD,攻击树,安全设计,风险评估,威胁分析,数据流图,信任边界,攻击面,威胁枚举
使用此技能时:
- 设计新系统或功能
- 进行安全架构审查
- 识别潜在攻击向量
- 优先考虑安全投资
- 记录安全假设
- 将安全集成到SDLC中
- 创建威胁模型为代码
快速决策树
- 开始威胁建模? → 从威胁建模流程开始
- 识别威胁? → 使用STRIDE方法论
- 优先考虑威胁? → 应用DREAD评分或攻击树
- 自动化威胁模型? → 参见references/threat-modeling-tools.md
- 特定架构模式? → 参见架构特定威胁
威胁建模流程
┌─────────────────────────────────────────────────────────────────┐
│ 威胁建模工作流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 1. 分解系统 2. 识别威胁 3. 优先考虑风险 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 系统 │──────▶│ 威胁 │───────▶│ 风险 │ │
│ │ 模型 │ │ (STRIDE) │ │ (DREAD) │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 数据流图 │ │ 攻击 │ │ 对策 │ │
│ │ 信任 │ │ 树 │ │ 待办事项 │ │
│ │ 边界 │ │ 模式 │ │ │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ 4. 文档化 ──────▶ 5. 验证 ──────▶ 6. 迭代 │
│ │
└─────────────────────────────────────────────────────────────────┘
步骤 1: 系统分解
创建数据流图(DFD),包含以下元素:
| 元素 | 符号 | 描述 |
|---|---|---|
| 外部实体 | 矩形 | 用户、外部系统 |
| 过程 | 圆形 | 转换数据的代码 |
| 数据存储 | 平行线 | 数据库、文件、缓存 |
| 数据流 | 箭头 | 数据移动 |
| 信任边界 | 虚线 | 安全边界 |
// 示例:电子商务系统分解
public enum ElementType
{
ExternalEntity, Process, DataStore, DataFlow
}
/// <summary>定义安全边界</summary>
public sealed record TrustBoundary(
string Id,
string Name,
string Description,
IReadOnlyList<string> Elements); // 包含元素的ID
/// <summary>数据流图元素</summary>
public sealed record DfdElement
{
public required string Id { get; init; }
public required string Name { get; init; }
public required ElementType ElementType { get; init; }
public string? TrustBoundary { get; init; }
public string Description { get; init; } = "";
}
/// <summary>元素之间的连接</summary>
public sealed record DataFlow
{
public required string Id { get; init; }
public required string Source { get; init; }
public required string Destination { get; init; }
public required string DataType { get; init; }
public required string Protocol { get; init; }
public bool Encrypted { get; init; }
public bool Authenticated { get; init; }
}
/// <summary>用于威胁分析的完整系统模型</summary>
public sealed class SystemModel(string name)
{
public string Name => name;
private readonly Dictionary<string, DfdElement> _elements = new();
private readonly List<DataFlow> _flows = [];
private readonly List<TrustBoundary> _trustBoundaries = [];
public IReadOnlyDictionary<string, DfdElement> Elements => _elements;
public IReadOnlyList<DataFlow> Flows => _flows;
public IReadOnlyList<TrustBoundary> TrustBoundaries => _trustBoundaries;
public void AddElement(DfdElement element) => _elements[element.Id] = element;
public void AddFlow(DataFlow flow) => _flows.Add(flow);
public void AddTrustBoundary(TrustBoundary boundary) => _trustBoundaries.Add(boundary);
/// <summary>识别跨越信任边界的流 - 高风险区域</summary>
public IReadOnlyList<DataFlow> GetCrossBoundaryFlows()
{
var crossBoundary = new List<DataFlow>();
foreach (var flow in _flows)
{
var sourceBoundary = _elements[flow.Source].TrustBoundary;
var destBoundary = _elements[flow.Destination].TrustBoundary;
if (sourceBoundary != destBoundary)
crossBoundary.Add(flow);
}
return crossBoundary;
}
}
// 示例用法
var model = new SystemModel("电子商务平台");
// 定义元素
model.AddElement(new DfdElement
{
Id = "user",
Name = "客户",
ElementType = ElementType.ExternalEntity,
TrustBoundary = "internet",
Description = "通过浏览器访问的终端用户"
});
model.AddElement(new DfdElement
{
Id = "web_app",
Name = "Web应用",
ElementType = ElementType.Process,
TrustBoundary = "dmz",
Description = "前端Web服务器"
});
model.AddElement(new DfdElement
{
Id = "api",
Name = "API网关",
ElementType = ElementType.Process,
TrustBoundary = "internal",
Description = "后端API服务"
});
model.AddElement(new DfdElement
{
Id = "db",
Name = "数据库",
ElementType = ElementType.DataStore,
TrustBoundary = "internal",
Description = "客户和订单数据"
});
// 定义流
model.AddFlow(new DataFlow
{
Id = "f1",
Source = "user",
Destination = "web_app",
DataType = "HTTP请求",
Protocol = "HTTPS",
Encrypted = true,
Authenticated = false
});
// 查找高风险流
var riskyFlows = model.GetCrossBoundaryFlows();
STRIDE方法论
STRIDE 是一个用于系统性威胁识别的威胁分类框架:
| 类别 | 威胁 | 安全属性 | 示例 |
|---|---|---|---|
| Spoofing | 冒充他人或某物 | 认证 | 被盗凭据、会话劫持 |
| Tampering | 修改数据或代码 | 完整性 | SQL注入、文件修改 |
| Repudiation | 否认操作 | 不可否认性 | 缺少审计日志 |
| Information Disclosure | 暴露信息 | 机密性 | 数据泄露、详细错误 |
| Denial of Service | 中断可用性 | 可用性 | 资源耗尽、DDoS |
| Elevation of Privilege | 获得未授权访问 | 授权 | 权限提升、IDOR |
按元素STRIDE分析
对每个DFD元素应用STRIDE:
using System.Collections.Frozen;
public enum StrideCategory
{
Spoofing, Tampering, Repudiation, InformationDisclosure, DenialOfService, ElevationOfPrivilege
}
/// <summary>哪些STRIDE类别适用于哪些元素类型</summary>
public static class StrideApplicability
{
public static readonly FrozenDictionary<ElementType, StrideCategory[]> Map =
new Dictionary<ElementType, StrideCategory[]>
{
[ElementType.ExternalEntity] =
[StrideCategory.Spoofing, StrideCategory.Repudiation],
[ElementType.Process] =
[StrideCategory.Spoofing, StrideCategory.Tampering, StrideCategory.Repudiation,
StrideCategory.InformationDisclosure, StrideCategory.DenialOfService,
StrideCategory.ElevationOfPrivilege],
[ElementType.DataStore] =
[StrideCategory.Tampering, StrideCategory.Repudiation,
StrideCategory.InformationDisclosure, StrideCategory.DenialOfService],
[ElementType.DataFlow] =
[StrideCategory.Tampering, StrideCategory.InformationDisclosure,
StrideCategory.DenialOfService]
}.ToFrozenDictionary();
}
/// <summary>识别的威胁</summary>
public sealed record Threat
{
public required string Id { get; init; }
public required StrideCategory Category { get; init; }
public required string ElementId { get; init; }
public required string Title { get; init; }
public required string Description { get; init; }
public required string AttackVector { get; init; }
public string Impact { get; init; } = "";
public string Likelihood { get; init; } = "Medium";
public IReadOnlyList<string> Mitigations { get; init; } = [];
}
/// <summary>用于生成的威胁模板</summary>
public sealed record ThreatTemplate(
string TitleFormat, string DescriptionFormat, string AttackVector, string[] Mitigations);
/// <summary>系统性STRIDE威胁识别</summary>
public sealed class StrideAnalyzer(SystemModel model)
{
private readonly List<Threat> _threats = [];
private int _threatCounter;
private static readonly Dictionary<(ElementType, StrideCategory), ThreatTemplate> Templates = new()
{
[(ElementType.Process, StrideCategory.Spoofing)] = new(
"{0}的欺骗",
"攻击者冒充{0}以获取未授权访问",
"凭据盗窃、会话劫持、证书伪造",
["强认证", "证书固定", "会话管理"]),
[(ElementType.Process, StrideCategory.Tampering)] = new(
"篡改{0}",
"攻击者修改由{0}处理的数据",
"输入操纵、代码注入、内存损坏",
["输入验证", "完整性检查", "代码签名"]),
[(ElementType.DataStore, StrideCategory.InformationDisclosure)] = new(
"从{0}的信息泄露",
"从{0}暴露敏感数据",
"SQL注入、配置错误、备份暴露",
["静态加密", "访问控制", "数据屏蔽"])
};
/// <summary>对所有元素执行STRIDE分析</summary>
public IReadOnlyList<Threat> Analyze()
{
// 分析元素
foreach (var element in model.Elements.Values)
{
if (StrideApplicability.Map.TryGetValue(element.ElementType, out var categories))
{
foreach (var category in categories)
_threats.AddRange(IdentifyThreats(element, category));
}
}
// 分析数据流
if (StrideApplicability.Map.TryGetValue(ElementType.DataFlow, out var flowCategories))
{
foreach (var flow in model.Flows)
{
foreach (var category in flowCategories)
_threats.AddRange(IdentifyFlowThreats(flow, category));
}
}
return _threats;
}
private IEnumerable<Threat> IdentifyThreats(DfdElement element, StrideCategory category)
{
var key = (element.ElementType, category);
if (!Templates.TryGetValue(key, out var template))
yield break;
_threatCounter++;
yield return new Threat
{
Id = $"T{_threatCounter:D3}",
Category = category,
ElementId = element.Id,
Title = string.Format(template.TitleFormat, element.Name),
Description = string.Format(template.DescriptionFormat, element.Name),
AttackVector = template.AttackVector,
Mitigations = template.Mitigations
};
}
private IEnumerable<Threat> IdentifyFlowThreats(DataFlow flow, StrideCategory category)
{
if (category == StrideCategory.InformationDisclosure && !flow.Encrypted)
{
_threatCounter++;
yield return new Threat
{
Id = $"T{_threatCounter:D3}",
Category = category,
ElementId = flow.Id,
Title = $"未加密的数据流: {flow.Source} -> {flow.Destination}",
Description = $"数据({flow.DataType})传输时未加密",
AttackVector = "网络嗅探、中间人攻击",
Impact = "高 - 数据暴露",
Mitigations = ["启用TLS", "使用VPN", "在应用层加密"]
};
}
if (category == StrideCategory.Tampering && !flow.Authenticated)
{
_threatCounter++;
yield return new Threat
{
Id = $"T{_threatCounter:D3}",
Category = category,
ElementId = flow.Id,
Title = $"未认证的数据流: {flow.Source} -> {flow.Destination}",
Description = "数据流缺乏认证 - 无法验证来源",
AttackVector = "消息注入、重放攻击",
Impact = "中 - 数据完整性受损",
Mitigations = ["相互TLS", "消息签名", "API认证"]
};
}
}
}
有关详细STRIDE分析示例,请参见references/stride-methodology.md。
DREAD风险评分
DREAD 为优先考虑提供定量风险评估:
| 因素 | 描述 | 标度 |
|---|---|---|
| Damage | 如果被利用的影响 | 1-10 |
| Reproducibility | 攻击复现的容易程度 | 1-10 |
| Exploitability | 利用攻击所需努力 | 1-10 |
| Affected Users | 影响范围 | 1-10 |
| Discoverability | 发现漏洞的可能性 | 1-10 |
/// <summary>DREAD风险评分</summary>
public readonly struct DreadScore
{
public int Damage { get; } // 1-10
public int Reproducibility { get; } // 1-10
public int Exploitability { get; } // 1-10
public int AffectedUsers { get; } // 1-10
public int Discoverability { get; } // 1-10
public DreadScore(int damage, int reproducibility, int exploitability,
int affectedUsers, int discoverability)
{
ValidateRange(damage, nameof(damage));
ValidateRange(reproducibility, nameof(reproducibility));
ValidateRange(exploitability, nameof(exploitability));
ValidateRange(affectedUsers, nameof(affectedUsers));
ValidateRange(discoverability, nameof(discoverability));
Damage = damage;
Reproducibility = reproducibility;
Exploitability = exploitability;
AffectedUsers = affectedUsers;
Discoverability = discoverability;
}
private static void ValidateRange(int value, string name)
{
if (value is < 1 or > 10)
throw new ArgumentOutOfRangeException(name, $"{name}必须介于1-10之间");
}
/// <summary>计算平均DREAD分数</summary>
public double Total => (Damage + Reproducibility + Exploitability +
AffectedUsers + Discoverability) / 5.0;
/// <summary>分类风险级别</summary>
public string RiskLevel => Total switch
{
>= 8 => "严重",
>= 6 => "高",
>= 4 => "中",
_ => "低"
};
}
/// <summary>使用DREAD评分优先考虑威胁</summary>
public sealed class ThreatPrioritizer
{
private readonly List<(Threat Threat, DreadScore Score)> _scoredThreats = [];
public void ScoreThreat(Threat threat, DreadScore score) =>
_scoredThreats.Add((threat, score));
/// <summary>按风险排序威胁(最高优先)</summary>
public IReadOnlyList<(Threat Threat, DreadScore Score)> GetPrioritizedList() =>
_scoredThreats.OrderByDescending(x => x.Score.Total).ToList();
/// <summary>生成风险矩阵摘要</summary>
public Dictionary<string, List<string>> GenerateRiskMatrix()
{
var matrix = new Dictionary<string, List<string>>
{
["严重"] = [], ["高"] = [], ["中"] = [], ["低"] = []
};
foreach (var (threat, score) in _scoredThreats)
matrix[score.RiskLevel].Add(threat.Id);
return matrix;
}
}
// 示例评分
var sqlInjectionScore = new DreadScore(
damage: 9, // 完整数据库泄露
reproducibility: 8, // 使用工具容易复现
exploitability: 7, // 熟知技术
affectedUsers: 10, // 所有用户可能受影响
discoverability: 6 // 需要测试来发现
);
Console.WriteLine($"风险分数: {sqlInjectionScore.Total}"); // 8.0
Console.WriteLine($"风险级别: {sqlInjectionScore.RiskLevel}"); // 严重
替代:基于CVSS的评分
为了与行业标准兼容,映射到CVSS:
/// <summary>CVSS 3.1基础分数组件</summary>
public sealed record CvssVector
{
public required string AttackVector { get; init; } // N, A, L, P
public required string AttackComplexity { get; init; } // L, H
public required string PrivilegesRequired { get; init; } // N, L, H
public required string UserInteraction { get; init; } // N, R
public required string Scope { get; init; } // U, C
public required string Confidentiality { get; init; } // N, L, H
public required string Integrity { get; init; } // N, L, H
public required string Availability { get; init; } // N, L, H
public string ToVectorString() =>
$"CVSS:3.1/AV:{AttackVector}/AC:{AttackComplexity}/" +
$"PR:{PrivilegesRequired}/UI:{UserInteraction}/" +
$"S:{Scope}/C:{Confidentiality}/I:{Integrity}/A:{Availability}";
}
攻击树
攻击树可视化攻击者如何实现目标:
┌─────────────────────┐
│ 窃取客户数据 │ (目标)
└─────────────────────┘
│
┌───────────────┼───────────────┐
│ │ │
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ SQL │ │ 钓鱼 │ │ 内部 │
│ 注入 │ │ 攻击 │ │ 威胁 │
│ [OR] │ │ [OR] │ │ [OR] │
└───────────┘ └───────────┘ └───────────┘
│ │ │
┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐
│ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐
│ 找到 │ │ 利用 │ │ 发送 │ │ 获取 │ │ 贿赂 │ │ 非工作时间 │
│ 漏洞 │ │ 输入 │ │ 假 │ │ 凭据 │ │ 员工 │ │ 访问 │
│ 端点 │ │ 字段 │ │ 邮件 │ │ 站点 │ │ │ │ │
│ [AND] │ │ [AND] │ │ [AND] │ │ [AND] │ │ [OR] │ │ [OR] │
└───────┘ └───────┘ └───────┘ └───────┘ └───────┘ └───────┘
public enum NodeOperator
{
And, // 所有子节点必须成功
Or // 任何子节点可以成功
}
/// <summary>攻击树中的节点</summary>
public sealed class AttackNode
{
public required string Id { get; init; }
public required string Description { get; init; }
public NodeOperator Operator { get; init; } = NodeOperator.Or;
public double Cost { get; init; } // 估计攻击成本
public double Probability { get; init; } = 0.5; // 成功概率
public string SkillRequired { get; init; } = "中";
public List<AttackNode> Children { get; } = [];
public List<string> Countermeasures { get; init; } = [];
public void AddChild(AttackNode child) => Children.Add(child);
/// <summary>基于操作符和子节点计算概率</summary>
public double CalculateProbability()
{
if (Children.Count == 0)
return Probability;
var childProbs = Children.Select(c => c.CalculateProbability()).ToList();
if (Operator == NodeOperator.And)
{
// 所有必须成功 - 乘以概率
return childProbs.Aggregate(1.0, (acc, p) => acc * p);
}
else // OR
{
// 任何可以成功 - 1 - (全部失败)
return 1.0 - childProbs.Aggregate(1.0, (acc, p) => acc * (1 - p));
}
}
/// <summary>计算最小攻击成本</summary>
public double CalculateMinCost()
{
if (Children.Count == 0)
return Cost;
var childCosts = Children.Select(c => c.CalculateMinCost()).ToList();
if (Operator == NodeOperator.And)
{
// 必须完成所有 - 成本求和
return childCosts.Sum();
}
else // OR
{
// 选择最便宜路径
return childCosts.Min();
}
}
}
/// <summary>分析攻击树进行风险评估</summary>
public sealed class AttackTreeAnalyzer(AttackNode root)
{
/// <summary>找到最便宜的进攻路径</summary>
public IReadOnlyList<AttackNode> FindCheapestPath() => FindPath(root, minimizeCost: true);
/// <summary>找到最可能的进攻路径</summary>
public IReadOnlyList<AttackNode> FindMostLikelyPath() => FindPath(root, minimizeCost: false);
private static List<AttackNode> FindPath(AttackNode node, bool minimizeCost)
{
var path = new List<AttackNode> { node };
if (node.Children.Count == 0)
return path;
if (node.Operator == NodeOperator.And)
{
// 必须遍历所有子节点
foreach (var child in node.Children)
path.AddRange(FindPath(child, minimizeCost));
}
else // OR
{
// 选择最佳子节点
var bestChild = minimizeCost
? node.Children.MinBy(c => c.CalculateMinCost())!
: node.Children.MaxBy(c => c.CalculateProbability())!;
path.AddRange(FindPath(bestChild, minimizeCost));
}
return path;
}
/// <summary>从树中收集所有对策</summary>
public HashSet<string> GetAllCountermeasures() => CollectCountermeasures(root);
private static HashSet<string> CollectCountermeasures(AttackNode node)
{
var measures = new HashSet<string>(node.Countermeasures);
foreach (var child in node.Children)
measures.UnionWith(CollectCountermeasures(child));
return measures;
}
}
// 示例:构建攻击树
var rootNode = new AttackNode
{
Id = "goal",
Description = "窃取客户数据",
Operator = NodeOperator.Or
};
var sqlInjection = new AttackNode
{
Id = "sqli",
Description = "SQL注入攻击",
Operator = NodeOperator.And,
Countermeasures = ["参数化查询", "WAF", "输入验证"]
};
sqlInjection.AddChild(new AttackNode
{
Id = "find_vuln",
Description = "找到易受攻击端点",
Cost = 100,
Probability = 0.7,
SkillRequired = "中"
});
sqlInjection.AddChild(new AttackNode
{
Id = "exploit",
Description = "利用注入点",
Cost = 200,
Probability = 0.8,
SkillRequired = "高"
});
rootNode.AddChild(sqlInjection);
// 分析
var analyzer = new AttackTreeAnalyzer(rootNode);
Console.WriteLine($"总体攻击概率: {rootNode.CalculateProbability():P2}");
Console.WriteLine($"最小攻击成本: ${rootNode.CalculateMinCost()}");
Console.WriteLine($"所需对策: {string.Join(", ", analyzer.GetAllCountermeasures())}");
架构特定威胁
微服务架构
| 组件 | 关键威胁 | 对策 |
|---|---|---|
| API网关 | DDoS、注入、认证绕过 | 速率限制、WAF、OAuth |
| 服务网格 | mTLS绕过、边车妥协 | 证书轮换、网络策略 |
| 消息队列 | 消息篡改、重放 | 消息签名、幂等性 |
| 服务发现 | 注册表中毒 | 安全注册、健康检查 |
无服务器架构
| 组件 | 关键威胁 | 对策 |
|---|---|---|
| 函数 | 冷启动攻击、注入 | 输入验证、最小权限 |
| 事件源 | 事件注入、DoS | 源验证、速率限制 |
| 共享租户 | 吵闹邻居、数据泄露 | 隔离、加密 |
容器/Kubernetes架构
| 组件 | 关键威胁 | 对策 |
|---|---|---|
| 容器运行时 | 逃逸、权限提升 | 无根、seccomp、AppArmor |
| 编排器 | API服务器妥协 | RBAC、审计日志、网络策略 |
| 注册表 | 镜像篡改、供应链 | 镜像签名、漏洞扫描 |
SDLC集成
何时进行威胁建模
| 阶段 | 活动 | 输出 |
|---|---|---|
| 设计 | 初始威胁模型 | 威胁登记册、DFD |
| 开发 | 为变更更新 | 更新的威胁、安全测试 |
| 代码审查 | 验证对策 | 安全检查清单 |
| 测试 | 验证对策 | 渗透测试计划 |
| 发布 | 最终审查 | 风险接受、剩余风险 |
| 运维 | 事件分析 | 更新的威胁模型 |
轻量级威胁建模
对于敏捷环境,使用快速威胁建模:
# threat-model.yaml - 每个功能的最小威胁模型
feature: 用户认证
date: 2024-01-15
author: 安全团队
assets:
- name: 用户凭据
classification: 机密
- name: 会话令牌
classification: 内部
threats:
- id: AUTH-001
category: 欺骗
description: 凭据填充攻击
risk: 高
mitigation: 速率限制、MFA、泄露检测
- id: AUTH-002
category: 信息泄露
description: 令牌在日志中暴露
risk: 中
mitigation: 令牌脱敏、结构化日志
mitigations_implemented:
- Argon2id密码哈希
- 短期过期的JWT
- 刷新令牌轮换
open_risks:
- 使用MD5的遗留系统(计划Q2迁移)
安全检查清单
在最终化威胁模型之前:
- [ ] 所有信任边界已识别
- [ ] 对每个元素应用了STRIDE
- [ ] 跨越边界的数据流已加密
- [ ] 在信任边界交叉处有认证
- [ ] 风险已优先考虑(DREAD/CVSS)
- [ ] 对策已映射到威胁
- [ ] 剩余风险已文档化
- [ ] 模型已由利益相关者审查
- [ ] 与问题跟踪集成
参考
- STRIDE方法论深入 - 带有示例的详细分析
- 威胁建模工具 - pytm, threagile, 自动化
用户面向界面
当用户直接调用时,此技能使用STRIDE方法论生成结构化威胁模型。
执行工作流程
- 解析参数 - 从
$ARGUMENTS提取组件或功能描述。如果未提供参数,询问用户要威胁建模什么。 - 理解系统 - 识别资产、数据流、信任边界和入口点。
- 创建数据流图 - 生成Mermaid表示法的DFD,显示组件、数据流和信任边界。
- 应用STRIDE分析 - 分析每个组件的欺骗、篡改、否认、信息泄露、拒绝服务和权限提升威胁。
- 构建攻击树 - 为高价值资产创建目标导向的攻击树。
- 评分风险 - 应用DREAD方法论(损害、可复现性、可利用性、受影响用户、可发现性)来优先考虑威胁。
- 推荐控制措施 - 提供优先排序的安全控制建议(必须拥有/应该拥有/可有可无)。
版本历史
- v1.0.0 (2025-12-26): 初始发布,包括STRIDE、DREAD、攻击树、架构模式
最后更新: 2025-12-26