Skip to content

feat: implement rate limiting, WAF protection, and CI security scanni… - #1200

Merged
famvilianity-eng merged 2 commits into
StellarCheckMate:mainfrom
paulinaapeh8:feature/983-984-rate-limiting-and-security-scanning
Aug 3, 2026
Merged

feat: implement rate limiting, WAF protection, and CI security scanni…#1200
famvilianity-eng merged 2 commits into
StellarCheckMate:mainfrom
paulinaapeh8:feature/983-984-rate-limiting-and-security-scanning

Conversation

@paulinaapeh8

Copy link
Copy Markdown
Contributor

…ng (#983 #984)

Issue #983 — Rate Limiting & DDoS Protection

  • Add oracle-service/src/middleware/rate_limit.rs

    • Token-bucket rate limiter per incoming HTTP request
    • Per-IP: 100 req/min (capacity=100, refill=100/60 tok/s)
    • Per-API-key (X-Api-Key header): 1000 req/min
    • Returns 429 Too Many Requests with X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, Retry-After headers
    • Background task prunes stale bucket entries every 60s
  • Add oracle-service/src/middleware/waf.rs

    • Burst guard: blocks >20 req/s from a single IP (429)
    • Body size guard: rejects Content-Length > 1 MiB (413)
    • URI length guard: rejects URIs > 2048 chars (400)
    • Null-byte guard: rejects URIs containing \0 (400)
  • Add oracle-service/src/middleware/mod.rs — module glue

  • Wire both layers into the axum router in main.rs

  • Add oracle-service/tests/rate_limiting.rs (8 integration tests)

    • test_ip_rate_limit_enforced
    • test_api_key_rate_limit_higher
    • test_rate_limit_headers_present
    • test_different_ips_independent
    • test_waf_blocks_large_body
    • test_waf_blocks_long_uri
    • test_waf_blocks_burst
    • test_full_stack_normal_traffic_passes

Issue #984 — CI/CD Security Scanning

  • Add .github/workflows/security-scanning.yml

    • Job 1: cargo-audit — fails CI on vulnerable dependencies
    • Job 2: cargo-deny — fails CI on license/ban violations
    • Job 3: semgrep — fails CI on SAST findings (p/rust + p/secrets)
    • Job 4: security-report — consolidated artifact on push to main
    • workflow_dispatch override: set override_vulnerabilities=true +
      justification to acknowledge known risks without blocking the pipeline
    • All scan results uploaded as 90-day artifacts
  • Update scripts/security-scan.sh

    • Add semgrep SAST step (skips gracefully if not installed)
    • Add cargo-deny step
    • Improved output formatting and report paths

Pre-existing fixes (needed to compile)

  • oracle-service/src/oracle/mod.rs: remove duplicate pub mod lichess_client
  • oracle-service/src/oracle/lichess_client.rs: rewrite with correct imports and proper with_config() constructor (was referencing undefined cfg var)
  • oracle-service/src/oracle/provider_error.rs: add From impl
  • oracle-service/src/poller.rs: handle new RateLimited/ConcurrencyLimitReached variants in classify_lichess_error and classify_chess_com_error
  • oracle-service/tests/e2e_tests.rs: fix ProviderError → ChessComError, fix dead-letter field access (e.entry.match_id, e.entry.attempts)
  • oracle-service/tests/load_tests.rs: fix import paths to sub-modules

All 115 tests pass.

Summary

Provide a short description of the change and the problem it fixes.

Related Issue

Link the issue number or task this PR addresses.

What changed

  • Contracts:
  • Tests:
  • Docs:
  • Events / API / storage:

Verification

  • What did you run to verify this change?
    • cargo test -p escrow
    • cargo test -p oracle
    • cargo fmt
    • cargo clippy

Checklist

  • I added or updated tests covering this change.
  • I updated documentation or confirmed no docs update is needed.
  • I confirmed any event/API/storage changes are documented and backward-compatible.
  • I manually verified the contract or CLI behavior where applicable.
  • I linked this PR to the related issue.
  • I included notes on any TTL or storage assumptions affecting contract state.

Notes

Add any additional details, risks, or follow-up tasks here.
Closes #983
Closes #984

…ng (StellarCheckMate#983 StellarCheckMate#984)

## Issue StellarCheckMate#983 — Rate Limiting & DDoS Protection

- Add oracle-service/src/middleware/rate_limit.rs
  - Token-bucket rate limiter per incoming HTTP request
  - Per-IP: 100 req/min (capacity=100, refill=100/60 tok/s)
  - Per-API-key (X-Api-Key header): 1000 req/min
  - Returns 429 Too Many Requests with X-RateLimit-Limit,
    X-RateLimit-Remaining, X-RateLimit-Reset, Retry-After headers
  - Background task prunes stale bucket entries every 60s

- Add oracle-service/src/middleware/waf.rs
  - Burst guard: blocks >20 req/s from a single IP (429)
  - Body size guard: rejects Content-Length > 1 MiB (413)
  - URI length guard: rejects URIs > 2048 chars (400)
  - Null-byte guard: rejects URIs containing \0 (400)

- Add oracle-service/src/middleware/mod.rs — module glue
- Wire both layers into the axum router in main.rs

- Add oracle-service/tests/rate_limiting.rs (8 integration tests)
  - test_ip_rate_limit_enforced
  - test_api_key_rate_limit_higher
  - test_rate_limit_headers_present
  - test_different_ips_independent
  - test_waf_blocks_large_body
  - test_waf_blocks_long_uri
  - test_waf_blocks_burst
  - test_full_stack_normal_traffic_passes

## Issue StellarCheckMate#984 — CI/CD Security Scanning

- Add .github/workflows/security-scanning.yml
  - Job 1: cargo-audit — fails CI on vulnerable dependencies
  - Job 2: cargo-deny  — fails CI on license/ban violations
  - Job 3: semgrep     — fails CI on SAST findings (p/rust + p/secrets)
  - Job 4: security-report — consolidated artifact on push to main
  - workflow_dispatch override: set override_vulnerabilities=true +
    justification to acknowledge known risks without blocking the pipeline
  - All scan results uploaded as 90-day artifacts

- Update scripts/security-scan.sh
  - Add semgrep SAST step (skips gracefully if not installed)
  - Add cargo-deny step
  - Improved output formatting and report paths

## Pre-existing fixes (needed to compile)

- oracle-service/src/oracle/mod.rs: remove duplicate pub mod lichess_client
- oracle-service/src/oracle/lichess_client.rs: rewrite with correct imports
  and proper with_config() constructor (was referencing undefined cfg var)
- oracle-service/src/oracle/provider_error.rs: add From<LichessError> impl
- oracle-service/src/poller.rs: handle new RateLimited/ConcurrencyLimitReached
  variants in classify_lichess_error and classify_chess_com_error
- oracle-service/tests/e2e_tests.rs: fix ProviderError → ChessComError,
  fix dead-letter field access (e.entry.match_id, e.entry.attempts)
- oracle-service/tests/load_tests.rs: fix import paths to sub-modules

All 115 tests pass.
@drips-wave

drips-wave Bot commented Jul 28, 2026

Copy link
Copy Markdown

@paulinaapeh8 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@yahia008

Copy link
Copy Markdown
Collaborator

hi fix conflict

@famvilianity-eng
famvilianity-eng merged commit 897c542 into StellarCheckMate:main Aug 3, 2026
11 of 17 checks passed
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.

Add CI/CD Pipeline Automated Security Scanning Implement Automated Rate Limiting and DDoS Protection

3 participants