mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-29 05:48:47 +03:00
WEBUI: Protect against timing attacks. Closes #2108.
This commit is contained in:
parent
09ab5c37ce
commit
6f14b34470
3 changed files with 22 additions and 1 deletions
14
src/misc.cpp
14
src/misc.cpp
|
@ -645,6 +645,20 @@ QString misc::accurateDoubleToString(const double &n, const int &precision, bool
|
||||||
return QString::number(std::floor(n*prec)/prec, 'f', precision);
|
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 {
|
namespace {
|
||||||
// Trick to get a portable sleep() function
|
// Trick to get a portable sleep() function
|
||||||
class SleeperThread : public QThread {
|
class SleeperThread : public QThread {
|
||||||
|
|
|
@ -106,6 +106,10 @@ namespace misc
|
||||||
bool naturalSort(QString left, QString right, bool& result);
|
bool naturalSort(QString left, QString right, bool& result);
|
||||||
#endif
|
#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);
|
void msleep(unsigned long msecs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,10 @@ void RequestHandler::action_public_login()
|
||||||
md5.addData(request().posts["password"].toLocal8Bit());
|
md5.addData(request().posts["password"].toLocal8Bit());
|
||||||
QString pass = md5.result().toHex();
|
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();
|
sessionStart();
|
||||||
print(QByteArray("Ok."), CONTENT_TYPE_TXT);
|
print(QByteArray("Ok."), CONTENT_TYPE_TXT);
|
||||||
|
|
Loading…
Reference in a new issue