Skip to content

Commit 96e1238

Browse files
lpcoxCopilot
andauthored
Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent 5c46899 commit 96e1238

File tree

1 file changed

+65
-8
lines changed

1 file changed

+65
-8
lines changed

src/docker-manager.ts

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2408,6 +2408,67 @@ export function resetAgentExternallyKilled(): void {
24082408
*
24092409
* @param workDir - AWF working directory (contains docker-compose.yml)
24102410
*/
2411+
function isSensitiveComposeEnvVar(name: string): boolean {
2412+
return /(TOKEN|KEY|SECRET)/i.test(name);
2413+
}
2414+
2415+
function sanitizeComposeEnvironment(environment: unknown): void {
2416+
if (Array.isArray(environment)) {
2417+
for (let i = 0; i < environment.length; i++) {
2418+
const entry = environment[i];
2419+
if (typeof entry !== 'string') {
2420+
continue;
2421+
}
2422+
2423+
const separatorIndex = entry.indexOf('=');
2424+
if (separatorIndex === -1) {
2425+
continue;
2426+
}
2427+
2428+
const key = entry.slice(0, separatorIndex);
2429+
if (isSensitiveComposeEnvVar(key)) {
2430+
environment[i] = `${key}=[REDACTED]`;
2431+
}
2432+
}
2433+
return;
2434+
}
2435+
2436+
if (environment && typeof environment === 'object') {
2437+
const values = environment as Record<string, unknown>;
2438+
for (const key of Object.keys(values)) {
2439+
if (isSensitiveComposeEnvVar(key)) {
2440+
values[key] = '[REDACTED]';
2441+
}
2442+
}
2443+
}
2444+
}
2445+
2446+
function sanitizeDockerComposeYaml(raw: string): string {
2447+
const parsed = yaml.load(raw);
2448+
if (!parsed || typeof parsed !== 'object') {
2449+
return raw;
2450+
}
2451+
2452+
const compose = parsed as Record<string, unknown>;
2453+
const services = compose.services;
2454+
if (!services || typeof services !== 'object' || Array.isArray(services)) {
2455+
return yaml.dump(compose, { lineWidth: -1 });
2456+
}
2457+
2458+
for (const service of Object.values(services as Record<string, unknown>)) {
2459+
if (!service || typeof service !== 'object' || Array.isArray(service)) {
2460+
continue;
2461+
}
2462+
2463+
const serviceConfig = service as Record<string, unknown>;
2464+
if ('environment' in serviceConfig) {
2465+
sanitizeComposeEnvironment(serviceConfig.environment);
2466+
}
2467+
}
2468+
2469+
return yaml.dump(compose, { lineWidth: -1 });
2470+
}
2471+
24112472
export async function collectDiagnosticLogs(workDir: string): Promise<void> {
24122473
const diagnosticsDir = path.join(workDir, 'diagnostics');
24132474
try {
@@ -2471,18 +2532,14 @@ export async function collectDiagnosticLogs(workDir: string): Promise<void> {
24712532
}
24722533
}
24732534

2474-
// Write a sanitized copy of docker-compose.yml — redact values of env vars
2475-
// whose name contains TOKEN, KEY, or SECRET (case-insensitive, e.g. github_token, API_KEY, Api_Key).
2476-
// \w* matches word characters [A-Za-z0-9_] so all valid identifier characters are covered.
2535+
// Write a sanitized copy of docker-compose.yml by parsing the YAML and redacting
2536+
// sensitive environment variable values under services[*].environment in both
2537+
// object/map and list forms.
24772538
const composeFile = path.join(workDir, 'docker-compose.yml');
24782539
if (fs.existsSync(composeFile)) {
24792540
try {
24802541
const raw = fs.readFileSync(composeFile, 'utf8');
2481-
// Match lines like: SOME_TOKEN_VAR: value or api_key: "value" or Api_Key: mixed
2482-
const sanitized = raw.replace(
2483-
/^(\s+\w*(?:TOKEN|KEY|SECRET)\w*\s*:.*)$/gim,
2484-
match => match.replace(/:\s*(.*)$/, ': [REDACTED]')
2485-
);
2542+
const sanitized = sanitizeDockerComposeYaml(raw);
24862543
fs.writeFileSync(path.join(diagnosticsDir, 'docker-compose.yml'), sanitized);
24872544
} catch (error) {
24882545
logger.debug('Could not write sanitized docker-compose.yml to diagnostics:', error);

0 commit comments

Comments
 (0)