towerops/docs/security-analysis.md
Graham McIntire 61a06fc11c
Add firmware version tracking system
- Add firmware context module with upsert, query, and logging functions
- Add FirmwareVersionFetcherWorker to fetch MikroTik RSS daily
- Add Oban cron schedules (2 AM dev, 4 AM prod)
- Add version change detection to Discovery module
- Track firmware history with PubSub broadcasts
- All tests passing

Phase 3-5 of firmware tracking implementation complete.
Next: LiveView UI indicators.
2026-02-01 10:46:27 -06:00

7.2 KiB

Security Analysis and Mitigations

This document tracks Sobelow security findings and the mitigations applied to address them.

Summary

As of 2026-02-01, the following high-confidence security issues have been addressed:

  • Config.CSP: Content-Security-Policy headers configured
  • Config.HTTPS: HTTPS enforcement enabled in production
  • Traversal.FileModule: Directory traversal protections added to MIB controller
  • ⚠️ Vendored Libraries: Low-risk warnings in SnmpKit (vendored library)

Fixed Issues

1. Config.CSP: Missing Content-Security-Policy (FIXED)

Severity: High Location: lib/towerops_web/router.ex:19 Status: Fixed

Mitigation: Added Content-Security-Policy headers to the :browser pipeline with LiveView-compatible settings:

plug :put_secure_browser_headers, %{
  "content-security-policy" =>
    "default-src 'self'; " <>
    "script-src 'self' 'unsafe-inline' 'unsafe-eval'; " <>
    "style-src 'self' 'unsafe-inline'; " <>
    "img-src 'self' data: https:; " <>
    "font-src 'self' data:; " <>
    "connect-src 'self' ws: wss:; " <>
    "frame-ancestors 'none';"
}

Note: 'unsafe-inline' for scripts is required for Phoenix LiveView to function. This is a documented requirement for LiveView applications.


2. Config.HTTPS: HTTPS Not Enabled (FIXED)

Severity: High Location: config/prod.exs Status: Fixed

Mitigation: Configured force_ssl in production endpoint configuration (config/runtime.exs):

config :towerops, ToweropsWeb.Endpoint,
  force_ssl: [
    hsts: true,
    rewrite_on: [:x_forwarded_host, :x_forwarded_port, :x_forwarded_proto]
  ]

Security Benefits:

  • Automatically redirects HTTP → HTTPS
  • Enables HSTS (HTTP Strict Transport Security)
  • Respects X-Forwarded-* headers from reverse proxy (Traefik)

3. Traversal.FileModule: Directory Traversal in MIB Controller (FIXED)

Severity: High Locations:

  • lib/towerops_web/controllers/api/v1/mib_controller.ex:119 (File.rm_rf)
  • lib/towerops_web/controllers/api/v1/mib_controller.ex:229 (File.cp)

Status: Fixed

Mitigation: Added comprehensive input validation to prevent directory traversal attacks:

Vendor Name Validation

defp validate_vendor_name(vendor) when is_binary(vendor) do
  # Reject path traversal characters
  if String.contains?(vendor, [".", "/", "\\", ":"]) do
    {:error, "Invalid vendor name: cannot contain path separators or dots"}
  else
    # Only allow alphanumeric, hyphen, underscore
    if vendor =~ ~r/^[a-zA-Z0-9_-]+$/ do
      :ok
    else
      {:error, "Invalid vendor name: must contain only letters, numbers, hyphens, and underscores"}
    end
  end
end

Filename Validation

defp validate_filename(filename) when is_binary(filename) do
  # Reject directory traversal sequences
  if String.contains?(filename, ["..", "/", "\\"]) or String.starts_with?(filename, ".") do
    {:error, "Invalid filename: cannot contain path separators or parent directory references"}
  else
    :ok
  end
end

Additional Protections:

  • All vendor names validated before path construction
  • Filenames sanitized with Path.basename/1
  • Superuser-only API access required for all MIB management endpoints
  • All operations logged for audit trail

Remaining Low-Risk Findings

Vendored Library Warnings (SnmpKit)

Severity: Low Confidence Status: ⚠️ Accepted Risk

The following warnings are in the vendored SnmpKit library (lib/snmpkit/):

Misc.BinToTerm: Unsafe binary_to_term

  • Location: lib/snmpkit/snmp_lib/mib/compiler.ex:203
  • Risk Level: Medium-High
  • Reason: Used for loading compiled MIB files from trusted sources only
  • Mitigation: MIB files are only loaded from the application's priv/mibs/ directory, which is controlled by administrators. No user-provided binary data is deserialized.

DOS.StringToAtom / DOS.ListToAtom

  • Locations: Multiple files in lib/snmpkit/snmp_lib/ and lib/snmpkit/snmp_mgr/
  • Risk Level: Low
  • Reason: SNMP MIB parsing and tokenization
  • Mitigation: MIB files are from trusted vendor sources and validated before processing. Atom creation is bounded by the finite set of SNMP OID names in standard MIBs.

Traversal.FileModule

  • Locations: MIB parser and compiler files
  • Risk Level: Low
  • Reason: MIB file reading from trusted directories
  • Mitigation: File paths are constructed from application-controlled base directories (priv/mibs/). User input does not directly influence file paths.

SQL.Query: SQL injection

  • Locations: lib/towerops/monitoring.ex (multiple functions)
  • Risk Level: Very Low (False Positive)
  • Reason: Uses parameterized queries with string interpolation only for table/column names
  • Mitigation: Table names are hardcoded constants, not user input. All user values use proper $1, $2 parameter binding.

Ignored Low-Confidence Warnings

The following warnings have been reviewed and determined to be false positives:

XSS.Raw in API Documentation

  • Location: lib/towerops_web/controllers/api_docs_html/index.html.heex
  • Reason: Uses raw(~S"""...""") to display static code examples in API documentation
  • Risk: None - all content is static, developer-authored code examples
  • No Action Required

Security Best Practices

File Upload Security

  1. Validate all filenames and vendor names
  2. Use Path.basename/1 to strip directory components
  3. Restrict operations to predefined base directories
  4. Require superuser authentication for file management
  5. Log all file operations for audit trail

HTTPS Configuration

  1. Force SSL with HSTS enabled
  2. Respect X-Forwarded-* headers from reverse proxy
  3. Use secure cipher suites (default Phoenix configuration)

Content Security Policy

  1. Default to 'self' for all resources
  2. Allow WebSocket connections for LiveView
  3. Prevent framing with frame-ancestors 'none'
  4. ⚠️ Allow 'unsafe-inline' scripts (required for LiveView)

Testing Recommendations

Manual Security Testing

  • Test MIB upload with path traversal attempts (../../../etc/passwd)
  • Verify HTTPS redirect in production environment
  • Test CSP headers don't break LiveView functionality
  • Verify file upload restrictions (filename validation)

Automated Testing

  • Run mix sobelow regularly in CI/CD pipeline
  • Monitor for new security vulnerabilities in dependencies
  • Use Dialyzer for type safety checks

Future Improvements

  1. Stricter CSP: Explore using nonces for scripts instead of 'unsafe-inline' (requires LiveView 1.0+)
  2. File Upload Limits: Add file size limits for MIB uploads
  3. Rate Limiting: Implement rate limiting on API endpoints
  4. Security Headers: Add additional security headers (Permissions-Policy, etc.)
  5. Dependency Scanning: Set up automated dependency vulnerability scanning

References