Security Examples

Validation rules to prevent common security issues.

No Hardcoded Secrets

Prevents committing hardcoded secrets and API keys.

import { defineCodeRule } from "@syncrolabs/claude-code-validator";

const SECRET_PATTERNS = [
  { regex: /api[_-]?key\s*=\s*['"][^'"]+['"]/i, name: "API key" },
  { regex: /password\s*=\s*['"][^'"]+['"]/i, name: "Password" },
  { regex: /secret\s*=\s*['"][^'"]+['"]/i, name: "Secret" },
  { regex: /token\s*=\s*['"][^'"]+['"]/i, name: "Token" },
  { regex: /sk-[a-zA-Z0-9]{32,}/, name: "OpenAI API key" },
  { regex: /ghp_[a-zA-Z0-9]{36}/, name: "GitHub token" },
];

export const noHardcodedSecrets = defineCodeRule({
  name: "no-hardcoded-secrets",
  description: "Prevents hardcoded secrets and API keys",

  shouldRun: (context) => {
    // Don't check .env files (those are for secrets)
    return !context.filePath.endsWith(".env");
  },

  validate(context) {
    const errors: string[] = [];

    for (const { regex, name } of SECRET_PATTERNS) {
      if (regex.test(context.content)) {
        errors.push(
          `❌ Hardcoded ${name} detected\n` +
            `   → Use environment variables instead\n` +
            `   â„šī¸  Example: process.env.API_KEY\n` +
            `   📄 File: ${context.filePath}`
        );
      }
    }

    return errors;
  },
});

Prevent XSS Vulnerabilities

Detects potentially dangerous HTML insertion patterns.

import { defineCodeRule } from "@syncrolabs/claude-code-validator";

export const preventXSS = defineCodeRule({
  name: "prevent-xss",
  description: "Prevents XSS vulnerabilities",

  shouldRun: (context) => /\.(vue|jsx|tsx)$/.test(context.filePath),

  validate(context) {
    const errors: string[] = [];

    // Check for v-html usage
    if (/v-html\s*=/.test(context.content)) {
      errors.push(
        `❌ v-html can lead to XSS vulnerabilities\n` +
          `   → Sanitize user input or use text interpolation\n` +
          `   â„šī¸  Consider using a library like DOMPurify\n` +
          `   📄 File: ${context.filePath}`
      );
    }

    // Check for dangerouslySetInnerHTML in React
    if (/dangerouslySetInnerHTML/.test(context.content)) {
      errors.push(
        `❌ dangerouslySetInnerHTML can lead to XSS\n` +
          `   → Sanitize content with DOMPurify first\n` +
          `   📄 File: ${context.filePath}`
      );
    }

    // Check for innerHTML usage
    if (/\.innerHTML\s*=/.test(context.content)) {
      errors.push(
        `❌ innerHTML assignment can lead to XSS\n` +
          `   → Use textContent or sanitize input\n` +
          `   📄 File: ${context.filePath}`
      );
    }

    return errors;
  },
});

SQL Injection Prevention

Detects string concatenation in SQL queries.

import { defineCodeRule } from "@syncrolabs/claude-code-validator";

export const preventSQLInjection = defineCodeRule({
  name: "prevent-sql-injection",
  description: "Prevents SQL injection vulnerabilities",

  shouldRun: (context) => /\.(ts|js)$/.test(context.filePath),

  validate(context) {
    const errors: string[] = [];

    // Check for string concatenation in SQL queries
    const sqlConcatPatterns = [
      /SELECT\s+.*?\+\s*\w+/i,
      /INSERT\s+.*?\+\s*\w+/i,
      /UPDATE\s+.*?\+\s*\w+/i,
      /DELETE\s+.*?\+\s*\w+/i,
      /WHERE\s+.*?\+\s*\w+/i,
    ];

    for (const pattern of sqlConcatPatterns) {
      if (pattern.test(context.content)) {
        errors.push(
          `❌ SQL query with string concatenation detected\n` +
            `   → Use parameterized queries instead\n` +
            `   â„šī¸  Example: db.query('SELECT * FROM users WHERE id = ?', [userId])\n` +
            `   📄 File: ${context.filePath}`
        );
        break;
      }
    }

    return errors;
  },
});

Secure Random Generation

Ensures cryptographically secure random number generation.

import { defineCodeRule } from "@syncrolabs/claude-code-validator";

export const secureRandom = defineCodeRule({
  name: "secure-random",
  description: "Enforces cryptographically secure random generation",

  shouldRun: (context) => /\.(ts|js)$/.test(context.filePath),

  validate(context) {
    const errors: string[] = [];

    // Check for Math.random() in security-sensitive contexts
    if (/Math\.random\(\)/.test(context.content)) {
      // Check if it's in a security-sensitive file
      const isSensitive = /auth|token|session|crypto|security|password/i.test(
        context.filePath
      );

      if (isSensitive) {
        errors.push(
          `❌ Math.random() is not cryptographically secure\n` +
            `   → Use crypto.randomBytes() or crypto.getRandomValues()\n` +
            `   â„šī¸  Example: crypto.randomBytes(32).toString('hex')\n` +
            `   📄 File: ${context.filePath}`
        );
      }
    }

    return errors;
  },
});

Example Usage

All security rules in one file:

// .claude/rules/security.ts
import { defineCodeRule } from "@syncrolabs/claude-code-validator";

export const noHardcodedSecrets = defineCodeRule({
  /* ... */
});
export const preventXSS = defineCodeRule({
  /* ... */
});
export const preventSQLInjection = defineCodeRule({
  /* ... */
});
export const secureRandom = defineCodeRule({
  /* ... */
});

All rules are automatically discovered and loaded!