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

Commit

Permalink
fix: improper input validation (#1506)
Browse files Browse the repository at this point in the history
* 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 <alan@tableflip.io>
  • Loading branch information
alanshaw committed Aug 17, 2018
1 parent 86c3d81 commit 91a482b
Show file tree
Hide file tree
Showing 19 changed files with 592 additions and 62 deletions.
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -93,6 +93,7 @@
"byteman": "^1.3.5",
"cids": "~0.5.3",
"debug": "^3.1.0",
"err-code": "^1.1.2",
"file-type": "^8.1.0",
"filesize": "^3.6.1",
"fnv1a": "^1.0.1",
Expand Down
19 changes: 13 additions & 6 deletions src/core/components/bitswap.js
Expand Up @@ -6,6 +6,7 @@ const setImmediate = require('async/setImmediate')
const Big = require('big.js')
const CID = require('cids')
const PeerId = require('peer-id')
const errCode = require('err-code')

function formatWantlist (list) {
return Array.from(list).map((e) => ({ '/': e[1].cid.toBaseEncodedString() }))
Expand Down Expand Up @@ -69,12 +70,18 @@ module.exports = function bitswap (self) {
if (!Array.isArray(keys)) {
keys = [keys]
}
keys = keys.map((key) => {
if (CID.isCID(key)) {
return key
}
return new CID(key)
})

try {
keys = keys.map((key) => {
if (CID.isCID(key)) {
return key
}
return new CID(key)
})
} catch (err) {
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
}

return setImmediate(() => callback(null, self._bitswap.unwant(keys)))
})
}
Expand Down
20 changes: 17 additions & 3 deletions src/core/components/block.js
Expand Up @@ -5,7 +5,9 @@ const multihash = require('multihashes')
const multihashing = require('multihashing-async')
const CID = require('cids')
const waterfall = require('async/waterfall')
const setImmediate = require('async/setImmediate')
const promisify = require('promisify-es6')
const errCode = require('err-code')

module.exports = function block (self) {
return {
Expand All @@ -17,7 +19,11 @@ module.exports = function block (self) {

options = options || {}

cid = cleanCid(cid)
try {
cid = cleanCid(cid)
} catch (err) {
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
}

if (options.preload !== false) {
self._preload(cid)
Expand Down Expand Up @@ -74,7 +80,11 @@ module.exports = function block (self) {
], callback)
}),
rm: promisify((cid, callback) => {
cid = cleanCid(cid)
try {
cid = cleanCid(cid)
} catch (err) {
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
}
self._blockService.delete(cid, callback)
}),
stat: promisify((cid, options, callback) => {
Expand All @@ -83,7 +93,11 @@ module.exports = function block (self) {
options = {}
}

cid = cleanCid(cid)
try {
cid = cleanCid(cid)
} catch (err) {
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
}

if (options.preload !== false) {
self._preload(cid)
Expand Down
30 changes: 26 additions & 4 deletions src/core/components/dag.js
Expand Up @@ -4,7 +4,9 @@ const promisify = require('promisify-es6')
const CID = require('cids')
const pull = require('pull-stream')
const mapAsync = require('async/map')
const setImmediate = require('async/setImmediate')
const flattenDeep = require('lodash/flattenDeep')
const errCode = require('err-code')

module.exports = function dag (self) {
return {
Expand Down Expand Up @@ -52,7 +54,13 @@ module.exports = function dag (self) {

if (typeof cid === 'string') {
const split = cid.split('/')
cid = new CID(split[0])

try {
cid = new CID(split[0])
} catch (err) {
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
}

split.shift()

if (split.length > 0) {
Expand All @@ -64,7 +72,7 @@ module.exports = function dag (self) {
try {
cid = new CID(cid)
} catch (err) {
return callback(err)
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
}
}

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

if (typeof cid === 'string') {
const split = cid.split('/')
cid = new CID(split[0])

try {
cid = new CID(split[0])
} catch (err) {
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
}

split.shift()

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

options = options || {}

self.dag.get(new CID(multihash), '', options, (err, res) => {
let cid

try {
cid = new CID(multihash)
} catch (err) {
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
}

self.dag.get(cid, '', options, (err, res) => {
if (err) { return callback(err) }

mapAsync(res.value.links, (link, cb) => {
Expand Down
15 changes: 14 additions & 1 deletion src/core/components/dht.js
Expand Up @@ -5,7 +5,9 @@ const every = require('async/every')
const PeerId = require('peer-id')
const CID = require('cids')
const each = require('async/each')
const setImmediate = require('async/setImmediate')
// const bsplit = require('buffer-split')
const errCode = require('err-code')

module.exports = (self) => {
return {
Expand Down Expand Up @@ -57,8 +59,19 @@ module.exports = (self) => {
* @returns {Promise<PeerInfo>|void}
*/
findprovs: promisify((key, opts, callback) => {
if (typeof opts === 'function') {
callback = opts
opts = {}
}

opts = opts || {}

if (typeof key === 'string') {
key = new CID(key)
try {
key = new CID(key)
} catch (err) {
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
}
}

if (typeof opts === 'function') {
Expand Down
40 changes: 25 additions & 15 deletions src/core/components/files.js
Expand Up @@ -17,6 +17,7 @@ const Duplex = require('readable-stream').Duplex
const OtherBuffer = require('buffer').Buffer
const CID = require('cids')
const toB58String = require('multihashes').toB58String
const errCode = require('err-code')

const WRAPPER = 'wrapper/'

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

if (options.preload !== false) {
const pathComponents = normalizePath(ipfsPath).split('/')
let pathComponents

try {
pathComponents = normalizePath(ipfsPath).split('/')
} catch (err) {
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_PATH')))
}

self._preload(pathComponents[0])
}

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

if (options.preload !== false) {
const pathComponents = normalizePath(ipfsPath).split('/')
let pathComponents

try {
pathComponents = normalizePath(ipfsPath).split('/')
} catch (err) {
return toStream.source(pull.error(errCode(err, 'ERR_INVALID_PATH')))
}

self._preload(pathComponents[0])
}

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

if (options.preload !== false) {
const pathComponents = normalizePath(ipfsPath).split('/')
let pathComponents

try {
pathComponents = normalizePath(ipfsPath).split('/')
} catch (err) {
return pull.error(errCode(err, 'ERR_INVALID_PATH'))
}

self._preload(pathComponents[0])
}

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

options = options || {}

if (options.preload !== false) {
const pathComponents = normalizePath(ipfsPath).split('/')
self._preload(pathComponents[0])
}

pull(
_lsPullStreamImmutable(ipfsPath, options),
pull.collect((err, values) => {
Expand All @@ -432,13 +449,6 @@ module.exports = function files (self) {
}),

lsReadableStreamImmutable: (ipfsPath, options) => {
options = options || {}

if (options.preload !== false) {
const pathComponents = normalizePath(ipfsPath).split('/')
self._preload(pathComponents[0])
}

return toStream.source(_lsPullStreamImmutable(ipfsPath, options))
},

Expand Down
20 changes: 16 additions & 4 deletions src/core/components/object.js
Expand Up @@ -9,6 +9,7 @@ const DAGLink = dagPB.DAGLink
const CID = require('cids')
const mh = require('multihashes')
const Unixfs = require('ipfs-unixfs')
const errCode = require('err-code')

function normalizeMultihash (multihash, enc) {
if (typeof multihash === 'string') {
Expand Down Expand Up @@ -188,7 +189,13 @@ module.exports = function object (self) {
}

function next () {
const cid = new CID(node.multihash)
let cid

try {
cid = new CID(node.multihash)
} catch (err) {
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
}

self._ipld.put(node, { cid }, (err) => {
if (err) {
Expand All @@ -210,14 +217,19 @@ module.exports = function object (self) {
options = {}
}

let mh
let mh, cid

try {
mh = normalizeMultihash(multihash, options.enc)
} catch (err) {
return callback(err)
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_MULTIHASH')))
}

try {
cid = new CID(mh)
} catch (err) {
return setImmediate(() => callback(errCode(err, 'ERR_INVALID_CID')))
}
let cid = new CID(mh)

if (options.cidVersion === 1) {
cid = cid.toV1()
Expand Down
9 changes: 5 additions & 4 deletions src/core/components/pin-set.js
Expand Up @@ -6,7 +6,8 @@ const protobuf = require('protons')
const fnv1a = require('fnv1a')
const varint = require('varint')
const { DAGNode, DAGLink } = require('ipld-dag-pb')
const async = require('async')
const some = require('async/some')
const eachOf = require('async/eachOf')

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

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

function searchChildren (root, cb) {
async.some(root.links, ({ multihash }, someCb) => {
some(root.links, ({ multihash }, someCb) => {
const bs58Link = toB58String(multihash)
if (bs58Link === childhash) { return someCb(null, true) }
if (bs58Link in seen) { return someCb(null, false) }
Expand Down Expand Up @@ -150,7 +151,7 @@ exports = module.exports = function (dag) {
return bins
}, {})

async.eachOf(bins, (bin, idx, eachCb) => {
eachOf(bins, (bin, idx, eachCb) => {
storePins(
bin,
depth + 1,
Expand Down Expand Up @@ -203,7 +204,7 @@ exports = module.exports = function (dag) {
return callback(err)
}

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

0 comments on commit 91a482b

Please sign in to comment.