dl-git-repo-safe 1.0.0

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 ADDED
@@ -0,0 +1,22 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
+
7
+ ## [1.0.0] - 2026-04-01
8
+
9
+ ### Changed
10
+ - Replaced `git-clone@^0.1.0` with `git-clone-safe@^1.2.0`
11
+ - Updated `require('git-clone')` to `require('git-clone-safe')` in `index.js`
12
+
13
+ ### Security
14
+ - **Fixed CVE-2022-25900**: Command injection vulnerability in `git-clone` package.
15
+ The original `git-clone` passes unsanitized arguments to the git binary, allowing
16
+ an attacker to inject arbitrary commands via crafted repository URLs. This fork
17
+ uses `git-clone-safe` which properly sanitizes all git clone arguments.
18
+
19
+ ### Note
20
+ - This is a fork of [`download-git-repo@3.0.2`](https://gitlab.com/flippidippi/download-git-repo)
21
+ with the single change of replacing the vulnerable dependency.
22
+ - The API is 100% compatible with the original package — drop-in replacement.
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) download-git-repo-safe contributors
4
+ Copyright (c) 2016 flippidippi (original download-git-repo)
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,149 @@
1
+ # download-git-repo-safe
2
+
3
+ > **⚠️ Security Notice**: This is a security-patched fork of [`download-git-repo`](https://gitlab.com/flippidippi/download-git-repo). It replaces the vulnerable `git-clone` dependency with [`git-clone-safe`](https://www.npmjs.com/package/git-clone-safe) to fix **CVE-2022-25900** (command injection via git clone).
4
+
5
+ Download and extract a git repository (GitHub, GitLab, Bitbucket) from node.
6
+
7
+ ## What Changed?
8
+
9
+ | | `download-git-repo` (original) | `download-git-repo-safe` (this fork) |
10
+ |---|---|---|
11
+ | `git-clone` | `^0.1.0` (vulnerable) | replaced with `git-clone-safe@^1.2.0` |
12
+ | CVE-2022-25900 | **Affected** | **Fixed** |
13
+ | API | — | **100% compatible** (drop-in replacement) |
14
+
15
+ ### CVE-2022-25900
16
+
17
+ The original `download-git-repo` depends on `git-clone@^0.1.0`, which is vulnerable to command injection. An attacker can craft a malicious repository URL that executes arbitrary commands on the system. This fork replaces `git-clone` with `git-clone-safe`, which properly sanitizes git clone arguments.
18
+
19
+ ## Migration
20
+
21
+ Replace `download-git-repo` with `download-git-repo-safe`:
22
+
23
+ ```bash
24
+ npm uninstall download-git-repo
25
+ npm install download-git-repo-safe
26
+ ```
27
+
28
+ Or use npm/yarn overrides to replace it transitively:
29
+
30
+ ```json
31
+ {
32
+ "overrides": {
33
+ "download-git-repo": "npm:download-git-repo-safe@^1.0.0"
34
+ }
35
+ }
36
+ ```
37
+
38
+ No code changes required — the API is identical.
39
+
40
+ ## Installation
41
+
42
+ $ npm install download-git-repo-safe
43
+
44
+ ## API
45
+
46
+ ### download(repository, destination, options, callback)
47
+
48
+ Download a git `repository` to a `destination` folder with `options`, and `callback`.
49
+
50
+ #### repository
51
+ The shorthand repository string to download the repository from:
52
+
53
+ - **GitHub** - `github:owner/name` or simply `owner/name`
54
+ - **GitLab** - `gitlab:owner/name`
55
+ - **Bitbucket** - `bitbucket:owner/name`
56
+
57
+ The `repository` parameter defaults to the `master` branch, but you can specify a branch or tag as a URL fragment like `owner/name#my-branch`.
58
+ In addition to specifying the type of where to download, you can also specify a custom origin like `gitlab:custom.com:owner/name`.
59
+ Custom origin will default to `https` or `git@` for http and clone downloads respectively, unless protocol is specified.
60
+ Feel free to submit an issue or pull request for additional origin options.
61
+
62
+ In addition to having the shorthand for supported git hosts, you can also hit a repository directly with:
63
+
64
+ - **Direct** - `direct:url`
65
+
66
+ This will bypass the shorthand normalizer and pass `url` directly.
67
+ If using `direct` without clone, you must pass the full url to the zip file, including paths to branches if needed.
68
+ If using `direct` with clone, you must pass the full url to the git repo and you can specify a branch like `direct:url#my-branch`.
69
+
70
+ #### destination
71
+ The file path to download the repository to.
72
+
73
+ #### options
74
+ An optional options object parameter with download options. Options include:
75
+
76
+ - `clone` - boolean default `false` - If true use `git clone` instead of an http download. While this can be a bit slower, it does allow private repositories to be used if the appropriate SSH keys are setup.
77
+ - All other options (`proxy`, `headers`, `filter`, etc.) will be passed down accordingly and may override defaults
78
+ - Additional download options: https://github.com/kevva/download#options
79
+ - Additional clone options: https://github.com/jaz303/git-clone#clonerepo-targetpath-options-cb
80
+
81
+ #### callback
82
+ The callback function as `function (err)`.
83
+
84
+ ## Examples
85
+ ### Shorthand
86
+ Using http download from Github repository at master.
87
+ ```javascript
88
+ var download = require('download-git-repo-safe')
89
+ download('flippidippi/download-git-repo-fixture', 'test/tmp', function (err) {
90
+ console.log(err ? 'Error' : 'Success')
91
+ })
92
+ ```
93
+
94
+ Using git clone from Bitbucket repository at my-branch.
95
+ ```javascript
96
+ download('bitbucket:flippidippi/download-git-repo-fixture#my-branch', 'test/tmp', { clone: true }, function (err) {
97
+ console.log(err ? 'Error' : 'Success')
98
+ })
99
+ ```
100
+
101
+ Using http download from GitLab repository with custom origin and token.
102
+ ```javascript
103
+ download('gitlab:mygitlab.com:flippidippi/download-git-repo-fixture#my-branch', 'test/tmp', { headers: { 'PRIVATE-TOKEN': '1234' } }, function (err) {
104
+ console.log(err ? 'Error' : 'Success')
105
+ })
106
+ ```
107
+
108
+ Using git clone from GitLab repository with custom origin and protocol.
109
+ Note that the repository type (`github`, `gitlab` etc.) is not required if cloning from a custom origin.
110
+ ```javascript
111
+ download('https://mygitlab.com:flippidippi/download-git-repo-fixture#my-branch', 'test/tmp', { clone: true }, function (err) {
112
+ console.log(err ? 'Error' : 'Success')
113
+ })
114
+ ```
115
+
116
+ ### Direct
117
+ Using http download from direct url.
118
+ ```javascript
119
+ download('direct:https://gitlab.com/flippidippi/download-git-repo-fixture/repository/archive.zip', 'test/tmp', function (err) {
120
+ console.log(err ? 'Error' : 'Success')
121
+ })
122
+ ```
123
+
124
+ Using git clone from direct url at master.
125
+ ```javascript
126
+ download('direct:https://gitlab.com/flippidippi/download-git-repo-fixture.git', 'test/tmp', { clone: true }, function (err) {
127
+ console.log(err ? 'Error' : 'Success')
128
+ })
129
+ ```
130
+
131
+ Using git clone from direct url at my-branch.
132
+ ```javascript
133
+ download('direct:https://gitlab.com/flippidippi/download-git-repo-fixture.git#my-branch', 'test/tmp', { clone: true }, function (err) {
134
+ console.log(err ? 'Error' : 'Success')
135
+ })
136
+ ```
137
+
138
+ ## Verification
139
+
140
+ To confirm `git-clone-safe` is installed instead of `git-clone`:
141
+
142
+ ```bash
143
+ npm ls git-clone git-clone-safe
144
+ npm audit
145
+ ```
146
+
147
+ ## License
148
+
149
+ MIT
package/index.js ADDED
@@ -0,0 +1,167 @@
1
+ var downloadUrl = require('download')
2
+ var gitclone = require('git-clone-safe')
3
+ var rm = require('rimraf').sync
4
+
5
+ /**
6
+ * Expose `download`.
7
+ */
8
+
9
+ module.exports = download
10
+
11
+ /**
12
+ * Download `repo` to `dest` and callback `fn(err)`.
13
+ *
14
+ * @param {String} repo
15
+ * @param {String} dest
16
+ * @param {Object} opts
17
+ * @param {Function} fn
18
+ */
19
+
20
+ function download (repo, dest, opts, fn) {
21
+ if (typeof opts === 'function') {
22
+ fn = opts
23
+ opts = null
24
+ }
25
+ opts = opts || {}
26
+ var clone = opts.clone || false
27
+ delete opts.clone
28
+
29
+ repo = normalize(repo)
30
+ var url = repo.url || getUrl(repo, clone)
31
+
32
+ if (clone) {
33
+ var cloneOptions = {
34
+ checkout: repo.checkout,
35
+ shallow: repo.checkout === 'master',
36
+ ...opts
37
+ }
38
+ gitclone(url, dest, cloneOptions, function (err) {
39
+ if (err === undefined) {
40
+ rm(dest + '/.git')
41
+ fn()
42
+ } else {
43
+ fn(err)
44
+ }
45
+ })
46
+ } else {
47
+ var downloadOptions = {
48
+ extract: true,
49
+ strip: 1,
50
+ mode: '666',
51
+ ...opts,
52
+ headers: {
53
+ accept: 'application/zip',
54
+ ...(opts.headers || {})
55
+ }
56
+ }
57
+ downloadUrl(url, dest, downloadOptions)
58
+ .then(function (data) {
59
+ fn()
60
+ })
61
+ .catch(function (err) {
62
+ fn(err)
63
+ })
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Normalize a repo string.
69
+ *
70
+ * @param {String} repo
71
+ * @return {Object}
72
+ */
73
+
74
+ function normalize (repo) {
75
+ var regex = /^(?:(direct):([^#]+)(?:#(.+))?)$/
76
+ var match = regex.exec(repo)
77
+
78
+ if (match) {
79
+ var url = match[2]
80
+ var directCheckout = match[3] || 'master'
81
+
82
+ return {
83
+ type: 'direct',
84
+ url: url,
85
+ checkout: directCheckout
86
+ }
87
+ } else {
88
+ regex = /^(?:(github|gitlab|bitbucket):)?(?:(.+):)?([^/]+)\/([^#]+)(?:#(.+))?$/
89
+ match = regex.exec(repo)
90
+ var type = match[1] || 'github'
91
+ var origin = match[2] || null
92
+ var owner = match[3]
93
+ var name = match[4]
94
+ var checkout = match[5] || 'master'
95
+
96
+ if (origin == null) {
97
+ if (type === 'github') {
98
+ origin = 'github.com'
99
+ } else if (type === 'gitlab') {
100
+ origin = 'gitlab.com'
101
+ } else if (type === 'bitbucket') {
102
+ origin = 'bitbucket.org'
103
+ }
104
+ }
105
+
106
+ return {
107
+ type: type,
108
+ origin: origin,
109
+ owner: owner,
110
+ name: name,
111
+ checkout: checkout
112
+ }
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Adds protocol to url in none specified
118
+ *
119
+ * @param {String} url
120
+ * @return {String}
121
+ */
122
+
123
+ function addProtocol (origin, clone) {
124
+ if (!/^(f|ht)tps?:\/\//i.test(origin)) {
125
+ if (clone) {
126
+ origin = 'git@' + origin
127
+ } else {
128
+ origin = 'https://' + origin
129
+ }
130
+ }
131
+
132
+ return origin
133
+ }
134
+
135
+ /**
136
+ * Return a zip or git url for a given `repo`.
137
+ *
138
+ * @param {Object} repo
139
+ * @return {String}
140
+ */
141
+
142
+ function getUrl (repo, clone) {
143
+ var url
144
+
145
+ // Get origin with protocol and add trailing slash or colon (for ssh)
146
+ var origin = addProtocol(repo.origin, clone)
147
+ if (/^git@/i.test(origin)) {
148
+ origin = origin + ':'
149
+ } else {
150
+ origin = origin + '/'
151
+ }
152
+
153
+ // Build url
154
+ if (clone) {
155
+ url = origin + repo.owner + '/' + repo.name + '.git'
156
+ } else {
157
+ if (repo.type === 'github') {
158
+ url = origin + repo.owner + '/' + repo.name + '/archive/' + repo.checkout + '.zip'
159
+ } else if (repo.type === 'gitlab') {
160
+ url = origin + repo.owner + '/' + repo.name + '/repository/archive.zip?ref=' + repo.checkout
161
+ } else if (repo.type === 'bitbucket') {
162
+ url = origin + repo.owner + '/' + repo.name + '/get/' + repo.checkout + '.zip'
163
+ }
164
+ }
165
+
166
+ return url
167
+ }
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "dl-git-repo-safe",
3
+ "version": "1.0.0",
4
+ "license": "MIT",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/nicolo-ribaudo/download-git-repo-safe.git"
8
+ },
9
+ "description": "Download and extract a git repository (GitHub, GitLab, Bitbucket) from node. Security-patched fork with git-clone-safe.",
10
+ "keywords": [
11
+ "download",
12
+ "github",
13
+ "gitlab",
14
+ "bitbucket",
15
+ "repo",
16
+ "repository",
17
+ "tar",
18
+ "extract",
19
+ "tarball",
20
+ "security",
21
+ "cve-2022-25900",
22
+ "safe"
23
+ ],
24
+ "scripts": {
25
+ "test": "mocha",
26
+ "lint": "standard --verbose | snazzy",
27
+ "lint:fix": "standard --verbose --fix | snazzy",
28
+ "precommit": "npm run lint"
29
+ },
30
+ "dependencies": {
31
+ "download": "^7.1.0",
32
+ "git-clone-safe": "^1.2.0",
33
+ "rimraf": "^3.0.0"
34
+ },
35
+ "devDependencies": {
36
+ "fs-readdir-recursive": "^1.1.0",
37
+ "husky": "^3.0.8",
38
+ "mocha": "^6.2.1",
39
+ "snazzy": "^8.0.0",
40
+ "standard": "^14.3.1"
41
+ },
42
+ "standard": {
43
+ "env": [
44
+ "mocha"
45
+ ]
46
+ }
47
+ }