@wayai/cli 0.3.100 → 0.3.101
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +38 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -44,30 +44,57 @@ function maskCredentialValues(text, keyRe, isValueEnd) {
|
|
|
44
44
|
}
|
|
45
45
|
return out + text.slice(copied);
|
|
46
46
|
}
|
|
47
|
+
function maskJwts(text) {
|
|
48
|
+
let out = "";
|
|
49
|
+
let copied = 0;
|
|
50
|
+
let cursor = 0;
|
|
51
|
+
while (cursor < text.length) {
|
|
52
|
+
while (cursor < text.length && !isBase64UrlChar(text[cursor])) cursor++;
|
|
53
|
+
const headerStart = cursor;
|
|
54
|
+
let tokenStart = -1;
|
|
55
|
+
while (cursor < text.length && isBase64UrlChar(text[cursor])) {
|
|
56
|
+
if (tokenStart < 0 && text[cursor] === "e" && text[cursor + 1] === "y" && text[cursor + 2] === "J") {
|
|
57
|
+
tokenStart = cursor;
|
|
58
|
+
}
|
|
59
|
+
cursor++;
|
|
60
|
+
}
|
|
61
|
+
const headerEnd = cursor;
|
|
62
|
+
if (headerStart === headerEnd) continue;
|
|
63
|
+
const hasJwtHeader = tokenStart >= headerStart && tokenStart + 3 < headerEnd;
|
|
64
|
+
if (!hasJwtHeader || text[headerEnd] !== ".") continue;
|
|
65
|
+
const payloadStart = headerEnd + 1;
|
|
66
|
+
cursor = payloadStart;
|
|
67
|
+
while (cursor < text.length && isBase64UrlChar(text[cursor])) cursor++;
|
|
68
|
+
const payloadEnd = cursor;
|
|
69
|
+
if (payloadEnd === payloadStart || text[payloadEnd] !== ".") continue;
|
|
70
|
+
const signatureStart = payloadEnd + 1;
|
|
71
|
+
cursor = signatureStart;
|
|
72
|
+
while (cursor < text.length && isBase64UrlChar(text[cursor])) cursor++;
|
|
73
|
+
if (cursor === signatureStart) continue;
|
|
74
|
+
out += text.slice(copied, tokenStart) + "[REDACTED_JWT]";
|
|
75
|
+
copied = cursor;
|
|
76
|
+
}
|
|
77
|
+
return out + text.slice(copied);
|
|
78
|
+
}
|
|
47
79
|
function maskSecretsInMessage(text) {
|
|
48
|
-
let out = text;
|
|
80
|
+
let out = maskJwts(text);
|
|
49
81
|
for (const [pattern, replacement] of SHAPE_PATTERNS) out = out.replace(pattern, replacement);
|
|
50
82
|
out = maskCredentialValues(out, JSON_KEY_RE, isJsonValueEnd);
|
|
51
83
|
out = maskCredentialValues(out, QUERY_KEY_RE, isQueryValueEnd);
|
|
52
84
|
return out.replace(BASE64_RE, maskBase64);
|
|
53
85
|
}
|
|
54
|
-
var CREDENTIAL_KEY_RE, FULLY_MASKED_VALUE_RE, isCredentialKey, SHAPE_PATTERNS, JSON_KEY_RE, isJsonValueEnd, QUERY_KEY_RE, isQueryValueEnd, BASE64_RE, maskBase64;
|
|
86
|
+
var CREDENTIAL_KEY_RE, FULLY_MASKED_VALUE_RE, isCredentialKey, isBase64UrlChar, SHAPE_PATTERNS, JSON_KEY_RE, isJsonValueEnd, QUERY_KEY_RE, isQueryValueEnd, BASE64_RE, maskBase64;
|
|
55
87
|
var init_mask_secrets = __esm({
|
|
56
88
|
"src/lib/mask-secrets.ts"() {
|
|
57
89
|
"use strict";
|
|
58
90
|
CREDENTIAL_KEY_RE = /token|secret|credential|password|passwd|api[_-]?key|authorization|private[_-]?key|session[_-]?id|cookie|jwt/i;
|
|
59
91
|
FULLY_MASKED_VALUE_RE = /^(?:Bearer\s+)?(?:way_|wst_)?\[REDACTED(?:_JWT|_BASE64)?\]$/;
|
|
60
92
|
isCredentialKey = (key) => CREDENTIAL_KEY_RE.test(key);
|
|
93
|
+
isBase64UrlChar = (char) => {
|
|
94
|
+
const code = char.charCodeAt(0);
|
|
95
|
+
return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || char === "-" || char === "_";
|
|
96
|
+
};
|
|
61
97
|
SHAPE_PATTERNS = [
|
|
62
|
-
// JWTs (header.payload.signature) — WorkOS access/refresh tokens, OAuth JWTs.
|
|
63
|
-
// Run first so a `Bearer <jwt>` collapses to the JWT placeholder.
|
|
64
|
-
//
|
|
65
|
-
// Deliberately NOT anchored with the lookbehind the base64 rule uses. It would
|
|
66
|
-
// make this linear (this rule is quadratic on a pathological `eyJeyJeyJ…` run),
|
|
67
|
-
// but it also NARROWS masking: `refresh-<jwt>` and `way_<jwt>` would stop
|
|
68
|
-
// matching and leak the token whole. Correctness of a redaction rule outranks
|
|
69
|
-
// its worst case on a body that has to be adversarial to hurt.
|
|
70
|
-
[/eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g, "[REDACTED_JWT]"],
|
|
71
98
|
// way_ scoped API tokens (keyring/CI credentials). Leading \b avoids
|
|
72
99
|
// over-redacting benign substrings (e.g. `gateway_config`); the charset is
|
|
73
100
|
// base64url (no `.`) so a trailing sentence period stays outside the match.
|