WEBUI: Protect against timing attacks. Closes #2108.

This commit is contained in:
sledgehammer999 2014-11-02 21:19:27 +02:00
parent 09ab5c37ce
commit 6f14b34470
3 changed files with 22 additions and 1 deletions

View file

@ -645,6 +645,20 @@ QString misc::accurateDoubleToString(const double &n, const int &precision, bool
return QString::number(std::floor(n*prec)/prec, 'f', precision);
}
// Implements constant-time comparison to protect against timing attacks
// Taken from https://crackstation.net/hashing-security.htm
bool misc::slowEquals(const QByteArray &a, const QByteArray &b)
{
int lengthA = a.length();
int lengthB = b.length();
int diff = lengthA ^ lengthB;
for(int i = 0; i < lengthA && i < lengthB; i++)
diff |= a[i] ^ b[i];
return (diff == 0);
}
namespace {
// Trick to get a portable sleep() function
class SleeperThread : public QThread {

View file

@ -106,6 +106,10 @@ namespace misc
bool naturalSort(QString left, QString right, bool& result);
#endif
// Implements constant-time comparison to protect against timing attacks
// Taken from https://crackstation.net/hashing-security.htm
bool slowEquals(const QByteArray &a, const QByteArray &b);
void msleep(unsigned long msecs);
}

View file

@ -136,7 +136,10 @@ void RequestHandler::action_public_login()
md5.addData(request().posts["password"].toLocal8Bit());
QString pass = md5.result().toHex();
if ((request().posts["username"] == pref->getWebUiUsername()) && (pass == pref->getWebUiPassword()))
bool equalUser = misc::slowEquals(request().posts["username"].toUtf8(), pref->getWebUiUsername().toUtf8());
bool equalPass = misc::slowEquals(pass.toUtf8(), pref->getWebUiPassword().toUtf8());
if (equalUser && equalPass)
{
sessionStart();
print(QByteArray("Ok."), CONTENT_TYPE_TXT);