Skip to content

Commit 9894911

Browse files
authored
feat: clean token from logged urls (#107)
* chore: remove unused log file * feat: clean token from logged urls and export helper
1 parent 4f82d0c commit 9894911

File tree

5 files changed

+56
-27
lines changed

5 files changed

+56
-27
lines changed

lib/check-response.js

+2-13
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const errors = require('./errors.js')
44
const { Response } = require('minipass-fetch')
55
const defaultOpts = require('./default-opts.js')
66
const log = require('proc-log')
7+
const cleanUrl = require('./clean-url.js')
78

89
/* eslint-disable-next-line max-len */
910
const moreInfoUrl = 'https://github.com/npm/cli/wiki/No-auth-for-URI,-but-auth-present-for-scoped-registry'
@@ -45,19 +46,7 @@ function logRequest (method, res, startTime) {
4546
const attemptStr = attempt && attempt > 1 ? ` attempt #${attempt}` : ''
4647
const cacheStatus = res.headers.get('x-local-cache-status')
4748
const cacheStr = cacheStatus ? ` (cache ${cacheStatus})` : ''
48-
49-
let urlStr
50-
try {
51-
const { URL } = require('url')
52-
const url = new URL(res.url)
53-
if (url.password) {
54-
url.password = '***'
55-
}
56-
57-
urlStr = url.toString()
58-
} catch (er) {
59-
urlStr = res.url
60-
}
49+
const urlStr = cleanUrl(res.url)
6150

6251
log.http(
6352
'fetch',

lib/clean-url.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const { URL } = require('url')
2+
3+
const replace = '***'
4+
const tokenRegex = /\bnpm_[a-zA-Z0-9]{36}\b/g
5+
const guidRegex = /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/g
6+
7+
const cleanUrl = (str) => {
8+
if (typeof str !== 'string' || !str) {
9+
return str
10+
}
11+
12+
try {
13+
const url = new URL(str)
14+
if (url.password) {
15+
str = str.replace(url.password, replace)
16+
}
17+
} catch {}
18+
19+
return str
20+
.replace(tokenRegex, `npm_${replace}`)
21+
.replace(guidRegex, `npm_${replace}`)
22+
}
23+
24+
module.exports = cleanUrl

lib/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -239,3 +239,5 @@ function getHeaders (uri, auth, opts) {
239239

240240
return headers
241241
}
242+
243+
module.exports.cleanUrl = require('./clean-url.js')

lib/silentlog.js

-14
This file was deleted.

test/check-response.js

+28
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,34 @@ t.test('redact password from log', t => {
135135
t.match(msg, /^GET 200 http:\/\/username:\*\*\*@example.com\/foo\/bar\/baz [0-9]+m?s/)
136136
})
137137

138+
t.test('redact well known token from log', t => {
139+
const headers = new Headers()
140+
const EE = require('events')
141+
headers.get = header => undefined
142+
const res = Object.assign({}, mockFetchRes, {
143+
headers,
144+
status: 200,
145+
url: `http://example.com/foo/bar/baz/npm_${'a'.repeat(36)}`,
146+
body: new EE(),
147+
})
148+
t.plan(2)
149+
let header, msg
150+
process.on('log', (level, ...args) => {
151+
if (level === 'http') {
152+
;[header, msg] = args
153+
}
154+
})
155+
checkResponse({
156+
method: 'get',
157+
res,
158+
registry,
159+
startTime,
160+
})
161+
res.body.emit('end')
162+
t.equal(header, 'fetch')
163+
t.match(msg, /^GET 200 http:\/\/example.com\/foo\/bar\/baz\/npm_\*\*\* [0-9]+m?s/)
164+
})
165+
138166
/* eslint-disable-next-line max-len */
139167
const moreInfoUrl = 'https://github.com/npm/cli/wiki/No-auth-for-URI,-but-auth-present-for-scoped-registry'
140168

0 commit comments

Comments
 (0)