Skip to content

fix(security): require distinct Fernet key, WS revocation fail-closed, salt_ops input validation, RBAC+SSRF guards (closes #578)#584

Merged
hellodk merged 2 commits into
masterfrom
fix/578-security
Jun 7, 2026
Merged

fix(security): require distinct Fernet key, WS revocation fail-closed, salt_ops input validation, RBAC+SSRF guards (closes #578)#584
hellodk merged 2 commits into
masterfrom
fix/578-security

Conversation

@hellodk

@hellodk hellodk commented Jun 7, 2026

Copy link
Copy Markdown
Owner

Summary

  • Fernet key isolation: _fernet_key() raises RuntimeError at startup in non-development environments when FERNET_SECRET_KEY is absent, preventing silent key derivation from JWT_SECRET. Dev mode retains the fallback with a loud warning. Key-migration instructions added inline.
  • WebSSH fail-closed: get_current_user_ws now re-raises any non-ValueError exception from is_token_revoked as a ValueError, rejecting the WebSocket connection instead of degrading open when Redis is unavailable.
  • salt_ops input validation: _validate_state_name (dotted-name allowlist regex) and _validate_minion_ids (_MINION_ID_RE, mirrors salt_keys.py) guard both /apply and /cmd endpoints. Globs, wildcards, commas, path traversal, and shell metacharacters are rejected with HTTP 422.
  • Nodes RBAC: GET /nodes/{id}, /facts, /packages upgraded from bare get_current_user to require_role("viewer", "operator", "admin").
  • SSRF guard: _ssrf_safe_url() helper added to security.py; called before urllib.request.urlopen in integration-status. Rejects non-http/https schemes and numeric IPs in loopback/private/link-local/metadata ranges (127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16, ::1).

Test plan

  • tests/unit/test_security_578.py — 23 new unit tests, all passing
  • pytest tests/unit/ -q — 2167 passed, 0 failures
  • ruff check + ruff format --check — 0 findings on changed files
  • All pre-commit hooks green (mypy, vulture, bandit, unit test presence)

Closes #578

🤖 Generated with Claude Code

…, salt_ops input validation, RBAC+SSRF guards (closes #578)

- platform_settings_svc: _fernet_key raises RuntimeError in non-dev when
  FERNET_SECRET_KEY is absent; dev-only JWT-derive fallback emits a loud
  warning. Includes key-migration instructions in the comment block.
- webssh get_current_user_ws: any exception from is_token_revoked now
  raises ValueError (fail-closed) instead of silently passing (degrade-open).
- salt_ops: _validate_state_name (dotted-name regex) and _validate_minion_ids
  (_MINION_ID_RE, mirrors salt_keys.py) guard both /apply and /cmd endpoints;
  globs, wildcards, commas, and shell metacharacters are rejected with 422.
- nodes.py: GET /{id}, /{id}/facts, /{id}/packages scoped from bare
  get_current_user to require_role("viewer","operator","admin").
- security.py: _ssrf_safe_url helper rejects file/ftp/non-http schemes and
  numeric IPs in loopback/private/link-local/metadata ranges before
  integration-status fires urllib.request.urlopen.
- tests/unit/test_security_578.py: 23 new unit tests covering all five fixes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@hellodk hellodk added bug Something is broken security Security fix or improvement p1-high Blocks a user flow labels Jun 7, 2026
@github-actions github-actions Bot added test Test coverage improvement frontend Frontend / React changes labels Jun 7, 2026
# Conflicts:
#	VERSION
#	frontend/package.json
@github-actions

github-actions Bot commented Jun 7, 2026

Copy link
Copy Markdown

Coverage Report

81.8% on fleet_platform/services/ (gate: 80%)

Gate passed

@hellodk
hellodk merged commit 43e52a0 into master Jun 7, 2026
10 checks passed
@hellodk
hellodk deleted the fix/578-security branch June 7, 2026 18:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something is broken frontend Frontend / React changes p1-high Blocks a user flow security Security fix or improvement test Test coverage improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Security: Fernet key derived from JWT_SECRET, WS revocation fails open, salt_ops state/target injection, RBAC enumeration gaps

1 participant