Skip to content
This repository was archived by the owner on Feb 12, 2024. It is now read-only.

Commit 91a482b

Browse files
authored
fix: improper input validation (#1506)
* fix: callback with error for invalid CIDs * fix: handle invalid path for files.get* * fix: handling for invalid pin type * fix: specify async functions to use * fix: handle invalid bandwidth poll interval * refactor: allow libp2p to handle multiaddr validation * fix: differentiate between invalid multihash and invalid CID License: MIT Signed-off-by: Alan Shaw <[email protected]>
1 parent 86c3d81 commit 91a482b

19 files changed

+592
-62
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
"byteman": "^1.3.5",
9494
"cids": "~0.5.3",
9595
"debug": "^3.1.0",
96+
"err-code": "^1.1.2",
9697
"file-type": "^8.1.0",
9798
"filesize": "^3.6.1",
9899
"fnv1a": "^1.0.1",

src/core/components/bitswap.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const setImmediate = require('async/setImmediate')
66
const Big = require('big.js')
77
const CID = require('cids')
88
const PeerId = require('peer-id')
9+
const errCode = require('err-code')
910

1011
function formatWantlist (list) {
1112
return Array.from(list).map((e) => ({ '/': e[1].cid.toBaseEncodedString() }))
@@ -69,12 +70,18 @@ module.exports = function bitswap (self) {
6970
if (!Array.isArray(keys)) {
7071
keys = [keys]
7172
}
72-
keys = keys.map((key) => {
73-
if (CID.isCID(key)) {
74-
return key
75-
}
76-
return new CID(key)
77-
})
73+
74+
try {
75+
keys = keys.map((key) => {
76+
if (CID.isCID(key)) {
77+
return key
78+
}
79+
return new CID(key)
80+
})
81+
} catch (err) {
82+
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
83+
}
84+
7885
return setImmediate(() => callback(null, self._bitswap.unwant(keys)))
7986
})
8087
}

src/core/components/block.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ const multihash = require('multihashes')
55
const multihashing = require('multihashing-async')
66
const CID = require('cids')
77
const waterfall = require('async/waterfall')
8+
const setImmediate = require('async/setImmediate')
89
const promisify = require('promisify-es6')
10+
const errCode = require('err-code')
911

1012
module.exports = function block (self) {
1113
return {
@@ -17,7 +19,11 @@ module.exports = function block (self) {
1719

1820
options = options || {}
1921

20-
cid = cleanCid(cid)
22+
try {
23+
cid = cleanCid(cid)
24+
} catch (err) {
25+
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
26+
}
2127

2228
if (options.preload !== false) {
2329
self._preload(cid)
@@ -74,7 +80,11 @@ module.exports = function block (self) {
7480
], callback)
7581
}),
7682
rm: promisify((cid, callback) => {
77-
cid = cleanCid(cid)
83+
try {
84+
cid = cleanCid(cid)
85+
} catch (err) {
86+
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
87+
}
7888
self._blockService.delete(cid, callback)
7989
}),
8090
stat: promisify((cid, options, callback) => {
@@ -83,7 +93,11 @@ module.exports = function block (self) {
8393
options = {}
8494
}
8595

86-
cid = cleanCid(cid)
96+
try {
97+
cid = cleanCid(cid)
98+
} catch (err) {
99+
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
100+
}
87101

88102
if (options.preload !== false) {
89103
self._preload(cid)

src/core/components/dag.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ const promisify = require('promisify-es6')
44
const CID = require('cids')
55
const pull = require('pull-stream')
66
const mapAsync = require('async/map')
7+
const setImmediate = require('async/setImmediate')
78
const flattenDeep = require('lodash/flattenDeep')
9+
const errCode = require('err-code')
810

911
module.exports = function dag (self) {
1012
return {
@@ -52,7 +54,13 @@ module.exports = function dag (self) {
5254

5355
if (typeof cid === 'string') {
5456
const split = cid.split('/')
55-
cid = new CID(split[0])
57+
58+
try {
59+
cid = new CID(split[0])
60+
} catch (err) {
61+
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
62+
}
63+
5664
split.shift()
5765

5866
if (split.length > 0) {
@@ -64,7 +72,7 @@ module.exports = function dag (self) {
6472
try {
6573
cid = new CID(cid)
6674
} catch (err) {
67-
return callback(err)
75+
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
6876
}
6977
}
7078

@@ -96,7 +104,13 @@ module.exports = function dag (self) {
96104

97105
if (typeof cid === 'string') {
98106
const split = cid.split('/')
99-
cid = new CID(split[0])
107+
108+
try {
109+
cid = new CID(split[0])
110+
} catch (err) {
111+
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
112+
}
113+
100114
split.shift()
101115

102116
if (split.length > 0) {
@@ -127,7 +141,15 @@ module.exports = function dag (self) {
127141

128142
options = options || {}
129143

130-
self.dag.get(new CID(multihash), '', options, (err, res) => {
144+
let cid
145+
146+
try {
147+
cid = new CID(multihash)
148+
} catch (err) {
149+
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
150+
}
151+
152+
self.dag.get(cid, '', options, (err, res) => {
131153
if (err) { return callback(err) }
132154

133155
mapAsync(res.value.links, (link, cb) => {

src/core/components/dht.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ const every = require('async/every')
55
const PeerId = require('peer-id')
66
const CID = require('cids')
77
const each = require('async/each')
8+
const setImmediate = require('async/setImmediate')
89
// const bsplit = require('buffer-split')
10+
const errCode = require('err-code')
911

1012
module.exports = (self) => {
1113
return {
@@ -57,8 +59,19 @@ module.exports = (self) => {
5759
* @returns {Promise<PeerInfo>|void}
5860
*/
5961
findprovs: promisify((key, opts, callback) => {
62+
if (typeof opts === 'function') {
63+
callback = opts
64+
opts = {}
65+
}
66+
67+
opts = opts || {}
68+
6069
if (typeof key === 'string') {
61-
key = new CID(key)
70+
try {
71+
key = new CID(key)
72+
} catch (err) {
73+
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
74+
}
6275
}
6376

6477
if (typeof opts === 'function') {

src/core/components/files.js

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const Duplex = require('readable-stream').Duplex
1717
const OtherBuffer = require('buffer').Buffer
1818
const CID = require('cids')
1919
const toB58String = require('multihashes').toB58String
20+
const errCode = require('err-code')
2021

2122
const WRAPPER = 'wrapper/'
2223

@@ -348,7 +349,14 @@ module.exports = function files (self) {
348349
options = options || {}
349350

350351
if (options.preload !== false) {
351-
const pathComponents = normalizePath(ipfsPath).split('/')
352+
let pathComponents
353+
354+
try {
355+
pathComponents = normalizePath(ipfsPath).split('/')
356+
} catch (err) {
357+
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_PATH')))
358+
}
359+
352360
self._preload(pathComponents[0])
353361
}
354362

@@ -376,7 +384,14 @@ module.exports = function files (self) {
376384
options = options || {}
377385

378386
if (options.preload !== false) {
379-
const pathComponents = normalizePath(ipfsPath).split('/')
387+
let pathComponents
388+
389+
try {
390+
pathComponents = normalizePath(ipfsPath).split('/')
391+
} catch (err) {
392+
return toStream.source(pull.error(errCode(err, 'ERR_INVALID_PATH')))
393+
}
394+
380395
self._preload(pathComponents[0])
381396
}
382397

@@ -399,7 +414,14 @@ module.exports = function files (self) {
399414
options = options || {}
400415

401416
if (options.preload !== false) {
402-
const pathComponents = normalizePath(ipfsPath).split('/')
417+
let pathComponents
418+
419+
try {
420+
pathComponents = normalizePath(ipfsPath).split('/')
421+
} catch (err) {
422+
return pull.error(errCode(err, 'ERR_INVALID_PATH'))
423+
}
424+
403425
self._preload(pathComponents[0])
404426
}
405427

@@ -414,11 +436,6 @@ module.exports = function files (self) {
414436

415437
options = options || {}
416438

417-
if (options.preload !== false) {
418-
const pathComponents = normalizePath(ipfsPath).split('/')
419-
self._preload(pathComponents[0])
420-
}
421-
422439
pull(
423440
_lsPullStreamImmutable(ipfsPath, options),
424441
pull.collect((err, values) => {
@@ -432,13 +449,6 @@ module.exports = function files (self) {
432449
}),
433450

434451
lsReadableStreamImmutable: (ipfsPath, options) => {
435-
options = options || {}
436-
437-
if (options.preload !== false) {
438-
const pathComponents = normalizePath(ipfsPath).split('/')
439-
self._preload(pathComponents[0])
440-
}
441-
442452
return toStream.source(_lsPullStreamImmutable(ipfsPath, options))
443453
},
444454

src/core/components/object.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const DAGLink = dagPB.DAGLink
99
const CID = require('cids')
1010
const mh = require('multihashes')
1111
const Unixfs = require('ipfs-unixfs')
12+
const errCode = require('err-code')
1213

1314
function normalizeMultihash (multihash, enc) {
1415
if (typeof multihash === 'string') {
@@ -188,7 +189,13 @@ module.exports = function object (self) {
188189
}
189190

190191
function next () {
191-
const cid = new CID(node.multihash)
192+
let cid
193+
194+
try {
195+
cid = new CID(node.multihash)
196+
} catch (err) {
197+
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
198+
}
192199

193200
self._ipld.put(node, { cid }, (err) => {
194201
if (err) {
@@ -210,14 +217,19 @@ module.exports = function object (self) {
210217
options = {}
211218
}
212219

213-
let mh
220+
let mh, cid
214221

215222
try {
216223
mh = normalizeMultihash(multihash, options.enc)
217224
} catch (err) {
218-
return callback(err)
225+
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_MULTIHASH')))
226+
}
227+
228+
try {
229+
cid = new CID(mh)
230+
} catch (err) {
231+
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
219232
}
220-
let cid = new CID(mh)
221233

222234
if (options.cidVersion === 1) {
223235
cid = cid.toV1()

src/core/components/pin-set.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ const protobuf = require('protons')
66
const fnv1a = require('fnv1a')
77
const varint = require('varint')
88
const { DAGNode, DAGLink } = require('ipld-dag-pb')
9-
const async = require('async')
9+
const some = require('async/some')
10+
const eachOf = require('async/eachOf')
1011

1112
const pbSchema = require('./pin.proto')
1213

@@ -67,7 +68,7 @@ exports = module.exports = function (dag) {
6768
return searchChildren(root, callback)
6869

6970
function searchChildren (root, cb) {
70-
async.some(root.links, ({ multihash }, someCb) => {
71+
some(root.links, ({ multihash }, someCb) => {
7172
const bs58Link = toB58String(multihash)
7273
if (bs58Link === childhash) { return someCb(null, true) }
7374
if (bs58Link in seen) { return someCb(null, false) }
@@ -150,7 +151,7 @@ exports = module.exports = function (dag) {
150151
return bins
151152
}, {})
152153

153-
async.eachOf(bins, (bin, idx, eachCb) => {
154+
eachOf(bins, (bin, idx, eachCb) => {
154155
storePins(
155156
bin,
156157
depth + 1,
@@ -203,7 +204,7 @@ exports = module.exports = function (dag) {
203204
return callback(err)
204205
}
205206

206-
async.eachOf(node.links, (link, idx, eachCb) => {
207+
eachOf(node.links, (link, idx, eachCb) => {
207208
if (idx < pbh.header.fanout) {
208209
// the first pbh.header.fanout links are fanout bins
209210
// if a fanout bin is not 'empty', dig into and walk its DAGLinks

0 commit comments

Comments
 (0)