summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2020-09-17 08:43:39 +0300
committerAndrew Dolgov <[email protected]>2020-09-17 08:43:39 +0300
commit1f79d614c4d24fdc0432fd6d080f29ca99b41fbf (patch)
tree9f8e4a9307f710cd834ba16c326b7f562b8a37d3
parent6a4b6cf603002ca0032c209b99da4ab76ac7e013 (diff)
fix OTP QR code not displayed because of CSRF token passed as a query
parameter use type-strict comparison when validating CSRF token on the backend
-rwxr-xr-xclasses/handler/public.php7
-rw-r--r--classes/pref/prefs.php35
-rw-r--r--include/functions.php2
3 files changed, 27 insertions, 17 deletions
diff --git a/classes/handler/public.php b/classes/handler/public.php
index 18be5c640..595473789 100755
--- a/classes/handler/public.php
+++ b/classes/handler/public.php
@@ -283,9 +283,12 @@ class Handler_Public extends Handler {
}
function logout() {
- if ($_POST["csrf_token"] == $_SESSION["csrf_token"]) {
+ if (validate_csrf($_POST["csrf_token"])) {
logout_user();
header("Location: index.php");
+ } else {
+ header("Content-Type: text/json");
+ print error_json(6);
}
}
@@ -777,7 +780,7 @@ class Handler_Public extends Handler {
<div class='content'>
<?php
- if (!$feed_url || $csrf_token != $_SESSION["csrf_token"]) {
+ if (!$feed_url || !validate_csrf($csrf_token)) {
?>
<form method="post">
<input type="hidden" name="op" value="subscribe">
diff --git a/classes/pref/prefs.php b/classes/pref/prefs.php
index b3341623c..3b129c7e5 100644
--- a/classes/pref/prefs.php
+++ b/classes/pref/prefs.php
@@ -8,7 +8,7 @@ class Pref_Prefs extends Handler_Protected {
private $profile_blacklist = [];
function csrf_ignore($method) {
- $csrf_ignored = array("index", "updateself", "customizecss", "editprefprofiles");
+ $csrf_ignored = array("index", "updateself", "customizecss", "editprefprofiles", "otpqrcode");
return array_search($method, $csrf_ignored) !== false;
}
@@ -483,8 +483,8 @@ class Pref_Prefs extends Handler_Protected {
if (function_exists("imagecreatefromstring")) {
print "<h3>" . __("Scan the following code by the Authenticator application or copy the key manually") . "</h3>";
- $csrf_token = $_SESSION["csrf_token"];
- print "<img alt='otp qr-code' src='backend.php?op=pref-prefs&method=otpqrcode&csrf_token=$csrf_token'>";
+ $csrf_token_hash = sha1($_SESSION["csrf_token"]);
+ print "<img alt='otp qr-code' src='backend.php?op=pref-prefs&method=otpqrcode&csrf_token_hash=$csrf_token_hash'>";
} else {
print_error("PHP GD functions are required to generate QR codes.");
print "<h3>" . __("Use the following OTP key with a compatible Authenticator application") . "</h3>";
@@ -1010,21 +1010,28 @@ class Pref_Prefs extends Handler_Protected {
}
function otpqrcode() {
- require_once "lib/phpqrcode/phpqrcode.php";
+ $csrf_token_hash = clean($_REQUEST["csrf_token_hash"]);
- $sth = $this->pdo->prepare("SELECT login
- FROM ttrss_users
- WHERE id = ?");
- $sth->execute([$_SESSION['uid']]);
+ if (sha1($_SESSION["csrf_token"] === $csrf_token_hash)) {
+ require_once "lib/phpqrcode/phpqrcode.php";
- if ($row = $sth->fetch()) {
- $secret = $this->otpsecret();
- $login = $row['login'];
+ $sth = $this->pdo->prepare("SELECT login
+ FROM ttrss_users
+ WHERE id = ?");
+ $sth->execute([$_SESSION['uid']]);
- if ($secret) {
- QRcode::png("otpauth://totp/".urlencode($login).
- "?secret=$secret&issuer=".urlencode("Tiny Tiny RSS"));
+ if ($row = $sth->fetch()) {
+ $secret = $this->otpsecret();
+ $login = $row['login'];
+
+ if ($secret) {
+ QRcode::png("otpauth://totp/".urlencode($login).
+ "?secret=$secret&issuer=".urlencode("Tiny Tiny RSS"));
+ }
}
+ } else {
+ header("Content-Type: text/json");
+ print error_json(6);
}
}
diff --git a/include/functions.php b/include/functions.php
index dfaf1895d..9989d7ecf 100644
--- a/include/functions.php
+++ b/include/functions.php
@@ -680,7 +680,7 @@
}
function validate_csrf($csrf_token) {
- return $csrf_token == $_SESSION['csrf_token'];
+ return $csrf_token === $_SESSION['csrf_token'];
}
function load_user_plugins($owner_uid, $pluginhost = false) {