DllSpy

扫描已编译的 .NET 程序集以发现输入面(HTTP 端点、SignalR 中心、WCF 服务、gRPC 服务、Razor 页面、Blazor 组件、Azure Functions、OData 端点),检查授权配置,并标记安全问题——所有这些无需运行应用程序。
提供 CLI 工具 和 PowerShell 模块。

安装
CLI
dotnet tool install -g DllSpy
PowerShell
Install-Module -Name DllSpy
用法
CLI
# 列出所有输入面
dllspy ./MyApi.dll
# 扫描安全漏洞
dllspy ./MyApi.dll -s
# 按输入面类型筛选(HttpEndpoint, SignalRMethod, WcfOperation, GrpcOperation, RazorPage, BlazorComponent, AzureFunction, ODataEndpoint)
dllspy ./MyApi.dll -t HttpEndpoint
# 按 HTTP 方法和类名筛选
dllspy ./MyApi.dll -m DELETE -c User*
# 仅显示已认证 / 匿名输入面
dllspy ./MyApi.dll --auth
dllspy ./MyApi.dll --anon
# 仅扫描宿主(可运行)程序集,跳过类库
dllspy ./MyApi.dll --host-only
# 以最低严重级别扫描
dllspy ./MyApi.dll -s --min-severity High
# 输出格式:table(默认), tsv, json
dllspy ./MyApi.dll -o json
dllspy ./MyApi.dll -o tsv
JSON + jq
# 列出所有未受保护的路由
dllspy ./MyApi.dll -o json | jq '[.[] | select(.requiresAuthorization == false) | .displayRoute]'
# 按类型统计输入面数量
dllspy ./MyApi.dll -o json | jq 'group_by(.surfaceType) | map({type: .[0].surfaceType, count: length})'
# 安全问题紧凑表格显示
dllspy ./MyApi.dll -s -o json | jq -r '.[] | [.severity, .surfaceRoute, .title] | @tsv'
PowerShell
# 所有输入面
Search-DllSpy -Path .\MyApi.dll
# 按输入面类型筛选
Search-DllSpy -Path .\MyApi.dll -Type HttpEndpoint
Search-DllSpy -Path .\MyApi.dll -Type SignalRMethod
Search-DllSpy -Path .\MyApi.dll -Type WcfOperation
Search-DllSpy -Path .\MyApi.dll -Type GrpcOperation
Search-DllSpy -Path .\MyApi.dll -Type RazorPage
Search-DllSpy -Path .\MyApi.dll -Type BlazorComponent
Search-DllSpy -Path .\MyApi.dll -Type AzureFunction
Search-DllSpy -Path .\MyApi.dll -Type ODataEndpoint
# 按 HTTP 方法筛选
Search-DllSpy -Path .\MyApi.dll -HttpMethod DELETE
# 按类名筛选(支持通配符)
Search-DllSpy -Path .\MyApi.dll -Class User*
# 仅显示已认证 / 匿名输入面
Search-DllSpy -Path .\MyApi.dll -RequiresAuth
Search-DllSpy -Path .\MyApi.dll -AllowAnonymous
# 仅扫描宿主(可运行)程序集,跳过类库
Search-DllSpy -Path .\bin\*.dll -HostOnly
# 查找安全问题
Test-DllSpy -Path .\MyApi.dll
# 仅限高严重性问题
Test-DllSpy -Path .\MyApi.dll -MinimumSeverity High
# 仅扫描宿主程序集以查找安全问题
Test-DllSpy -Path .\bin\*.dll -HostOnly
# 详细视图
Test-DllSpy -Path .\MyApi.dll | Format-List
支持的框架
| 框架 | 检测方法 | 输入面类型 |
|---|
| ASP.NET Core / Web API | 控制器基类、[ApiController]、命名约定 | HttpEndpoint |
| SignalR | Hub / Hub<T> 继承 | SignalRMethod |
| WCF | [ServiceContract] 接口 + [OperationContract] 方法 | WcfOperation |
| gRPC | 生成的基类含 BindService | GrpcOperation |
| Razor Pages | PageModel 继承,On{Verb}[Handler][Async] 方法 | RazorPage |
| Blazor | ComponentBase 继承 + [Route] 特性 | BlazorComponent |
| Azure Functions | [FunctionName] / [Function] + [HttpTrigger] 参数 | AzureFunction |
| OData | ODataController 继承 | ODataEndpoint |
安全规则
HTTP 端点
| 严重级别 | 规则 | 描述 |
|---|
| 高 | 未认证的状态变更端点 | 没有 [Authorize] 的 DELETE、POST、PUT 或 PATCH |
| 中 | 缺少授权声明 | 端点既没有 [Authorize] 也没有 [AllowAnonymous] |
| 低 | 已授权但未指定角色/策略 | 存在 [Authorize] 但未指定 Roles 或 Policy |
SignalR Hub 方法
| 严重级别 | 规则 | 描述 |
|---|
| 高 | 未认证的 hub 方法 | 没有 [Authorize] 的 hub 方法(客户端可直接调用) |
| 低 | 已授权但未指定角色/策略 | 存在 [Authorize] 但未指定 Roles 或 Policy |
WCF 操作
| 严重级别 | 规则 | 描述 |
|---|
| 高 | 未认证的 WCF 操作 | 没有 [PrincipalPermission] 或 [Authorize] 的操作 |
| 低 | 已授权但未指定角色 | 存在 [PrincipalPermission] 但未指定 Role |
gRPC 操作
| 严重级别 | 规则 | 描述 |
|---|
| 高 | 未认证的 gRPC 操作 | 没有 [Authorize] 的服务方法 |
| 低 | 已授权但未指定角色/策略 | 存在 [Authorize] 但未指定 Roles 或 Policy |
Razor 页面处理程序
| 严重级别 | 规则 | 描述 |
|---|
| 高 | 未认证的状态变更处理程序 | 没有 [Authorize] 的 POST、PUT、DELETE 或 PATCH 处理程序 |
| 中 | 缺少授权声明 | 处理程序既没有 [Authorize] 也没有 [AllowAnonymous] |
| 低 | 已授权但未指定角色/策略 | 存在 [Authorize] 但未指定 Roles 或 Policy |
Blazor 可路由组件
| 严重级别 | 规则 | 描述 |
|---|
| 高 | 未认证的可路由组件 | 有 [Route] 但没有 [Authorize] 的组件 |
| 低 | 已授权但未指定角色/策略 | 存在 [Authorize] 但未指定 Roles 或 Policy |
Azure Functions
| 严重级别 | 规则 | 描述 |
|---|
| 高 | 未认证的 Azure Functions | AuthorizationLevel.Anonymous 且没有 [Authorize] 特性 |
| 低 | 已授权但未指定角色/策略 | 存在 [Authorize] 但未指定 Roles 或 Policy |
OData 端点
| 严重级别 | 规则 | 描述 |
|---|
| 高 | 未认证的状态变更端点 | 没有 [Authorize] 的 DELETE、POST、PUT 或 PATCH |
| 中 | 缺少授权声明 | 端点既没有 [Authorize] 也没有 [AllowAnonymous] |
| 低 | 已授权但未指定角色/策略 | 存在 [Authorize] 但未指定 Roles 或 Policy |
许可证
参见 LICENSE。