Skip to main content

Static security scanner for AI-generated web app code. Finds hardcoded secrets, injection risks, CORS misconfigs and more.

Project description

security-scan

Static security scanner purpose-built for AI-generated web app code.

AI code generators (Lovable, Bolt, v0, Cursor, Copilot) frequently produce code with hardcoded secrets, missing auth guards, SQL injection patterns, and CORS misconfigs. This scanner catches those before they hit production.

Zero dependencies. Pure Python stdlib.


Quick start

# Clone and install
git clone https://github.com/nometria/security-scanner
cd security-scanner
pip install -e .

# Scan your project
security-scan ./my-app

# Scan a directory and output JSON
security-scan ./my-app --format json

# Scan the included example file
security-scan examples/ --no-color

Rules

Rule Severity Catches
SEC-001 ๐Ÿ”ด CRITICAL Hardcoded API keys, tokens, passwords, JWT secrets
SEC-002 ๐ŸŸ  HIGH .env file committed without .gitignore entry
SEC-003 ๐ŸŸ  HIGH Dangerous eval() / exec() usage
SEC-004 ๐ŸŸ  HIGH SQL injection (string interpolation in queries)
SEC-005 ๐ŸŸ  HIGH Missing auth middleware on API routes
SEC-006 ๐ŸŸก MEDIUM CORS wildcard * in production code
SEC-007 ๐Ÿ”ต LOW HTTP (not HTTPS) hardcoded URLs
SEC-008 ๐ŸŸ  HIGH Exposed admin routes without auth
SEC-009 ๐ŸŸ  HIGH Auth tokens stored in localStorage (XSS risk)
SEC-010 ๐ŸŸก MEDIUM process.env values logged to console
SEC-011 ๐Ÿ”ด CRITICAL Supabase service_role key used client-side
SEC-012 ๐ŸŸก MEDIUM Dependency confusion risk in package.json

Install

pip install security-scan        # PyPI (coming soon)

# From source:
git clone https://github.com/nometria/security-scanner
cd security-scanner
pip install -e .

Usage

# Scan current directory
security-scan .

# Scan a specific project
security-scan ./my-vite-app

# JSON output (for CI pipelines)
security-scan . --format json --output report.json

# SARIF output (GitHub Code Scanning)
security-scan . --format sarif --output results.sarif

# Markdown report
security-scan . --format markdown --output security-report.md

# Only fail on critical issues (default: high+)
security-scan . --fail-on critical

# No color (CI-friendly)
security-scan . --no-color

# Watch mode โ€” re-scans on file changes (polls every 2s)
security-scan . --watch

# Watch with JSON output
security-scan ./my-app --watch --format json

Watch mode

The --watch flag monitors your project for file changes and re-runs the scan automatically. Uses lightweight mtime polling (every 2 seconds) with zero extra dependencies -- no watchdog needed.

On each change only the modified files are re-scanned (incremental), while the full findings list is kept up to date. The terminal is cleared and refreshed so you always see a clean report.

$ security-scan ./my-app --watch

[14:31:55] Full scan

โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
  SECURITY SCAN โ€” 12 files scanned, 3 findings
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
  ...

Watching for changes... (Ctrl+C to stop)

[14:32:07] Re-scanned 1 changed file(s)

โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
  SECURITY SCAN โ€” 13 files scanned, 2 findings
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
  ...

Watching for changes... (Ctrl+C to stop)

In watch mode the process runs continuously and does not exit on findings, making it suitable for IDE integration and development workflows.

IDE integration

Run the scanner in a side terminal while you code -- findings update live as you save files.

VS Code -- open a terminal pane (Ctrl+`` ) and run:

security-scan --watch .

Split the terminal so the scan output is always visible beside your editor.

JetBrains (WebStorm / PyCharm) -- add an External Tool or Run Configuration:

  • Program: security-scan
  • Arguments: --watch $ProjectFileDir$
  • Working directory: $ProjectFileDir$

Neovim / tmux -- keep a tmux split running:

tmux split-window -h 'security-scan --watch .'

CI / pre-commit -- for one-shot scans in CI, omit --watch:

security-scan . --format sarif --output results.sarif --fail-on high

GitHub Action

Use the composite GitHub Action for a turnkey CI integration with PR comments, SARIF upload, and configurable failure thresholds.

# .github/workflows/security-scan.yml
name: Security Scan
on:
  push:
    branches: [main]
  pull_request:

permissions:
  contents: read
  pull-requests: write
  security-events: write

jobs:
  security-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: nometria/security-scanner@main
        with:
          target_dir: '.'
          format: 'text'
          fail_on_findings: 'true'
          fail_on: 'high'
          post_comment: 'true'
          sarif_upload: 'true'

Action inputs

Input Default Description
target_dir . Directory to scan
format text Output format: text, json, or markdown
fail_on_findings true Fail the action if findings meet the severity threshold
fail_on high Minimum severity to fail: critical, high, medium, low, any
post_comment true Post results as a PR comment (pull_request events only)
sarif_upload true Upload SARIF results to GitHub Code Scanning
python_version 3.11 Python version to use

Action outputs

Output Description
passed true if no findings at or above the fail threshold
findings_count Total number of findings
critical_count Number of critical findings
report Full scan report in the requested format

See examples/security-scan-action.yml for a complete workflow example.

Manual pip-based workflow

If you prefer not to use the composite action, you can install and run directly:

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: '3.11' }
      - run: pip install ai-security-scan
      - run: security-scan . --format sarif --output results.sarif --fail-on high
      - uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: results.sarif

Use as a library

from security_scanner import scan_project

result = scan_project("./my-app")

print(f"Passed: {result.passed}")
print(f"Critical: {result.critical_count}")

for finding in result.findings:
    print(f"[{finding.severity}] {finding.rule_id}: {finding.file}:{finding.line}")
    print(f"  {finding.message}")
    print(f"  Fix: {finding.fix}")

Add custom rules

from security_scanner.scanner import Finding, HIGH

def check_no_http_fetch(path, rel, lines):
    findings = []
    for i, line in enumerate(lines, 1):
        if 'fetch("http://' in line:
            findings.append(Finding(
                rule_id="CUSTOM-001", severity=HIGH,
                file=rel, line=i,
                message="fetch() called with HTTP URL",
                fix="Use HTTPS for all fetch calls."
            ))
    return findings

# Register in scanner.py scan_project() loop

Immediate next steps

  1. Publish to PyPI: pip install ai-security-scan Done
  2. Publish to npm as npx security-scan wrapper
  3. Submit to GitHub Marketplace as an Action Done (action.yml)
  4. Add SEC-005 (missing auth middleware) โ€” requires AST parsing
  5. Add --watch mode for IDE integration Done (--watch flag with incremental re-scan)

Commercial viability

  • Open source it โ€” "security scanner for AI-generated code" is high SEO value
  • Drive inbound: every AI app builder user is a potential Nometria customer
  • Upsell: "scan found issues โ†’ let us help you fix and self-host securely"
  • GitHub App: auto-scan every PR, post findings as PR review comments โ€” $9โ€“19/mo/repo

Example output

Running security-scan examples/ --no-color against the included examples/vulnerable.js:

Scanning /tmp/ownmy-releases/security-scanner/examples ...

โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
  SECURITY SCAN โ€” 1 files scanned, 5 findings
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

  ๐Ÿ”ด [CRITICAL] SEC-001
     File   : vulnerable.js:4
     Issue  : Hardcoded API key detected
     Code   : const API_KEY = "sk-live-abc123def456ghi789jkl012mno345pqr678";
     Fix    : Move to environment variables. Never commit secrets to source control.

  ๐Ÿ”ด [CRITICAL] SEC-001
     File   : vulnerable.js:5
     Issue  : Hardcoded password detected
     Code   : const DB_PASSWORD = "SuperSecret123!";
     Fix    : Move to environment variables. Never commit secrets to source control.

  ๐ŸŸ  [HIGH] SEC-003
     File   : vulnerable.js:10
     Issue  : Dangerous eval/exec usage โ€” potential code injection
     Code   : return eval(input);
     Fix    : Avoid eval/exec with user input. Use JSON.parse() or safe alternatives.

  ๐ŸŸ  [HIGH] SEC-004
     File   : vulnerable.js:15
     Issue  : Potential SQL injection โ€” string interpolation in query
     Code   : const query = `SELECT * FROM users WHERE id = ${userId}`;
     Fix    : Use parameterised queries: db.query('SELECT * FROM t WHERE id = $1', [id])

  ๐ŸŸ  [HIGH] SEC-004
     File   : vulnerable.js:20
     Issue  : Potential SQL injection โ€” string interpolation in query
     Code   : const sql = "SELECT * FROM products WHERE name = '" + term + "'";
     Fix    : Use parameterised queries: db.query('SELECT * FROM t WHERE id = $1', [id])

โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
  Critical: 2  |  High: 3  |  Medium: 0  |  Low: 0
  Overall: โŒ FAIL
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ai_security_scan-0.2.0.tar.gz (17.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ai_security_scan-0.2.0-py3-none-any.whl (15.2 kB view details)

Uploaded Python 3

File details

Details for the file ai_security_scan-0.2.0.tar.gz.

File metadata

  • Download URL: ai_security_scan-0.2.0.tar.gz
  • Upload date:
  • Size: 17.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for ai_security_scan-0.2.0.tar.gz
Algorithm Hash digest
SHA256 fb7f92d8511de4b63ae97b1da905f5d78bb1927e95a4efe9c4330745b09392d5
MD5 d0af9f8be5ddb32102048eefb319d536
BLAKE2b-256 129fd08b093ae10083769e7ca792ae76e2feef0d374bb46d028d0963ed9154d2

See more details on using hashes here.

File details

Details for the file ai_security_scan-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for ai_security_scan-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7d68596318e295c5e50b9cfaaff641087af6903b9ed7736acc4116737cf8280a
MD5 88df5ecb0cea7458c82f4ae4a34487d8
BLAKE2b-256 33c5c8b9af694668ad5c294b44bb29f6f45d6ef5c2100560083c0afe9a5e5c15

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page