@@ -42,6 +42,63 @@ MIIEpAIBAAKCAQEA7
4242 "See docs/authentication.md for how API keys are issued and rotated. No secrets in this paragraph." ;
4343 expect ( scrubSecretShapedContent ( text ) ) . toBe ( text ) ;
4444 } ) ;
45+
46+ test ( "redacts bare-KEY env assignments (CL-10756)" , ( ) => {
47+ for ( const key of [ "OPENAI_KEY" , "STRIPE_KEY" , "GITHUB_KEY" ] ) {
48+ const text = `./app/.env:7:${ key } =proj-live-value-9z` ;
49+ const out = scrubSecretShapedContent ( text ) ;
50+ expect ( out ) . toContain ( `${ key } =${ CREDENTIAL_REDACTION } ` ) ;
51+ expect ( out ) . not . toContain ( "proj-live-value-9z" ) ;
52+ }
53+ } ) ;
54+
55+ test ( "redacts credential-bearing DATABASE_URL connection strings (CL-10756)" , ( ) => {
56+ const text =
57+ "./app/.env:2:DATABASE_URL=postgres://admin:s3cret-pw@db.internal:5432/appdb" ;
58+ const out = scrubSecretShapedContent ( text ) ;
59+ expect ( out ) . toContain ( `DATABASE_URL=${ CREDENTIAL_REDACTION } ` ) ;
60+ expect ( out ) . not . toContain ( "s3cret-pw" ) ;
61+ } ) ;
62+
63+ test ( "leaves non-secret KEY words and credential-less URLs alone (CL-10756)" , ( ) => {
64+ expect ( scrubSecretShapedContent ( "MONKEY=banana" ) ) . toBe ( "MONKEY=banana" ) ;
65+ expect ( scrubSecretShapedContent ( "DATABASE_URL=sqlite:///local.db" ) ) . toBe (
66+ "DATABASE_URL=sqlite:///local.db" ,
67+ ) ;
68+ } ) ;
69+
70+ test ( "leaves scoped npm URLs and email-query URLs readable" , ( ) => {
71+ const registry = "REGISTRY_URL=https://registry.npmjs.org/@scope/pkg" ;
72+ const docs = "DOCS_URL=https://medium.com/@octocat/hello" ;
73+ const support =
74+ "SUPPORT_URL=https://example.com/help?email=dev@example.com" ;
75+ expect ( scrubSecretShapedContent ( registry ) ) . toBe ( registry ) ;
76+ expect ( scrubSecretShapedContent ( docs ) ) . toBe ( docs ) ;
77+ expect ( scrubSecretShapedContent ( support ) ) . toBe ( support ) ;
78+ } ) ;
79+
80+ test ( "redacts user:pass@host connection URLs" , ( ) => {
81+ const text = "DATABASE_URL=postgres://admin:foo@db.internal:5432/appdb" ;
82+ const out = scrubSecretShapedContent ( text ) ;
83+ expect ( out ) . toBe ( `DATABASE_URL=${ CREDENTIAL_REDACTION } ` ) ;
84+ expect ( out ) . not . toContain ( "admin:foo" ) ;
85+ } ) ;
86+
87+ test ( "redacts the whole env value when it contains its own key" , ( ) => {
88+ const text = "OPENAI_KEY=proj-OPENAI_KEY-live-value-9z" ;
89+ const out = scrubSecretShapedContent ( text ) ;
90+ expect ( out ) . toBe ( `OPENAI_KEY=${ CREDENTIAL_REDACTION } ` ) ;
91+ expect ( out ) . not . toContain ( "proj-" ) ;
92+ expect ( out ) . not . toContain ( "live-value-9z" ) ;
93+ } ) ;
94+
95+ test ( "redacts Password= DSNs that lack a scheme" , ( ) => {
96+ const text =
97+ "DATABASE_URL=Server=db.internal;Database=appdb;User Id=admin;Password=s3cret-pw;" ;
98+ const out = scrubSecretShapedContent ( text ) ;
99+ expect ( out ) . toBe ( `DATABASE_URL=${ CREDENTIAL_REDACTION } ` ) ;
100+ expect ( out ) . not . toContain ( "s3cret-pw" ) ;
101+ } ) ;
45102} ) ;
46103
47104describe ( "scrubSecretShapedValue" , ( ) => {
@@ -219,6 +276,24 @@ describe("toolResultSecretScrubPlugin", () => {
219276 expect ( result . content ) . toContain ( CREDENTIAL_REDACTION ) ;
220277 expect ( result . content ) . not . toContain ( "supersecretvalue" ) ;
221278 } ) ;
279+ test ( "scrubs bare-KEY and DATABASE_URL through the shared middleware path (CL-10756)" , async ( ) => {
280+ const plugin = toolResultSecretScrubPlugin ( ) ;
281+ if ( plugin . middleware === undefined )
282+ throw new Error ( "expected middleware plugin" ) ;
283+ const handler = plugin . middleware (
284+ next (
285+ "secrets/.env:7:OPENAI_KEY=proj-live-value-9z\nsecrets/.env:2:DATABASE_URL=postgres://admin:s3cret-pw@db.internal:5432/appdb" ,
286+ ) ,
287+ ) ;
288+ const result = await handler (
289+ { id : "c2" , name : "read_file" , arguments : { path : "secrets/.env" } } ,
290+ new AbortController ( ) . signal ,
291+ ) ;
292+ expect ( result . content ) . toContain ( `OPENAI_KEY=${ CREDENTIAL_REDACTION } ` ) ;
293+ expect ( result . content ) . toContain ( `DATABASE_URL=${ CREDENTIAL_REDACTION } ` ) ;
294+ expect ( result . content ) . not . toContain ( "proj-live-value-9z" ) ;
295+ expect ( result . content ) . not . toContain ( "s3cret-pw" ) ;
296+ } ) ;
222297 test ( "scrubs error results without stringifying object content" , async ( ) => {
223298 const plugin = toolResultSecretScrubPlugin ( ) ;
224299 if ( plugin . middleware === undefined )
0 commit comments