Skip to content

[CHORE]: Achieve zero flagged Bandit issues #421

@crivetimihai

Description

@crivetimihai

🔧 Chore — Achieve Zero Bandit Security Findings


🧭 Chore Summary

Drive the Bandit security scanner to 0 actionable issues while keeping all tests green and maintaining code functionality.


🧱 Areas Affected

  • Pre-commit hooks / security checks
  • Build system / Make targets (make bandit, make security)
  • GitHub Actions / CI pipeline
  • Runtime codebase (security fixes, safe temp-files, proper bindings, etc.)

⚙️ Context / Rationale

Bandit static security analysis surfaces vulnerable patterns—hardcoded secrets, shell injection risks, insecure bindings—before they reach production. A clean security scan ensures we maintain secure coding practices and catch potential vulnerabilities early.


📦 Related Make Targets

Target Purpose
make bandit Run Bandit security scanner
make security Meta-target for all security checks
make pre-commit Execute all hooks locally (including Bandit)
make lint Meta-target including security checks
make test Unit / integration tests

Bold targets are mandatory; CI must fail if any of them reports issues.


📋 Acceptance Criteria

  • make bandit exits 0 with 0 High/Medium findings (and ideally 0 Low).
  • No use of # nosec without documented justification.
  • make pre-commit runs clean with no security issues.
  • make test passes (security fixes don't break functionality).
  • GitHub Actions enforces Bandit checks (e.g. bandit -r . -ll -i).
  • Changelog entry under "Security" or "Maintenance".

🛠️ Task List (suggested flow)

  1. Baseline scan

    make bandit | tee bandit-baseline.txt
    # Or for more detail:
    bandit -r . -f json -o bandit-report.json
  2. Common Bandit fixes

    Bandit ID Issue Fix Strategy
    B108 Hardcoded tmp directory Use tempfile.TemporaryDirectory() or Path(tempfile.gettempdir()) / ...
    B104 Bind to 0.0.0.0 Default to 127.0.0.1; use env var for external binding
    B113 Request without timeout Add explicit timeout= parameter to all HTTP calls
    B101 Use of assert Replace with if not condition: raise ValueError(...)
    B404/B603/B607 Subprocess usage Use subprocess.run() with full paths, shell=False, validated inputs
    B105/B106/B107 Hardcoded passwords Move to environment variables or secure config
    B201 Flask debug=True Ensure debug mode is disabled in production
    B324 Weak hash functions Use SHA256+ instead of MD5/SHA1 for security purposes
    B703 Django mark_safe Validate/sanitize all HTML before marking safe
  3. Security patterns to implement

    • Environment variables: Never hardcode secrets, use os.getenv() with defaults
    • Path construction: Use pathlib.Path instead of string concatenation
    • Input validation: Sanitize all external inputs before use
    • Cryptography: Use established libraries (cryptography, secrets) not custom implementations
    • File permissions: Set restrictive permissions on sensitive files
  4. Testing security fixes

    # After each fix, verify functionality isn't broken
    make test
    # Re-run Bandit to confirm issue is resolved
    bandit -r path/to/fixed/module.py
  5. Suppressions (last resort)

    • Use # nosec B101 only with clear justification comment
    • Document in code why the pattern is safe in this specific context
    • Consider refactoring to avoid the pattern entirely
    • Example:
      # nosec B104 - Binding to 0.0.0.0 required for container deployment
      # Protected by firewall rules and ingress configuration
      app.run(host='0.0.0.0', port=8080)
  6. CI integration

    • Configure Bandit in .bandit config file for consistency
    • Set appropriate severity threshold (typically exclude Low unless critical)
    • Example GitHub Action step:
      - name: Run Bandit Security Scan
        run: |
          pip install bandit
          bandit -r . -ll -i -f json -o bandit-report.json
          bandit -r . -ll -i
  7. Progressive enforcement

    • Start with High severity issues
    • Move to Medium severity
    • Address Low severity where practical
    • Document accepted risks
  8. Final validation

    # Full security check
    make bandit
    # Ensure no regressions
    make lint test
    # Verify in container
    make docker-prod docker-test

📖 References


🧩 Additional Notes

  • Bandit's default profile is strict; tune via .bandit config file only if necessary
  • Some patterns (like assert in tests) can be excluded via config rather than inline comments
  • Keep fixes atomic (one issue type per commit) to simplify review and potential reverts
  • Consider adding bandit to pre-commit hooks for early detection:
    - repo: https://github.com/PyCQA/bandit
      rev: '1.7.5'
      hooks:
      - id: bandit
        args: ['-ll', '-i']

Metadata

Metadata

Assignees

Labels

choreLinting, formatting, dependency hygiene, or project maintenance chorescicdIssue with CI/CD process (GitHub Actions, scaffolding)devopsDevOps activities (containers, automation, deployment, makefiles, etc)triageIssues / Features awaiting triage

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions