AgentSkillsCN

Security Scanner

安全扫描仪

SKILL.md

Security Scanner

Scan infrastructure configuration files for security vulnerabilities, misconfigurations, and deviations from best practices.

Scan Targets

Docker Compose Files

Scan docker-compose.yml, docker-compose.*.yml, compose.yml

Critical Issues (Severity: HIGH)

IssueDetectionFix
Public port bindingports: ["8080:8080"]Use 127.0.0.1:8080:8080
Privileged containerprivileged: trueRemove or use specific capabilities
Host network modenetwork_mode: hostUse bridge network
Writable /etc or /rootVolume mounts to sensitive pathsUse read-only or avoid
Root userNo user: specifiedAdd user: "1000:1000"
Missing security_optNo security_opt sectionAdd no-new-privileges:true

Medium Issues (Severity: MEDIUM)

IssueDetectionFix
No health checkMissing healthcheck:Add health check
No resource limitsMissing deploy.resourcesAdd CPU/memory limits
No restart policyMissing restart:Add unless-stopped
Default bridge networkNo custom networksDefine isolated networks
No logging limitsMissing logging.optionsAdd max-size, max-file

Low Issues (Severity: LOW)

IssueDetectionFix
Using latest tagimage: app:latestPin specific version
Deprecated version keyversion: "3.8"Remove (optional in modern Docker)
No container nameMissing container_nameAdd for easier management

Kubernetes Manifests

Scan *.yaml, *.yml files with Kubernetes API objects

Critical Issues

IssueDetectionFix
Running as rootrunAsUser: 0 or missingSet runAsNonRoot: true
Privileged podprivileged: trueSet privileged: false
Host PID/NetworkhostPID: trueRemove
No resource limitsMissing resources.limitsDefine limits
Writable root FSreadOnlyRootFilesystem: falseSet to true
All capabilitiescapabilities: add: [ALL]Drop ALL, add specific

Medium Issues

IssueDetectionFix
No network policyMissing NetworkPolicyCreate restrictive policy
No pod securityMissing securityContextAdd security context
No liveness probeMissing livenessProbeAdd health check
Service type LoadBalancertype: LoadBalancerUse ClusterIP + Ingress

Terraform Files

Scan *.tf, *.tfvars files

Critical Issues

IssueDetectionFix
Open security group0.0.0.0/0 in ingressRestrict to specific IPs
Public S3 bucketacl = "public-read"Use private
Unencrypted storageMissing encryption configEnable encryption
Hardcoded secretspassword = "..."Use variables/secrets manager
No state encryptionPlain state fileEnable encryption

Medium Issues

IssueDetectionFix
Default VPCUsing default VPCCreate custom VPC
No VPC flow logsMissing flow logsEnable for audit
IMDSv1 enabledMissing IMDSv2 requirementRequire IMDSv2
No backupMissing backup configEnable automated backups

Scan Output Format

Summary Report

code
╔══════════════════════════════════════════════════════════════╗
║              SECURITY SCAN REPORT                            ║
║              2025-12-10 14:30:00                             ║
╠══════════════════════════════════════════════════════════════╣
║  Files Scanned: 5                                            ║
║  Issues Found:  12                                           ║
║                                                              ║
║  ⛔ Critical: 3                                              ║
║  ⚠️  Medium:   5                                              ║
║  ℹ️  Low:      4                                              ║
╚══════════════════════════════════════════════════════════════╝

Detailed Findings

code
⛔ CRITICAL: Public Port Exposure
   File: docker-compose.yml
   Line: 15
   Service: web

   Found:
     ports:
       - "8080:8080"

   Risk: Port 8080 is exposed to all network interfaces (0.0.0.0).
         Attackers can access this service from the internet.

   Fix:
     ports:
       - "127.0.0.1:8080:8080"

   Reference: CIS Docker Benchmark 5.13

Scan Rules

Docker Compose Rules

yaml
rules:
  - id: DC001
    name: public-port-binding
    severity: critical
    pattern: 'ports:\s*-\s*"?\d+:\d+"?'
    exclude: '127\.0\.0\.1:|localhost:'
    message: "Port exposed publicly without localhost binding"
    fix: "Prepend 127.0.0.1: to port binding"

  - id: DC002
    name: privileged-container
    severity: critical
    pattern: 'privileged:\s*true'
    message: "Container running in privileged mode"
    fix: "Remove privileged: true or use specific capabilities"

  - id: DC003
    name: missing-security-opt
    severity: high
    pattern: 'services:'
    require: 'security_opt:'
    message: "Service missing security_opt configuration"
    fix: "Add security_opt: [no-new-privileges:true]"

  - id: DC004
    name: no-health-check
    severity: medium
    pattern: 'services:'
    require: 'healthcheck:'
    message: "Service missing health check"
    fix: "Add healthcheck with test, interval, timeout"

  - id: DC005
    name: no-resource-limits
    severity: medium
    pattern: 'services:'
    require: 'deploy:\s*resources:\s*limits:'
    message: "Service missing resource limits"
    fix: "Add deploy.resources.limits for CPU and memory"

  - id: DC006
    name: host-network
    severity: critical
    pattern: 'network_mode:\s*host'
    message: "Container using host network mode"
    fix: "Use bridge network with explicit port bindings"

  - id: DC007
    name: latest-tag
    severity: low
    pattern: 'image:\s*\S+:latest'
    message: "Using latest tag which is mutable"
    fix: "Pin to specific version tag"

Kubernetes Rules

yaml
rules:
  - id: K8S001
    name: run-as-root
    severity: critical
    pattern: 'runAsUser:\s*0'
    message: "Container configured to run as root"
    fix: "Set runAsNonRoot: true or specify non-root user"

  - id: K8S002
    name: privileged-pod
    severity: critical
    pattern: 'privileged:\s*true'
    message: "Pod running in privileged mode"
    fix: "Set privileged: false"

  - id: K8S003
    name: no-security-context
    severity: high
    pattern: 'containers:'
    require: 'securityContext:'
    message: "Container missing security context"
    fix: "Add securityContext with appropriate restrictions"

  - id: K8S004
    name: capabilities-all
    severity: critical
    pattern: 'capabilities:\s*add:\s*\[\s*ALL'
    message: "Container granted all capabilities"
    fix: "Drop ALL capabilities and add only required ones"

  - id: K8S005
    name: host-pid
    severity: critical
    pattern: 'hostPID:\s*true'
    message: "Pod sharing host PID namespace"
    fix: "Remove hostPID: true"

Terraform Rules

yaml
rules:
  - id: TF001
    name: open-security-group
    severity: critical
    pattern: 'cidr_blocks\s*=\s*\["0\.0\.0\.0/0"\]'
    context: 'ingress'
    message: "Security group allows traffic from anywhere"
    fix: "Restrict to specific IP ranges"

  - id: TF002
    name: public-s3-bucket
    severity: critical
    pattern: 'acl\s*=\s*"public'
    message: "S3 bucket configured for public access"
    fix: "Use acl = \"private\" and bucket policies"

  - id: TF003
    name: unencrypted-ebs
    severity: high
    pattern: 'aws_ebs_volume'
    require: 'encrypted\s*=\s*true'
    message: "EBS volume not encrypted"
    fix: "Add encrypted = true"

  - id: TF004
    name: hardcoded-credentials
    severity: critical
    pattern: '(password|secret|key)\s*=\s*"[^"$]+'
    message: "Hardcoded credentials in Terraform"
    fix: "Use variables or secrets manager"

Integration

As Pre-Write Hook

This skill can be integrated as a validation hook:

json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Write|Edit",
      "hooks": [{
        "type": "command",
        "command": "security-scan --file $FILE_PATH"
      }]
    }]
  }
}

As CI/CD Step

yaml
# GitHub Actions
- name: Security Scan
  run: |
    claude plugin run security-scanner --path .
    if [ $? -ne 0 ]; then
      echo "Security issues found!"
      exit 1
    fi

Remediation Guidance

When issues are found, the scanner provides:

  1. What: Clear description of the issue
  2. Why: Risk explanation with real-world impact
  3. Where: Exact file and line number
  4. How: Specific fix with code example
  5. Reference: Link to security benchmark or standard

False Positive Handling

Some patterns may be intentional. Mark as accepted:

yaml
# security-scan: ignore DC001
ports:
  - "0.0.0.0:443:443"  # Intentionally public (reverse proxy)

Or create .security-scan-ignore:

yaml
ignore:
  - rule: DC001
    file: nginx/docker-compose.yml
    reason: "Nginx is intentionally public-facing"

Compliance Mapping

RuleCIS DockerCIS KubernetesOWASP
DC0015.13-A05
DC0025.4-A01
DC0035.25-A05
K8S001-5.2.6A01
K8S002-5.2.1A01
TF001--A05