Reject costly hashed proofs

This commit is contained in:
Yarmo Mackenbach 2022-09-21 15:30:35 +02:00
parent ea95f3014d
commit 26d9b3108f
No known key found for this signature in database
GPG key ID: 37367F4AF4087AD1
2 changed files with 38 additions and 5 deletions

View file

@ -38,15 +38,34 @@ const containsProof = async (data, fingerprint, claimFormat) => {
let match
while (!result && (match = hashRe.exec(data)) != null) {
let timeoutHandle
const timeoutPromise = new Promise((resolve, reject) => {
timeoutHandle = setTimeout(
() => {
resolve(false)
}, 1000
)
})
switch (match[1]) {
case '2a':
case '2b':
case '2y':
try {
result = await bcryptVerify({
// Patch until promise.race properly works on WASM
if (parseInt(match[0].split('$')[2]) > 12) continue
const hashPromise = bcryptVerify({
password: fingerprintURI,
hash: match[0]
})
.then(result => result)
.catch(_ => false)
result = await Promise.race([hashPromise, timeoutPromise]).then((result) => {
clearTimeout(timeoutHandle)
return result
})
} catch (err) {
result = false
}
@ -57,10 +76,17 @@ const containsProof = async (data, fingerprint, claimFormat) => {
case 'argon2d':
case 'argon2id':
try {
result = await argon2Verify({
const hashPromise = argon2Verify({
password: fingerprintURI,
hash: match[0]
})
.then(result => result)
.catch(_ => false)
result = await Promise.race([hashPromise, timeoutPromise]).then((result) => {
clearTimeout(timeoutHandle)
return result
})
} catch (err) {
result = false
}

View file

@ -38,6 +38,9 @@ const bcryptCorrectProofData = [
const bcryptIncorrectProofData = [
'$2y$10$iHUhy320iUqJRVh7a/WlneAuJA/xRI/YEv7qxW8jfCDVmC7bmezX2'
]
const bcryptCostlyProofData = [
'$2y$16$4Knuu11ZyPXa1qxEbEsKQemKY6ZHM8Bk7WElYfL8q5kmzNjY1Ty8W'
]
const claimData = doipjs.claimDefinitions.data.irc.processURI('irc://domain.tld/test')
describe('verifications.run', () => {
@ -45,7 +48,7 @@ describe('verifications.run', () => {
const result = await doipjs.verifications.run(plaintextCorrectProofData, claimData, fingerprint)
expect(result.result).to.be.true
})
it('should not verify a wrong plaintext proof', async () => {
it('should reject a wrong plaintext proof', async () => {
const result = await doipjs.verifications.run(plaintextIncorrectProofData, claimData, fingerprint)
expect(result.result).to.be.false
})
@ -53,7 +56,7 @@ describe('verifications.run', () => {
const result = await doipjs.verifications.run(argon2CorrectProofData, claimData, fingerprint)
expect(result.result).to.be.true
})
it('should not verify a wrong argon2-hashed proof', async () => {
it('should reject a wrong argon2-hashed proof', async () => {
const result = await doipjs.verifications.run(argon2IncorrectProofData, claimData, fingerprint)
expect(result.result).to.be.false
})
@ -61,8 +64,12 @@ describe('verifications.run', () => {
const result = await doipjs.verifications.run(bcryptCorrectProofData, claimData, fingerprint)
expect(result.result).to.be.true
})
it('should not verify a wrong bcrypt-hashed proof', async () => {
it('should reject a wrong bcrypt-hashed proof', async () => {
const result = await doipjs.verifications.run(bcryptIncorrectProofData, claimData, fingerprint)
expect(result.result).to.be.false
})
it('should reject a too costly hashed proof', async () => {
const result = await doipjs.verifications.run(bcryptCostlyProofData, claimData, fingerprint)
expect(result.result).to.be.false
})
})