Dotnet Source and Assembly Inspector (Dosai)
May 23, 2026 · View on GitHub
Dosai inspects source code, assemblies, and NuGet packages. It extracts methods, dependencies, API endpoints, call graphs, data-flow slices, crypto evidence, and package reachability facts for security review.
Usage
Dosai [command] [options]
Commands
Use methods for method inventory, endpoints, call graph, and dependency evidence. For managed assemblies, methods also extracts IL method-body call edges, portable PDB call locations, delegate targets, and lightweight virtual-call candidates. Use dataflows for source-to-sink slicing. Use crypto for cryptographic assets, materials, misuse findings, reachability, and CBOM evidence. agent-context, query, mcp, report, and diff support review automation and CI workflows.
For detailed command usage, implementation notes, algorithms, strengths, and limitations, see the Dosai command reference.
Common options
--path is the file or directory to inspect. --o sets the output path and defaults to dosai.json. Use --help for command-specific options.
Data-flow analysis
dataflows includes built-in .NET source and sink packs for ASP.NET, data access, filesystem, serialization, cloud/serverless, RPC, auth-sensitive APIs, and crypto-sensitive APIs. Custom pattern JSON can add sources, sinks, passthroughs, and sanitizers. Sanitizer matches stop taint propagation, and validators such as Regex.IsMatch suppress guarded true branches.
dotnet run --project ./Dosai/Dosai.csproj -- dataflows \
--path ./Dosai \
--o /tmp/dosai-dataflows.json \
--pattern-packs all \
--graph-format graphml \
--graph-out /tmp/dosai-dataflows.graphml
The data-flow engine performs field-sensitive property/field taint where receiver identity is available and emits simple interprocedural summaries for parameter-to-return and parameter-to-sink callees. For C# and VB source it uses Roslyn IOperation; for assembly-only inputs it reconstructs method-body flow from IL metadata, control-flow branches, portable PDB sequence points and local scopes, async/iterator/display-class captured fields, external passthrough summaries, emitted framework attributes, and package dependency scope. Slices can carry taint kinds, field paths, confidence, source/assembly evidence, and F#/R/VC++ frontend evidence for common script and native input and sink patterns.
dataflows is quiet by default and writes the JSON/graph artifacts. Add --print during local triage to render each slice as a stack-trace-style path with frames such as at Source/cli args [dfn1] in Program.cs:5:5, code snippets, symbols, PURLs, and via ... edge transitions:
dotnet run --project ./Dosai/Dosai.csproj -- dataflows \
--path ./Dosai \
--o /tmp/dosai-dataflows.json \
--print
Pass custom patterns with --patterns ./dataflow-patterns.json; the file is merged with built-in patterns. See Data-flow custom patterns for the JSON schema, pattern kinds, and examples, and Built-in data-flow pattern pack catalog for the contents of --pattern-packs.
The analyzer is optimized for full source-tree CI runs: pattern matching is indexed by hot lookup kind, syntax text is cached for code-like matches, assembly dependency directories are scoped with .deps.json when available, and slice construction uses indexed graph edges. Dosai's CI smoke test runs dataflows --path ./Dosai and assembly-only fixtures to guard both source and binary paths.
Source, binary, and combined analysis share a method identity and evidence model. Method inventory records, call graph nodes/edges, method calls, data-flow nodes, and method summaries can identify whether evidence came from Roslyn source, assembly metadata, IL call/data-flow reconstruction, delegate targets, virtual candidates, external summaries, framework models, or language frontends.
Cryptography and CBOM evidence
crypto detects algorithms, operations, key and certificate material, TLS settings, weak algorithms, hardcoded material, static IVs and nonces, insecure RNG, disabled certificate validation, legacy TLS references, and low PBKDF2 iteration counts. Findings include source locations, best-effort reachability from CLI and API entry points, and crypto-specific data-flow slice IDs when matching source-to-sink paths are available.
Native Dosai JSON:
dotnet run --project ./Dosai/Dosai.csproj -- crypto \
--path ./Dosai \
--o /tmp/dosai-crypto.json \
--format dosai
Combined CycloneDX-style CBOM output:
dotnet run --project ./Dosai/Dosai.csproj -- crypto \
--path ./Dosai \
--o /tmp/dosai-cbom.json \
--format cyclonedx
The CycloneDX mode preserves Dosai properties such as dosai:crypto:family, dosai:crypto:strength, dosai:crypto:reachableFromEntryPoint, dosai:crypto:evidenceType, and dosai:location so downstream BOM tooling can correlate code-level crypto assets, operations, materials, protocols, and findings with package BOMs without a separate evidence sidecar.
CBOM output can also include graph sidecars for full path inspection:
dotnet run --project ./Dosai/Dosai.csproj -- crypto \
--path ./Dosai \
--o /tmp/dosai-cbom.json \
--format cyclonedx \
--graph-format graphml,gexf
The CBOM includes dosai:crypto:dataFlowSliceIds, dosai:crypto:sourceMaterialIds, and dosai:crypto:sinkOperationIds properties where Dosai can correlate material sources to crypto operations. Graph sidecars preserve the detailed data-flow nodes and edges.
F#, R, and VC++ frontends
Dosai also analyzes F#, R, and VC++/C/C++ source. The F# frontend uses FSharp.Compiler.Service when available and records compiler-service evidence for .fs, .fsi, and .fsx files. The R frontend uses Rscript with R's native getParseData parser when R is installed, then falls back to managed lexical extraction if needed. The VC++ frontend extracts functions, includes, calls, native sinks, and crypto/TLS evidence from .c, .cpp, .cc, .cxx, .h, .hpp, and .hh files without requiring compile_commands.json.
Frontend evidence is conservative when project metadata is incomplete. It still provides inventory, callgraph, data-flow, and crypto coverage without failing analysis on missing references, missing R installations, or absent native build metadata.
Querying JSON
dotnet run --project ./Dosai/Dosai.csproj -- query \
--input /tmp/dosai-dataflows.json \
--query 'slices[sinkCategory=sql]' \
--o /tmp/sql-slices.json
Supported collection aliases include nodes, edges, slices, weaknesses, entrypoints, packages, dangerous, summaries, assets, operations, materials, protocols, and findings. Filters support =, !=, ~=, >, <, >=, and <=.
For operators, aliases, nested-property filters, and MCP query examples, see Dosai query language.
MCP-style stdio server
printf '{"jsonrpc":"2.0","id":1,"method":"tools/list"}\n' | \
dotnet run --project ./Dosai/Dosai.csproj -- mcp --path ./Dosai
For local-agent loops, MCP tool calls, prompt-size strategy, and CI automation recipes, see AI-agent and automation workflows.
The server exposes dosai.methods, dosai.dataflows, dosai.crypto, dosai.agent_context, and dosai.query tool calls as line-delimited JSON-RPC responses.
API authorization metadata
Endpoint extraction records richer auth context from attributes and common minimal API chains, including authorization policies, roles, authentication schemes, required scopes/claims, CORS policies, anonymous access, and antiforgery hints.
Developers
Running code directly from the code repository
Build with dotnet build ./Dosai, then run a command such as:
dotnet run --project ./Dosai -- methods --path ./Dosai/Dosai.cs
dotnet run --project ./Dosai -- methods --path ./MyPackage.1.0.0.nupkg
dotnet run --project ./Dosai -- crypto --path ./Dosai --format cyclonedx --o /tmp/dosai-cbom.json
Generating a self-contained executable for a system
For Windows, run dotnet publish -r win-x64 --self-contained. For Linux, run dotnet publish -r linux-x64 --self-contained.
Invoking the self-contained executable
After publishing, invoke Dosai.exe methods --path ./app.dll on Windows or Dosai methods --path ./src on Linux.
Run unit tests
dotnet test
Technical Overview
Dosai uses the Microsoft.CodeAnalysis (Roslyn) API and .NET Reflection to extract metadata from source code and compiled assemblies. It provides a unified view of code structure and dependencies across different .NET compilation outputs.
Core Components
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Source Code │ │ .NET Assembly │ │ .nupkg File │
│ (.cs, .vb) │ │ (.dll, .exe) │ │ │
└─────────┬───────┘ └─────────┬───────┘ └─────────┬───────┘
│ │ │
│ │ │ (Extract)
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Roslyn │ │ Reflection │ │ Extracted │
│ Analysis │ │ Analysis │───────▶│ Directory │
│ │ │ │ │ │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
│ │ │
└────────────────────┼──────────────────────┘
│
▼
┌─────────────────┐
│ Unified JSON │
│ Output Model │
│ (MethodsSlice) │
└─────────────────┘
GetSourceMethods: Uses Roslyn'sSyntaxTree,SemanticModel, and symbol analysis (IMethodSymbol,INamespaceSymbol, etc.) for C# and VB source. F#, R, and VC++/C/C++ use dedicated language frontends. The method pipeline extracts signatures, dependencies, property/field/event declarations, endpoint metadata, and call graph information.GetAssemblyMethods: Uses .NET Reflection (Assembly.LoadFrom,Type.GetMethods, etc.) to load compiled assemblies (.dll, .exe) and extract method metadata, including signatures, attributes, and inheritance details.GetAssemblyInformation: Uses Reflection andFileVersionInfoto gather metadata about assemblies such as version, location, dependencies, and target framework.GetMethodsFromNupkg: Extracts the .nupkg archive (ZIP format) to a temporary directory, filters relevant assemblies and source files, then delegates analysis to the existingGetMethodslogic.DataFlowAnalyzer: Builds source-to-sink slices with pattern packs, sanitizer handling, validator guard suppression, method summaries, field-sensitive taint keys, graph exports, package reachability, and weakness candidates.CryptoAnalyzer: Detects cryptographic assets, operations, materials, weak crypto, TLS validation bypasses, low PBKDF2 iterations, and CBOM evidence with best-effort reachability.
Output Schema
The output is a JSON object conforming to the MethodsSlice class structure, containing:
Dependencies: List of external namespaces/libraries used.Methods: List ofMethodobjects detailing signatures, locations, parameters, return types, etc.MethodCalls: List ofMethodCallsobjects representing invocations found in source code.Properties,Fields,Events,Constructors: Lists of corresponding member types found in source.CallGraph: List ofMethodCallEdgeobjects defining the call graph structure.AssemblyInformation: List ofAssemblyInfoobjects detailing the inspected assemblies.SourceAssemblyMapping: List ofSourceAssemblyMappingobjects linking source locations to assembly definitions.
NuGet Package (.nupkg) Handling
.nupkg files are ZIP archives. GetMethodsFromNupkg performs the following steps:
- Creates a temporary directory.
- Uses
System.IO.Compression.ZipFile.OpenReadto read the .nupkg. - Enumerates entries, skipping metadata files (
.nuspec,package/, etc.). - Extracts files with relevant extensions (
.dll,.exe,.cs,.vb,.fs). - Calls the standard
GetMethodson the temporary directory. - Cleans up the temporary directory after analysis.
Complementary Analysis with OWASP blint
See this document for integration ideas.
Integration with YARA cli
See Yara Usage docs
License
MIT