Skip to content

Security Scanning

This document describes the security scanning tools and processes for the DSTA project.

Overview

DSTA uses two complementary security scanning tools:

  1. Bandit - Static code analysis to find common security issues in Python code
  2. Safety - Dependency vulnerability scanning to identify known security vulnerabilities in packages

Quick Start

Run All Security Scans Locally

./scripts/security-scan.sh

This script will: - Install bandit and safety if not present - Run bandit code security scan - Run safety dependency vulnerability scan - Generate detailed reports in security-reports/

Run Individual Tools

Bandit (Code Security)

# Basic scan
bandit -r src/

# With configuration
bandit -r src/ -c .bandit

# Generate JSON report
bandit -r src/ -c .bandit -f json -o bandit-report.json

Safety (Dependency Vulnerabilities)

# Scan current environment
pip freeze > requirements.txt
safety check --file=requirements.txt

# With JSON output
safety check --file=requirements.txt --output=json --save-json=safety-report.json

Configuration

Bandit Configuration (.bandit)

Located at project root, controls: - Excluded directories (tests, venv, etc.) - Skipped test IDs - Confidence and severity thresholds - Output formatting

Example customizations:

# Skip specific test
skips = ['B101']  # Skip assert usage check

# Set thresholds
confidence = MEDIUM  # LOW, MEDIUM, HIGH
severity = MEDIUM    # LOW, MEDIUM, HIGH

Safety Configuration (.safety-policy.yml)

Located at project root, controls: - Ignored vulnerabilities (with expiration) - Ignored packages - Minimum severity threshold - Files to scan

Example customizations:

security:
  ignore-vulnerabilities:
    - id: "12345"
      reason: "False positive - doesn't affect our usage"
      expires: "2026-12-31"

  minimum-severity: "high"  # Only report high+ severity

CI/CD Integration

GitHub Actions Workflow

Security scans run automatically on: - Push to main or develop branches - Pull requests to main or develop - Daily at 2 AM UTC (scheduled)

Workflow file: .github/workflows/security.yml

Viewing Reports

  1. Go to Actions tab in GitHub
  2. Select "Security Scanning" workflow
  3. Click on latest run
  4. Download artifacts:
  5. bandit-security-report - Bandit JSON results
  6. safety-vulnerability-report - Safety JSON results

Handling Failures

If security scan fails in CI:

  1. Check the workflow logs for details
  2. Download and review the artifact reports
  3. Fix identified issues or add exceptions (with justification)
  4. Re-run the workflow

Common Security Issues

Bandit Issues

B201/B301: Pickle Usage

# ❌ Insecure
import pickle
data = pickle.load(file)

# ✅ Secure - use JSON instead
import json
data = json.load(file)

B608: SQL Injection

# ❌ Insecure
query = f"SELECT * FROM users WHERE id = {user_id}"

# ✅ Secure - use parameterized queries
query = "SELECT * FROM users WHERE id = %s"
cursor.execute(query, (user_id,))

B105/B106: Hardcoded Passwords

# ❌ Insecure
password = "my_secret_password"

# ✅ Secure - use environment variables
import os
password = os.getenv("DB_PASSWORD")

B404: Import of subprocess

# If you need subprocess, use it safely:
import subprocess

# ✅ Avoid shell=True
subprocess.run(["ls", "-la"], check=True)

# ❌ Never use shell=True with user input
subprocess.run(f"ls {user_input}", shell=True)  # DANGEROUS!

Safety Issues

When Safety finds vulnerabilities:

  1. Update the package (preferred):

    pip install --upgrade package-name
    

  2. Check if vulnerability applies to your usage:

  3. Read the CVE details
  4. Determine if your code uses the vulnerable feature

  5. Add exception if needed (with strong justification):

    # .safety-policy.yml
    security:
      ignore-vulnerabilities:
        - id: "12345"
          reason: "We don't use the vulnerable feature X"
          expires: "2026-06-30"
    

Security Best Practices

Code Security

  1. Never hardcode secrets - use environment variables or secret management
  2. Validate all inputs - especially user-provided data
  3. Use parameterized queries - prevent SQL injection
  4. Avoid shell=True in subprocess calls
  5. Use safe deserialization - prefer JSON over pickle
  6. Keep dependencies updated - regularly run pip list --outdated

API Security

  1. Use HTTPS for all external communications
  2. Validate API keys before use
  3. Rate limit API calls to prevent abuse
  4. Sanitize error messages - don't expose internal details
  5. Log security events - authentication, authorization failures

Django Security

  1. Use Django's built-in protection for CSRF, XSS, SQL injection
  2. Set DEBUG=False in production
  3. Configure ALLOWED_HOSTS properly
  4. Use strong SECRET_KEY from environment variable
  5. Enable security middleware

Ignoring False Positives

Bandit

To skip specific issues inline:

# nosec B201
import pickle  # Safe in this context because...

Or configure in .bandit:

skips = ['B201']

Safety

Add to .safety-policy.yml:

security:
  ignore-vulnerabilities:
    - id: "CVE-2024-12345"
      reason: "Detailed explanation..."
      expires: "2026-12-31"  # Must justify and set expiration

Maintenance

Weekly Tasks

  1. Review security reports from automated scans
  2. Update dependencies with security patches
  3. Review and remove expired exceptions

Monthly Tasks

  1. Run full security audit: ./scripts/security-scan.sh
  2. Review all ignored vulnerabilities in .safety-policy.yml
  3. Update bandit and safety to latest versions
  4. Check for new security best practices

Before Each Release

  1. Run comprehensive security scan
  2. Ensure all known vulnerabilities are addressed
  3. Review and update security documentation
  4. Verify all secrets are properly externalized

Resources

  • Bandit Documentation: https://bandit.readthedocs.io/
  • Safety Documentation: https://docs.pyup.io/
  • Python Security Best Practices: https://python.readthedocs.io/en/latest/library/security_warnings.html
  • OWASP Top 10: https://owasp.org/www-project-top-ten/
  • Django Security: https://docs.djangoproject.com/en/stable/topics/security/

Support

If you encounter security issues:

  1. Do not commit security vulnerabilities to the repository
  2. Run security scans before creating pull requests
  3. Document exceptions with clear justification and expiration dates
  4. Report critical security issues privately to the maintainers

For questions or issues with security scanning, open an issue with the security label.