forked from Mirrors/doipjs
Reject costly hashed proofs
This commit is contained in:
parent
ea95f3014d
commit
26d9b3108f
2 changed files with 38 additions and 5 deletions
|
@ -38,15 +38,34 @@ const containsProof = async (data, fingerprint, claimFormat) => {
|
||||||
let match
|
let match
|
||||||
|
|
||||||
while (!result && (match = hashRe.exec(data)) != null) {
|
while (!result && (match = hashRe.exec(data)) != null) {
|
||||||
|
let timeoutHandle
|
||||||
|
const timeoutPromise = new Promise((resolve, reject) => {
|
||||||
|
timeoutHandle = setTimeout(
|
||||||
|
() => {
|
||||||
|
resolve(false)
|
||||||
|
}, 1000
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
switch (match[1]) {
|
switch (match[1]) {
|
||||||
case '2a':
|
case '2a':
|
||||||
case '2b':
|
case '2b':
|
||||||
case '2y':
|
case '2y':
|
||||||
try {
|
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,
|
password: fingerprintURI,
|
||||||
hash: match[0]
|
hash: match[0]
|
||||||
})
|
})
|
||||||
|
.then(result => result)
|
||||||
|
.catch(_ => false)
|
||||||
|
|
||||||
|
result = await Promise.race([hashPromise, timeoutPromise]).then((result) => {
|
||||||
|
clearTimeout(timeoutHandle)
|
||||||
|
return result
|
||||||
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
result = false
|
result = false
|
||||||
}
|
}
|
||||||
|
@ -57,10 +76,17 @@ const containsProof = async (data, fingerprint, claimFormat) => {
|
||||||
case 'argon2d':
|
case 'argon2d':
|
||||||
case 'argon2id':
|
case 'argon2id':
|
||||||
try {
|
try {
|
||||||
result = await argon2Verify({
|
const hashPromise = argon2Verify({
|
||||||
password: fingerprintURI,
|
password: fingerprintURI,
|
||||||
hash: match[0]
|
hash: match[0]
|
||||||
})
|
})
|
||||||
|
.then(result => result)
|
||||||
|
.catch(_ => false)
|
||||||
|
|
||||||
|
result = await Promise.race([hashPromise, timeoutPromise]).then((result) => {
|
||||||
|
clearTimeout(timeoutHandle)
|
||||||
|
return result
|
||||||
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
result = false
|
result = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,9 @@ const bcryptCorrectProofData = [
|
||||||
const bcryptIncorrectProofData = [
|
const bcryptIncorrectProofData = [
|
||||||
'$2y$10$iHUhy320iUqJRVh7a/WlneAuJA/xRI/YEv7qxW8jfCDVmC7bmezX2'
|
'$2y$10$iHUhy320iUqJRVh7a/WlneAuJA/xRI/YEv7qxW8jfCDVmC7bmezX2'
|
||||||
]
|
]
|
||||||
|
const bcryptCostlyProofData = [
|
||||||
|
'$2y$16$4Knuu11ZyPXa1qxEbEsKQemKY6ZHM8Bk7WElYfL8q5kmzNjY1Ty8W'
|
||||||
|
]
|
||||||
const claimData = doipjs.claimDefinitions.data.irc.processURI('irc://domain.tld/test')
|
const claimData = doipjs.claimDefinitions.data.irc.processURI('irc://domain.tld/test')
|
||||||
|
|
||||||
describe('verifications.run', () => {
|
describe('verifications.run', () => {
|
||||||
|
@ -45,7 +48,7 @@ describe('verifications.run', () => {
|
||||||
const result = await doipjs.verifications.run(plaintextCorrectProofData, claimData, fingerprint)
|
const result = await doipjs.verifications.run(plaintextCorrectProofData, claimData, fingerprint)
|
||||||
expect(result.result).to.be.true
|
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)
|
const result = await doipjs.verifications.run(plaintextIncorrectProofData, claimData, fingerprint)
|
||||||
expect(result.result).to.be.false
|
expect(result.result).to.be.false
|
||||||
})
|
})
|
||||||
|
@ -53,7 +56,7 @@ describe('verifications.run', () => {
|
||||||
const result = await doipjs.verifications.run(argon2CorrectProofData, claimData, fingerprint)
|
const result = await doipjs.verifications.run(argon2CorrectProofData, claimData, fingerprint)
|
||||||
expect(result.result).to.be.true
|
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)
|
const result = await doipjs.verifications.run(argon2IncorrectProofData, claimData, fingerprint)
|
||||||
expect(result.result).to.be.false
|
expect(result.result).to.be.false
|
||||||
})
|
})
|
||||||
|
@ -61,8 +64,12 @@ describe('verifications.run', () => {
|
||||||
const result = await doipjs.verifications.run(bcryptCorrectProofData, claimData, fingerprint)
|
const result = await doipjs.verifications.run(bcryptCorrectProofData, claimData, fingerprint)
|
||||||
expect(result.result).to.be.true
|
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)
|
const result = await doipjs.verifications.run(bcryptIncorrectProofData, claimData, fingerprint)
|
||||||
expect(result.result).to.be.false
|
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
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue