Skip to content

Instantly share code, notes, and snippets.

@insin
Last active July 13, 2018 03:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save insin/f1ceeb0691725dddba3113cf2858508e to your computer and use it in GitHub Desktop.
Save insin/f1ceeb0691725dddba3113cf2858508e to your computer and use it in GitHub Desktop.
Check your saved Firefox logins against the Pwned Passwords API (run in Tools → Web Developer → Browser Console)
function sha1(input) {
let converter = Components.classes['@mozilla.org/intl/scriptableunicodeconverter']
.createInstance(Components.interfaces.nsIScriptableUnicodeConverter)
converter.charset = 'UTF-8'
let data = converter.convertToByteArray(input)
let ch = Components.classes['@mozilla.org/security/hash;1']
.createInstance(Components.interfaces.nsICryptoHash)
ch.init(ch.SHA1)
ch.update(data, data.length)
let hash = ch.finish(false)
return Array.from(hash, (c, i) => ('0' + hash.charCodeAt(i).toString(16)).slice(-2)).join('')
}
async function checkLogins() {
let s = (n) => n === 1 ? '' : 's'
let loginManager = Components.classes['@mozilla.org/login-manager;1']
.getService(Components.interfaces.nsILoginManager)
let logins = loginManager.getAllLogins().filter(l => l.hostname.startsWith('http'))
console.log(`Checking ${logins.length} login${s(logins.length)}`)
let pwnedPasswords = []
let progress = 0
for (let login of logins) {
let hashedPassword = sha1(login.password).toUpperCase()
let prefix = hashedPassword.slice(0, 5)
let response = await fetch(`https://api.pwnedpasswords.com/range/${prefix}`, {cache: 'no-store'})
if (response.status !== 200) throw new Error(response)
let pwnedSuffixes = await response.text()
for (let pwnedSuffix of pwnedSuffixes.split(/\n/g)) {
let [suffix, count] = pwnedSuffix.split(':')
if (prefix + suffix === hashedPassword) {
pwnedPasswords.push({hostname: login.hostname, pwnedCount: Number(count)})
break
}
}
progress++
if (progress < logins.length && progress % Math.floor(logins.length / 10) === 0) {
console.log(`${Math.ceil(progress / logins.length * 100)}% done`)
}
}
console.log(`Found ${pwnedPasswords.length} pwned password${s(pwnedPasswords.length)}`)
if (pwnedPasswords.length > 0) {
pwnedPasswords.sort((a, b) => b.pwnedCount - a.pwnedCount)
console.table(pwnedPasswords)
}
}
checkLogins()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment