@pnpm/error 1100.2.1 → 1100.2.2
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/CHANGELOG.md +7 -0
- package/lib/index.d.ts +13 -0
- package/lib/index.js +27 -25
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
package/lib/index.d.ts
CHANGED
|
@@ -38,6 +38,19 @@ export declare class FetchTimeoutError extends PnpmError {
|
|
|
38
38
|
cause: unknown;
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Strip `user:pass@` (or `user@`) userinfo that follows a URL scheme in any
|
|
43
|
+
* text, e.g. `GET https://user:pass@host/pkg: ...` → `GET https://host/pkg: ...`.
|
|
44
|
+
* A registry configured as `https://user:pass@host/` would otherwise leak its
|
|
45
|
+
* embedded basic-auth credentials into every error message that interpolates
|
|
46
|
+
* the request URL (terminal output, CI logs). `FetchError` already hides the
|
|
47
|
+
* auth *header*; this covers credentials carried in the URL itself.
|
|
48
|
+
*
|
|
49
|
+
* Implemented as a single forward scan rather than a regex: `text` is
|
|
50
|
+
* uncontrolled (it interpolates the request URL), so a backtracking pattern is
|
|
51
|
+
* a ReDoS vector, and the scan strips up to the **last** `@` in the authority
|
|
52
|
+
* so a raw `@` inside the password (`user:p@ss@host`) doesn't leak its tail.
|
|
53
|
+
*/
|
|
41
54
|
export declare function redactUrlCredentials(text: string): string;
|
|
42
55
|
/**
|
|
43
56
|
* Make untrusted, URL-bearing text safe to print or log: redact inline
|
package/lib/index.js
CHANGED
|
@@ -68,19 +68,6 @@ export class FetchTimeoutError extends PnpmError {
|
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
-
/**
|
|
72
|
-
* Strip `user:pass@` (or `user@`) userinfo that follows a URL scheme in any
|
|
73
|
-
* text, e.g. `GET https://user:pass@host/pkg: …` → `GET https://host/pkg: …`.
|
|
74
|
-
* A registry configured as `https://user:pass@host/` would otherwise leak its
|
|
75
|
-
* embedded basic-auth credentials into every error message that interpolates
|
|
76
|
-
* the request URL (terminal output, CI logs). `FetchError` already hides the
|
|
77
|
-
* auth *header*; this covers credentials carried in the URL itself.
|
|
78
|
-
*
|
|
79
|
-
* Implemented as a single forward scan rather than a regex: `text` is
|
|
80
|
-
* uncontrolled (it interpolates the request URL), so a backtracking pattern is
|
|
81
|
-
* a ReDoS vector, and the scan strips up to the **last** `@` in the authority
|
|
82
|
-
* so a raw `@` inside the password (`user:p@ss@host`) doesn't leak its tail.
|
|
83
|
-
*/
|
|
84
71
|
/**
|
|
85
72
|
* A request URL made safe to print: its `user:pass@` userinfo and control
|
|
86
73
|
* characters redacted ({@link redactAndSanitize}), then everything from the
|
|
@@ -107,6 +94,19 @@ function redactUrlSecrets(url) {
|
|
|
107
94
|
return '[hidden]';
|
|
108
95
|
return sanitized.split(/[?#]/)[0];
|
|
109
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Strip `user:pass@` (or `user@`) userinfo that follows a URL scheme in any
|
|
99
|
+
* text, e.g. `GET https://user:pass@host/pkg: ...` → `GET https://host/pkg: ...`.
|
|
100
|
+
* A registry configured as `https://user:pass@host/` would otherwise leak its
|
|
101
|
+
* embedded basic-auth credentials into every error message that interpolates
|
|
102
|
+
* the request URL (terminal output, CI logs). `FetchError` already hides the
|
|
103
|
+
* auth *header*; this covers credentials carried in the URL itself.
|
|
104
|
+
*
|
|
105
|
+
* Implemented as a single forward scan rather than a regex: `text` is
|
|
106
|
+
* uncontrolled (it interpolates the request URL), so a backtracking pattern is
|
|
107
|
+
* a ReDoS vector, and the scan strips up to the **last** `@` in the authority
|
|
108
|
+
* so a raw `@` inside the password (`user:p@ss@host`) doesn't leak its tail.
|
|
109
|
+
*/
|
|
110
110
|
export function redactUrlCredentials(text) {
|
|
111
111
|
let result = '';
|
|
112
112
|
let cursor = 0;
|
|
@@ -122,21 +122,23 @@ export function redactUrlCredentials(text) {
|
|
|
122
122
|
// bare `://` in the text is left untouched.
|
|
123
123
|
if (schemeSep === 0 || !isSchemeTailChar(text.charCodeAt(schemeSep - 1)))
|
|
124
124
|
continue;
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
for (let i = authorityStart; i < text.length; i++) {
|
|
129
|
-
const code = text.charCodeAt(i);
|
|
130
|
-
if (code === 0x2f || code === 0x3f || code === 0x23 || isAsciiWhitespace(code))
|
|
131
|
-
break;
|
|
132
|
-
if (code === 0x40)
|
|
133
|
-
lastAt = i;
|
|
134
|
-
}
|
|
135
|
-
if (lastAt !== -1)
|
|
136
|
-
cursor = lastAt + 1;
|
|
125
|
+
const userinfoEnd = findAuthorityUserinfoEnd(text, authorityStart);
|
|
126
|
+
if (userinfoEnd !== -1)
|
|
127
|
+
cursor = userinfoEnd;
|
|
137
128
|
}
|
|
138
129
|
return result;
|
|
139
130
|
}
|
|
131
|
+
function findAuthorityUserinfoEnd(text, authorityStart) {
|
|
132
|
+
let lastAt = -1;
|
|
133
|
+
for (let index = authorityStart; index < text.length; index++) {
|
|
134
|
+
const code = text.charCodeAt(index);
|
|
135
|
+
if (code === 0x2f || code === 0x3f || code === 0x23 || isAsciiWhitespace(code))
|
|
136
|
+
break;
|
|
137
|
+
if (code === 0x40)
|
|
138
|
+
lastAt = index;
|
|
139
|
+
}
|
|
140
|
+
return lastAt === -1 ? -1 : lastAt + 1;
|
|
141
|
+
}
|
|
140
142
|
/**
|
|
141
143
|
* Make untrusted, URL-bearing text safe to print or log: redact inline
|
|
142
144
|
* `user:pass@` credentials ({@link redactUrlCredentials}) and strip every
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/error",
|
|
3
|
-
"version": "1100.2.
|
|
3
|
+
"version": "1100.2.2",
|
|
4
4
|
"description": "An error class for pnpm errors",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"!*.map"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@pnpm/constants": "1102.0.
|
|
31
|
+
"@pnpm/constants": "1102.0.1"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@jest/globals": "30.4.1",
|
|
35
|
-
"@pnpm/error": "1100.2.
|
|
35
|
+
"@pnpm/error": "1100.2.2"
|
|
36
36
|
},
|
|
37
37
|
"engines": {
|
|
38
38
|
"node": ">=22.13"
|