class

Analyzer::Ruby::ActionCable

Inherits Analyzer::Ruby::RubyEngine < Analyzer < FileHelper < Reference < Object

Surfaces Rails Action Cable real-time attack surface as ws:// endpoints. An ApplicationCable::Channel subclass exposes public methods the client invokes as actions (perform("speak", ...)) over the cable connection; mount ActionCable.server => "/cable" mounts the connection in config/routes.rb. Each callable action becomes one endpoint ws://<mount>/<Channel>/<action> (bare ws://<mount>/<Channel> when a channel has no actions), method "SEND", protocol "ws" — so the existing WebsocketTagger tags them.

Line-scan analyzer (Ruby house style). The cable mount lives in routes.rb while channels live under app/channels/, so the mount is collected across every .rb file first, then joined onto the channels.

Constants

CABLE_MOUNT = /\bmount\s+ActionCable\.server\s*=>\s*["']([^"']+)["']/

mount ActionCable.server => "/cable".

CABLE_MOUNT_MARKER_RE = Regex.union("ActionCable.server")

Whole-buffer gates for the per-file loop below, one precompiled matcher instead of a String#includes? scan per .rb file.

CHANNEL_CLASS = /^\s*class\s+(\w+)\s*<\s*(?:ApplicationCable::Channel|ActionCable::Channel::Base)\b/

class ChatChannel < ApplicationCable::Channel (or the framework base ActionCable::Channel::Base). The base module class ApplicationCable::Channel < ... carries a :: in the subclass name, so (\w+) never matches it — the base definition is skipped.

CHANNEL_MARKER_RE = Regex.union("Channel")
DEF_RE = /^\s*def\s+([a-z_]\w*[?!]?)\s*(?:[(\s]|$)/

An instance method definition (Ruby CLI house-style regex).

DEFAULT_MOUNT = "cable"

Rails' default Action Cable mount path when routes.rb does not mount it explicitly (a standalone cable server still serves /cable).

NON_ACTION_METHODS = Set {"subscribed", "unsubscribed", "initialize"}

Action Cable lifecycle callbacks — never client-invocable actions.

NON_CHANNEL_NAMES = Set {"Channel"}

The generated ApplicationCable::Channel base (class Channel < ActionCable::Channel::Base) matches CHANNEL_CLASS but is the shared base, not a real channel. Real channels follow the <Feature>Channel convention, so the bare name "Channel" is the base to skip.

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