Skip to content

Commit 31140a7

Browse files
stevenhilderdarcyclarke
authored andcommittedFeb 25, 2020
Ensure passwords in hosted Git URLs are correctly escaped
PR-URL: #58 Credit: @stevenhilder Close: #58 Reviewed-by: @darcyclarke
1 parent 4636ac9 commit 31140a7

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed
 

‎index.js

+10-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ function fromUrl (giturl, opts) {
4747
var gitHostInfo = gitHosts[gitHostName]
4848
var auth = null
4949
if (parsed.auth && authProtocols[parsed.protocol]) {
50-
auth = decodeURIComponent(parsed.auth)
50+
auth = parsed.auth
5151
}
5252
var committish = parsed.hash ? decodeURIComponent(parsed.hash.substr(1)) : null
5353
var user = null
@@ -106,7 +106,15 @@ function fixupUnqualifiedGist (giturl) {
106106

107107
function parseGitUrl (giturl) {
108108
var matched = giturl.match(/^([^@]+)@([^:/]+):[/]?((?:[^/]+[/])?[^/]+?)(?:[.]git)?(#.*)?$/)
109-
if (!matched) return url.parse(giturl)
109+
if (!matched) {
110+
var legacy = url.parse(giturl)
111+
if (legacy.auth) {
112+
var whatwg = new url.URL(giturl)
113+
legacy.auth = whatwg.username || ''
114+
if (whatwg.password) legacy.auth += ':' + whatwg.password
115+
}
116+
return legacy
117+
}
110118
return {
111119
protocol: 'git+ssh:',
112120
slashes: true,

‎test/auth.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
var HostedGitInfo = require('../')
2+
3+
var tap = require('tap')
4+
var url = require('url')
5+
6+
// Auth credentials with special characters (colon and/or at-sign) should remain correctly escaped
7+
var parsedInfo = HostedGitInfo.fromUrl('https://user%3An%40me:p%40ss%3Aword@github.com/npm/hosted-git-info.git')
8+
tap.equal(parsedInfo.auth, 'user%3An%40me:p%40ss%3Aword')
9+
10+
// Node.js' built-in `url` module should be able to parse the resulting url
11+
var parsedUrl = new url.URL(parsedInfo.toString())
12+
tap.equal(parsedUrl.username, 'user%3An%40me')
13+
tap.equal(parsedUrl.password, 'p%40ss%3Aword')
14+
tap.equal(parsedUrl.hostname, 'github.com')
15+
16+
// For full backwards-compatibility; support auth where only username or only password is provided
17+
tap.equal(HostedGitInfo.fromUrl('https://user%3An%40me@github.com/npm/hosted-git-info.git').auth, 'user%3An%40me')
18+
tap.equal(HostedGitInfo.fromUrl('https://:p%40ss%3Aword@github.com/npm/hosted-git-info.git').auth, ':p%40ss%3Aword')

0 commit comments

Comments
 (0)
Please sign in to comment.