Skip to main content

Overview

The DriverManager class handles driver loading, registration, and lifecycle. It’s the central point for managing recording and running drivers in Vulcn.

Import

import { DriverManager, driverManager } from "@vulcn/engine";
driverManager is a default shared instance. Create your own new DriverManager() for isolated testing.

Constructor

const manager = new DriverManager();
Creates a new DriverManager with no drivers registered.

Methods

register

Register a driver with the manager.
register(driver: VulcnDriver, source?: DriverSource): void
Parameters:
  • driver - The driver to register
  • source - Optional source type ("npm", "local", "builtin")
Example:
import browserDriver from "@vulcn/driver-browser";

manager.register(browserDriver);
The first registered driver automatically becomes the default driver.

load

Load a driver from npm or a local file path.
async load(nameOrPath: string): Promise<void>
Parameters:
  • nameOrPath - npm package name or file path
Example:
// Load from npm
await manager.load("@vulcn/driver-browser");

// Load from local file
await manager.load("./my-custom-driver.js");

get

Get a loaded driver by name.
get(name: string): VulcnDriver | undefined
Example:
const driver = manager.get("browser");
if (driver) {
  console.log(driver.version);
}

getDefault

Get the current default driver.
getDefault(): VulcnDriver | undefined

setDefault

Set the default driver by name.
setDefault(name: string): void
Throws: Error if driver is not registered.

has

Check if a driver is registered.
has(name: string): boolean

list

Get all registered drivers.
list(): LoadedDriver[]
Returns: Array of loaded driver info including source metadata.

getForSession

Get the appropriate driver for a session.
getForSession(session: Session): VulcnDriver
Throws: Error if the session’s driver is not registered. Example:
const session = parseSession(yaml);
const driver = manager.getForSession(session);
console.log(`Using ${driver.name} driver`);

startRecording

Start recording with a specific driver.
async startRecording(
  driverName: string,
  config: Record<string, unknown>,
  options?: RecordOptions
): Promise<RecordingHandle>
Parameters:
  • driverName - Name of the driver to use
  • config - Driver-specific configuration
  • options - Optional recording options
Returns: A RecordingHandle for controlling the recording. Example:
const handle = await manager.startRecording("browser", {
  startUrl: "https://example.com",
  browser: "chromium",
});

// Wait for user interaction...

const session = await handle.stop();

crawl

Auto-crawl a URL to discover forms and generate sessions.
async crawl(
  driverName: string,
  config: Record<string, unknown>,
  options?: CrawlOptions
): Promise<Session[]>
Parameters:
  • driverName - Name of the driver to use (must support crawling)
  • config - Driver-specific configuration (e.g., startUrl, browser)
  • options - Crawl options (depth, page limits, etc.)
Returns: Array of Session objects, one per discovered injectable form. Throws: Error if the driver doesn’t support auto-crawl. Example:
const sessions = await manager.crawl(
  "browser",
  {
    startUrl: "https://example.com",
    browser: "chromium",
    headless: true,
  },
  {
    maxDepth: 2,
    maxPages: 20,
  },
);

console.log(`Discovered ${sessions.length} injectable forms`);

// Execute each session with payloads
for (const session of sessions) {
  const result = await manager.execute(session, pluginManager);
}
Not all drivers support crawl(). Currently only the browser driver implements auto-crawl. Calling crawl() on a driver that doesn’t support it throws a clear error.

execute

Execute a session with payloads.
async execute(
  session: Session,
  pluginManager: PluginManager,
  options?: RunOptions
): Promise<RunResult>
Parameters:
  • session - The session to execute
  • pluginManager - Plugin manager with payloads loaded
  • options - Run options (headless, callbacks, etc.)
Returns: RunResult with findings and statistics. Example:
const result = await manager.execute(session, pluginManager, {
  headless: true,
  onFinding: (finding) => console.log("Found:", finding.title),
});

console.log(`Found ${result.findings.length} vulnerabilities`);

Types

VulcnDriver

interface VulcnDriver {
  name: string;
  version: string;
  apiVersion?: number;
  description?: string;
  configSchema?: z.ZodSchema;
  stepTypes: string[];
  recorder: RecorderDriver;
  runner: RunnerDriver;
}

LoadedDriver

interface LoadedDriver {
  driver: VulcnDriver;
  source: DriverSource;
}

type DriverSource = "npm" | "local" | "builtin";

RecordingHandle

interface RecordingHandle {
  stop(): Promise<Session>;
  abort(): Promise<void>;
  getSteps(): Step[];
  addStep(step: Omit<Step, "id" | "timestamp">): void;
}

CrawlOptions

interface CrawlOptions {
  /** Maximum crawl depth (0 = only the given URL, default: 2) */
  maxDepth?: number;
  /** Maximum number of pages to visit (default: 20) */
  maxPages?: number;
  /** Page load timeout in milliseconds (default: 10000) */
  pageTimeout?: number;
  /** Only follow same-origin links (default: true) */
  sameOrigin?: boolean;
  /** Callback fired after each page is crawled */
  onPageCrawled?: (url: string, formsFound: number) => void;
}

Session

interface Session {
  name: string;
  driver: string;
  driverConfig: Record<string, unknown>;
  steps: Step[];
  metadata?: {
    recordedAt?: string;
    version?: string;
    [key: string]: unknown;
  };
}

Step

interface Step {
  id: string;
  type: string;
  timestamp: number;
  [key: string]: unknown;
}

RunResult

interface RunResult {
  findings: Finding[];
  stepsExecuted: number;
  payloadsTested: number;
  duration: number;
  errors: string[];
}

Complete Example

import { DriverManager, PluginManager } from "@vulcn/engine";
import browserDriver from "@vulcn/driver-browser";
import payloadsPlugin from "@vulcn/plugin-payloads";
import xssPlugin from "@vulcn/plugin-detect-xss";

async function runSecurityTest() {
  // Set up driver manager
  const driverManager = new DriverManager();
  driverManager.register(browserDriver);

  // Set up plugin manager
  const pluginManager = new PluginManager();
  pluginManager.addPlugin(payloadsPlugin, { builtin: true });
  pluginManager.addPlugin(xssPlugin);
  await pluginManager.initialize();

  // Record a session
  const handle = await driverManager.startRecording("browser", {
    startUrl: "https://vulnerable-app.example.com",
    browser: "chromium",
    headless: false,
  });

  console.log("Recording... press Ctrl+C when done");

  // In real usage, you'd wait for user interaction
  // For this example, we'll stop immediately
  const session = await handle.stop();

  // Execute with payloads
  const result = await driverManager.execute(session, pluginManager, {
    headless: true,
    onFinding: (finding) => {
      console.log(`🚨 ${finding.severity}: ${finding.title}`);
    },
  });

  console.log(`\nResults:`);
  console.log(`  Steps: ${result.stepsExecuted}`);
  console.log(`  Payloads: ${result.payloadsTested}`);
  console.log(`  Findings: ${result.findings.length}`);
  console.log(`  Duration: ${result.duration}ms`);
}

runSecurityTest().catch(console.error);

Creating Drivers

Learn how to build custom drivers