fix(folder trust): add validation for trusted folder level (#12215)

Co-authored-by: Gal Zahavi <38544478+galz10@users.noreply.github.com>
This commit is contained in:
Adam Weidman
2025-12-19 19:13:03 -05:00
committed by GitHub
parent 41a1a3eed1
commit 8ed0f8981f
2 changed files with 68 additions and 2 deletions

View File

@@ -424,3 +424,52 @@ describe('Trusted Folders Caching', () => {
expect(readSpy).toHaveBeenCalledTimes(2);
});
});
describe('invalid trust levels', () => {
const mockCwd = '/user/folder';
const mockRules: Record<string, TrustLevel> = {};
beforeEach(() => {
resetTrustedFoldersForTesting();
vi.spyOn(process, 'cwd').mockImplementation(() => mockCwd);
vi.spyOn(fs, 'readFileSync').mockImplementation((p) => {
if (p === getTrustedFoldersPath()) {
return JSON.stringify(mockRules);
}
return '{}';
});
vi.spyOn(fs, 'existsSync').mockImplementation(
(p) => p === getTrustedFoldersPath(),
);
});
afterEach(() => {
vi.restoreAllMocks();
// Clear the object
Object.keys(mockRules).forEach((key) => delete mockRules[key]);
});
it('should create a comprehensive error message for invalid trust level', () => {
mockRules[mockCwd] = 'INVALID_TRUST_LEVEL' as TrustLevel;
const { errors } = loadTrustedFolders();
const possibleValues = Object.values(TrustLevel).join(', ');
expect(errors.length).toBe(1);
expect(errors[0].message).toBe(
`Invalid trust level "INVALID_TRUST_LEVEL" for path "${mockCwd}". Possible values are: ${possibleValues}.`,
);
});
it('should throw a fatal error for invalid trust level', () => {
const mockSettings: Settings = {
security: {
folderTrust: {
enabled: true,
},
},
};
mockRules[mockCwd] = 'INVALID_TRUST_LEVEL' as TrustLevel;
expect(() => isWorkspaceTrusted(mockSettings)).toThrow(FatalConfigError);
});
});

View File

@@ -36,6 +36,13 @@ export enum TrustLevel {
DO_NOT_TRUST = 'DO_NOT_TRUST',
}
export function isTrustLevel(value: unknown): value is TrustLevel {
return (
typeof value === 'string' &&
Object.values(TrustLevel).includes(value as TrustLevel)
);
}
export interface TrustRule {
path: string;
trustLevel: TrustLevel;
@@ -151,7 +158,7 @@ export function loadTrustedFolders(): LoadedTrustedFolders {
}
const errors: TrustedFoldersError[] = [];
let userConfig: Record<string, TrustLevel> = {};
const userConfig: Record<string, TrustLevel> = {};
const userPath = getTrustedFoldersPath();
@@ -171,7 +178,17 @@ export function loadTrustedFolders(): LoadedTrustedFolders {
path: userPath,
});
} else {
userConfig = parsed as Record<string, TrustLevel>;
for (const [path, trustLevel] of Object.entries(parsed)) {
if (isTrustLevel(trustLevel)) {
userConfig[path] = trustLevel;
} else {
const possibleValues = Object.values(TrustLevel).join(', ');
errors.push({
message: `Invalid trust level "${trustLevel}" for path "${path}". Possible values are: ${possibleValues}.`,
path: userPath,
});
}
}
}
}
} catch (error: unknown) {