Skip to content

Use Cases

Practical real-world examples for using mcp-scan effectively.


Table of Contents

  1. Developing an MCP Server
  2. Security Audit
  3. Legacy Code Migration
  4. Third-Party Code Review
  5. Compliance
  6. Continuous Monitoring
  7. Integration with Existing Tools
  8. Team Training

Developing an MCP Server

Scenario

You are developing an MCP server that allows users to execute queries against a database.

Initial Code (Vulnerable)

# server.py
from mcp import Server, tool
import sqlite3

server = Server("db-query-server")

@tool
def query_database(sql_query: str) -> str:
    """Execute a SQL query against the database."""
    conn = sqlite3.connect('app.db')
    cursor = conn.cursor()
    cursor.execute(sql_query)  # VULNERABLE: SQL Injection
    return str(cursor.fetchall())

@tool
def read_config(filename: str) -> str:
    """Read a configuration file."""
    with open(filename, 'r') as f:  # VULNERABLE: Path Traversal
        return f.read()

if __name__ == "__main__":
    server.run()

Step 1: Initial Scan

mcp-scan scan . --output json > initial-scan.json

Results:

CRITICAL: 2
  - MCP-D002: SQL injection via string concatenation (server.py:12)
  - MCP-B002: Potential path traversal (server.py:17)

MSSS Score: 35/100
Compliance Level: 0 (Not Compliant)

Step 2: Fix Vulnerabilities

# server.py (fixed)
from mcp import Server, tool
import sqlite3
import os

server = Server("db-query-server")

# List of allowed queries
ALLOWED_QUERIES = {
    "list_users": "SELECT id, name FROM users",
    "count_orders": "SELECT COUNT(*) FROM orders",
}

ALLOWED_CONFIG_FILES = ["app.yaml", "settings.yaml"]
CONFIG_DIR = "/etc/myapp/"

@tool
def query_database(query_name: str) -> str:
    """Execute a predefined SQL query.

    Args:
        query_name: Name of the query to execute. Must be one of:
                   'list_users', 'count_orders'
    """
    if query_name not in ALLOWED_QUERIES:
        return f"Error: Unknown query '{query_name}'. Allowed: {list(ALLOWED_QUERIES.keys())}"

    sql = ALLOWED_QUERIES[query_name]
    conn = sqlite3.connect('app.db')
    cursor = conn.cursor()
    cursor.execute(sql)  # Safe: predefined SQL
    return str(cursor.fetchall())

@tool
def read_config(filename: str) -> str:
    """Read a configuration file.

    Args:
        filename: Name of the config file. Must be one of:
                 'app.yaml', 'settings.yaml'
    """
    # Validate filename
    if filename not in ALLOWED_CONFIG_FILES:
        return f"Error: File '{filename}' not allowed"

    # Use basename to prevent path traversal
    safe_name = os.path.basename(filename)
    filepath = os.path.join(CONFIG_DIR, safe_name)

    # Verify it stays in allowed directory
    if not os.path.abspath(filepath).startswith(os.path.abspath(CONFIG_DIR)):
        return "Error: Invalid path"

    with open(filepath, 'r') as f:
        return f.read()

if __name__ == "__main__":
    server.run()

Step 3: Re-scan

mcp-scan scan . --output json > fixed-scan.json

Results:

No findings detected.

MSSS Score: 100/100
Compliance Level: 3 (Certified)

Step 4: Configure CI/CD

# .github/workflows/security.yml
name: Security

on: [push, pull_request]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: |
          curl -sSL https://raw.githubusercontent.com/mcphub/mcp-scan/main/install.sh | bash
          mcp-scan scan . --fail-on high --output sarif > results.sarif
      - uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: results.sarif

Security Audit

Scenario

Your company needs to audit an MCP server before deploying it to production.

Step 1: Audit Configuration

# .mcp-scan-audit.yaml
include:
  - "**/*.py"
  - "**/*.ts"
  - "**/*.js"

exclude:
  - "**/tests/**"
  - "**/node_modules/**"

scan:
  mode: deep
  timeout: 1h
  fail_on: medium

rules:
  disabled: []
  severity_overrides:
    MCP-E001: critical
    MCP-E002: critical

output:
  redact_snippets: true  # Confidentiality

llm:
  enabled: true
  threshold: 0.8

ml:
  enabled: true
  confidence_threshold: 0.8

codeql:
  enabled: true

Step 2: Run Audit

# Create audit directory
mkdir -p audit-$(date +%Y%m%d)
cd audit-$(date +%Y%m%d)

# Run deep scan
mcp-scan scan /path/to/mcp-server \
  --config ../.mcp-scan-audit.yaml \
  --mode deep \
  --output evidence \
  > evidence-bundle.json

# Generate SARIF report
mcp-scan scan /path/to/mcp-server \
  --config ../.mcp-scan-audit.yaml \
  --mode deep \
  --output sarif \
  > audit-sarif.sarif

# Extract MCP surface
mcp-scan surface /path/to/mcp-server \
  --output json \
  > mcp-surface.json

Step 3: Analyze Results

# Summary of findings
jq '.summary' evidence-bundle.json

# Critical findings
jq '.findings[] | select(.severity == "critical")' evidence-bundle.json

# MSSS score
jq '.msss_score' evidence-bundle.json

# Detected tools
jq '.mcp_surface.tools[].name' evidence-bundle.json

Step 4: Generate Report

# Script to generate report
cat > generate-report.sh << 'EOF'
#!/bin/bash

BUNDLE=$1
DATE=$(date +%Y-%m-%d)

echo "# Security Audit Report"
echo "Date: $DATE"
echo ""
echo "## Executive Summary"
echo ""
echo "| Metric | Value |"
echo "|--------|-------|"
echo "| MSSS Score | $(jq '.msss_score.score' $BUNDLE)/100 |"
echo "| Compliance Level | $(jq -r '.msss_score.level_name' $BUNDLE) |"
echo "| Total Findings | $(jq '.summary.total' $BUNDLE) |"
echo "| Critical | $(jq '.summary.by_severity.critical' $BUNDLE) |"
echo "| High | $(jq '.summary.by_severity.high' $BUNDLE) |"
echo ""
echo "## Critical Findings"
echo ""
jq -r '.findings[] | select(.severity == "critical") | "- **\(.rule_id)**: \(.title)\n  - File: \(.location.file):\(.location.line)\n  - Remediation: \(.remediation)"' $BUNDLE
EOF

chmod +x generate-report.sh
./generate-report.sh evidence-bundle.json > AUDIT-REPORT.md

Legacy Code Migration

Scenario

You have an old MCP server that needs to be updated and secured.

Step 1: Initial Assessment

# Complete scan of legacy code
mcp-scan scan ./legacy-server \
  --mode deep \
  --output json \
  > legacy-scan.json

# View summary
jq '.summary' legacy-scan.json

# List all findings by file
jq '[.findings[] | {file: .location.file, rule: .rule_id}] | group_by(.file) | map({file: .[0].file, count: length})' legacy-scan.json

Step 2: Create Legacy Baseline

# Generate baseline for findings that cannot be fixed immediately
mcp-scan baseline generate \
  --from legacy-scan.json \
  --reason "Legacy code - scheduled for refactoring in Q2 2026" \
  --accepted-by "tech-lead@example.com" \
  --output legacy-baseline.json

# Review and edit baseline
nano legacy-baseline.json

Step 3: Prioritize Fixes

# Create priority list
jq -r '.findings | group_by(.severity) | map({severity: .[0].severity, items: map({file: .location.file, rule: .rule_id, line: .location.line})})' legacy-scan.json > priorities.json

# Critical first
echo "=== CRITICAL (Fix immediately) ==="
jq '.[] | select(.severity == "critical") | .items[]' priorities.json

# Then high
echo "=== HIGH (Fix this week) ==="
jq '.[] | select(.severity == "high") | .items[]' priorities.json

Step 4: Incremental Migration

# Configuration for migration
cat > .mcp-scan-migration.yaml << 'EOF'
scan:
  mode: fast
  fail_on: critical  # Only block new critical issues

# Use legacy baseline
# mcp-scan scan . --baseline legacy-baseline.json
EOF

# Scan for new findings only
mcp-scan scan ./legacy-server \
  --baseline legacy-baseline.json \
  --fail-on critical

Step 5: Progress Tracking

# Tracking script
cat > track-progress.sh << 'EOF'
#!/bin/bash

DATE=$(date +%Y-%m-%d)
BASELINE_COUNT=$(jq '.entries | length' legacy-baseline.json)
SCAN_COUNT=$(jq '.summary.total' legacy-scan.json)

echo "$DATE,$BASELINE_COUNT,$SCAN_COUNT" >> migration-progress.csv
echo "Date: $DATE"
echo "Baselined: $BASELINE_COUNT"
echo "Total (pre-fix): $SCAN_COUNT"
echo "Fixed: $((SCAN_COUNT - BASELINE_COUNT))"
EOF

Third-Party Code Review

Scenario

You need to evaluate a third-party MCP server before integrating it.

Step 1: Preparation

# Clone repository
git clone https://github.com/third-party/mcp-server.git
cd mcp-server

# View structure
find . -name "*.py" -o -name "*.ts" -o -name "*.js" | head -20

Step 2: Complete Scan

# Scan with all options
mcp-scan scan . \
  --mode deep \
  --output evidence \
  > third-party-audit.json

# View MCP surface
mcp-scan surface . --output json > surface.json

Step 3: Risk Analysis

# Analysis script
cat > analyze-third-party.sh << 'EOF'
#!/bin/bash

EVIDENCE=$1

echo "=== RISK ANALYSIS ==="
echo ""

# Score
SCORE=$(jq '.msss_score.score' $EVIDENCE)
echo "MSSS Score: $SCORE/100"

if [ $SCORE -lt 60 ]; then
  echo "RISK: HIGH - Does not meet minimum requirements"
elif [ $SCORE -lt 80 ]; then
  echo "RISK: MEDIUM - Meets basic requirements"
else
  echo "RISK: LOW - Meets enterprise requirements"
fi

echo ""
echo "=== ATTACK SURFACE ==="
TOOLS=$(jq '.mcp_surface.tools | length' $EVIDENCE)
echo "Exposed tools: $TOOLS"
jq -r '.mcp_surface.tools[] | "  - \(.name): \(.description // "No description")"' $EVIDENCE

echo ""
echo "=== FINDINGS BY SEVERITY ==="
jq -r '.summary.by_severity | to_entries | map("  \(.key): \(.value)") | .[]' $EVIDENCE

echo ""
echo "=== CRITICAL FINDINGS ==="
jq -r '.findings[] | select(.severity == "critical") | "  - \(.rule_id): \(.title)"' $EVIDENCE

echo ""
echo "=== RECOMMENDATION ==="
CRITICAL=$(jq '.summary.by_severity.critical' $EVIDENCE)
HIGH=$(jq '.summary.by_severity.high' $EVIDENCE)

if [ $CRITICAL -gt 0 ]; then
  echo "DO NOT APPROVE - Contains critical vulnerabilities"
elif [ $HIGH -gt 2 ]; then
  echo "REVIEW - Multiple high vulnerabilities"
elif [ $SCORE -ge 80 ]; then
  echo "APPROVE with conditions"
else
  echo "APPROVE for limited use"
fi
EOF

chmod +x analyze-third-party.sh
./analyze-third-party.sh third-party-audit.json

Step 4: Document Decision

# Generate decision document
cat > SECURITY-REVIEW.md << EOF
# Security Review: third-party/mcp-server

## Date: $(date +%Y-%m-%d)

## Scan Results

- **MSSS Score:** $(jq '.msss_score.score' third-party-audit.json)/100
- **Level:** $(jq -r '.msss_score.level_name' third-party-audit.json)

## Findings

| Severity | Count |
|----------|-------|
| Critical | $(jq '.summary.by_severity.critical' third-party-audit.json) |
| High | $(jq '.summary.by_severity.high' third-party-audit.json) |
| Medium | $(jq '.summary.by_severity.medium' third-party-audit.json) |
| Low | $(jq '.summary.by_severity.low' third-party-audit.json) |

## Decision

[ ] Approved
[ ] Approved with conditions
[ ] Rejected

## Conditions (if applicable)

-

## Reviewed by

-
EOF

Compliance

Scenario

Your organization requires security analysis evidence for SOC2/ISO27001 audits.

Step 1: Compliance Configuration

# .mcp-scan-compliance.yaml
scan:
  mode: deep
  timeout: 1h

rules:
  disabled: []
  severity_overrides:
    MCP-E001: critical
    MCP-E002: critical
    MCP-E005: critical
    MCP-A003: critical
    MCP-A004: critical

output:
  redact_snippets: true

llm:
  enabled: true
  threshold: 0.9

codeql:
  enabled: true

Step 2: Scan with Evidence

# Create evidence directory
AUDIT_DIR="compliance-evidence-$(date +%Y%m%d)"
mkdir -p $AUDIT_DIR

# Complete scan
mcp-scan scan . \
  --config .mcp-scan-compliance.yaml \
  --mode deep \
  --output evidence \
  > $AUDIT_DIR/evidence-bundle.json

# Hash the evidence
sha256sum $AUDIT_DIR/evidence-bundle.json > $AUDIT_DIR/evidence.sha256

# Metadata
cat > $AUDIT_DIR/metadata.json << EOF
{
  "scan_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
  "tool": "mcp-scan",
  "version": "$(mcp-scan version --short)",
  "repository": "$(git remote get-url origin)",
  "commit": "$(git rev-parse HEAD)",
  "branch": "$(git branch --show-current)"
}
EOF

Step 3: Generate Compliance Report

# Report script
cat > generate-compliance-report.py << 'EOF'
#!/usr/bin/env python3
import json
import sys
from datetime import datetime

with open(sys.argv[1]) as f:
    evidence = json.load(f)

report = f"""
# Security Compliance Report

## General Information

- **Scan Date:** {evidence['scan_info']['started_at']}
- **Tool:** mcp-scan v{evidence['version']}
- **Mode:** {evidence['scan_info']['mode']}
- **Duration:** {evidence['duration']['total_ms']}ms

## Security Result

| Metric | Value |
|--------|-------|
| MSSS Score | {evidence['msss_score']['score']}/100 |
| Compliance Level | {evidence['msss_score']['level_name']} |

### Requirements Mapping

| Requirement | Status | Evidence |
|-------------|--------|----------|
| Access Control (A.9) | {'Compliant' if evidence['msss_score']['score'] >= 60 else 'Non-Compliant'} | Score >= 60 |
| Development Security (A.14) | {'Compliant' if evidence['summary']['by_severity'].get('critical', 0) == 0 else 'Non-Compliant'} | No critical findings |
| Vulnerability Management (A.12) | Compliant | Automated scanning |

## Findings

| Severity | Count |
|----------|-------|
| Critical | {evidence['summary']['by_severity'].get('critical', 0)} |
| High | {evidence['summary']['by_severity'].get('high', 0)} |
| Medium | {evidence['summary']['by_severity'].get('medium', 0)} |
| Low | {evidence['summary']['by_severity'].get('low', 0)} |

## Conclusion

The system {'meets' if evidence['msss_score']['level'] >= 1 else 'DOES NOT meet'} the
minimum security requirements established.

---
Automatically generated by mcp-scan
"""

print(report)
EOF

python3 generate-compliance-report.py $AUDIT_DIR/evidence-bundle.json > $AUDIT_DIR/COMPLIANCE-REPORT.md

Step 4: Archive Evidence

# Create evidence package
cd $AUDIT_DIR
tar -czvf ../compliance-evidence-$(date +%Y%m%d).tar.gz .

# Verify integrity
sha256sum ../compliance-evidence-$(date +%Y%m%d).tar.gz

Continuous Monitoring

Scenario

You want to monitor the security posture of your MCP server over time.

Step 1: Monitoring Script

#!/bin/bash
# monitor-security.sh

REPO_PATH=$1
DATA_DIR="${2:-./security-metrics}"

mkdir -p $DATA_DIR

# Run scan
mcp-scan scan $REPO_PATH --mode fast --output json > /tmp/scan-result.json

# Extract metrics
DATE=$(date +%Y-%m-%d)
SCORE=$(jq '.msss_score.score' /tmp/scan-result.json)
TOTAL=$(jq '.summary.total' /tmp/scan-result.json)
CRITICAL=$(jq '.summary.by_severity.critical' /tmp/scan-result.json)
HIGH=$(jq '.summary.by_severity.high' /tmp/scan-result.json)
MEDIUM=$(jq '.summary.by_severity.medium' /tmp/scan-result.json)

# Save metrics
echo "$DATE,$SCORE,$TOTAL,$CRITICAL,$HIGH,$MEDIUM" >> $DATA_DIR/metrics.csv

# Save complete result
cp /tmp/scan-result.json $DATA_DIR/scan-$DATE.json

# Show summary
echo "=== Security Metrics for $DATE ==="
echo "Score: $SCORE/100"
echo "Total: $TOTAL (C:$CRITICAL H:$HIGH M:$MEDIUM)"

# Alert if score drops
if [ -f $DATA_DIR/last-score ]; then
  LAST_SCORE=$(cat $DATA_DIR/last-score)
  if [ $SCORE -lt $LAST_SCORE ]; then
    echo "WARNING: Score decreased from $LAST_SCORE to $SCORE"
  fi
fi
echo $SCORE > $DATA_DIR/last-score

Step 2: Configure Cron

# Run daily
crontab -e

# Add line:
0 2 * * * /path/to/monitor-security.sh /path/to/repo /path/to/metrics >> /var/log/security-monitor.log 2>&1

Step 3: Metrics Dashboard

#!/usr/bin/env python3
# generate-dashboard.py

import csv
import json
from datetime import datetime

def generate_dashboard(metrics_file, output_file):
    with open(metrics_file) as f:
        reader = csv.reader(f)
        data = list(reader)

    html = """
    <!DOCTYPE html>
    <html>
    <head>
        <title>Security Dashboard</title>
        <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
        <style>
            body { font-family: Arial, sans-serif; margin: 20px; }
            .card { border: 1px solid #ddd; padding: 20px; margin: 10px; border-radius: 8px; }
            .score { font-size: 48px; font-weight: bold; }
            .score.good { color: green; }
            .score.medium { color: orange; }
            .score.bad { color: red; }
        </style>
    </head>
    <body>
        <h1>Security Dashboard</h1>

        <div class="card">
            <h2>Current Score</h2>
            <div class="score {score_class}">{current_score}/100</div>
        </div>

        <div class="card">
            <h2>Score Trend</h2>
            <canvas id="scoreChart"></canvas>
        </div>

        <script>
            const ctx = document.getElementById('scoreChart').getContext('2d');
            new Chart(ctx, {{
                type: 'line',
                data: {{
                    labels: {labels},
                    datasets: [{{
                        label: 'MSSS Score',
                        data: {scores},
                        borderColor: 'blue',
                        fill: false
                    }}]
                }},
                options: {{
                    scales: {{
                        y: {{ min: 0, max: 100 }}
                    }}
                }}
            }});
        </script>
    </body>
    </html>
    """

    labels = [row[0] for row in data[-30:]]  # Last 30 days
    scores = [int(row[1]) for row in data[-30:]]
    current_score = scores[-1] if scores else 0

    score_class = "good" if current_score >= 80 else "medium" if current_score >= 60 else "bad"

    html = html.format(
        current_score=current_score,
        score_class=score_class,
        labels=json.dumps(labels),
        scores=json.dumps(scores)
    )

    with open(output_file, 'w') as f:
        f.write(html)

if __name__ == "__main__":
    import sys
    generate_dashboard(sys.argv[1], sys.argv[2])

Integration with Existing Tools

With SonarQube

# Convert results to SonarQube Generic Issue format
mcp-scan scan . --output json | jq '{
  issues: [.findings[] | {
    engineId: "mcp-scan",
    ruleId: .rule_id,
    severity: (if .severity == "critical" then "CRITICAL" elif .severity == "high" then "MAJOR" elif .severity == "medium" then "MINOR" else "INFO" end),
    type: "VULNERABILITY",
    primaryLocation: {
      message: .title,
      filePath: .location.file,
      textRange: {
        startLine: .location.line,
        endLine: .location.end_line
      }
    }
  }]
}' > sonar-issues.json

# Upload to SonarQube
sonar-scanner -Dsonar.externalIssuesReportPaths=sonar-issues.json

With Jira

# Create Jira issues for critical findings
mcp-scan scan . --output json | jq -r '.findings[] | select(.severity == "critical") | @json' | while read finding; do
  TITLE=$(echo $finding | jq -r '.title')
  DESC=$(echo $finding | jq -r '.description')
  FILE=$(echo $finding | jq -r '.location.file')
  LINE=$(echo $finding | jq -r '.location.line')

  curl -X POST \
    -H "Content-Type: application/json" \
    -u "$JIRA_USER:$JIRA_TOKEN" \
    "$JIRA_URL/rest/api/2/issue" \
    -d "{
      \"fields\": {
        \"project\": {\"key\": \"SEC\"},
        \"summary\": \"[MCP-Scan] $TITLE\",
        \"description\": \"$DESC\\n\\nLocation: $FILE:$LINE\",
        \"issuetype\": {\"name\": \"Security Vulnerability\"},
        \"priority\": {\"name\": \"Critical\"}
      }
    }"
done

With Slack Webhooks

#!/bin/bash
# notify-slack.sh

WEBHOOK_URL=$1
RESULTS=$2

SCORE=$(jq '.msss_score.score' $RESULTS)
CRITICAL=$(jq '.summary.by_severity.critical' $RESULTS)
HIGH=$(jq '.summary.by_severity.high' $RESULTS)

if [ $CRITICAL -gt 0 ] || [ $HIGH -gt 0 ]; then
  COLOR="danger"
  EMOJI=":warning:"
else
  COLOR="good"
  EMOJI=":white_check_mark:"
fi

curl -X POST $WEBHOOK_URL \
  -H 'Content-Type: application/json' \
  -d "{
    \"attachments\": [{
      \"color\": \"$COLOR\",
      \"title\": \"$EMOJI Security Scan Results\",
      \"fields\": [
        {\"title\": \"Score\", \"value\": \"$SCORE/100\", \"short\": true},
        {\"title\": \"Critical\", \"value\": \"$CRITICAL\", \"short\": true},
        {\"title\": \"High\", \"value\": \"$HIGH\", \"short\": true}
      ]
    }]
  }"

Team Training

Scenario

You want to use mcp-scan to train your team on MCP security.

Training Material

# Create training project
mkdir mcp-security-training
cd mcp-security-training

# Create vulnerable exercises
cat > exercise1_rce.py << 'EOF'
"""Exercise 1: Detect RCE

Your mission: Find and fix the command execution vulnerability.
"""
from mcp import tool
import subprocess

@tool
def run_command(cmd: str) -> str:
    """Run a system command."""
    # TODO: This line is vulnerable. How would you fix it?
    return subprocess.check_output(cmd, shell=True).decode()

# HINT: Use a list of allowed commands or subprocess without shell=True
EOF

cat > exercise2_sqli.py << 'EOF'
"""Exercise 2: Detect SQL Injection

Your mission: Find and fix the SQL injection vulnerability.
"""
from mcp import tool
import sqlite3

@tool
def search_user(name: str) -> str:
    """Search for a user by name."""
    conn = sqlite3.connect('users.db')
    cursor = conn.cursor()
    # TODO: This query is vulnerable. How would you fix it?
    cursor.execute(f"SELECT * FROM users WHERE name = '{name}'")
    return str(cursor.fetchall())

# HINT: Use parameters instead of f-strings
EOF

# Create exercise guide
cat > TRAINING.md << 'EOF'
# MCP Security Training

## Exercises

### Exercise 1: Remote Command Execution
- File: exercise1_rce.py
- Objective: Identify and fix RCE vulnerability

```bash
# Scan
mcp-scan scan exercise1_rce.py

# View finding
mcp-scan scan exercise1_rce.py --output json | jq '.findings[0]'

Exercise 2: SQL Injection

  • File: exercise2_sqli.py
  • Objective: Identify and fix SQL injection
# Scan
mcp-scan scan exercise2_sqli.py

Verification

After fixing, run:

mcp-scan scan . --fail-on low

If there are no findings, you completed the exercise. EOF

### Interactive Workshop

```bash
#!/bin/bash
# workshop.sh - Interactive security workshop

echo "=== MCP Security Workshop ==="
echo ""
echo "This workshop will guide you through detecting and fixing vulnerabilities."
echo ""

# Exercise 1
echo "=== EXERCISE 1: RCE ==="
echo "Scanning exercise1_rce.py..."
mcp-scan scan exercise1_rce.py
echo ""
read -p "Press Enter to see the solution..."
echo ""
echo "SOLUTION: Use a whitelist of allowed commands:"
echo "
ALLOWED_COMMANDS = ['ls', 'pwd', 'date']
if cmd not in ALLOWED_COMMANDS:
    return 'Command not allowed'
return subprocess.check_output([cmd])
"

# Exercise 2
echo ""
echo "=== EXERCISE 2: SQL Injection ==="
echo "Scanning exercise2_sqli.py..."
mcp-scan scan exercise2_sqli.py
echo ""
read -p "Press Enter to see the solution..."
echo ""
echo "SOLUTION: Use SQL parameters:"
echo "
cursor.execute('SELECT * FROM users WHERE name = ?', (name,))
"

echo ""
echo "=== WORKSHOP COMPLETED ==="


Previous: CI/CD Integration | Back to Index: README