Skip to content

PR 1: Python — Security Middleware tests#439

Merged
nitrobass24 merged 2 commits into
developfrom
test/security-middleware
May 1, 2026
Merged

PR 1: Python — Security Middleware tests#439
nitrobass24 merged 2 commits into
developfrom
test/security-middleware

Conversation

@nitrobass24
Copy link
Copy Markdown
Owner

@nitrobass24 nitrobass24 commented May 1, 2026

Summary

  • Adds comprehensive unit tests for web/security.py covering all four security subsystems
  • CSRF protection (15 tests): safe method exemption, loopback bypass with/without proxy headers, origin/referer matching, port normalization (80/443), _origin_tuple helper parsing
  • Rate limiting (10 tests): _RateLimiter per-IP tracking, limit enforcement, stale entry sweep, SSE stream exemption, disable flag, X-Forwarded-For extraction, 429 + Retry-After response
  • Security headers (5 tests): X-Content-Type-Options, X-Frame-Options, CSP, Referrer-Policy on GET and POST
  • API key auth (10 tests): enabled/disabled states, valid/invalid/missing key, non-server paths unprotected, /server/config/get exempt, SSE query param and header auth

Test plan

  • cd src/python && PYTHONPATH=. python3 -m pytest tests/unittests/test_web/test_security.py -v — 47 passed
  • python3 -m ruff check tests/unittests/test_web/test_security.py — all checks passed
  • python3 -m ruff format --check tests/unittests/test_web/test_security.py — already formatted

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Tests
    • Enhanced test coverage for web security features including CSRF protection, rate limiting, security response headers, and API key authentication.

Cover all four security subsystems in web/security.py:
- CSRF protection: safe method exemption, loopback bypass, origin/referer
  matching, port normalization, proxy header detection
- Rate limiting: per-IP tracking, limit enforcement, stale sweep, SSE
  exemption, disable flag, X-Forwarded-For extraction
- Security headers: nosniff, X-Frame-Options, CSP, Referrer-Policy
- API key auth: enabled/disabled states, exempt paths, SSE query param,
  header validation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: a4160623-2169-4b7b-bd85-fa12c1de5552

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a comprehensive unit test suite for web security features covering CSRF protection, rate limiting logic, security response headers, and API key authentication mechanisms, validating edge cases including proxy header handling, port normalization, and trusted IP selection.

Changes

Cohort / File(s) Summary
Web Security Tests
src/python/tests/unittests/test_web/test_security.py
New test suite with 526 lines covering CSRF protection (safe-method exemption, loopback behavior, proxy header interaction, origin/referer matching, port normalization), rate limiting (_RateLimiter thresholds, per-IP tracking, retry-after behavior, stale entry sweeping, middleware integration, SSE exemption), security headers (presence and content validation on GET and POST), and API key authentication (enabled/disabled modes, protected routes, error responses, exemptions, header/query parameter access).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 24.59% 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 'Python — Security Middleware tests' is directly related to the changeset, which adds a comprehensive unit test suite for web security features as described in the summary.
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 test/security-middleware

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.

@nitrobass24 nitrobass24 changed the title Add security middleware unit tests (47 tests) PR 1: Python — Security Middleware tests May 1, 2026
@nitrobass24
Copy link
Copy Markdown
Owner Author

@CodeRabbit review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@nitrobass24
Copy link
Copy Markdown
Owner Author

@CodeRabbit review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/python/tests/unittests/test_web/test_security.py`:
- Around line 326-385: Both tests currently register custom before_request hooks
instead of exercising the real middleware; replace those hooks to call
install_rate_limiting so you validate production behavior. Modify
test_rate_limit_returns_429_with_retry_after to call install_rate_limiting(app,
max_requests=2, window_seconds=60) (or monkeypatch the _RateLimiter constructor
to return a limiter with those thresholds) and then drive requests with TestApp
and assert status 429 and presence of "Retry-After". Modify
test_x_forwarded_for_used_when_trusted to call install_rate_limiting(app,
max_requests=2, window_seconds=60, trust_x_forwarded_for=True) (or patch
configuration so X-Forwarded-For is trusted), then send three requests with
X-Forwarded-For and assert the third returns 429; remove the duplicated custom
hook logic in both tests and rely on install_rate_limiting, keeping assertions
for Retry-After and 429 as-is.
🪄 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: 173e7bf4-6e59-4725-8289-2518824cac7b

📥 Commits

Reviewing files that changed from the base of the PR and between cf856e6 and 09e6f6f.

📒 Files selected for processing (1)
  • src/python/tests/unittests/test_web/test_security.py

Comment on lines +326 to +385
def test_rate_limit_returns_429_with_retry_after(self):
app = _make_app_with_route()
limiter = _RateLimiter(max_requests=2, window_seconds=60)

@app.hook("before_request")
def _rate_limit():
ip = bottle.request.environ.get("REMOTE_ADDR", "127.0.0.1")
if not limiter.is_allowed(ip):
retry = limiter.retry_after(ip)
resp = bottle.HTTPError(429, "Rate limit exceeded")
resp.headers["Retry-After"] = str(retry)
raise resp

test_app = TestApp(app)
test_app.get("/test", extra_environ={"REMOTE_ADDR": "10.0.0.1"})
test_app.get("/test", extra_environ={"REMOTE_ADDR": "10.0.0.1"})
resp = test_app.get(
"/test",
extra_environ={"REMOTE_ADDR": "10.0.0.1"},
expect_errors=True,
)
self.assertEqual(resp.status_int, 429)
self.assertIn("Retry-After", resp.headers)

def test_x_forwarded_for_used_when_trusted(self):
app = _make_app_with_route()
limiter = _RateLimiter(max_requests=2, window_seconds=60)

@app.hook("before_request")
def _rate_limit():
ip = None
forwarded = bottle.request.get_header("X-Forwarded-For")
if forwarded:
ip = forwarded.split(",")[0].strip()
if not ip:
ip = bottle.request.environ.get("REMOTE_ADDR", "127.0.0.1")
if not limiter.is_allowed(ip):
raise bottle.HTTPError(429, "Rate limit exceeded")

test_app = TestApp(app)

# Requests with X-Forwarded-For should use the forwarded IP
test_app.get(
"/test",
headers={"X-Forwarded-For": "192.168.1.100"},
extra_environ={"REMOTE_ADDR": "127.0.0.1"},
)
test_app.get(
"/test",
headers={"X-Forwarded-For": "192.168.1.100"},
extra_environ={"REMOTE_ADDR": "127.0.0.1"},
)
# Third request from same forwarded IP should be rejected
resp = test_app.get(
"/test",
headers={"X-Forwarded-For": "192.168.1.100"},
extra_environ={"REMOTE_ADDR": "127.0.0.1"},
expect_errors=True,
)
self.assertEqual(resp.status_int, 429)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Rate-limiting middleware behavior is not fully validated here.

test_rate_limit_returns_429_with_retry_after and test_x_forwarded_for_used_when_trusted build custom before_request hooks instead of invoking install_rate_limiting(...). That means these assertions can still pass even if the real middleware’s IP extraction / 429 / Retry-After logic regresses.

Please switch these to exercise install_rate_limiting directly (configure or patch limiter thresholds as needed) so the tests verify production behavior, not duplicated test-local logic.

Based on learnings: "When adding a feature, add unit tests for all new logic covering happy path, edge cases, and error/validation paths; for new API endpoints, add integration tests using WebTest/TestApp".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/python/tests/unittests/test_web/test_security.py` around lines 326 - 385,
Both tests currently register custom before_request hooks instead of exercising
the real middleware; replace those hooks to call install_rate_limiting so you
validate production behavior. Modify
test_rate_limit_returns_429_with_retry_after to call install_rate_limiting(app,
max_requests=2, window_seconds=60) (or monkeypatch the _RateLimiter constructor
to return a limiter with those thresholds) and then drive requests with TestApp
and assert status 429 and presence of "Retry-After". Modify
test_x_forwarded_for_used_when_trusted to call install_rate_limiting(app,
max_requests=2, window_seconds=60, trust_x_forwarded_for=True) (or patch
configuration so X-Forwarded-For is trusted), then send three requests with
X-Forwarded-For and assert the third returns 429; remove the duplicated custom
hook logic in both tests and rely on install_rate_limiting, keeping assertions
for Retry-After and 429 as-is.

@nitrobass24 nitrobass24 merged commit 9e95c56 into develop May 1, 2026
18 checks passed
@nitrobass24 nitrobass24 deleted the test/security-middleware branch May 1, 2026 19:01
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