🐛 bug: Fix CORS subdomain wildcard boundary#3690
Conversation
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughRefactors CORS middleware wildcard-origin handling to centralize origin trimming and improve wildcard/subdomain processing; tightens subdomain.match validation with explicit early-return checks; updates tests to accept whitespace-padded wildcard entries and add malformed/empty subdomain cases. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant CORS_Middleware
participant SubdomainMatcher
Client->>CORS_Middleware: Request with Origin
CORS_Middleware->>CORS_Middleware: Trim origin -> trimmedOrigin
alt Exact allowlist entry
CORS_Middleware-->>Client: Set Access-Control-Allow-Origin = Origin
else Wildcard pattern found ("://*.")
CORS_Middleware->>CORS_Middleware: Build withoutWildcard (remove "*.")
CORS_Middleware->>CORS_Middleware: normalizeOrigin(withoutWildcard)
CORS_Middleware->>SubdomainMatcher: match(prefix, suffix, origin)
alt match == true
CORS_Middleware-->>Client: Set Access-Control-Allow-Origin = Origin
else
CORS_Middleware-->>Client: Do not set Access-Control-Allow-Origin
end
else No match
CORS_Middleware-->>Client: Do not set Access-Control-Allow-Origin
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. 📜 Recent review detailsConfiguration used: CodeRabbit UI 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
✨ Finishing Touches
🧪 Generate unit 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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Summary of Changes
Hello @gaby, 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 addresses a potential vulnerability or incorrect behavior in the CORS subdomain wildcard handling. The primary goal is to harden the existing logic to ensure that only truly valid subdomains are matched, thereby preventing unintended access or security bypasses. The changes involve refining the subdomain matching algorithm and introducing new regression tests to validate the robustness of the fix against malformed subdomain patterns.
Highlights
- Enhanced CORS Subdomain Validation: The logic for matching subdomains in CORS has been strengthened to correctly identify and reject malformed or invalid subdomain patterns, improving security and reliability.
- Improved
subdomain.matchFunction: Thesubdomain.matchmethod inmiddleware/cors/utils.gonow includes explicit checks for origin length, prefix/suffix matching, and proper domain normalization to ensure accurate boundary verification. - New Regression Tests for Malformed Subdomains: Comprehensive test cases have been added in
cors_test.goandutils_test.goto specifically cover scenarios with malformed subdomains, ensuring the fix prevents future regressions.
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 in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| 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 issue 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
-
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. ↩
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3690 +/- ##
==========================================
+ Coverage 91.98% 92.00% +0.01%
==========================================
Files 114 114
Lines 11485 11504 +19
==========================================
+ Hits 10565 10584 +19
Misses 661 661
Partials 259 259
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Code Review
This pull request aims to fix a CORS subdomain wildcard vulnerability. While the intent is correct and regression tests have been added, the implementation of the fix in subdomain.match is still flawed and does not correctly validate the subdomain boundary. A malicious origin like http://evil.comexample.com would still be allowed for a pattern http://*.example.com. I've provided a corrected implementation for subdomain.match that properly checks for the domain separator.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request aims to fix a CORS subdomain wildcard vulnerability. The changes are a good step, correctly adjusting index calculations and improving the matching logic in utils.go. However, I've identified a critical bug in the same code block where an index from the raw origin string is used on a normalized string of a potentially different length. This can break subdomain matching when origins are configured with extra whitespace. I've left a detailed comment on this issue. Addressing this bug is crucial for the feature to work reliably.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request effectively hardens the CORS subdomain wildcard handling, addressing a security vulnerability where a malformed origin could bypass the policy. The changes in subdomain.match to verify host boundaries are correct, and the logic for parsing wildcard origins has been improved. The addition of regression tests is also a great practice. My only suggestion is to replace magic numbers with len() calls to improve code readability and maintainability.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request effectively hardens the CORS subdomain wildcard handling, fixing a potential vulnerability where a malformed origin could be incorrectly allowed. The changes in subdomain.match correctly enforce that a dot separator must exist for a valid subdomain match. The addition of regression tests for malformed subdomains is also a great improvement. I have one suggestion to slightly improve performance and readability in the match function by reordering the checks.
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request provides a solid fix for a potential security issue in CORS subdomain wildcard handling. The logic for parsing and matching wildcard origins has been correctly hardened, and the new regression tests ensure this behavior is maintained. The changes are well-implemented. I have one minor suggestion to improve code readability.
There was a problem hiding this comment.
Pull Request Overview
This PR fixes a security vulnerability in CORS subdomain wildcard handling by implementing proper host boundary validation. The fix prevents malicious domains from bypassing CORS restrictions by exploiting loose subdomain matching.
Key changes:
- Enhanced the
subdomain.match()method to require a dot separator before the domain suffix - Updated test cases to remove leading dots from suffix patterns for consistency
- Added regression tests to verify that malformed subdomains are properly rejected
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| middleware/cors/utils.go | Implements stricter subdomain matching with dot boundary validation |
| middleware/cors/cors.go | Updates subdomain parsing logic to handle wildcard patterns correctly |
| middleware/cors/utils_test.go | Updates test cases and adds regression test for malformed subdomain attacks |
| middleware/cors/cors_test.go | Adds integration test to verify malformed subdomain rejection |
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (2)
middleware/cors/utils.go (1)
64-77: Dot-boundary enforcement is correct; length-first check prevents off-by-one.This fixes the previously exploitable suffix match by requiring a '.' immediately before the suffix and short-circuiting on insufficient length. Good separation of prefix/suffix checks and clear early returns.
middleware/cors/cors.go (1)
49-58: Whitespace-trim + scheme-based split fixes prior index misuse.Computing the wildcard removal on
trimmedOrigin, then deriving the scheme boundary fromnormalizedOriginaddresses the earlier bug where indices from a raw origin (with spaces) were used against normalized strings.
🧹 Nitpick comments (3)
middleware/cors/utils.go (1)
15-28: Docstring is misleading vs behavior (IPv6 ports, path/query/fragment preservation).The comment says “removes the scheme and port,” but the implementation:
- Preserves IPv6 ports (by design with the leading '[' check).
- Preserves path/query/fragment (as tests also assert).
Suggest updating the comment to reflect actual behavior for accuracy.
-// normalizeDomain removes the scheme and port from the input domain +// normalizeDomain removes the scheme and (for hostnames/IPv4) the port from the input. +// For IPv6 literals (e.g. [::1]:8080), the port is preserved to avoid ambiguity with +// the address colons. Path, query, and fragment (if present) are preserved.middleware/cors/utils_test.go (1)
138-161: Duplicate test names; make them unique for clearer failures.Two cases are both named “match with different scheme”. Rename to distinguish which side has the https/http mismatch.
- { - name: "match with different scheme", + { + name: "scheme mismatch (pattern http://api. vs origin https://...)", sub: subdomain{prefix: "http://api.", suffix: "example.com"}, origin: "https://api.service.example.com", expected: false, }, { - name: "match with different scheme", + name: "scheme mismatch (pattern https:// vs origin http://...)", sub: subdomain{prefix: "https://", suffix: "example.com"}, origin: "http://api.service.example.com", expected: false, },middleware/cors/cors.go (1)
49-58: Minor readability improvement: use Replace and name the separators.This reduces mental parsing of slice indices and avoids repeating magic strings.
- trimmedOrigin := utils.Trim(origin, ' ') - if i := strings.Index(trimmedOrigin, "://*."); i != -1 { - withoutWildcard := trimmedOrigin[:i+len("://")] + trimmedOrigin[i+len("://*."):] + trimmedOrigin := utils.Trim(origin, ' ') + const schemeSep = "://" + const wildcardToken = "://*." + if strings.Contains(trimmedOrigin, wildcardToken) { + withoutWildcard := strings.Replace(trimmedOrigin, wildcardToken, schemeSep, 1) isValid, normalizedOrigin := normalizeOrigin(withoutWildcard) if !isValid { panic("[CORS] Invalid origin format in configuration: " + trimmedOrigin) } - schemeSep := strings.Index(normalizedOrigin, "://") + len("://") - sd := subdomain{prefix: normalizedOrigin[:schemeSep], suffix: normalizedOrigin[schemeSep:]} + schemeIdx := strings.Index(normalizedOrigin, schemeSep) + len(schemeSep) + sd := subdomain{prefix: normalizedOrigin[:schemeIdx], suffix: normalizedOrigin[schemeIdx:]} allowSOrigins = append(allowSOrigins, sd) } else {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (4)
middleware/cors/cors.go(1 hunks)middleware/cors/cors_test.go(2 hunks)middleware/cors/utils.go(1 hunks)middleware/cors/utils_test.go(2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
middleware/cors/cors_test.go (2)
client/request.go (2)
Request(46-71)Header(675-677)constants.go (5)
MethodOptions(12-12)HeaderAccessControlRequestMethod(205-205)MethodGet(5-5)HeaderOrigin(206-206)HeaderAccessControlAllowOrigin(201-201)
🔇 Additional comments (4)
middleware/cors/utils_test.go (2)
119-119: Benchmark updated to dotless suffix matches the new matcher contract.Using
suffix: "example.com"aligns with the new dot-before-suffix rule in subdomain.match. Looks good.
181-186: Nice regression: malformed subdomain is correctly rejected.This guards the
evil.comexample.comcase that previously slipped through. Good addition.middleware/cors/cors_test.go (2)
329-329: Good: config trims surrounding whitespace in AllowOrigins.This ensures wildcard parsing is resilient to common config formatting. Test reads well.
364-376: Solid negative test for malformed subdomain preflight.Confirms
http://evil.comexample.comis disallowed forhttp://*.example.com. This directly covers the boundary bug.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
middleware/cors/utils.go (2)
65-68: Tighten the length guard to reject empty-label cases like http://.example.comAs written, http://.example.com will pass: it satisfies prefix/suffix and the character before suffix is '.', but there is no label before that dot. Require at least one label character and a dot before the suffix by bumping the threshold by +1.
Apply this diff:
- // Not a subdomain if not long enough for a dot separator. - if len(o) <= len(s.prefix)+len(s.suffix) { + // Not a subdomain if not long enough for "label + dot" before the suffix. + // Need at least one character label and a '.' before the suffix. + if len(o) <= len(s.prefix)+len(s.suffix)+1 { return false }
74-76: Optional: Assert a non-empty label before the dot for extra hardeningIf you want an explicit check in addition to the stricter length guard, verify that there’s at least one valid label character before the '.':
- This blocks inputs like http://..example.com or http://.example.com even if they slip past other guards.
- Keep it lightweight to avoid over-validating DNS rules.
Apply this diff:
// Check for the dot separator. suffixStartIndex := len(o) - len(s.suffix) - return suffixStartIndex > 0 && o[suffixStartIndex-1] == '.' + if suffixStartIndex <= 0 || o[suffixStartIndex-1] != '.' { + return false + } + // Ensure at least one non-separator character before the dot. + if suffixStartIndex-2 < 0 { + return false + } + c := o[suffixStartIndex-2] + // Accept a-z, 0-9, or '-' as a minimal label-char set. + if !((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-') { + return false + } + return trueAlternatively, keep the code as-is and cover this via tests (see next comment).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
middleware/cors/utils.go(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: unit (1.25.x, macos-latest)
- GitHub Check: unit (1.25.x, windows-latest)
- GitHub Check: Compare
- GitHub Check: unit (1.25.x, macos-13)
- GitHub Check: repeated
🔇 Additional comments (1)
middleware/cors/utils.go (1)
65-76: Dot-boundary subdomain match fix looks solid
- Early length guard, separate prefix/suffix checks, and the explicit “dot before suffix” test close the prior vulnerability where evil.comexample.com could match *.example.com.
- The extra bounds check on suffixStartIndex prevents panics.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
middleware/cors/utils.go (1)
74-76: Disallow empty labels like.example.comora..example.com(optional hardening)As written, an origin such as
http://.example.comwill pass: it has the required dot before the suffix but with an empty label. Browsers won’t typically emit such Origins, but hardening here avoids edge-case mis-matches and aligns with the intent to only allow well-formed subdomains.Apply this diff to ensure there’s at least one non-dot character before the separator dot:
- // Check for the dot separator. - suffixStartIndex := len(o) - len(s.suffix) - return suffixStartIndex > 0 && o[suffixStartIndex-1] == '.' + // Check for the dot separator and ensure there's a non-empty label before it. + suffixStartIndex := len(o) - len(s.suffix) + dotIndex := suffixStartIndex - 1 + if dotIndex <= len(s.prefix) || o[dotIndex] != '.' { + return false + } + // Disallow empty label directly before the suffix, e.g., http://.example.com or http://a..example.com + if o[dotIndex-1] == '.' { + return false + } + return true
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
middleware/cors/utils.go(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: repeated
- GitHub Check: unit (1.25.x, macos-latest)
- GitHub Check: unit (1.25.x, windows-latest)
- GitHub Check: Compare
🔇 Additional comments (2)
middleware/cors/utils.go (2)
65-76: Subdomain boundary hardened correctly (dot separator + early length check) — LGTMThe added length guard and explicit dot-before-suffix check address the prior “comexample.com” bypass and make the matching semantics clear and robust.
70-72: Normalization invariants verified in CORS and CSRF code
- The
subdomain.prefixandsuffixvalues are constructed exclusively fromnormalizeOrigin(…), which returns a fully lower-casedscheme://host(including any port).- All runtime calls to
subdomain.match(o)receiveoasstrings.ToLower(c.Get(fiber.HeaderOrigin))(for CORS) or similarly lower-cased in CSRF, and HTTP Origin headers never include path/query/fragment.- Port semantics are preserved by
normalizeOrigin(it includesparsedOrigin.Host, which contains the port if specified), andHasPrefix/HasSuffixmatching therefore enforces exact port presence/absence.No further changes required.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
middleware/cors/utils.go(1 hunks)
🧰 Additional context used
🪛 GitHub Check: modernize
middleware/cors/utils.go
[failure] 88-88:
Ranging over SplitSeq is more efficient
[failure] 88-88:
Loop can be simplified using slices.Contains
🪛 GitHub Check: lint
middleware/cors/utils.go
[failure] 78-78:
File is not properly formatted (gofmt)
🪛 GitHub Actions: golangci-lint
middleware/cors/utils.go
[error] 78-78: golangci-lint: File is not properly formatted (gofmt). Run 'gofmt -w' to fix formatting.
🪛 GitHub Actions: Modernize Lint
middleware/cors/utils.go
[error] 88-88: go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest -test=false ./...: Loop can be simplified using slices.Contains
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: repeated
- GitHub Check: unit (1.25.x, macos-13)
- GitHub Check: unit (1.25.x, macos-latest)
- GitHub Check: unit (1.25.x, windows-latest)
- GitHub Check: Compare
🔇 Additional comments (3)
middleware/cors/utils.go (3)
65-72: Good early guards; prefix/suffix checks look correctThe min-length guard and subsequent HasPrefix/HasSuffix checks are in the right order. This sets up the boundary verification reliably and addresses the prior “evil.comexample.com” suffix-only match pitfall when combined with the dot check below.
82-87: Explicit empty subdomain guard is correctThe early return on empty subdomain (e.g., origin like “https://.example.com”) is necessary and aligns with the new negative test cases. No changes needed.
88-92: Use slices.Contains to simplify empty-label checkReplace the manual loop over
strings.Split(sub, ".")with a single call toslices.Contains:- for _, label := range strings.Split(sub, ".") { - if label == "" { - return false - } - } + labels := strings.Split(sub, ".") + if slices.Contains(labels, "") { + return false + }And add the
"slices"import alongside"strings":import ( "net/url" "slices" "strings" )Before merging, please manually verify:
- Your build/CI environment is running Go 1.21 or later (the
slicespackage was added in Go 1.21).- The file is correctly formatted (e.g. run
gofmt -l middleware/cors/utils.goorgo fmt).
sixcolors
left a comment
There was a problem hiding this comment.
Analysis of Wildcard Behavior: Current vs. Proposed
This PR addresses a potential security "foot-gun" in how wildcard subdomains are handled, making the behavior safer and more predictable for the CORS middleware.
1. Current Behavior in CORS and CSRF Middleware: The Lenient, Suffix-Based Match
Currently, both the CORS and CSRF middlewares use a simple prefix and suffix check for wildcards. This was the original design.
- Behavior: An origin like
https://*.example.comis treated as a pattern that must start withhttps://and end with.example.com. - What it Matches:
https://api.example.com(Correct)https://v1.api.example.com(Correct)
- The "Foot-Gun":
- It also matches
https://example.com. This is becausehttps://example.comstarts with the prefix and ends with the suffix, with an empty string in between where the wildcard*is. - It could also match
https://some-ext.example.comif the pattern was*ext.example.com.
- It also matches
While this was the original intention, it violates the principle of least privilege. A developer specifying *.example.com almost always intends to allow subdomains only, not the apex/root domain itself. This unexpected match could lead to security vulnerabilities.
2. This PR's Change (New CORS Behavior): The Stricter, Boundary-Enforced Match
This PR updates the CORS middleware to fix this potential "foot-gun." It now enforces that the wildcard * must represent one or more complete and valid DNS labels (the parts of a domain between dots).
- Behavior: An origin like
https://*.example.comrequires the incoming origin to have the same scheme and suffix, but critically, it also requires a.dot separator immediately before the suffix part that is matched. - What it Matches:
https://api.example.com(Correct)https://v1.api.example.com(Correct)
- What it Correctly Rejects:
- It does not match
https://example.combecause there is no subdomain label and no dot before.example.com. - It does not match
https://.example.combecause the subdomain label is empty.
- It does not match
This new behavior is more intuitive, secure, and aligns with what developers typically expect from a subdomain wildcard.
Is the New Behavior the Best? Does it Match Other Frameworks?
Yes, the new, stricter behavior introduced by this PR is not only better but is also the standard convention adopted by most major web frameworks and security libraries.
- Express.js (
corspackage): Enforces subdomain boundaries and correctly handles multiple levels. - Django (
django-cors-headers): Encourages explicit regexes that enforce subdomain boundaries. - Ruby on Rails (
rack-cors): Uses regex that correctly matches single and multiple-level subdomains but not the apex domain. - OWASP CSRFGuard: Recommends treating
*as a wildcard for a single, valid subdomain label.
Final Recommendation
Approved. This change is a clear security and usability improvement for the CORS middleware.
I strongly recommend opening a follow-up PR for the CSRF middleware to adopt this same stricter matching logic. This will ensure consistent, secure behavior across the entire framework.
Summary