Skip to content

fix Client settings UI to accept * as accepted headers#2400

Merged
akshaydeo merged 1 commit into
mainfrom
03-30-fix_client_settings_ui_to_accept_as_accepted_headers
Mar 30, 2026
Merged

fix Client settings UI to accept * as accepted headers#2400
akshaydeo merged 1 commit into
mainfrom
03-30-fix_client_settings_ui_to_accept_as_accepted_headers

Conversation

@akshaydeo
Copy link
Copy Markdown
Contributor

@akshaydeo akshaydeo commented Mar 30, 2026

Summary

Relaxes header filter validation to allow wildcard patterns that match security headers while maintaining strict validation for exact security header names. This change recognizes that security headers are unconditionally stripped at runtime regardless of configuration.

Changes

  • Modified validateHeaderFilterConfig to only reject exact security header names in allowlist/denylist
  • Removed validation logic that prevented wildcard patterns from matching security headers
  • Updated function comments to clarify that wildcard patterns are allowed because security headers are always stripped at runtime
  • Fixed error message in UI to correctly reference "client config" instead of "core config"

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Chore/CI

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (Next.js)
  • Docs

How to test

Validate that wildcard patterns in header filter configuration are now accepted:

# Core/Transports
go version
go test ./transports/bifrost-http/handlers/...

# Test specific scenarios:
# - Wildcard patterns like "authorization*" should be accepted
# - Exact security header names like "authorization" should still be rejected
# - Invalid wildcard syntax should still be rejected

# UI
cd ui
pnpm i || npm i
pnpm test || npm test
pnpm build || npm run build

Screenshots/Recordings

N/A - Backend validation changes only

Breaking changes

  • Yes
  • No

Related issues

N/A

Security considerations

This change maintains security by ensuring security headers are always stripped at runtime in ctx.go, regardless of allowlist/denylist configuration. The validation change only affects configuration acceptance, not runtime behavior.

Checklist

  • I read docs/contributing/README.md and followed the guidelines
  • I added/updated tests where appropriate
  • I updated documentation where needed
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@akshaydeo akshaydeo marked this pull request as ready for review March 30, 2026 15:37
@github-actions
Copy link
Copy Markdown
Contributor

🧪 Test Suite Available

This PR can be tested by a repository admin.

Run tests for PR #2400

Copy link
Copy Markdown
Contributor Author

akshaydeo commented Mar 30, 2026

Merge activity

  • Mar 30, 3:38 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Mar 30, 3:38 PM UTC: @akshaydeo merged this pull request with Graphite.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 30, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a86b93e6-62e4-4320-9b2d-0171af75b620

📥 Commits

Reviewing files that changed from the base of the PR and between ba19555 and 9d1685e.

📒 Files selected for processing (3)
  • transports/bifrost-http/handlers/config.go
  • transports/bifrost-http/handlers/config_headerfilter_test.go
  • ui/app/workspace/config/views/clientSettingsView.tsx

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Refined header-filter validation: only exact security header names are treated as configured; wildcard patterns that match known security headers are allowed because those headers are removed at runtime.
    • Clarified error text shown when saving client configuration failures occur (now references "client" config).

Walkthrough

Header-filter validation was changed to only consider exact security header names in allowlists/denylists (wildcards are not expanded during validation). Tests were updated to reflect runtime-stripped wildcard behavior. A UI toast message was corrected from "core" to "client" config on save failure.

Changes

Cohort / File(s) Summary
Header Filter Validation
transports/bifrost-http/handlers/config.go, transports/bifrost-http/handlers/config_headerfilter_test.go
Validation now checks only exact matches against known security header names; wildcard patterns in allowlist/denylist are not expanded during validation. Tests updated to expect success where patterns are runtime-stripped.
UI Error Message
ui/app/workspace/config/views/clientSettingsView.tsx
Changed error toast text from "Failed to save core config: …" to "Failed to save client config: …".

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 I nibble code where wildcards play,
I trim the names that stray away.
Exact matches kept, patterns spared for runtime,
A tiny toast fixed — hop, all's fine! 🥕✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 03-30-fix_client_settings_ui_to_accept_as_accepted_headers

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

@akshaydeo akshaydeo merged commit 7e3e1d2 into main Mar 30, 2026
17 of 19 checks passed
@akshaydeo akshaydeo deleted the 03-30-fix_client_settings_ui_to_accept_as_accepted_headers branch March 30, 2026 15:38
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 30, 2026

Confidence Score: 2/5

Not safe to merge — the runtime security claim underpinning the change is incorrect for authorization, and the change could allow credential injection to upstream providers.

A P1 security defect: the PR removes a validation guard based on the incorrect premise that authorization is always stripped at runtime, but ctx.go's securityDenylist does not include authorization. This opens a real forwarding path for raw Authorization headers to upstream AI providers.

transports/bifrost-http/handlers/config.go and transports/bifrost-http/lib/ctx.go (not in diff, but is the root cause).

Important Files Changed

Filename Overview
transports/bifrost-http/handlers/config.go Relaxes wildcard validation for security headers, but the justification ("always stripped at runtime") is incorrect — authorization is absent from the runtime securityDenylist, so wildcards like authorization* in the allowlist can cause authorization headers to be forwarded to upstream providers.
transports/bifrost-http/handlers/config_headerfilter_test.go Tests correctly reflect the new (relaxed) validation behavior; the tests themselves are well-structured, but they validate a behaviour that contains a security gap.
ui/app/workspace/config/views/clientSettingsView.tsx Trivial one-line fix correcting "core config" to "client config" in the error toast message — correct and safe.

Reviews (1): Last reviewed commit: "fix Client settings UI to accept * as ac..." | Re-trigger Greptile

Comment on lines +835 to 846
// Check allowlist for exact security header names.
// Wildcard patterns are allowed — security headers are always stripped at runtime
// unconditionally in ctx.go, regardless of allowlist/denylist configuration.
for _, header := range config.Allowlist {
headerLower := strings.ToLower(strings.TrimSpace(header))
if strings.Contains(headerLower, "*") {
for _, secHeader := range securityHeaders {
if lib.HeaderMatchesPattern(headerLower, secHeader) && !slices.Contains(foundSecurityHeaders, secHeader) {
foundSecurityHeaders = append(foundSecurityHeaders, secHeader)
}
}
continue
}
if slices.Contains(securityHeaders, headerLower) {
foundSecurityHeaders = append(foundSecurityHeaders, headerLower)
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 authorization is NOT in the runtime security denylist

The PR comment says "security headers are always stripped at runtime unconditionally in ctx.go", but that's only true for most of the security headers — authorization is not in the securityDenylist map in ctx.go:

// ctx.go ~line 146
securityDenylist := map[string]bool{
    "proxy-authorization": true,
    "cookie":              true,
    "host":                true,
    "content-length":      true,
    "connection":          true,
    "transfer-encoding":   true,
    "x-api-key":           true,
    "x-goog-api-key":      true,
    "x-bf-api-key":        true,
    "x-bf-api-key-id":     true,
    "x-bf-vk":             true,
    // ← "authorization" is absent
}

The direct-header-forwarding path in ctx.go (lines ~358–378) only guards against securityDenylist headers. Because authorization is absent from that map, a request-level client that sends Authorization: Bearer sk-ant-… will have that header forwarded directly to the upstream AI provider whenever:

  1. The allowlist contains a wildcard such as authorization* or * (now accepted by this PR), and
  2. The authorization header doesn't happen to carry a governance virtual-key prefix (which causes return true early at line 231–237, before the forwarding section is reached).

In practice this means: if an admin configures authorization* in the header-filter allowlist (newly valid under this change), any API caller can inject an arbitrary Authorization header and Bifrost will forward it to the upstream provider — overriding Bifrost's own credential management.

The original validation that rejected wildcard patterns matching security headers was the correct guard. If the intent is to allow authorization* for non-security custom headers, authorization should first be added to the securityDenylist in ctx.go so the runtime actually enforces the strip unconditionally.

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