Skip to content

Commit 8c9b74e

Browse files
committed
fix: redact each configured GitLab API URL before joining startup log
1 parent f90b113 commit 8c9b74e

2 files changed

Lines changed: 29 additions & 5 deletions

File tree

‎index.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16969,7 +16969,7 @@ async function runServer() {
1696916969
}
1697016970

1697116971
logger.info(
16972-
`Configured GitLab API URLs: ${redactUrlSecretsInText(GITLAB_API_URLS.join(", "))}`
16972+
`Configured GitLab API URLs: ${GITLAB_API_URLS.map(redactUrlSecretsInText).join(", ")}`
1697316973
);
1697416974
logger.info(`Default GitLab API URL: ${redactUrlSecretsInText(GITLAB_API_URL)}`);
1697516975

‎test/startup-url-redaction.test.ts‎

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,19 @@ const REPO_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..
99
const SECRET_USER = "fakeuser";
1010
const SECRET_PASSWORD = "fakepass";
1111
const SECRET_QUERY = "fakesecret123";
12+
const SLASHLESS_PASSWORD = "slashless-pass";
13+
const DEFAULT_STARTUP_API_URL = `https://${SECRET_USER}:${SECRET_PASSWORD}@gitlab.example.com/api/v4?private_token=${SECRET_QUERY}`;
14+
const SLASHLESS_LIST_API_URL = `https://gitlab.example/api/v4,https:slashless-user:${SLASHLESS_PASSWORD}@other.example`;
1215

1316
interface StartupLogs {
1417
readonly stdout: string;
1518
readonly stderr: string;
1619
}
1720

18-
function startupEnv(): Record<string, string> {
21+
function startupEnv(apiUrl: string): Record<string, string> {
1922
const env: Record<string, string> = {
2023
GITLAB_PERSONAL_ACCESS_TOKEN: "glpat-fakefakefake",
21-
GITLAB_API_URL: `https://${SECRET_USER}:${SECRET_PASSWORD}@gitlab.example.com/api/v4?private_token=${SECRET_QUERY}`,
24+
GITLAB_API_URL: apiUrl,
2225
GITLAB_DISABLE_VERSION_CHECK: "true",
2326
LOG_LEVEL: "info",
2427
};
@@ -31,10 +34,12 @@ function startupEnv(): Record<string, string> {
3134
return env;
3235
}
3336

34-
async function captureStartupLogsAsync(): Promise<StartupLogs> {
37+
async function captureStartupLogsAsync(
38+
apiUrl: string = DEFAULT_STARTUP_API_URL
39+
): Promise<StartupLogs> {
3540
const child = spawn(process.execPath, [path.join(REPO_ROOT, "build/index.js")], {
3641
cwd: REPO_ROOT,
37-
env: startupEnv(),
42+
env: startupEnv(apiUrl),
3843
stdio: ["pipe", "pipe", "pipe"],
3944
});
4045
const stdoutChunks: Buffer[] = [];
@@ -144,4 +149,23 @@ describe("When the stdio server starts", () => {
144149
assert.equal(logs.stdout, "");
145150
});
146151
});
152+
153+
describe("with a later slashless URL in GITLAB_API_URL", () => {
154+
it("should redact each configured URL", async () => {
155+
const logs = await captureStartupLogsAsync(SLASHLESS_LIST_API_URL);
156+
157+
assert.equal(
158+
logs.stderr.includes(
159+
"Configured GitLab API URLs: https://gitlab.example/api/v4, https:[REDACTED]@other.example/api/v4"
160+
),
161+
true
162+
);
163+
});
164+
165+
it("should omit the slashless password from stderr", async () => {
166+
const logs = await captureStartupLogsAsync(SLASHLESS_LIST_API_URL);
167+
168+
assert.equal(logs.stderr.includes(SLASHLESS_PASSWORD), false);
169+
});
170+
});
147171
});

0 commit comments

Comments
 (0)