Skip to content

🛡️ Sentinel: [HIGH] Fix CORS wildcard subdomain vulnerability#197

Draft
EffortlessSteven wants to merge 1 commit intomainfrom
sentinel-fix-cors-wildcard-2296705249216256093
Draft

🛡️ Sentinel: [HIGH] Fix CORS wildcard subdomain vulnerability#197
EffortlessSteven wants to merge 1 commit intomainfrom
sentinel-fix-cors-wildcard-2296705249216256093

Conversation

@EffortlessSteven
Copy link
Member

🛡️ Sentinel: [HIGH] Fix CORS wildcard subdomain vulnerability

🚨 Severity: HIGH
💡 Vulnerability: CORS configuration using wildcard subdomains (e.g., https://*.example.com) allowed unauthorized origins like https://evilexample.com because the validation logic only checked if the origin string ended with the domain suffix.
🎯 Impact: Attackers could bypass CORS protections by registering domains that end with the target domain name, potentially accessing sensitive API endpoints or data.
🔧 Fix: Updated the is_origin_allowed logic in both crates/app-http and crates/http-middleware to explicitly verify that the matching suffix is preceded by a dot (.), ensuring only valid subdomains are accepted.
✅ Verification: Added a new regression test file crates/app-http/tests/cors_reproduction.rs and updated unit tests in crates/http-middleware/src/cors.rs to confirm that evilexample.com is rejected while api.example.com remains allowed. All tests passed.


PR created automatically by Jules for task 2296705249216256093 started by @EffortlessSteven

This commit addresses a security vulnerability where CORS wildcard matching
(e.g., `*.example.com`) incorrectly allowed domains that ended with the suffix
but were not valid subdomains (e.g., `evilexample.com`).

Changes:
- Enforce that wildcard suffix matches are preceded by a dot (`.`) in `app-http`.
- Apply the same fix to `http-middleware` to resolve code duplication issues.
- Add regression tests in both crates to verify the fix and prevent recurrence.
- Document the vulnerability and learning in `.jules/sentinel.md`.

The fix ensures that only true subdomains are allowed when using wildcard patterns.
@google-labs-jules
Copy link

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

Copilot AI review requested due to automatic review settings February 14, 2026 02:43
@coderabbitai
Copy link

coderabbitai bot commented Feb 14, 2026

Warning

Rate limit exceeded

@EffortlessSteven has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 7 seconds before requesting another review.

⌛ 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.


Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login.

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

@gemini-code-assist
Copy link

Summary of Changes

Hello @EffortlessSteven, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request implements a critical security fix for a high-severity CORS wildcard subdomain vulnerability. The changes refine the origin validation logic to prevent malicious domains from bypassing security checks, thereby safeguarding sensitive API endpoints and data. The solution ensures that only properly formed subdomains are recognized, significantly enhancing the application's security posture against unauthorized access.

Highlights

  • CORS Wildcard Subdomain Vulnerability Fix: Addressed a high-severity vulnerability where CORS configurations using wildcard subdomains (e.g., https://*.example.com) could be bypassed by unauthorized origins like https://evilexample.com due to insufficient validation logic.
  • Enhanced Subdomain Validation: Updated the is_origin_allowed logic in both crates/app-http and crates/http-middleware to explicitly verify that a matching suffix is preceded by a dot (.), ensuring only valid subdomains are accepted.
  • Comprehensive Test Coverage: Introduced a new regression test file (crates/app-http/tests/cors_reproduction.rs) and updated existing unit tests in crates/http-middleware/src/cors.rs to confirm the fix, rejecting evilexample.com while allowing legitimate subdomains.
  • Security Documentation Update: Documented the CORS wildcard subdomain vulnerability, its learning, and prevention in the .jules/sentinel.md file.
Changelog
  • .jules/sentinel.md
    • Added a new entry detailing the CORS wildcard subdomain vulnerability, its lessons learned, and prevention strategies.
  • crates/app-http/src/middleware/cors.rs
    • Modified the is_origin_allowed function to include a check for a preceding dot when matching wildcard domains, preventing partial domain matches.
  • crates/app-http/tests/cors_reproduction.rs
    • Added a new test file to specifically reproduce and verify the fix for the CORS wildcard subdomain vulnerability.
  • crates/http-middleware/src/cors.rs
    • Modified the is_origin_allowed function to include a check for a preceding dot when matching wildcard domains, preventing partial domain matches.
    • Added a new test case within existing unit tests to confirm that evilexample.com is correctly rejected by the updated logic.
Activity
  • The pull request was automatically created by Jules for task 2296705249216256093, initiated by @EffortlessSteven.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

The pull request correctly addresses a significant CORS wildcard subdomain vulnerability by adding a check for a dot separator. The fix is implemented in both app-http and http-middleware crates, and is well-tested with new and updated tests that cover the vulnerability scenario. My feedback includes suggestions to refactor the implementation using more idiomatic Rust constructs for improved readability and safety, but the core logic of the fix is sound.

Comment on lines +228 to +234
if !origin.ends_with(wildcard_domain) {
return false;
}
// Ensure the suffix match is preceded by a dot to prevent partial domain matches
// e.g. "evilexample.com" should not match "*.example.com"
let prefix_len = origin.len() - wildcard_domain.len();
return prefix_len > 0 && origin.as_bytes()[prefix_len - 1] == b'.';

Choose a reason for hiding this comment

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

medium

This logic can be expressed more concisely and safely using strip_suffix and map_or. This avoids manual byte indexing, is more idiomatic, and less error-prone. You can move the explanatory comment from lines 231-232 to be just above the new return statement.

                    return origin.strip_suffix(wildcard_domain).map_or(false, |p| p.ends_with('.'));

Comment on lines +123 to +129
if !origin.ends_with(wildcard_domain) {
return false;
}
// Ensure the suffix match is preceded by a dot to prevent partial domain matches
// e.g. "evilexample.com" should not match "*.example.com"
let prefix_len = origin.len() - wildcard_domain.len();
return prefix_len > 0 && origin.as_bytes()[prefix_len - 1] == b'.';

Choose a reason for hiding this comment

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

medium

This logic can be expressed more concisely and safely using strip_suffix and map_or. This avoids manual byte indexing, is more idiomatic, and less error-prone. You can move the explanatory comment from lines 126-127 to be just above the new return statement.

                    return origin.strip_suffix(wildcard_domain).map_or(false, |p| p.ends_with('.'));

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a high-severity CORS security vulnerability where wildcard subdomain patterns (e.g., https://*.example.com) incorrectly allowed unauthorized origins with domains ending in the target domain (e.g., https://evilexample.com). The fix adds explicit validation to ensure the matched suffix is preceded by a dot, preventing partial domain matches.

Changes:

  • Updated CORS validation logic in both http-middleware and app-http crates to verify dot-prefix before accepting wildcard matches
  • Added regression test in new integration test file and updated existing unit tests
  • Documented the vulnerability and fix in sentinel.md for future reference

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
crates/http-middleware/src/cors.rs Fixed wildcard subdomain validation logic and added security regression test to unit tests
crates/app-http/src/middleware/cors.rs Applied identical fix to the duplicated CORS implementation in app-http crate
crates/app-http/tests/cors_reproduction.rs New integration test file verifying the security fix prevents evilexample.com from matching *.example.com
.jules/sentinel.md Documented the vulnerability, root cause, and prevention strategy for future reference

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +17 to +20
// This should NOT be allowed.
// Previously, "evilexample.com" would match because it ends with "example.com".
// The fix ensures that there is a dot separator.
assert!(!config.is_origin_allowed("https://evilexample.com"), "Security regression: evilexample.com matched *.example.com");
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

The test cases should include verification that the base domain (https://example.com) is correctly rejected when matching against *.example.com. The current fix would reject it (because the character before "example.com" would be '/' not '.'), but this important edge case is not explicitly tested. Consider adding: assert!(!config.is_origin_allowed("https://example.com")); to verify wildcards only match subdomains, not the base domain itself.

Suggested change
// This should NOT be allowed.
// Previously, "evilexample.com" would match because it ends with "example.com".
// The fix ensures that there is a dot separator.
assert!(!config.is_origin_allowed("https://evilexample.com"), "Security regression: evilexample.com matched *.example.com");
// These should NOT be allowed.
// Base domain must not match a subdomain wildcard.
assert!(
!config.is_origin_allowed("https://example.com"),
"Security regression: example.com matched *.example.com"
);
// Previously, "evilexample.com" would match because it ends with "example.com".
// The fix ensures that there is a dot separator.
assert!(
!config.is_origin_allowed("https://evilexample.com"),
"Security regression: evilexample.com matched *.example.com"
);

Copilot uses AI. Check for mistakes.
Comment on lines 291 to 304
#[test]
fn test_cors_config_subdomain_wildcard() {
let config = CorsConfig {
allowed_origins: vec!["https://*.example.com".to_string()],
..Default::default()
};
assert!(config.is_origin_allowed("https://api.example.com"));
assert!(config.is_origin_allowed("https://app.example.com"));
assert!(!config.is_origin_allowed("https://malicious.com"));

// Test for security vulnerability fix:
// "evilexample.com" ends with "example.com" but should NOT match "*.example.com"
assert!(!config.is_origin_allowed("https://evilexample.com"));
}
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

The test should also verify that the base domain (https://example.com) is correctly rejected when matching against *.example.com, and that multi-level subdomains (e.g., https://api.v2.example.com) are correctly accepted. These edge cases help ensure the fix handles all scenarios correctly and prevents future regressions.

Copilot uses AI. Check for mistakes.
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.

2 participants