@@ -227,6 +227,95 @@ describe('Credential Hiding Security', () => {
227227 } , 120000 ) ;
228228 } ) ;
229229
230+ describe ( 'All 14 Credential Paths Coverage' , ( ) => {
231+ // These tests cover the 11 credential paths not tested by Tests 1-4 above.
232+ // Each path is hidden via /dev/null mount and should return empty content.
233+
234+ const untestedPaths = [
235+ { name : 'SSH id_rsa' , path : '.ssh/id_rsa' } ,
236+ { name : 'SSH id_ed25519' , path : '.ssh/id_ed25519' } ,
237+ { name : 'SSH id_ecdsa' , path : '.ssh/id_ecdsa' } ,
238+ { name : 'SSH id_dsa' , path : '.ssh/id_dsa' } ,
239+ { name : 'AWS credentials' , path : '.aws/credentials' } ,
240+ { name : 'AWS config' , path : '.aws/config' } ,
241+ { name : 'Kube config' , path : '.kube/config' } ,
242+ { name : 'Azure credentials' , path : '.azure/credentials' } ,
243+ { name : 'GCloud credentials.db' , path : '.config/gcloud/credentials.db' } ,
244+ { name : 'Cargo credentials' , path : '.cargo/credentials' } ,
245+ { name : 'Composer auth.json' , path : '.composer/auth.json' } ,
246+ ] ;
247+
248+ test ( 'All untested credential files are hidden at direct home path (0 bytes)' , async ( ) => {
249+ const homeDir = os . homedir ( ) ;
250+ const paths = untestedPaths . map ( p => `${ homeDir } /${ p . path } ` ) . join ( ' ' ) ;
251+
252+ // Check all credential files in a single container run for efficiency.
253+ // wc -c reports byte count; /dev/null-mounted files should be 0 bytes.
254+ // Use '|| true' to prevent failures when files don't exist
255+ const result = await runner . runWithSudo (
256+ `sh -c 'for f in ${ paths } ; do if [ -f "$f" ]; then wc -c "$f"; fi; done 2>&1 || true'` ,
257+ {
258+ allowDomains : [ 'github.com' ] ,
259+ logLevel : 'debug' ,
260+ timeout : 60000 ,
261+ }
262+ ) ;
263+
264+ expect ( result ) . toSucceed ( ) ;
265+ const cleanOutput = extractCommandOutput ( result . stdout ) ;
266+ const lines = cleanOutput . split ( '\n' ) . filter ( l => l . match ( / ^ \s * \d + / ) ) ;
267+ // Each file should be 0 bytes (hidden via /dev/null)
268+ lines . forEach ( line => {
269+ const size = parseInt ( line . trim ( ) . split ( / \s + / ) [ 0 ] ) ;
270+ expect ( size ) . toBe ( 0 ) ;
271+ } ) ;
272+ // Verify we checked all 11 files
273+ expect ( lines . length ) . toBe ( untestedPaths . length ) ;
274+ } , 120000 ) ;
275+
276+ test ( 'All untested credential files are hidden at /host path (0 bytes)' , async ( ) => {
277+ const homeDir = os . homedir ( ) ;
278+ const paths = untestedPaths . map ( p => `/host${ homeDir } /${ p . path } ` ) . join ( ' ' ) ;
279+
280+ const result = await runner . runWithSudo (
281+ `sh -c 'for f in ${ paths } ; do if [ -f "$f" ]; then wc -c "$f"; fi; done 2>&1 || true'` ,
282+ {
283+ allowDomains : [ 'github.com' ] ,
284+ logLevel : 'debug' ,
285+ timeout : 60000 ,
286+ }
287+ ) ;
288+
289+ expect ( result ) . toSucceed ( ) ;
290+ const cleanOutput = extractCommandOutput ( result . stdout ) ;
291+ const lines = cleanOutput . split ( '\n' ) . filter ( l => l . match ( / ^ \s * \d + / ) ) ;
292+ lines . forEach ( line => {
293+ const size = parseInt ( line . trim ( ) . split ( / \s + / ) [ 0 ] ) ;
294+ expect ( size ) . toBe ( 0 ) ;
295+ } ) ;
296+ expect ( lines . length ) . toBe ( untestedPaths . length ) ;
297+ } , 120000 ) ;
298+
299+ test ( 'cat on each untested credential file returns empty content' , async ( ) => {
300+ const homeDir = os . homedir ( ) ;
301+ const paths = untestedPaths . map ( p => `${ homeDir } /${ p . path } ` ) . join ( ' ' ) ;
302+
303+ // cat all files and concatenate output - should be empty
304+ const result = await runner . runWithSudo (
305+ `sh -c 'for f in ${ paths } ; do if [ -f "$f" ]; then cat "$f"; fi; done 2>&1 || true'` ,
306+ {
307+ allowDomains : [ 'github.com' ] ,
308+ logLevel : 'debug' ,
309+ timeout : 60000 ,
310+ }
311+ ) ;
312+
313+ expect ( result ) . toSucceed ( ) ;
314+ // All content should be empty (no credential data leaked)
315+ const cleanOutput = extractCommandOutput ( result . stdout ) . trim ( ) ;
316+ expect ( cleanOutput ) . toBe ( '' ) ;
317+ } , 120000 ) ;
318+ } ) ;
230319
231320 describe ( 'Security Verification' , ( ) => {
232321 test ( 'Test 12: Simulated exfiltration attack gets empty data' , async ( ) => {
0 commit comments