HIBP API V3 is not free anymore => checking of user names removed. Passwords still checked...

This commit is contained in:
leolivier 2019-12-29 16:56:09 +01:00
parent b56214d46a
commit 7a45018373
4 changed files with 46 additions and 29 deletions

View File

@ -14,7 +14,11 @@
<body>
<h1>KeeWeb Plugin: HaveIBeenPwned</h1>
<a href="https://plugins.keeweb.info/plugins/haveibeenpwned">https://plugins.keeweb.info/plugins/haveibeenpwned</a>
<p>This plugin checks the <a href="https://haveibeenpwned.com">HaveIBeenPwned</a> site each time you enter either a user name or a password to look if they have been pawned in a breach. The password is safely checked (not sent over the network).</p>
<p>This plugin checks the <a href="https://haveibeenpwned.com">HaveIBeenPwned</a> site each time you enter a password to look if it has been pawned in a breach. <br/>
<i>Note: Passwords is safely checked (only a hash is sent over the network).</i></p>
<p>Since the V3 version of the <a href="https://haveibeenpwned.com">HaveIBeenPwned</a> API (mid 2019), checking user names is not free anymore
(3.5$/month, see <a href="https://haveibeenpwned.com/API/Key">API V3 Key</a>)...<br/>
So user name checking has been disabled in the latest version of this plugin.</p>
<p>Freely inspired from the equivalent keepass plugin</p>
</body>
</html>

View File

@ -1,5 +1,5 @@
{
"version": "0.1.0",
"version": "0.1.7",
"manifestVersion": "0.1.0",
"name": "haveibeenpwned",
"description": "Check HaveIBeenPwned password database",
@ -9,10 +9,10 @@
"url": "https://github.com/leolivier"
},
"resources": {
"js": "J4heWnJtiOqcd4MUZ9skJztilT4tyT9EhGmuE+NkjDNXZFFKEnOEiIUboFV8LeXEAQZk+jHLY8s1Xxxt9v1tNq8RqeYrzNl+Cjuj4jZSaMDheDJsnp1AFkbZAEteR3UGk54uVjdwEPhCJm5qjCEi7IfIO8eTEl8HbjIkBAX91D3gh1e8+EM2v7XQ9wj/q5HbKQFNQSYMB4VO752ZdcZtLu52xJU29EjOkHZBkbo7zPMZtqGwqEvaa8E6DOnpnYruzh/XSMimbbG5aN66JjPEPTNkjWjJGD8XsCzyDJee3doLroK1C7sanM46KnKszVAAZ2zJU5dpV99ojDTykHCK0w==",
"css": "FOHXfuz24aCv4zj2TnMUbZDGjJHRMaXwVQUlLNPL2GJku+W/FsAqrcdtZeWNmFW07J/jVFZd3sQA9uSJYn8BWdxGxlabT+nKWDdkjVjPed5wghvRZRkzwkI4oR6SCaaTM5uUtS/7QkKiHaLdo9AwS0A7fuuQ0icxENxkDa/E8Evf4EwAbGtFgAAAwP5yZtyIK+nwjvsOfYut01m1uiq461whTiTGPAqSCd5pMqFv7JhJAlrRqYAtgQUL64K/MrCjHbOsl4sYYwITFb/w3rPhzgCkE6rTFWo6WOwpsIAbVJq5qhPgsXTQq1zZSNVLO7Q3n2j4t4jcmpDzlL1+OenEgg=="
"js": "CR/pcbMGlka6OI5sVMV50m+GFuJOT3I4Geuf7wWvjVHGeIqf2ffegVlMJ9/nkLv+d9RmLfQaHCDN1IUfAqrdo/MxRGZVBvIwOUBe/U/Fzw3u11C/qCfvF526CNS5Lj9xW3ZLMCHvgbSpNigVl3HIYJ3wW8Zz+2dLKQPaotrdW5ILKES7sLOO2sgIQy7adF3CJNelezgzLQEGO7IBv1IyM/qnQYhK9mHvYHCGJyIE/sjUe8KbOODnkMCmOfP6A2TYZWlyKR0ATQE+frgIK/Ur/M+4ntafkralCyhfBUHpe+5REeZI5buaklCx6nF6QUs/U41cCP178HM69sItDrjWnQ==",
"css": "em80YYK5vogs+ctoz9AtDdvsQfc8mstefQ5Nhu/cxpmg4/I12u95rEcQdAvQ36iA+Q3QqtnbSfKZt4zLexJWvWsPX9+nPJdLPfkTm0xKtjvl8gwGuUJfCkinV661RRsmS9n5Cs3scjeiZrnt501JPZ9+kU7OGVCl8cNb+5DNms1EVoWieeyJo2saODN4LGEA242t9Ol6y4bnDZmzDiB+TvIhNt4joncRaAf45zfzda9+XZK4S8ZrjHO9sJXXaR5WKVB15zckyGKziSpZBJqzqMONEQqJVqmuefzkcif+vGMmhnWenaGZuxybxwkWY3Cq0I30VtxvUXNLB3XR1h/s2Q=="
},
"url": "https://plugins.keeweb.info/plugins/haveibeenpwned",
"publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp9Cay/z7whBsHcf9klDjlA4qylWT7a/igTJ2nvUq2XuQrx98PTOexzzzg5oflk8nPEaMIsaFIf90V/rvQjJ1z9DR4zuQKDb4/GZVzxoylECAwNk80LvSPc1G0+6mwXIFp48wc6Advd4iYQCMkzWDCJXEm/1E+q85ty+H6EaLleKcJI0vlW96bbA9vFCmOsM5PYZfoGnVFRBLVthyUcGneilMvsxu5J7DKggQKPs04/WQZ5oHbUG83mxkxTdYDC3glpvV4BiaAD6z+2usO+fA97bXb+rY3O2iHJgWsa7jH0ybO0Nif6txE4d2+LJOLmfoImv7kdyu/eN3A78KejCOhwIDAQAB",
"publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmycO5RAzrGrdP1pFZd3YCqS9MwTJxoL4PxO+um6NS4Af3XviV0VFr/OBL19PBq8c8EBbIYRrh202PbO7/DzRDUegUPONvD3sw15887prtclf7mX8urF3aOy9iEVe0tn2+HqEjDEPf4uuR6UD2HRUECFgc5veQ/JzXenBYKWj+q5axSFnaonRHv5qDK0+9Ja2bNgaNqfJC+h0jkajA8N4i/EPhQdvYHgUn+k0rCxKSwKaR1Tad+ixuyR8eG7Nv6t7fEbOmUOvr6G+bWcW/GmhoGA0pgYY1WfjDSPZMsMXNEXt+XLKziPz6Q5x4iX4XIHjIDbQQVnDZWvFCiWmW04S4QIDAQAB",
"license": "MIT"
}
}

View File

@ -4,7 +4,7 @@
text-align: center;
background-color: var(--text-color);
background-size:cover;
position: relative;;
position: relative;
width:1.5em;
height:1.5em;
animation: hibp-spin 1s linear 0s infinite;

View File

@ -4,15 +4,15 @@
* @license MIT
*/
const Logger = require('util/logger');
const Logger = require('util/logger').Logger;
// change log level here.
const LogLevel = Logger.Level.Info;
const DetailsView = require('views/details/details-view');
const InputFx = require('util/input-fx');
const DetailsView = require('views/details/details-view').DetailsView;
const InputFx = require('util/ui/input-fx').InputFx;
const Kdbxweb = require('kdbxweb');
const _ = require('_');
const Tip = require('util/tip');
const utilFn = require('util/fn');
const Tip = require('util/ui/tip').Tip;
const detailsViewFieldChanged = DetailsView.prototype.fieldChanged;
let _seen = [];
@ -26,6 +26,7 @@ class HIBPUtils {
this.logger = new Logger('HaveIBeenPwned');
this.logger.setLevel(LogLevel);
};
replacer(key, value) {
if (value != null && typeof value === 'object') {
if (_seen.indexOf(value) >= 0) {
@ -35,11 +36,13 @@ class HIBPUtils {
}
return value;
};
stringify(obj) {
const ret = JSON.stringify(obj, this.replacer);
_seen = [];
return ret;
};
xhrcall (config) {
const xhr = new XMLHttpRequest();
if (config.responseType) {
@ -64,12 +67,13 @@ class HIBPUtils {
});
xhr.open(config.method || 'GET', config.url);
if (config.headers) {
config.headers.forEach((value, key) => {
xhr.setRequestHeader(key, value);
});
for (var key in config.headers) {
xhr.setRequestHeader(key, config.headers[key]);
};
};
xhr.send(config.data);
};
hex (buffer) {
const hexCodes = [];
const view = new DataView(buffer);
@ -86,6 +90,7 @@ class HIBPUtils {
// Join all the hex strings into one
return hexCodes.join('');
};
digest(algo, str) {
const buffer = Kdbxweb.ByteUtils.stringToBytes(str);
const subtle = window.crypto.subtle || window.crypto.webkitSubtle;
@ -94,12 +99,15 @@ class HIBPUtils {
return _self.hex(hash);
});
};
sha1(str) {
return this.digest('SHA-1', str);
};
sha256(str) {
return this.digest('SHA-256', str);
};
alert (el, msg) {
// Alerts.info({ body: msg, title: 'HaveIBeenPwned' });
el.focus();
@ -108,6 +116,7 @@ class HIBPUtils {
Tip.createTip(el, { title: msg, placement: 'bottom' });
InputFx.shake(el);
};
passed(el, msg) {
hibp.logger.info(msg);
el.removeClass('input--error');
@ -126,14 +135,14 @@ DetailsView.prototype.checkNamePwned = function (name) {
url: url,
method: 'GET',
responseType: 'json',
headers: undefined,
headers: { "Access-Control-Allow-Origin" : '*'}, //, "Access-Control-Allow-Methods" : 'GET,OPTIONS', "Access-Control-Allow-Headers" : 'Content-Type'},
data: null,
statuses: [200, 404],
success: (data, xhr) => {
if (data && data.length > 0) {
hibp.logger.debug('found breaches ' + JSON.stringify(data));
let breaches = '';
data.forEach(breach => { breaches += '<li>' + _.escape(breach.Name) + '</li>\n'; });
data.forEach(breach => { breaches += '<li>' + utilFn.escape(breach.Name) + '</li>\n'; });
hibp.alert(this.userEditView.$el, `WARNING! This account has been pawned in the following breaches<br/>\n<ul>\n${breaches}\n</ul>\n<p>Please check on <a href='https://haveibeenpwned.com'>https://haveibeenpwned.com</a>\n`);
} else {
hibp.passed(this.userEditView.$el, 'check pwned user name passed...');
@ -149,7 +158,7 @@ DetailsView.prototype.checkPwdPwned = function (passwordHash) {
url: `https://api.pwnedpasswords.com/range/${prefix}`,
method: 'GET',
responseType: 'text',
headers: undefined,
headers: {'Access-Control-Allow-Origin': '*'},
data: null,
statuses: [200, 404],
success: data => {
@ -159,7 +168,7 @@ DetailsView.prototype.checkPwdPwned = function (passwordHash) {
const h = line.split(':');
const suffix = h[0];
if (prefix + suffix === passwordHash) {
const nb = _.escape(h[1]);
const nb = utilFn.escape(h[1]);
hibp.alert(this.passEditView.$el, `WARNING: This password is referenced as pawned ${nb} times on <a href='https://haveibeenpwned.com'>https://haveibeenpwned.com</a>!\n`);
}
});
@ -195,21 +204,22 @@ module.exports.getSettings = function () {
label: 'Check passwords against HaveIBeenPwned list',
type: 'checkbox',
value: hibp.checkPwnedPwd
}, {
name: 'checkPwnedName',
label: 'Check user ids against HaveIBeenPwned list',
type: 'checkbox',
value: hibp.checkPwnedName
// disabled since API V3 of HaveIbeenPwned is not free anymore for checking accounts
// }, {
// name: 'checkPwnedName',
// label: 'Check user ids against HaveIBeenPwned list',
// type: 'checkbox',
// value: hibp.checkPwnedName
}, {
name: 'blockPwnedPwd',
label: 'Block pwned passwords if they are in HaveIBeenPwned list',
type: 'checkbox',
value: hibp.blockPwnedPwd
}, {
name: 'blockPwnedName',
label: 'Block pwned names if they are in HaveIBeenPwned list',
type: 'checkbox',
value: hibp.blockPwnedName
// }, {
// name: 'blockPwnedName',
// label: 'Block pwned names if they are in HaveIBeenPwned list',
// type: 'checkbox',
// value: hibp.blockPwnedName
}];
};
@ -218,6 +228,9 @@ module.exports.setSettings = function (changes) {
const ccfield = field.substr(0, 1).toLowerCase() + field.substring(1);
hibp[ccfield] = changes[field];
}
// disabled since API V3 of HaveIbeenPwned is not free anymore for checking accounts
hibp.checkPwnedName = false;
hibp.blockPwnedName = false
};
module.exports.uninstall = function () {