class

Analyzer::CSharp::SignalR

Inherits Analyzer::CSharp::Common < Analyzer < FileHelper < Reference < Object

Surfaces ASP.NET Core SignalR real-time attack surface as ws:// endpoints. A SignalR Hub subclass exposes public methods the client invokes over a long-lived connection; MapHub<T>("/path") mounts the hub at a route. Each callable hub method becomes one endpoint ws://<hub-route>/<method> (bare ws://<hub-route> when a hub has no callable methods), method "SEND", protocol "ws" — so the existing WebsocketTagger tags them. Method parameters (minus DI/service types) become params (param_type "json").

Line-scan analyzer (C# house style; there is no C# engine). Hub classes and their MapHub<T> mounts routinely live in different files (ChatHub.cs vs Program.cs), so routes and hubs are collected across every .cs file first, then joined.

Constants

CLASS_OPEN = /\bclass\s+(\w+)(?:\s*<[^>]*>)?\s*(?::[^{]*)?/

Any class Name ... opener — used to bound a hub body and to detect a custom-base hub whose name was mounted via MapHub<T>.

HUB_CLASS = /\bclass\s+(\w+)(?:\s*<[^>]*>)?\s*:\s*(?:[\w.]+\.)?(?:Hub(?:\s*<[^>]*>)?|DynamicHub)\b/

A hub class: the base list's first entry (C# requires the base class first) is Hub, Hub<T> or DynamicHub, optionally namespace- qualified. Custom base hubs (: ChatHubBase) are still caught when the class is named in a MapHub<T> mount (see hub_class?).

MAP_HUB = /\bMapHub\s*<\s*([\w.]+)\s*>\s*\(\s*@?"([^"]+)"/

app.MapHub<ChatHub>("/chatHub") / endpoints.MapHub<ChatHub>("/hub").

NON_EVENT_METHODS = Set {"OnConnectedAsync", "OnDisconnectedAsync", "OnConnected", "OnDisconnected", "OnReconnected", "Dispose", "DisposeAsync"}

Lifecycle / infrastructure methods that are never client-invocable events even when declared public.

PUBLIC_METHOD = /^\s*public\s+((?:(?:static|async|virtual|override|sealed|new|unsafe)\s+)*)(?:[\w<>\[\],.?]+\s+)+(\w+)\s*\(/

A public instance method — a SignalR client-callable event. override is excluded (lifecycle hooks OnConnectedAsync/OnDisconnectedAsync), as are constructors and Dispose. Requires an opening paren so properties/fields are skipped.

Class methods

tech_name
Source

Instance methods

analyze
Source
tech

Instance-side view of the same declaration. The per-file rescues live on this base class, which has no way to name the analyzer that is running inside them, so a skipped file could not be attributed to a tech. Deriving it from analyzer_for keeps the name written exactly once.

Source