DllSpy.PowerShell.dll-Help.xml

<?xml version="1.0" encoding="utf-8"?>
<helpItems schema="maml"
  xmlns="http://msh"
  xmlns:maml="http://schemas.microsoft.com/maml/2004/10"
  xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10"
  xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
 
  <!-- ======================================================================
       Search-DllSpy
       ====================================================================== -->
  <command:command>
    <command:details>
      <command:name>Search-DllSpy</command:name>
      <command:verb>Search</command:verb>
      <command:noun>DllSpy</command:noun>
      <maml:description>
        <maml:para>Discovers input surfaces (HTTP endpoints, SignalR hub methods) in compiled .NET assemblies using reflection.</maml:para>
      </maml:description>
    </command:details>
 
    <maml:description>
      <maml:para>Scans one or more .NET assemblies for ASP.NET Core controllers and SignalR hubs, extracting all input surfaces with their routes, HTTP methods, authorization requirements, parameters, and return types.</maml:para>
      <maml:para>HTTP endpoints are detected by controller inheritance (ControllerBase, Controller, ApiController), the [ApiController] attribute, or by naming convention. SignalR hubs are detected by inheritance from Hub or Hub&lt;T&gt;.</maml:para>
      <maml:para>Routes for HTTP endpoints are resolved by combining controller-level and action-level [Route] templates. SignalR hub routes use conventional naming (strip "Hub" suffix).</maml:para>
    </maml:description>
 
    <command:syntax>
      <command:syntaxItem>
        <maml:name>Search-DllSpy</maml:name>
        <command:parameter required="true" position="0" pipelineInput="true (ByValue, ByPropertyName)">
          <maml:name>Path</maml:name>
          <command:parameterValue required="true">String[]</command:parameterValue>
        </command:parameter>
        <command:parameter required="false">
          <maml:name>Type</maml:name>
          <command:parameterValue required="true">SurfaceType</command:parameterValue>
        </command:parameter>
        <command:parameter required="false">
          <maml:name>HttpMethod</maml:name>
          <command:parameterValue required="true">String</command:parameterValue>
        </command:parameter>
        <command:parameter required="false">
          <maml:name>RequiresAuth</maml:name>
        </command:parameter>
        <command:parameter required="false">
          <maml:name>AllowAnonymous</maml:name>
        </command:parameter>
        <command:parameter required="false">
          <maml:name>Class</maml:name>
          <command:parameterValue required="true">String</command:parameterValue>
        </command:parameter>
      </command:syntaxItem>
    </command:syntax>
 
    <command:parameters>
      <command:parameter required="true" position="0" pipelineInput="true (ByValue, ByPropertyName)">
        <maml:name>Path</maml:name>
        <maml:description>
          <maml:para>Path to one or more .NET assembly files (.dll). Supports wildcards and pipeline input. You can pipe FileInfo objects (e.g. from Get-ChildItem) directly.</maml:para>
        </maml:description>
        <command:parameterValue required="true">String[]</command:parameterValue>
        <dev:type>
          <maml:name>String[]</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
 
      <command:parameter required="false">
        <maml:name>Type</maml:name>
        <maml:description>
          <maml:para>Filter surfaces by type. Valid values: HttpEndpoint, SignalRMethod. When omitted, all surface types are returned.</maml:para>
        </maml:description>
        <command:parameterValue required="true">SurfaceType</command:parameterValue>
        <dev:type>
          <maml:name>Spy.Core.Contracts.SurfaceType</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
 
      <command:parameter required="false">
        <maml:name>HttpMethod</maml:name>
        <maml:description>
          <maml:para>Filter HTTP endpoints by HTTP method. Valid values: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS. Only applies to HttpEndpoint surfaces.</maml:para>
        </maml:description>
        <command:parameterValue required="true">String</command:parameterValue>
        <dev:type>
          <maml:name>String</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
 
      <command:parameter required="false">
        <maml:name>RequiresAuth</maml:name>
        <maml:description>
          <maml:para>When specified, only returns surfaces that require authorization.</maml:para>
        </maml:description>
        <dev:type>
          <maml:name>SwitchParameter</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
 
      <command:parameter required="false">
        <maml:name>AllowAnonymous</maml:name>
        <maml:description>
          <maml:para>When specified, only returns surfaces that allow anonymous access.</maml:para>
        </maml:description>
        <dev:type>
          <maml:name>SwitchParameter</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
 
      <command:parameter required="false">
        <maml:name>Class</maml:name>
        <maml:description>
          <maml:para>Filter surfaces by class name (controller or hub). Supports wildcards (e.g. "User*", "*Hub"). The match is case-insensitive.</maml:para>
        </maml:description>
        <command:parameterValue required="true">String</command:parameterValue>
        <dev:type>
          <maml:name>String</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
    </command:parameters>
 
    <command:inputTypes>
      <command:inputType>
        <dev:type>
          <maml:name>System.String[]</maml:name>
        </dev:type>
        <maml:description>
          <maml:para>Assembly file paths. You can also pipe FileInfo objects from Get-ChildItem.</maml:para>
        </maml:description>
      </command:inputType>
    </command:inputTypes>
 
    <command:returnValues>
      <command:returnValue>
        <dev:type>
          <maml:name>Spy.Core.Contracts.InputSurface</maml:name>
        </dev:type>
        <maml:description>
          <maml:para>Objects representing discovered input surfaces. HttpEndpoint objects include Route, HttpMethod, ClassName, MethodName, and authorization details. SignalRMethod objects include HubName, HubRoute, MethodName, streaming flags, and authorization details.</maml:para>
        </maml:description>
      </command:returnValue>
    </command:returnValues>
 
    <maml:alertSet>
      <maml:alert>
        <maml:para>The assembly is loaded via System.Reflection. Dependent assemblies (e.g. ASP.NET Core framework) do not need to be present — Spy reads attributes by name rather than by type identity.</maml:para>
        <maml:para>SignalR hub routes are conventional (strip "Hub" suffix) since actual MapHub routes are not discoverable via reflection.</maml:para>
      </maml:alert>
    </maml:alertSet>
 
    <command:examples>
      <command:example>
        <maml:title>Example 1: Discover all surfaces</maml:title>
        <dev:code>Search-DllSpy -Path .\MyApi.dll</dev:code>
        <dev:remarks>
          <maml:para>Scans MyApi.dll and returns all discovered HTTP endpoints and SignalR hub methods.</maml:para>
        </dev:remarks>
      </command:example>
 
      <command:example>
        <maml:title>Example 2: Only HTTP endpoints</maml:title>
        <dev:code>Search-DllSpy -Path .\MyApi.dll -Type HttpEndpoint</dev:code>
        <dev:remarks>
          <maml:para>Returns only HTTP endpoints, excluding SignalR methods.</maml:para>
        </dev:remarks>
      </command:example>
 
      <command:example>
        <maml:title>Example 3: Only SignalR hub methods</maml:title>
        <dev:code>Search-DllSpy -Path .\MyApi.dll -Type SignalRMethod</dev:code>
        <dev:remarks>
          <maml:para>Returns only SignalR hub methods.</maml:para>
        </dev:remarks>
      </command:example>
 
      <command:example>
        <maml:title>Example 4: Filter by HTTP method</maml:title>
        <dev:code>Search-DllSpy -Path .\MyApi.dll -HttpMethod DELETE</dev:code>
        <dev:remarks>
          <maml:para>Returns only DELETE HTTP endpoints. Useful for auditing destructive operations.</maml:para>
        </dev:remarks>
      </command:example>
 
      <command:example>
        <maml:title>Example 5: Filter by class name with wildcards</maml:title>
        <dev:code>Search-DllSpy -Path .\MyApi.dll -Class Chat*</dev:code>
        <dev:remarks>
          <maml:para>Returns surfaces from classes whose names start with "Chat" (e.g. ChatHub, ChatController).</maml:para>
        </dev:remarks>
      </command:example>
 
      <command:example>
        <maml:title>Example 6: Scan multiple assemblies via pipeline</maml:title>
        <dev:code>Get-ChildItem .\bin\Release\net8.0\*.dll | Search-DllSpy</dev:code>
        <dev:remarks>
          <maml:para>Pipes all DLLs in the output directory to Spy. Assemblies without controllers or hubs produce no output.</maml:para>
        </dev:remarks>
      </command:example>
    </command:examples>
  </command:command>
 
  <!-- ======================================================================
       Test-DllSpy
       ====================================================================== -->
  <command:command>
    <command:details>
      <command:name>Test-DllSpy</command:name>
      <command:verb>Test</command:verb>
      <command:noun>DllSpy</command:noun>
      <maml:description>
        <maml:para>Analyzes .NET assemblies for security vulnerabilities in input surfaces.</maml:para>
      </maml:description>
    </command:details>
 
    <maml:description>
      <maml:para>Scans one or more .NET assemblies and applies security analysis rules to every discovered input surface (HTTP endpoints and SignalR hub methods). Issues are categorized by severity:</maml:para>
      <maml:para>HTTP endpoints:</maml:para>
      <maml:para>- High: State-changing endpoints (DELETE, POST, PUT, PATCH) without [Authorize]</maml:para>
      <maml:para>- Medium: Endpoints with neither [Authorize] nor [AllowAnonymous] (unclear security intent)</maml:para>
      <maml:para>- Low: [Authorize] present but without specific Roles or Policy</maml:para>
      <maml:para>SignalR hub methods:</maml:para>
      <maml:para>- High: Hub methods without [Authorize] (directly invocable by clients)</maml:para>
      <maml:para>- Low: [Authorize] present but without specific Roles or Policy</maml:para>
      <maml:para>Each issue includes a description of the problem and a remediation recommendation.</maml:para>
    </maml:description>
 
    <command:syntax>
      <command:syntaxItem>
        <maml:name>Test-DllSpy</maml:name>
        <command:parameter required="true" position="0" pipelineInput="true (ByValue, ByPropertyName)">
          <maml:name>Path</maml:name>
          <command:parameterValue required="true">String[]</command:parameterValue>
        </command:parameter>
        <command:parameter required="false">
          <maml:name>MinimumSeverity</maml:name>
          <command:parameterValue required="true">SecuritySeverity</command:parameterValue>
        </command:parameter>
        <command:parameter required="false">
          <maml:name>Type</maml:name>
          <command:parameterValue required="true">SurfaceType</command:parameterValue>
        </command:parameter>
      </command:syntaxItem>
    </command:syntax>
 
    <command:parameters>
      <command:parameter required="true" position="0" pipelineInput="true (ByValue, ByPropertyName)">
        <maml:name>Path</maml:name>
        <maml:description>
          <maml:para>Path to one or more .NET assembly files (.dll). Supports wildcards and pipeline input.</maml:para>
        </maml:description>
        <command:parameterValue required="true">String[]</command:parameterValue>
        <dev:type>
          <maml:name>String[]</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
 
      <command:parameter required="false">
        <maml:name>MinimumSeverity</maml:name>
        <maml:description>
          <maml:para>Only report issues at or above this severity level. Valid values: Info, Low, Medium, High, Critical. Defaults to Info (show everything).</maml:para>
        </maml:description>
        <command:parameterValue required="true">SecuritySeverity</command:parameterValue>
        <dev:type>
          <maml:name>Spy.Core.Contracts.SecuritySeverity</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>Info</dev:defaultValue>
      </command:parameter>
 
      <command:parameter required="false">
        <maml:name>Type</maml:name>
        <maml:description>
          <maml:para>Filter issues by surface type. Valid values: HttpEndpoint, SignalRMethod. When omitted, issues for all surface types are returned.</maml:para>
        </maml:description>
        <command:parameterValue required="true">SurfaceType</command:parameterValue>
        <dev:type>
          <maml:name>Spy.Core.Contracts.SurfaceType</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
    </command:parameters>
 
    <command:inputTypes>
      <command:inputType>
        <dev:type>
          <maml:name>System.String[]</maml:name>
        </dev:type>
        <maml:description>
          <maml:para>Assembly file paths. You can also pipe FileInfo objects from Get-ChildItem.</maml:para>
        </maml:description>
      </command:inputType>
    </command:inputTypes>
 
    <command:returnValues>
      <command:returnValue>
        <dev:type>
          <maml:name>Spy.Core.Contracts.SecurityIssue</maml:name>
        </dev:type>
        <maml:description>
          <maml:para>Objects representing security issues found, including Severity, SurfaceType, Title, Description, SurfaceRoute, ClassName, MethodName, and Recommendation.</maml:para>
        </maml:description>
      </command:returnValue>
    </command:returnValues>
 
    <maml:alertSet>
      <maml:alert>
        <maml:para>High-severity issues also produce a warning message via Write-Warning with the count of issues found.</maml:para>
      </maml:alert>
    </maml:alertSet>
 
    <command:examples>
      <command:example>
        <maml:title>Example 1: Find all security issues</maml:title>
        <dev:code>Test-DllSpy -Path .\MyApi.dll</dev:code>
        <dev:remarks>
          <maml:para>Scans MyApi.dll and returns all security issues sorted by severity (highest first).</maml:para>
        </dev:remarks>
      </command:example>
 
      <command:example>
        <maml:title>Example 2: Only high-severity issues</maml:title>
        <dev:code>Test-DllSpy -Path .\MyApi.dll -MinimumSeverity High</dev:code>
        <dev:remarks>
          <maml:para>Returns only High and Critical severity issues. Useful for CI/CD gates.</maml:para>
        </dev:remarks>
      </command:example>
 
      <command:example>
        <maml:title>Example 3: Only SignalR issues</maml:title>
        <dev:code>Test-DllSpy -Path .\MyApi.dll -Type SignalRMethod</dev:code>
        <dev:remarks>
          <maml:para>Returns only security issues related to SignalR hub methods.</maml:para>
        </dev:remarks>
      </command:example>
 
      <command:example>
        <maml:title>Example 4: CI/CD security gate</maml:title>
        <dev:code>$issues = Test-DllSpy -Path .\MyApi.dll -MinimumSeverity High
if ($issues) { Write-Error "Found $($issues.Count) high-severity issues"; exit 1 }</dev:code>
        <dev:remarks>
          <maml:para>Fails the build if any high-severity security issues are detected.</maml:para>
        </dev:remarks>
      </command:example>
 
      <command:example>
        <maml:title>Example 5: Scan multiple assemblies</maml:title>
        <dev:code>Get-ChildItem .\services\*\bin\Release\*.dll | Test-DllSpy -MinimumSeverity Medium</dev:code>
        <dev:remarks>
          <maml:para>Scans all service assemblies for medium-severity or higher issues.</maml:para>
        </dev:remarks>
      </command:example>
    </command:examples>
  </command:command>
 
</helpItems>