@mnemonik/cli 7.141.0 → 7.141.1
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/auth/credentials.js +266 -3
- package/dist/auth/index.js +266 -3
- package/dist/auth/installSession.js +262 -0
- package/dist/auth/status.js +262 -0
- package/dist/authorizationWords.js +262 -0
- package/dist/diagnostics.js +266 -3
- package/dist/digests.json +38 -38
- package/dist/hooksLog.js +4 -0
- package/dist/identity/migrate.js +266 -3
- package/dist/install/hosts.js +262 -0
- package/dist/install/journal.js +266 -3
- package/dist/install/journey.js +266 -3
- package/dist/install/ownership.js +266 -3
- package/dist/install/transaction.js +266 -3
- package/dist/install/ui.js +266 -3
- package/dist/installSession.js +262 -0
- package/dist/installation.js +266 -3
- package/dist/launcher.js +266 -3
- package/dist/preflight.js +354 -92
- package/dist/project/eligibility.js +266 -3
- package/dist/project/records.js +266 -3
- package/dist/project.js +270 -7
- package/dist/router.js +270 -7
- package/dist/runtime/releaseSource.js +266 -3
- package/dist/runtime/selfUpdate.js +266 -3
- package/dist/runtime/signers.js +67 -7
- package/dist/runtime/store.js +4 -0
- package/dist/runtime/updateCheck.js +266 -3
- package/dist/sbom.json +21 -21
- package/dist/scanner/control.js +266 -3
- package/dist/scanner/data.js +262 -0
- package/dist/scanner/discover.js +354 -92
- package/dist/scanner/enable.js +270 -7
- package/dist/scanner/picker.js +325 -63
- package/dist/scanner/service.js +266 -3
- package/dist/scanner/update.js +266 -3
- package/dist/scanner-release.json +24 -24
- package/dist/status.js +266 -3
- package/dist/vendor/local-setup.js +266 -3
- package/package.json +31 -31
package/dist/runtime/signers.js
CHANGED
|
@@ -890,6 +890,61 @@ var init_protectedPaths = __esm({
|
|
|
890
890
|
});
|
|
891
891
|
|
|
892
892
|
// packages/shared/dist/secretPatterns.js
|
|
893
|
+
function redactSecretValue(value) {
|
|
894
|
+
return SECRET_REDACTION_PLACEHOLDER + (value.match(/\\(?:\r\n|[\r\n])|\r\n|[\r\n]|\\[rn]/g)?.join("") ?? "");
|
|
895
|
+
}
|
|
896
|
+
function redactLabeledValues(text) {
|
|
897
|
+
let result = "";
|
|
898
|
+
let offset = 0;
|
|
899
|
+
LABELED_VALUE_RE.lastIndex = 0;
|
|
900
|
+
for (const match of text.matchAll(LABELED_VALUE_RE)) {
|
|
901
|
+
if (match.index < offset)
|
|
902
|
+
continue;
|
|
903
|
+
const start = match.index + match[0].length;
|
|
904
|
+
const escaped = text[start] === "\\" && /^["']/.test(text.charAt(start + 1));
|
|
905
|
+
const quote2 = escaped ? text.charAt(start + 1) : /^["'`]/.test(text.charAt(start)) ? text.charAt(start) : "";
|
|
906
|
+
const delimiter = (escaped ? "\\" : "") + quote2;
|
|
907
|
+
let end = start;
|
|
908
|
+
let closed = false;
|
|
909
|
+
if (quote2) {
|
|
910
|
+
end += delimiter.length;
|
|
911
|
+
while (end < text.length) {
|
|
912
|
+
if (text[end] === "\\") {
|
|
913
|
+
if (escaped) {
|
|
914
|
+
const begin = end;
|
|
915
|
+
while (text[end] === "\\")
|
|
916
|
+
end++;
|
|
917
|
+
if (text[end] === quote2 && (end - begin) % 4 === 1) {
|
|
918
|
+
end++;
|
|
919
|
+
closed = true;
|
|
920
|
+
break;
|
|
921
|
+
}
|
|
922
|
+
end = Math.min(end + 1, text.length);
|
|
923
|
+
} else {
|
|
924
|
+
end = Math.min(end + 2, text.length);
|
|
925
|
+
}
|
|
926
|
+
} else if (text[end++] === quote2 && !escaped) {
|
|
927
|
+
closed = true;
|
|
928
|
+
break;
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
} else {
|
|
932
|
+
end += /^(?:\\[^\r\n]|[^\s"'`,;()[\]{}\\])+/.exec(text.slice(start))?.[0].length ?? 0;
|
|
933
|
+
}
|
|
934
|
+
const value = text.slice(start, end);
|
|
935
|
+
if (!/[A-Za-z0-9]/.test(value) || ENV_READ_VALUE_RE.test(match[0] + value))
|
|
936
|
+
continue;
|
|
937
|
+
if (quote2 && !escaped && (text[match.index - 1] === quote2 || text[match.index - 1] === "^" && text[match.index - 2] === quote2 && (start + 1 === text.length || /\s/.test(text.charAt(start + 1)))))
|
|
938
|
+
continue;
|
|
939
|
+
if (/aws_secret_access_key/i.test(match[0]) && /^<[^>]*>$/.test(value))
|
|
940
|
+
continue;
|
|
941
|
+
const body = quote2 ? value.slice(delimiter.length, closed ? -delimiter.length : void 0) : value.replace(/(?:\*\/|[.!?]+)$/, "");
|
|
942
|
+
const tail = quote2 ? closed ? delimiter : "" : value.slice(body.length);
|
|
943
|
+
result += text.slice(offset, start) + delimiter + redactSecretValue(body) + tail;
|
|
944
|
+
offset = end;
|
|
945
|
+
}
|
|
946
|
+
return result + text.slice(offset);
|
|
947
|
+
}
|
|
893
948
|
function shannonEntropy(token) {
|
|
894
949
|
const counts = /* @__PURE__ */ new Map();
|
|
895
950
|
for (const ch of token)
|
|
@@ -950,17 +1005,25 @@ function scrubSecrets(text) {
|
|
|
950
1005
|
return text;
|
|
951
1006
|
let result = text;
|
|
952
1007
|
for (const pattern of SECRET_PATTERNS) {
|
|
953
|
-
|
|
1008
|
+
if (pattern === LABELED_VALUE_RE) {
|
|
1009
|
+
result = redactLabeledValues(result);
|
|
1010
|
+
} else {
|
|
1011
|
+
result = result.replace(pattern, (match) => ENV_READ_VALUE_RE.test(match) ? match : redactSecretValue(match));
|
|
1012
|
+
}
|
|
954
1013
|
}
|
|
955
1014
|
return redactHighEntropyTokens(result);
|
|
956
1015
|
}
|
|
957
|
-
var SECRET_REDACTION_PLACEHOLDER, SECRET_PATTERNS, ENV_READ_VALUE_RE, ENTROPY_MIN_LENGTH, ENTROPY_MIN_BITS_PER_CHAR, ENTROPY_MAX_STRUCTURED_SEGMENT, ENTROPY_MAX_LOWERCASE_RUN, ENTROPY_CANDIDATE_RE, ENTROPY_CONTEXT_RE, ENTROPY_OPERATOR_TAIL_RE, ENTROPY_HEXISH_RE, ENTROPY_STRUCTURED_RE;
|
|
1016
|
+
var SECRET_REDACTION_PLACEHOLDER, SECRET_LABEL, SECRET_LABEL_RE, LABELED_VALUE_RE, SECRET_PATTERNS, ENV_READ_VALUE_RE, ENTROPY_MIN_LENGTH, ENTROPY_MIN_BITS_PER_CHAR, ENTROPY_MAX_STRUCTURED_SEGMENT, ENTROPY_MAX_LOWERCASE_RUN, ENTROPY_CANDIDATE_RE, ENTROPY_CONTEXT_RE, ENTROPY_OPERATOR_TAIL_RE, ENTROPY_HEXISH_RE, ENTROPY_STRUCTURED_RE;
|
|
958
1017
|
var init_secretPatterns = __esm({
|
|
959
1018
|
"packages/shared/dist/secretPatterns.js"() {
|
|
960
1019
|
"use strict";
|
|
961
1020
|
SECRET_REDACTION_PLACEHOLDER = "[REDACTED]";
|
|
1021
|
+
SECRET_LABEL = String.raw`[\w$-]*(?:api[_-]?key|secret|token|password|credential|auth)|aws_secret_access_key`;
|
|
1022
|
+
SECRET_LABEL_RE = new RegExp(`^(?:${SECRET_LABEL}|MYSQL_PWD|SSHPASS)$`, "i");
|
|
1023
|
+
LABELED_VALUE_RE = new RegExp(String.raw`(?<![\w$-])((["']?)(?:${SECRET_LABEL})\2\s*[:=]\s*)(?=\S)`, "gi");
|
|
962
1024
|
SECRET_PATTERNS = [
|
|
963
|
-
|
|
1025
|
+
LABELED_VALUE_RE,
|
|
1026
|
+
// Select the label; the linear reader consumes its complete value.
|
|
964
1027
|
// Stripe-shape: (sk|pk)_(live|test)_<24+ alphanumerics>. Catches modern
|
|
965
1028
|
// Stripe keys whose body is split by an environment separator that
|
|
966
1029
|
// breaks the contiguous-alphanum pattern below. Required `live|test`
|
|
@@ -981,10 +1044,7 @@ var init_secretPatterns = __esm({
|
|
|
981
1044
|
// \b-delimited, so prose ("AKIAMIA is a place name") cannot match.
|
|
982
1045
|
/\bAKIA[0-9A-Z]{16}\b/g,
|
|
983
1046
|
/\bASIA[0-9A-Z]{16}\b/g,
|
|
984
|
-
// AWS secret access
|
|
985
|
-
// NOT cover this: its `secret` alternative must be followed immediately by
|
|
986
|
-
// `[:=]`, and here it is followed by `_access_key`.
|
|
987
|
-
/\baws_secret_access_key\s*[:=]\s*[A-Za-z0-9/+=]{40}\b/gi,
|
|
1047
|
+
// Labeled AWS secret access keys are covered by LABELED_VALUE_RE, including quotes.
|
|
988
1048
|
// JWT: three base64url segments. Length minimums keep dotted identifiers
|
|
989
1049
|
// (`payload.header.signature`) out.
|
|
990
1050
|
/\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{5,}\b/g,
|
package/dist/runtime/store.js
CHANGED
|
@@ -435,9 +435,13 @@ var init_protectedPaths = __esm({
|
|
|
435
435
|
});
|
|
436
436
|
|
|
437
437
|
// packages/shared/dist/secretPatterns.js
|
|
438
|
+
var SECRET_LABEL, SECRET_LABEL_RE, LABELED_VALUE_RE;
|
|
438
439
|
var init_secretPatterns = __esm({
|
|
439
440
|
"packages/shared/dist/secretPatterns.js"() {
|
|
440
441
|
"use strict";
|
|
442
|
+
SECRET_LABEL = String.raw`[\w$-]*(?:api[_-]?key|secret|token|password|credential|auth)|aws_secret_access_key`;
|
|
443
|
+
SECRET_LABEL_RE = new RegExp(`^(?:${SECRET_LABEL}|MYSQL_PWD|SSHPASS)$`, "i");
|
|
444
|
+
LABELED_VALUE_RE = new RegExp(String.raw`(?<![\w$-])((["']?)(?:${SECRET_LABEL})\2\s*[:=]\s*)(?=\S)`, "gi");
|
|
441
445
|
}
|
|
442
446
|
});
|
|
443
447
|
|
|
@@ -886,9 +886,13 @@ var require_ignore = __commonJS({
|
|
|
886
886
|
});
|
|
887
887
|
|
|
888
888
|
// packages/shared/dist/secretPatterns.js
|
|
889
|
+
var SECRET_LABEL, SECRET_LABEL_RE, LABELED_VALUE_RE;
|
|
889
890
|
var init_secretPatterns = __esm({
|
|
890
891
|
"packages/shared/dist/secretPatterns.js"() {
|
|
891
892
|
"use strict";
|
|
893
|
+
SECRET_LABEL = String.raw`[\w$-]*(?:api[_-]?key|secret|token|password|credential|auth)|aws_secret_access_key`;
|
|
894
|
+
SECRET_LABEL_RE = new RegExp(`^(?:${SECRET_LABEL}|MYSQL_PWD|SSHPASS)$`, "i");
|
|
895
|
+
LABELED_VALUE_RE = new RegExp(String.raw`(?<![\w$-])((["']?)(?:${SECRET_LABEL})\2\s*[:=]\s*)(?=\S)`, "gi");
|
|
892
896
|
}
|
|
893
897
|
});
|
|
894
898
|
|
|
@@ -2722,9 +2726,6 @@ var MCP_INSTRUCTIONS = getMcpInstructions();
|
|
|
2722
2726
|
|
|
2723
2727
|
// packages/shared/dist/codeScanner.js
|
|
2724
2728
|
var import_ignore = __toESM(require_ignore(), 1);
|
|
2725
|
-
init_secretPatterns();
|
|
2726
|
-
init_protectedPaths();
|
|
2727
|
-
init_projectIdentityFile();
|
|
2728
2729
|
|
|
2729
2730
|
// node_modules/web-tree-sitter/web-tree-sitter.js
|
|
2730
2731
|
var __defProp2 = Object.defineProperty;
|
|
@@ -6777,7 +6778,269 @@ var WASM_DIR = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "wasm")
|
|
|
6777
6778
|
// packages/shared/dist/ast/astChunker.js
|
|
6778
6779
|
var MAX_AST_PARSE_BYTES = 2 * 1024 * 1024;
|
|
6779
6780
|
|
|
6781
|
+
// packages/shared/dist/redactCredentials.js
|
|
6782
|
+
var REDACTED = "<redacted credential>";
|
|
6783
|
+
var MAX_PEM_BODY_LENGTH = 8 * 1024;
|
|
6784
|
+
var LETTER_OR_DIGIT = /[A-Za-z0-9]/;
|
|
6785
|
+
function hasLetterOrDigit(value) {
|
|
6786
|
+
return LETTER_OR_DIGIT.test(value);
|
|
6787
|
+
}
|
|
6788
|
+
function redactContextValue(match, head = "", value = "") {
|
|
6789
|
+
return hasLetterOrDigit(value) ? `${head}${REDACTED}` : match;
|
|
6790
|
+
}
|
|
6791
|
+
var PLACEHOLDER_PASSWORD = /^(?:\[REDACTED(?::[A-Za-z0-9_-]+)?\]|redacted|<[^<>]*>|\{\{[^{}]*\}\}|\$\{[^{}]+\}|%[A-Za-z_][A-Za-z0-9_]*%|\*+|x{3,}|\.\.\.|\u2026|password|passwd|pass|pwd|pw|secret|changeme|change[_-]me|example|test|(?:your|my)[a-z_-]*?(?:password|passwd|pass|pwd|secret|key|token|here))$/i;
|
|
6792
|
+
var PLACEHOLDER_ENV_VAR = /^\$[A-Z_][A-Z0-9_]*$/;
|
|
6793
|
+
function isPlaceholderPassword(password) {
|
|
6794
|
+
return PLACEHOLDER_PASSWORD.test(password) || PLACEHOLDER_ENV_VAR.test(password);
|
|
6795
|
+
}
|
|
6796
|
+
function redactUrlPassword(match, head = "", password = "") {
|
|
6797
|
+
return isPlaceholderPassword(password) || !hasLetterOrDigit(password) ? match : `${head}${REDACTED}@`;
|
|
6798
|
+
}
|
|
6799
|
+
var SHELL_WORD = String.raw`'[^'\n]*'|"[^"\n]*"|(?!${REDACTED})[^\s'"\`;|&()[\]{}\\,/][^\s'"\`;|&]*`;
|
|
6800
|
+
var OPENING_QUOTE = String.raw`(["'\`]?)`;
|
|
6801
|
+
var TRAILING_PUNCTUATION = /[.,:;!?)\]}]+$/;
|
|
6802
|
+
var PROSE_WORDS = /* @__PURE__ */ new Set([
|
|
6803
|
+
"a",
|
|
6804
|
+
"an",
|
|
6805
|
+
"and",
|
|
6806
|
+
"as",
|
|
6807
|
+
"for",
|
|
6808
|
+
"in",
|
|
6809
|
+
"is",
|
|
6810
|
+
"it",
|
|
6811
|
+
"on",
|
|
6812
|
+
"or",
|
|
6813
|
+
"the",
|
|
6814
|
+
"to",
|
|
6815
|
+
"with",
|
|
6816
|
+
"flag",
|
|
6817
|
+
"option",
|
|
6818
|
+
"argument",
|
|
6819
|
+
"instead",
|
|
6820
|
+
"which",
|
|
6821
|
+
"that",
|
|
6822
|
+
"this",
|
|
6823
|
+
"puts",
|
|
6824
|
+
"passes",
|
|
6825
|
+
"leaks",
|
|
6826
|
+
"exposes"
|
|
6827
|
+
]);
|
|
6828
|
+
var REGEX_DELIMITER = /\/(?:[{}()[\];]|$)/;
|
|
6829
|
+
function shellWordSecret(word) {
|
|
6830
|
+
const quote = word[0];
|
|
6831
|
+
if ((quote === "'" || quote === '"') && word.length >= 2 && word.endsWith(quote)) {
|
|
6832
|
+
const inner = word.slice(1, -1);
|
|
6833
|
+
if (!hasLetterOrDigit(inner) || quote === '"' && inner.startsWith("$"))
|
|
6834
|
+
return null;
|
|
6835
|
+
if (inner !== inner.trim())
|
|
6836
|
+
return null;
|
|
6837
|
+
return isPlaceholderPassword(inner) ? null : inner;
|
|
6838
|
+
}
|
|
6839
|
+
if (word.startsWith("$"))
|
|
6840
|
+
return null;
|
|
6841
|
+
const core = word.replace(TRAILING_PUNCTUATION, "");
|
|
6842
|
+
if (!hasLetterOrDigit(core) || isPlaceholderPassword(core))
|
|
6843
|
+
return null;
|
|
6844
|
+
if (REGEX_DELIMITER.test(core))
|
|
6845
|
+
return null;
|
|
6846
|
+
return PROSE_WORDS.has(core.toLowerCase()) ? null : core;
|
|
6847
|
+
}
|
|
6848
|
+
function redactShellWord(match, head = "", word = "", tail = "") {
|
|
6849
|
+
return shellWordSecret(word) === null ? match : `${head}${REDACTED}${tail}`;
|
|
6850
|
+
}
|
|
6851
|
+
function redactQuotedShellWord(match, head = "", openingQuote = "", word = "", tail = "") {
|
|
6852
|
+
if (openingQuote !== "" && word.startsWith(openingQuote))
|
|
6853
|
+
return match;
|
|
6854
|
+
return redactShellWord(match, head, word, tail);
|
|
6855
|
+
}
|
|
6856
|
+
var SSHPASS_COMMAND = String.raw`ssh|scp|sftp|rsync|ssh-copy-id|ansible[\w-]*`;
|
|
6857
|
+
function redactSshpassWord(match, head = "", openingQuote = "", word = "", tail = "", command = "") {
|
|
6858
|
+
if (openingQuote !== "" && word.startsWith(openingQuote))
|
|
6859
|
+
return match;
|
|
6860
|
+
const secret = shellWordSecret(word);
|
|
6861
|
+
if (secret === null)
|
|
6862
|
+
return match;
|
|
6863
|
+
const bare = word[0] !== "'" && word[0] !== '"';
|
|
6864
|
+
if (bare && /^[a-z]+$/.test(secret) && command === "")
|
|
6865
|
+
return match;
|
|
6866
|
+
return `${head}${REDACTED}${tail}`;
|
|
6867
|
+
}
|
|
6868
|
+
var PATTERNS = [
|
|
6869
|
+
{
|
|
6870
|
+
kind: "bearer",
|
|
6871
|
+
pattern: /(\bBearer\s+)([^\s]{40,})/gi,
|
|
6872
|
+
replacement: redactContextValue,
|
|
6873
|
+
secretGroup: 2
|
|
6874
|
+
},
|
|
6875
|
+
{
|
|
6876
|
+
// Before openai, whose sk- shape would otherwise claim these keys.
|
|
6877
|
+
kind: "anthropic",
|
|
6878
|
+
pattern: /(?<![A-Za-z0-9_-])sk-ant-(?=[_-]*[A-Za-z0-9])[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g,
|
|
6879
|
+
replacement: REDACTED
|
|
6880
|
+
},
|
|
6881
|
+
{
|
|
6882
|
+
kind: "openai",
|
|
6883
|
+
pattern: /(?<![A-Za-z0-9_-])sk-(?:proj-)?(?=[_-]*[A-Za-z0-9])[A-Za-z0-9_-]{16,}(?![A-Za-z0-9_-])/g,
|
|
6884
|
+
replacement: REDACTED
|
|
6885
|
+
},
|
|
6886
|
+
{
|
|
6887
|
+
kind: "shopify",
|
|
6888
|
+
pattern: /(?<![A-Za-z0-9_])shp(?:at|ss|ca)_[A-Za-z0-9]{16,}(?![A-Za-z0-9])/g,
|
|
6889
|
+
replacement: REDACTED
|
|
6890
|
+
},
|
|
6891
|
+
{
|
|
6892
|
+
kind: "aws_access_key",
|
|
6893
|
+
pattern: /(?<![A-Z0-9])AKIA[A-Z0-9]{16}(?![A-Z0-9])/g,
|
|
6894
|
+
replacement: REDACTED
|
|
6895
|
+
},
|
|
6896
|
+
{
|
|
6897
|
+
kind: "github",
|
|
6898
|
+
pattern: /(?<![A-Za-z0-9_])gh[opu]_[A-Za-z0-9]{20,}(?![A-Za-z0-9])/g,
|
|
6899
|
+
replacement: REDACTED
|
|
6900
|
+
},
|
|
6901
|
+
{
|
|
6902
|
+
kind: "slack",
|
|
6903
|
+
pattern: /(?<![A-Za-z0-9-])xox[abp]-(?=-*[A-Za-z0-9])[A-Za-z0-9-]{10,}(?![A-Za-z0-9-])/g,
|
|
6904
|
+
replacement: REDACTED
|
|
6905
|
+
},
|
|
6906
|
+
{
|
|
6907
|
+
kind: "sentry",
|
|
6908
|
+
pattern: /(?<![A-Za-z0-9_])sntry[us]_(?=[_-]*[A-Za-z0-9])[A-Za-z0-9_-]{16,}(?![A-Za-z0-9_-])/g,
|
|
6909
|
+
replacement: REDACTED
|
|
6910
|
+
},
|
|
6911
|
+
{
|
|
6912
|
+
kind: "fly",
|
|
6913
|
+
pattern: /(?<![A-Za-z0-9_])(?:FlyV1\s+)?fm2_(?=[_-]*[A-Za-z0-9])[A-Za-z0-9_-]{16,}(?![A-Za-z0-9_-])/g,
|
|
6914
|
+
replacement: REDACTED
|
|
6915
|
+
},
|
|
6916
|
+
{
|
|
6917
|
+
kind: "google_api_key",
|
|
6918
|
+
pattern: /(?<![A-Za-z0-9_-])AIza(?=[_-]*[A-Za-z0-9])[0-9A-Za-z_-]{35}(?![A-Za-z0-9_-])/g,
|
|
6919
|
+
replacement: REDACTED
|
|
6920
|
+
},
|
|
6921
|
+
{
|
|
6922
|
+
kind: "jwt",
|
|
6923
|
+
// header.payload.signature, both JSON segments starting eyJ. The length
|
|
6924
|
+
// floors keep `eyJ...` prose and signature-less examples out.
|
|
6925
|
+
pattern: /(?<![A-Za-z0-9_-])eyJ[A-Za-z0-9_-]{8,}\.eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{16,}(?![A-Za-z0-9_-])/g,
|
|
6926
|
+
replacement: REDACTED
|
|
6927
|
+
},
|
|
6928
|
+
{
|
|
6929
|
+
kind: "mnemonik_component_token",
|
|
6930
|
+
// mnc_ / mncr_ + 43 base64url (oauth/components.ts); 32+ also catches a
|
|
6931
|
+
// partial token. The body must contain an upper-case letter or digit, so a
|
|
6932
|
+
// snake_case identifier is not mistaken for one; the 8-character
|
|
6933
|
+
// display prefix (mnc_ + 8) is too short.
|
|
6934
|
+
pattern: /(?<![A-Za-z0-9_])mncr?_(?=[A-Za-z0-9_-]*[A-Z0-9])[A-Za-z0-9_-]{32,}/g,
|
|
6935
|
+
replacement: REDACTED
|
|
6936
|
+
},
|
|
6937
|
+
{
|
|
6938
|
+
kind: "stripe",
|
|
6939
|
+
// Secret and restricted keys (sk_/rk_ live|test) and webhook signing secrets.
|
|
6940
|
+
pattern: /(?<![A-Za-z0-9_])(?:(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}|whsec_[A-Za-z0-9]{20,})(?![A-Za-z0-9])/g,
|
|
6941
|
+
replacement: REDACTED
|
|
6942
|
+
},
|
|
6943
|
+
{
|
|
6944
|
+
kind: "mnemonik_proxy_token",
|
|
6945
|
+
// pxt_ + 32 hex (the format server.ts validates). A bare prefix in prose is left.
|
|
6946
|
+
pattern: /(?<![A-Za-z0-9_])pxt_[0-9a-f]{32,}/g,
|
|
6947
|
+
replacement: REDACTED
|
|
6948
|
+
},
|
|
6949
|
+
{
|
|
6950
|
+
kind: "mnemonik_api_key",
|
|
6951
|
+
// mnk_ + 64 hex (AuthManager.generateApiKey); 32+ also catches a half key.
|
|
6952
|
+
// The stored 12-character key_prefix (mnk_ + 8 hex) is not a credential.
|
|
6953
|
+
pattern: /(?<![A-Za-z0-9_])mnk_[0-9a-f]{32,}/g,
|
|
6954
|
+
replacement: REDACTED
|
|
6955
|
+
},
|
|
6956
|
+
{
|
|
6957
|
+
kind: "mnemonik_api_key_legacy",
|
|
6958
|
+
// mnk_ + 43 base64url: keys minted by hand before AuthManager's hex form
|
|
6959
|
+
// (production's only key in 2026-10 has this shape, and one stored memory
|
|
6960
|
+
// held a development key in it). Authentication accepts any mnk_ bearer.
|
|
6961
|
+
// The body needs upper and lower case and a digit, so a snake_case
|
|
6962
|
+
// identifier that starts mnk_ is not taken for one.
|
|
6963
|
+
pattern: /(?<![A-Za-z0-9_])mnk_(?=[A-Za-z0-9_-]*[A-Z])(?=[A-Za-z0-9_-]*[a-z])(?=[A-Za-z0-9_-]*[0-9])[A-Za-z0-9_-]{40,}(?![A-Za-z0-9_-])/g,
|
|
6964
|
+
replacement: REDACTED
|
|
6965
|
+
},
|
|
6966
|
+
{
|
|
6967
|
+
kind: "named_value",
|
|
6968
|
+
pattern: /(\b[A-Za-z_][A-Za-z0-9_]*(?:_TOKEN|_KEY|_SECRET|_PASSWORD|_PASS|APIKEY|API_KEY)\s*(?:=|:)\s*)([^\s]{16,})/gi,
|
|
6969
|
+
replacement: redactContextValue,
|
|
6970
|
+
secretGroup: 2
|
|
6971
|
+
},
|
|
6972
|
+
{
|
|
6973
|
+
kind: "connection_string",
|
|
6974
|
+
// scheme://user:password@host: only the password is replaced; scheme,
|
|
6975
|
+
// user, host and database stay readable. The user may be empty
|
|
6976
|
+
// (redis://:password@host). The password runs to the last `@` before a
|
|
6977
|
+
// path, query, fragment, quote or whitespace, so an unencoded `@` inside
|
|
6978
|
+
// it is still covered. Runs after named_value, which already replaces a
|
|
6979
|
+
// whole URL assigned to a secret-named variable.
|
|
6980
|
+
pattern: /\b((?:postgres(?:ql)?|mysql|mariadb|mongodb|rediss?|amqps?|mssql|sqlserver)(?:\+[a-z0-9]+)?:\/\/[^\s:/?#@'"`<>]{0,256}:)([^\s/?#'"`]{1,512})@/gi,
|
|
6981
|
+
replacement: redactUrlPassword,
|
|
6982
|
+
secretGroup: 2
|
|
6983
|
+
},
|
|
6984
|
+
{
|
|
6985
|
+
kind: "url_basic_auth",
|
|
6986
|
+
// https://user:password@host: same shape and placeholder rules as a
|
|
6987
|
+
// connection string; only the password is replaced.
|
|
6988
|
+
pattern: /\b(https?:\/\/[^\s:/?#@'"`<>]{0,256}:)([^\s/?#'"`]{1,512})@/gi,
|
|
6989
|
+
replacement: redactUrlPassword,
|
|
6990
|
+
secretGroup: 2
|
|
6991
|
+
},
|
|
6992
|
+
// Command-line passwords. Each keeps the command and replaces only the
|
|
6993
|
+
// password word; an expansion or placeholder in that position is left.
|
|
6994
|
+
{
|
|
6995
|
+
// sshpass -p <password> (also -p'<password>' and -p"<password>"), after
|
|
6996
|
+
// any other sshpass flags. 13 memories, 11 scanner chunks, 15 versions and
|
|
6997
|
+
// 6 dated facts in production held one on 2026-10-12.
|
|
6998
|
+
kind: "sshpass_password",
|
|
6999
|
+
pattern: new RegExp(String.raw`(${OPENING_QUOTE}\bsshpass(?:[ \t]+-[a-oq-zA-Z]\S*)*[ \t]+-p[ \t]*)(${SHELL_WORD})()(?=((?:[ \t]+(?:${SSHPASS_COMMAND})(?![\w-]))?))`, "g"),
|
|
7000
|
+
replacement: redactSshpassWord,
|
|
7001
|
+
secretGroup: 3,
|
|
7002
|
+
commandLine: true
|
|
7003
|
+
},
|
|
7004
|
+
{
|
|
7005
|
+
// Environment variables whose only purpose is a password, in shell
|
|
7006
|
+
// assignment form (no space around `=`): libpq's PGPASSWORD (one memory,
|
|
7007
|
+
// version and fact in production), MySQL's MYSQL_PWD, sshpass -e's
|
|
7008
|
+
// SSHPASS. named_value needs an `_PASSWORD`-style suffix and 16
|
|
7009
|
+
// characters, so it misses all three. Not an awk program that matches or
|
|
7010
|
+
// prints the assignment: `/^PGPASSWORD=/ { print "PGPASSWORD=" pw }`.
|
|
7011
|
+
kind: "password_env_var",
|
|
7012
|
+
pattern: new RegExp(String.raw`(${OPENING_QUOTE}\b(?:PGPASSWORD|MYSQL_PWD|SSHPASS)=)(${SHELL_WORD})()`, "g"),
|
|
7013
|
+
replacement: redactQuotedShellWord,
|
|
7014
|
+
secretGroup: 3,
|
|
7015
|
+
commandLine: true
|
|
7016
|
+
},
|
|
7017
|
+
{
|
|
7018
|
+
// --password=<value>, the long option every CLI that takes one spells
|
|
7019
|
+
// this way. The `=` keeps prose about the option ("--password is
|
|
7020
|
+
// required") out; the spaced form is not matched for that reason.
|
|
7021
|
+
kind: "password_option",
|
|
7022
|
+
pattern: new RegExp(String.raw`(${OPENING_QUOTE}(?<![\w-])--password=)(${SHELL_WORD})()`, "g"),
|
|
7023
|
+
replacement: redactQuotedShellWord,
|
|
7024
|
+
secretGroup: 3,
|
|
7025
|
+
commandLine: true
|
|
7026
|
+
},
|
|
7027
|
+
{
|
|
7028
|
+
// echo <password> | sudo -S: sudo reads the password from stdin. One
|
|
7029
|
+
// memory, two versions and two facts in production.
|
|
7030
|
+
kind: "sudo_password",
|
|
7031
|
+
pattern: new RegExp(String.raw`(\becho[ \t]+(?:-[neE]+[ \t]+)?)(${SHELL_WORD})([ \t]*\|[ \t]*sudo\b[^|\n]*?[ \t](?:-[A-Za-z]*S[A-Za-z]*|--stdin)\b)`, "g"),
|
|
7032
|
+
replacement: redactShellWord,
|
|
7033
|
+
secretGroup: 2,
|
|
7034
|
+
commandLine: true
|
|
7035
|
+
}
|
|
7036
|
+
];
|
|
7037
|
+
|
|
7038
|
+
// packages/shared/dist/sourceRedaction.js
|
|
7039
|
+
init_secretPatterns();
|
|
7040
|
+
|
|
6780
7041
|
// packages/shared/dist/codeScanner.js
|
|
7042
|
+
init_protectedPaths();
|
|
7043
|
+
init_projectIdentityFile();
|
|
6781
7044
|
var MAX_SCANNED_FILE_BYTES = 10 * 1024 * 1024;
|
|
6782
7045
|
var BUILT_IN_IGNORE_DIRS = [
|
|
6783
7046
|
// JS / web
|
package/dist/sbom.json
CHANGED
|
@@ -17,13 +17,13 @@
|
|
|
17
17
|
}
|
|
18
18
|
],
|
|
19
19
|
"component": {
|
|
20
|
-
"bom-ref": "@mnemonik/cli@0.1.
|
|
20
|
+
"bom-ref": "@mnemonik/cli@0.1.155",
|
|
21
21
|
"type": "library",
|
|
22
22
|
"name": "@mnemonik/cli",
|
|
23
|
-
"version": "0.1.
|
|
23
|
+
"version": "0.1.155",
|
|
24
24
|
"scope": "required",
|
|
25
25
|
"description": "Mnemonik installer and local project helper",
|
|
26
|
-
"purl": "pkg:npm/%40mnemonik/cli@0.1.
|
|
26
|
+
"purl": "pkg:npm/%40mnemonik/cli@0.1.155",
|
|
27
27
|
"properties": [],
|
|
28
28
|
"externalReferences": [
|
|
29
29
|
{
|
|
@@ -35,12 +35,12 @@
|
|
|
35
35
|
},
|
|
36
36
|
"components": [
|
|
37
37
|
{
|
|
38
|
-
"bom-ref": "@mnemonik/credentials@0.1.
|
|
38
|
+
"bom-ref": "@mnemonik/credentials@0.1.155",
|
|
39
39
|
"type": "library",
|
|
40
40
|
"name": "@mnemonik/credentials",
|
|
41
|
-
"version": "0.1.
|
|
41
|
+
"version": "0.1.155",
|
|
42
42
|
"scope": "required",
|
|
43
|
-
"purl": "pkg:npm/%40mnemonik/credentials@0.1.
|
|
43
|
+
"purl": "pkg:npm/%40mnemonik/credentials@0.1.155",
|
|
44
44
|
"properties": [],
|
|
45
45
|
"externalReferences": [
|
|
46
46
|
{
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
]
|
|
51
51
|
},
|
|
52
52
|
{
|
|
53
|
-
"bom-ref": "@mnemonik/local-setup@0.1.
|
|
53
|
+
"bom-ref": "@mnemonik/local-setup@0.1.155",
|
|
54
54
|
"type": "library",
|
|
55
55
|
"name": "@mnemonik/local-setup",
|
|
56
|
-
"version": "0.1.
|
|
56
|
+
"version": "0.1.155",
|
|
57
57
|
"scope": "required",
|
|
58
|
-
"purl": "pkg:npm/%40mnemonik/local-setup@0.1.
|
|
58
|
+
"purl": "pkg:npm/%40mnemonik/local-setup@0.1.155",
|
|
59
59
|
"properties": [],
|
|
60
60
|
"externalReferences": [
|
|
61
61
|
{
|
|
@@ -65,14 +65,14 @@
|
|
|
65
65
|
]
|
|
66
66
|
},
|
|
67
67
|
{
|
|
68
|
-
"bom-ref": "@mnemonik/shared@7.141.
|
|
68
|
+
"bom-ref": "@mnemonik/shared@7.141.1",
|
|
69
69
|
"type": "library",
|
|
70
70
|
"name": "@mnemonik/shared",
|
|
71
|
-
"version": "7.141.
|
|
71
|
+
"version": "7.141.1",
|
|
72
72
|
"scope": "required",
|
|
73
73
|
"author": "Anthony",
|
|
74
74
|
"description": "Shared constants and utilities for Mnemonik packages",
|
|
75
|
-
"purl": "pkg:npm/%40mnemonik/shared@7.141.
|
|
75
|
+
"purl": "pkg:npm/%40mnemonik/shared@7.141.1",
|
|
76
76
|
"properties": [],
|
|
77
77
|
"externalReferences": [
|
|
78
78
|
{
|
|
@@ -271,29 +271,29 @@
|
|
|
271
271
|
],
|
|
272
272
|
"dependencies": [
|
|
273
273
|
{
|
|
274
|
-
"ref": "@mnemonik/cli@0.1.
|
|
274
|
+
"ref": "@mnemonik/cli@0.1.155",
|
|
275
275
|
"dependsOn": [
|
|
276
|
-
"@mnemonik/credentials@0.1.
|
|
277
|
-
"@mnemonik/local-setup@0.1.
|
|
278
|
-
"@mnemonik/shared@7.141.
|
|
276
|
+
"@mnemonik/credentials@0.1.155",
|
|
277
|
+
"@mnemonik/local-setup@0.1.155",
|
|
278
|
+
"@mnemonik/shared@7.141.1",
|
|
279
279
|
"smol-toml@1.9.0"
|
|
280
280
|
]
|
|
281
281
|
},
|
|
282
282
|
{
|
|
283
|
-
"ref": "@mnemonik/credentials@0.1.
|
|
283
|
+
"ref": "@mnemonik/credentials@0.1.155",
|
|
284
284
|
"dependsOn": [
|
|
285
|
-
"@mnemonik/local-setup@0.1.
|
|
285
|
+
"@mnemonik/local-setup@0.1.155"
|
|
286
286
|
]
|
|
287
287
|
},
|
|
288
288
|
{
|
|
289
|
-
"ref": "@mnemonik/local-setup@0.1.
|
|
289
|
+
"ref": "@mnemonik/local-setup@0.1.155",
|
|
290
290
|
"dependsOn": [
|
|
291
|
-
"@mnemonik/shared@7.141.
|
|
291
|
+
"@mnemonik/shared@7.141.1",
|
|
292
292
|
"proper-lockfile@4.1.2"
|
|
293
293
|
]
|
|
294
294
|
},
|
|
295
295
|
{
|
|
296
|
-
"ref": "@mnemonik/shared@7.141.
|
|
296
|
+
"ref": "@mnemonik/shared@7.141.1",
|
|
297
297
|
"dependsOn": [
|
|
298
298
|
"ignore@7.0.12",
|
|
299
299
|
"web-tree-sitter@0.27.0"
|