mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-08-04 14:57:42 +00:00
🛡️ fix: Match the full whitespace set in messageFilter starter patterns
RE2's `\s` omits the vertical tab and `\p{Zs}` omits U+2028, U+2029, and
U+FEFF, so a separator built from one of those characters slipped past the
`api-key` and `Bearer` starter patterns and reached the model. Broaden the
starter whitespace class to the full JavaScript whitespace set so those
separators are covered again.
This commit is contained in:
parent
67977a8c05
commit
3ae8dbef28
3 changed files with 22 additions and 8 deletions
|
|
@ -894,9 +894,12 @@ endpoints:
|
|||
# # (optional) Pick a subset of the starter catalog by id; omit to
|
||||
# # enable all starters (sk_prefix, bearer_header, api_key_header).
|
||||
# starterPatterns: [sk_prefix, bearer_header, api_key_header]
|
||||
# # (optional) Operator-defined patterns. Each entry needs id,
|
||||
# # label, and a regex in RE2 syntax (backreferences and lookaround
|
||||
# # are not supported); the regex is validated at config load time.
|
||||
# # (optional) Operator-defined patterns. Each entry needs id, label,
|
||||
# # and a regex in RE2 syntax and semantics (RE2 is a linear-time engine
|
||||
# # with no catastrophic backtracking; a few escapes such as \p, \A, and
|
||||
# # \s differ from JavaScript). Backreferences and lookaround are not
|
||||
# # supported; the regex is validated against the RE2 engine at config
|
||||
# # load time and a pattern it cannot compile is rejected.
|
||||
# customPatterns:
|
||||
# - id: anthropic_api_key
|
||||
# label: Anthropic API key
|
||||
|
|
|
|||
|
|
@ -94,9 +94,15 @@ describe('messageFilterPii middleware', () => {
|
|||
expect(capturedRes.status).toBe(400);
|
||||
});
|
||||
|
||||
it('rejects an api-key header separated by non-ASCII whitespace', () => {
|
||||
const nbsp = String.fromCharCode(0x00a0);
|
||||
const { capturedRes, nextCalls } = runMiddleware({}, { text: `api-key:${nbsp}foo123bar` });
|
||||
it.each([
|
||||
['U+00A0 no-break space', 0x00a0],
|
||||
['U+000B vertical tab', 0x000b],
|
||||
['U+2028 line separator', 0x2028],
|
||||
['U+2029 paragraph separator', 0x2029],
|
||||
['U+FEFF zero-width no-break space', 0xfeff],
|
||||
])('rejects an api-key header separated by %s', (_label, code) => {
|
||||
const ws = String.fromCharCode(code);
|
||||
const { capturedRes, nextCalls } = runMiddleware({}, { text: `api-key:${ws}foo123bar` });
|
||||
expect(nextCalls).toBe(0);
|
||||
expect(capturedRes.status).toBe(400);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -29,17 +29,22 @@ export function configureMessageFilterRegexValidator(): void {
|
|||
|
||||
type CompiledPattern = { id: string; label: string; pattern: RE2JS };
|
||||
|
||||
const WHITESPACE = '\\s\\p{Zs}\\x0B\\x{2028}\\x{2029}\\x{FEFF}';
|
||||
|
||||
const STARTER_PATTERNS: CompiledPattern[] = [
|
||||
{ id: 'sk_prefix', label: 'sk- prefix token', pattern: RE2JS.compile('\\b(sk-)[a-zA-Z0-9_-]+') },
|
||||
{
|
||||
id: 'bearer_header',
|
||||
label: 'Bearer token',
|
||||
pattern: RE2JS.compile('\\b(Bearer )[^\\s\\p{Zs}"\']+', RE2JS.CASE_INSENSITIVE),
|
||||
pattern: RE2JS.compile(`\\b(Bearer )[^${WHITESPACE}"']+`, RE2JS.CASE_INSENSITIVE),
|
||||
},
|
||||
{
|
||||
id: 'api_key_header',
|
||||
label: 'api-key header',
|
||||
pattern: RE2JS.compile('\\b(api-key:?[\\s\\p{Zs}]+)[^\\s\\p{Zs}"\']+', RE2JS.CASE_INSENSITIVE),
|
||||
pattern: RE2JS.compile(
|
||||
`\\b(api-key:?[${WHITESPACE}]+)[^${WHITESPACE}"']+`,
|
||||
RE2JS.CASE_INSENSITIVE,
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue