Skip to content

Feat: Expand security test coverage and reorganize auth test suite#390

Open
Harrio-6 wants to merge 13 commits into
mainfrom
Security-tests
Open

Feat: Expand security test coverage and reorganize auth test suite#390
Harrio-6 wants to merge 13 commits into
mainfrom
Security-tests

Conversation

@Harrio-6
Copy link
Copy Markdown
Collaborator

@Harrio-6 Harrio-6 commented May 12, 2026

Reorganizes the auth/security test suite by removing redundant or overly broad test files and replacing them with focused, targeted security tests. Adds new coverage for OAuth callback token redaction, secret leakage on errors, OAuth state/CSRF validation, and RBAC decorator behavior. Cleans up conftest.py and trims unrelated noise from the DB connection pool tests.

Summary by CodeRabbit

  • Bug Fixes

    • Improved error handling to prevent sensitive information (API keys, secrets, passwords) from appearing in error logs and HTTP responses.
    • Sanitized exception messages in error responses to avoid exposing sensitive data.
  • Tests

    • Added comprehensive OAuth and CSRF security tests for state validation and concurrent request handling.
    • Added RBAC escalation guard tests to verify permission enforcement.
    • Added input validation and secret redaction tests across OAuth callbacks and database connections.

Review Change Stack

@Harrio-6 Harrio-6 requested a review from a team as a code owner May 12, 2026 15:51
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 12, 2026

Warning

Rate limit exceeded

@Harrio-6 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 57 minutes and 50 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 05b38826-4899-4974-a1fe-32d8c9600d5b

📥 Commits

Reviewing files that changed from the base of the PR and between 60cb2f2 and dca2373.

📒 Files selected for processing (9)
  • server/guardrails/input_rail.py
  • server/tests/auth/test_rbac_decorators.py
  • server/tests/db/test_connection_pool.py
  • server/tests/security/conftest.py
  • server/tests/security/test_input_rail.py
  • server/tests/security/test_oauth_callback_redaction.py
  • server/tests/security/test_secret_leak_on_error.py
  • server/utils/db/db_adapters.py
  • server/utils/security/command_safety.py

Walkthrough

This PR hardens secret leakage prevention by modifying three production code paths to log exception type names instead of full exception messages, then adds comprehensive security tests verifying that OAuth2 state, RBAC decorators, and infrastructure layers fail safely without exposing sensitive data through exception channels.

Changes

Secret Leakage Prevention in Error Handling

Layer / File(s) Summary
Production Exception Logging Hardening
server/routes/atlassian/atlassian_routes.py, server/utils/db/db_adapters.py, server/utils/security/command_safety.py
Three production paths now log exception type names (type(e).__name__) instead of full exception strings when handling OAuth token exchange, database connection, and LLM safety check failures, reducing the risk of secrets in exception messages appearing in logs.
OAuth2 State Cache Adversarial Testing
server/tests/auth/test_oauth2_state_cache.py
OAuth2 state cache module gains adversarial test coverage including concurrent single-use race conditions, cross-user CSRF substitution, replay attacks, TTL expiry, and token consumption scenarios. New _in_memory_redis helper provides thread-safe Redis emulation for concurrency and TTL simulation.
RBAC Decorator Escalation Guard Testing
server/tests/auth/test_rbac_decorators.py
RBAC decorator tests expand to verify exception message sanitization in 500 responses and add escalation guard scenarios: empty/null permissions still fail with 401, enforcer is not invoked without user identity, and positional/corrupted user_id from outer decorators cannot bypass request-based identity resolution.
End-to-End OAuth Callback Redaction Testing
server/tests/security/test_oauth_callback_redaction.py
New test module verifies that Atlassian and Notion OAuth callback handlers redact client_secret material from HTTP response bodies and log output when token exchange fails, ensuring error responses are generic and include no sensitive markers. Includes fixtures, mocking utilities, and assertions for both OAuth providers.
Infrastructure Layer Secret Leak Detection
server/tests/security/test_input_rail.py, server/tests/security/test_secret_leak_on_error.py
New and expanded tests verify that LLM API key and database password secrets embedded in infrastructure layer exceptions do not appear in safety judge verdict fields, HTTP response bodies, or captured log messages. Covers input rail validation, command safety, and DB connection pool error paths.

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly Related PRs

  • Arvo-AI/aurora#368: Both PRs modify the same OAuth2 state cache test module, adding overlapping/related tests for concurrency, single-use, TTL, and edge-case behaviors.
  • Arvo-AI/aurora#369: Both PRs modify server/tests/auth/test_rbac_decorators.py and expand RBAC decorator tests for related authorization and security scenarios.

Suggested Reviewers

  • beng360
  • damianloch

Poem

🐰 Secrets tucked inside exceptions?
Not today—type names only, please!
RBAC guards, OAuth walls,
Redis races, TTL falls,
A fortress built on fail-closed dreams. 🛡️

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: expanding security test coverage and reorganizing the auth test suite, which matches the raw summary showing multiple new security tests added and auth tests reorganized.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch Security-tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment thread server/tests/security/test_secret_leak_on_error.py Fixed
Comment thread server/tests/security/test_secret_leak_on_error.py Fixed
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@server/tests/security/test_input_rail.py`:
- Around line 157-160: The test currently checks each caplog.records using
record.getMessage(), which misses exception tracebacks logged by
logger.exception; update the test in test_input_rail.py to also assert that the
secret string "sk-proj-DO_NOT_LEAK_XYZ" is not present in caplog.text (the full
captured log output) in addition to the existing per-record checks, so any
leakage via tracebacks or exception formatting is detected; keep the existing
loop over caplog.records and add a single assertion like `assert
"sk-proj-DO_NOT_LEAK_XYZ" not in caplog.text` referencing caplog.text and
record.getMessage()/caplog.records.

In `@server/tests/security/test_oauth_callback_redaction.py`:
- Around line 78-85: The test helper _build_app currently imports
utils.auth.oauth2_state_cache which throws if REDIS_URL is unset; before
importing state_cache_mod in _build_app (and the other helper that does the
same) set a test default REDIS_URL in the test environment (use the monkeypatch
fixture or os.environ) so the import succeeds; specifically, update the
_build_app helper in server/tests/security/test_oauth_callback_redaction.py to
set REDIS_URL before importing utils.auth.oauth2_state_cache (and mirror the
same change in the second helper that imports oauth2_state_cache).

In `@server/tests/security/test_secret_leak_on_error.py`:
- Around line 71-74: The tests iterate over caplog.records and assert
_LLM_API_KEY_MARKER not in record.getMessage(), but that misses API keys that
only appear in exception tracebacks; update the assertions in
test_secret_leak_on_error.py (the loop using caplog.records and the related
assertions at the other block around lines 100-103) to also assert
_LLM_API_KEY_MARKER not in caplog.text so the entire captured log (including
tracebacks) is checked; keep the existing per-record assertions and add a single
caplog.text check after the loop for comprehensive coverage.

In `@server/utils/db/db_adapters.py`:
- Around line 75-76: The user DB connection path currently logs the full
exception text in connect_to_db_as_user (which may leak secrets); change its
logger.error call to mirror the admin path by logging only the exception
type/name (e.g., use type(e).__name__) and a short context message, and keep the
existing exception raising behavior (do not include the raw exception or
traceback in the log message). Target the logger.error call inside the
connect_to_db_as_user function to make this change.

In `@server/utils/security/command_safety.py`:
- Around line 179-180: The current logger.exception call leaks the original
exception text via traceback; replace logger.exception("[CommandSafety] LLM call
failed: %s", type(e).__name__) with a non-traceback log (e.g., logger.error or
logger.error(..., exc_info=False)) that only records the safe identifier
(type(e).__name__) and never includes exc_info or the full exception message,
then return _fail_verdict(type(e).__name__) as before; update the code around
the exception handler that references logger.exception, the exception variable
e, and _fail_verdict to ensure no traceback or raw exception text is logged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b9c42d25-0464-4640-9e9c-ec1aba35e10a

📥 Commits

Reviewing files that changed from the base of the PR and between 617dd40 and 60cb2f2.

📒 Files selected for processing (8)
  • server/routes/atlassian/atlassian_routes.py
  • server/tests/auth/test_oauth2_state_cache.py
  • server/tests/auth/test_rbac_decorators.py
  • server/tests/security/test_input_rail.py
  • server/tests/security/test_oauth_callback_redaction.py
  • server/tests/security/test_secret_leak_on_error.py
  • server/utils/db/db_adapters.py
  • server/utils/security/command_safety.py

Comment thread server/tests/security/test_input_rail.py
Comment thread server/tests/security/test_oauth_callback_redaction.py Outdated
Comment thread server/tests/security/test_secret_leak_on_error.py
Comment thread server/utils/db/db_adapters.py
Comment thread server/utils/security/command_safety.py Outdated
@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant