mirror of
https://github.com/renovatebot/renovate.git
synced 2026-10-27 15:58:48 +00:00
54384ff3e5
* chore(util): note that `httpsCertificate` and `httpsCertificateAuthority` aren't secret
Although we're currently treating them as such, they're not technically
unsafe to appear in the logs, as a Certificate (and the authority) are
public.
* fix(util/host-rules): sanitise TLS credential fields in hostRules
We previously noted that the `httpsPrivateKey`, `httpsCertificate`, and
`httpsCertificateAuthority` fields would be marked as confidential, but
we weren't correctly sanitising them.
We can make sure that these fields are correctly flagged as secret
("confidential") and that they need to be sanitised when referenced.
Although the `httpsCertificate` and `httpsCertificateAuthority` aren't
secret, we can keep them sanitised for consistency with how we've
currently documented them as being sanitised.
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
* test(util/host-rules): ensure that all secret fields are marked as secret
As a way to make sure that new fields being added `HostRule`s are
considered as to whether the field should be marked as secret
("confidential") or not, we can add a test (and a compile-time
exhaustive check) to validate that `redactedFields` and
`confidentialFields` are kept in sync.
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
---------
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
73 lines
1.8 KiB
TypeScript
73 lines
1.8 KiB
TypeScript
import { isNonEmptyString } from '@sindresorhus/is';
|
|
import { toBase64 } from './string.ts';
|
|
|
|
const globalSecrets = new Set<string>();
|
|
const repoSecrets = new Set<string>();
|
|
|
|
export const redactedFields = [
|
|
'authorization',
|
|
'token',
|
|
'githubAppKey',
|
|
'npmToken',
|
|
'npmrc',
|
|
'privateKey',
|
|
'privateKeyOld',
|
|
'gitPrivateKey',
|
|
'forkToken',
|
|
'password',
|
|
/* not actually sensitive, but redacted nonetheless */
|
|
'httpsCertificate',
|
|
'httpsPrivateKey',
|
|
/* not actually sensitive, but redacted nonetheless */
|
|
'httpsCertificateAuthority',
|
|
];
|
|
|
|
// TODO: returns null or undefined only when input is null or undefined.
|
|
export function sanitize(input: string): string;
|
|
export function sanitize(
|
|
input: string | null | undefined,
|
|
): string | null | undefined;
|
|
export function sanitize(
|
|
input: string | null | undefined,
|
|
): string | null | undefined {
|
|
if (!input) {
|
|
return input;
|
|
}
|
|
let output: string = input;
|
|
[globalSecrets, repoSecrets].forEach((secrets) => {
|
|
secrets.forEach((secret) => {
|
|
while (output.includes(secret)) {
|
|
output = output.replace(secret, '**redacted**');
|
|
}
|
|
});
|
|
});
|
|
return output;
|
|
}
|
|
|
|
const GITHUB_APP_TOKEN_PREFIX = 'x-access-token:';
|
|
|
|
export function addSecretForSanitizing(
|
|
secret: string | undefined,
|
|
type = 'repo',
|
|
): void {
|
|
if (!isNonEmptyString(secret)) {
|
|
return;
|
|
}
|
|
const secrets = type === 'repo' ? repoSecrets : globalSecrets;
|
|
secrets.add(secret);
|
|
secrets.add(toBase64(secret));
|
|
if (secret.startsWith(GITHUB_APP_TOKEN_PREFIX)) {
|
|
const trimmedSecret = secret.replace(GITHUB_APP_TOKEN_PREFIX, '');
|
|
secrets.add(trimmedSecret);
|
|
secrets.add(toBase64(trimmedSecret));
|
|
}
|
|
}
|
|
|
|
export function clearRepoSanitizedSecretsList(): void {
|
|
repoSecrets.clear();
|
|
}
|
|
|
|
export function clearGlobalSanitizedSecretsList(): void {
|
|
globalSecrets.clear();
|
|
}
|