Skip to content

Commit

Permalink
feat: clean token from logged urls (#107)
Browse files Browse the repository at this point in the history
* chore: remove unused log file

* feat: clean token from logged urls and export helper
  • Loading branch information
lukekarrys committed Mar 22, 2022
1 parent 4f82d0c commit 9894911
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 27 deletions.
15 changes: 2 additions & 13 deletions lib/check-response.js
Expand Up @@ -4,6 +4,7 @@ const errors = require('./errors.js')
const { Response } = require('minipass-fetch')
const defaultOpts = require('./default-opts.js')
const log = require('proc-log')
const cleanUrl = require('./clean-url.js')

/* eslint-disable-next-line max-len */
const moreInfoUrl = 'https://github.com/npm/cli/wiki/No-auth-for-URI,-but-auth-present-for-scoped-registry'
Expand Down Expand Up @@ -45,19 +46,7 @@ function logRequest (method, res, startTime) {
const attemptStr = attempt && attempt > 1 ? ` attempt #${attempt}` : ''
const cacheStatus = res.headers.get('x-local-cache-status')
const cacheStr = cacheStatus ? ` (cache ${cacheStatus})` : ''

let urlStr
try {
const { URL } = require('url')
const url = new URL(res.url)
if (url.password) {
url.password = '***'
}

urlStr = url.toString()
} catch (er) {
urlStr = res.url
}
const urlStr = cleanUrl(res.url)

log.http(
'fetch',
Expand Down
24 changes: 24 additions & 0 deletions lib/clean-url.js
@@ -0,0 +1,24 @@
const { URL } = require('url')

const replace = '***'
const tokenRegex = /\bnpm_[a-zA-Z0-9]{36}\b/g
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

const cleanUrl = (str) => {
if (typeof str !== 'string' || !str) {
return str
}

try {
const url = new URL(str)
if (url.password) {
str = str.replace(url.password, replace)
}
} catch {}

return str
.replace(tokenRegex, `npm_${replace}`)
.replace(guidRegex, `npm_${replace}`)
}

module.exports = cleanUrl
2 changes: 2 additions & 0 deletions lib/index.js
Expand Up @@ -239,3 +239,5 @@ function getHeaders (uri, auth, opts) {

return headers
}

module.exports.cleanUrl = require('./clean-url.js')
14 changes: 0 additions & 14 deletions lib/silentlog.js

This file was deleted.

28 changes: 28 additions & 0 deletions test/check-response.js
Expand Up @@ -135,6 +135,34 @@ t.test('redact password from log', t => {
t.match(msg, /^GET 200 http:\/\/username:\*\*\*@example.com\/foo\/bar\/baz [0-9]+m?s/)
})

t.test('redact well known token from log', t => {
const headers = new Headers()
const EE = require('events')
headers.get = header => undefined
const res = Object.assign({}, mockFetchRes, {
headers,
status: 200,
url: `http://example.com/foo/bar/baz/npm_${'a'.repeat(36)}`,
body: new EE(),
})
t.plan(2)
let header, msg
process.on('log', (level, ...args) => {
if (level === 'http') {
;[header, msg] = args
}
})
checkResponse({
method: 'get',
res,
registry,
startTime,
})
res.body.emit('end')
t.equal(header, 'fetch')
t.match(msg, /^GET 200 http:\/\/example.com\/foo\/bar\/baz\/npm_\*\*\* [0-9]+m?s/)
})

/* eslint-disable-next-line max-len */
const moreInfoUrl = 'https://github.com/npm/cli/wiki/No-auth-for-URI,-but-auth-present-for-scoped-registry'

Expand Down

0 comments on commit 9894911

Please sign in to comment.