Skip to main content

Cyberstrike is now open source! AI-powered penetration testing for security professionals. Star on GitHub

Plugin Hooks

Plugin hooks allow you to create reusable extensions that hook into Cyberstrike’s tool execution lifecycle.

📊 DIAGRAM: plugin-hook-architecture.mmd

Plugin hook execution flow

Overview

Plugin hooks are npm packages that:

  • Hook into tool execution
  • Modify tool behavior
  • Add validation logic
  • Implement security policies
  • Extend functionality

Plugin Structure

Basic Plugin

src/index.ts
import { CyberstrikePlugin, ToolHook } from '@cyberstrike/plugin';
export default class MyPlugin implements CyberstrikePlugin {
name = 'my-plugin';
version = '1.0.0';
hooks: ToolHook[] = [
{
event: 'preToolUse',
matcher: 'Bash',
handler: async (context) => {
// Validate command before execution
if (context.args.command.includes('rm -rf')) {
return {
action: 'block',
message: 'Dangerous command blocked'
};
}
return { action: 'continue' };
}
}
];
}

Package Structure

my-cyberstrike-plugin/
├── src/
│ ├── index.ts
│ └── hooks/
│ ├── bash-validator.ts
│ └── write-checker.ts
├── package.json
└── tsconfig.json

package.json

{
"name": "cyberstrike-plugin-security",
"version": "1.0.0",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"cyberstrike": {
"plugin": true
},
"peerDependencies": {
"@cyberstrike/plugin": "^1.0.0"
}
}

Hook Events

PreToolUse

Runs before a tool executes:

{
event: 'preToolUse',
matcher: 'Bash',
handler: async (context) => {
const { tool, args } = context;
// Validate arguments
if (!isValidCommand(args.command)) {
return {
action: 'block',
message: 'Invalid command'
};
}
// Modify arguments
return {
action: 'continue',
args: {
...args,
command: sanitizeCommand(args.command)
}
};
}
}

PostToolUse

Runs after a tool executes:

{
event: 'postToolUse',
matcher: '*',
handler: async (context) => {
const { tool, args, result } = context;
// Log tool usage
await logToolUsage(tool, args, result);
// Modify result if needed
return {
action: 'continue',
result: sanitizeOutput(result)
};
}
}

SessionStart

Runs when a session begins:

{
event: 'sessionStart',
handler: async (context) => {
// Initialize plugin state
await initializeSession(context.sessionId);
return { action: 'continue' };
}
}

SessionEnd

Runs when a session ends:

{
event: 'sessionEnd',
handler: async (context) => {
// Cleanup plugin state
await cleanupSession(context.sessionId);
// Generate session report
await generateReport(context.sessionId);
return { action: 'continue' };
}
}

Notification

Runs on various events:

{
event: 'notification',
handler: async (context) => {
const { type, message } = context;
if (type === 'error') {
await alertAdmin(message);
}
return { action: 'continue' };
}
}

Matcher Patterns

Exact Match

matcher: 'Bash' // Only Bash tool
matcher: 'Write' // Only Write tool

Wildcard

matcher: '*' // All tools
matcher: 'File*' // File-related tools

Array Match

matcher: ['Bash', 'Write', 'Edit'] // Multiple tools

Custom Matcher

matcher: (tool, args) => {
// Custom matching logic
return tool === 'Bash' && args.command.startsWith('npm');
}

Handler Actions

Continue

Allow execution to proceed:

return { action: 'continue' };

Continue with Modifications

return {
action: 'continue',
args: modifiedArgs,
result: modifiedResult
};

Block

Prevent execution:

return {
action: 'block',
message: 'Operation not allowed'
};

Approve

Skip permission prompt:

return {
action: 'approve',
message: 'Auto-approved by policy'
};

Context Object

PreToolUse Context

interface PreToolUseContext {
tool: string;
args: Record<string, any>;
sessionId: string;
workingDirectory: string;
user: {
id: string;
permissions: string[];
};
}

PostToolUse Context

interface PostToolUseContext {
tool: string;
args: Record<string, any>;
result: {
success: boolean;
output: string;
error?: string;
};
duration: number;
sessionId: string;
}

Configuration

Enable Plugin

~/.cyberstrike/config.json
{
"plugins": [
"cyberstrike-plugin-security",
"./local-plugin"
]
}

Plugin Options

{
"plugins": [
{
"name": "cyberstrike-plugin-security",
"options": {
"strictMode": true,
"logLevel": "debug"
}
}
]
}

Example Plugins

Command Validator

import { CyberstrikePlugin } from '@cyberstrike/plugin';
const BLOCKED_COMMANDS = ['rm -rf', 'dd if=', 'mkfs', ':(){ :|:& };:'];
export default class CommandValidator implements CyberstrikePlugin {
name = 'command-validator';
version = '1.0.0';
hooks = [
{
event: 'preToolUse',
matcher: 'Bash',
handler: async ({ args }) => {
for (const blocked of BLOCKED_COMMANDS) {
if (args.command.includes(blocked)) {
return {
action: 'block',
message: `Blocked dangerous command: ${blocked}`
};
}
}
return { action: 'continue' };
}
}
];
}

Audit Logger

import { CyberstrikePlugin } from '@cyberstrike/plugin';
import fs from 'fs/promises';
export default class AuditLogger implements CyberstrikePlugin {
name = 'audit-logger';
version = '1.0.0';
hooks = [
{
event: 'postToolUse',
matcher: '*',
handler: async (context) => {
const entry = {
timestamp: new Date().toISOString(),
tool: context.tool,
args: context.args,
success: context.result.success,
duration: context.duration
};
await fs.appendFile(
'/var/log/cyberstrike/audit.jsonl',
JSON.stringify(entry) + '\n'
);
return { action: 'continue' };
}
}
];
}

Secret Scanner

import { CyberstrikePlugin } from '@cyberstrike/plugin';
const SECRET_PATTERNS = [
/api[_-]?key\s*[:=]\s*['"][^'"]+['"]/i,
/password\s*[:=]\s*['"][^'"]+['"]/i,
/secret\s*[:=]\s*['"][^'"]+['"]/i,
];
export default class SecretScanner implements CyberstrikePlugin {
name = 'secret-scanner';
version = '1.0.0';
hooks = [
{
event: 'preToolUse',
matcher: 'Write',
handler: async ({ args }) => {
for (const pattern of SECRET_PATTERNS) {
if (pattern.test(args.content)) {
return {
action: 'block',
message: 'Potential secret detected in file content'
};
}
}
return { action: 'continue' };
}
}
];
}

Publishing Plugins

npm Publish

Terminal window
npm publish --access public

Plugin Registry

Register your plugin in the Cyberstrike plugin registry for discovery.

Best Practices

  1. Keep hooks fast - Avoid blocking operations
  2. Handle errors - Don’t crash on plugin errors
  3. Log appropriately - Use proper log levels
  4. Test thoroughly - Test all hook scenarios
  5. Document behavior - Explain what plugin does

Tip

Use the postToolUse hook for logging and auditing without affecting tool execution.