summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2020-09-15 16:12:53 +0300
committerAndrew Dolgov <[email protected]>2020-09-15 16:12:53 +0300
commit8080c525fd453bfba9c35f01a08013e148bb2144 (patch)
treed17bf661dfebf3d2ea16c78d821dbb78f07bf0d3
parentaeaafefa07b31c99efd27653ad22f4040572d441 (diff)
- backend: require CSRF token to be passed via POST
- do not leak CSRF token via GET request in feed debugger - rework Article/redirect to use POST
-rw-r--r--backend.php2
-rwxr-xr-xclasses/feeds.php4
-rwxr-xr-xclasses/handler/public.php6
-rw-r--r--js/App.js35
-rw-r--r--js/Article.js34
-rwxr-xr-xjs/FeedTree.js5
6 files changed, 45 insertions, 41 deletions
diff --git a/backend.php b/backend.php
index e65ce1b94..1bbeec2bd 100644
--- a/backend.php
+++ b/backend.php
@@ -20,7 +20,7 @@
return;
}
- @$csrf_token = $_REQUEST['csrf_token'];
+ @$csrf_token = $_POST['csrf_token'];
require_once "autoload.php";
require_once "sessions.php";
diff --git a/classes/feeds.php b/classes/feeds.php
index 58ba1b6f8..71890f6ab 100755
--- a/classes/feeds.php
+++ b/classes/feeds.php
@@ -751,7 +751,7 @@ class Feeds extends Handler_Protected {
$feed_id = (int)$_REQUEST["feed_id"];
@$do_update = $_REQUEST["action"] == "do_update";
- $csrf_token = $_REQUEST["csrf_token"];
+ $csrf_token = $_POST["csrf_token"];
$sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ? AND owner_uid = ?");
$sth->execute([$feed_id, $_SESSION['uid']]);
@@ -799,7 +799,7 @@ class Feeds extends Handler_Protected {
<div class="container">
<h1>Feed Debugger: <?php echo "$feed_id: " . $this->getFeedTitle($feed_id) ?></h1>
<div class="content">
- <form method="GET" action="">
+ <form method="post" action="">
<input type="hidden" name="op" value="feeds">
<input type="hidden" name="method" value="update_debugger">
<input type="hidden" name="xdebug" value="1">
diff --git a/classes/handler/public.php b/classes/handler/public.php
index 7f8d01ad0..e4199a95e 100755
--- a/classes/handler/public.php
+++ b/classes/handler/public.php
@@ -291,7 +291,7 @@ class Handler_Public extends Handler {
$uuid = clean($_REQUEST["key"]);
if ($uuid) {
- $sth = $this->pdo->prepare("SELECT ref_id, owner_uid
+ $sth = $this->pdo->prepare("SELECT ref_id, owner_uid
FROM ttrss_user_entries WHERE uuid = ?");
$sth->execute([$uuid]);
@@ -366,7 +366,7 @@ class Handler_Public extends Handler {
}
body.css_loading * {
display : none;
- }
+ }
</style>
<link rel='shortcut icon' type='image/png' href='images/favicon.png'>
<link rel='icon' type='image/png' sizes='72x72' href='images/favicon-72px.png'>";
@@ -728,7 +728,7 @@ class Handler_Public extends Handler {
if ($_SESSION["uid"]) {
$feed_url = trim(clean($_REQUEST["feed_url"]));
- $csrf_token = clean($_REQUEST["csrf_token"]);
+ $csrf_token = clean($_POST["csrf_token"]);
header('Content-Type: text/html; charset=utf-8');
?>
diff --git a/js/App.js b/js/App.js
index 2bc2020bb..1bf4ed881 100644
--- a/js/App.js
+++ b/js/App.js
@@ -126,7 +126,33 @@ const App = {
return callOriginal(options);
}
);
- },
+ },
+ postOpenWindow: function(target, params) {
+ const w = window.open("");
+
+ if (w) {
+ w.opener = null;
+
+ const form = document.createElement("form");
+
+ form.setAttribute("method", "post");
+ form.setAttribute("action", App.getInitParam("self_url_prefix") + "/" + target);
+
+ for (const [k,v] of Object.entries(params)) {
+ const field = document.createElement("input");
+
+ field.setAttribute("name", k);
+ field.setAttribute("value", v);
+ field.setAttribute("type", "hidden");
+
+ form.appendChild(field);
+ }
+
+ w.document.body.appendChild(form);
+ form.submit();
+ }
+
+ },
urlParam: function(param) {
return String(window.location.href).parseQuery()[param];
},
@@ -986,8 +1012,11 @@ const App = {
};
this.hotkey_actions["feed_debug_update"] = () => {
if (!Feeds.activeIsCat() && parseInt(Feeds.getActive()) > 0) {
- window.open("backend.php?op=feeds&method=update_debugger&feed_id=" + Feeds.getActive() +
- "&csrf_token=" + this.getInitParam("csrf_token"));
+ //window.open("backend.php?op=feeds&method=update_debugger&feed_id=" + Feeds.getActive());
+
+ /* global __csrf_token */
+ App.postOpenWindow("backend.php", {op: "feeds", method: "update_debugger", feed_id: Feeds.getActive(), csrf_token: __csrf_token});
+
} else {
alert("You can't debug this kind of feed.");
}
diff --git a/js/Article.js b/js/Article.js
index e2284b190..174015a61 100644
--- a/js/Article.js
+++ b/js/Article.js
@@ -131,37 +131,11 @@ const Article = {
});
},
openInNewWindow: function (id) {
+ /* global __csrf_token */
+ App.postOpenWindow("backend.php",
+ { "op": "article", "method": "redirect", "id": id, "csrf_token": __csrf_token });
- const w = window.open("");
-
- if (w) {
- w.opener = null;
-
- const form = document.createElement("form");
-
- form.setAttribute("method", "post");
- form.setAttribute("action", App.getInitParam("self_url_prefix") + "/backend.php");
-
- /* global __csrf_token */
-
- const params = { "op": "article", "method": "redirect", "id": id, "csrf_token": __csrf_token };
-
- for (const [k,v] of Object.entries(params)) {
- const field = document.createElement("input");
-
- field.setAttribute("name", k);
- field.setAttribute("value", v);
- field.setAttribute("type", "hidden");
-
- form.appendChild(field);
- }
-
- w.document.body.appendChild(form);
- form.submit();
-
- Headlines.toggleUnread(id, 0);
- }
-
+ Headlines.toggleUnread(id, 0);
},
render: function (article) {
App.cleanupMemory("content-insert");
diff --git a/js/FeedTree.js b/js/FeedTree.js
index 74c29d2f7..c61d8a50f 100755
--- a/js/FeedTree.js
+++ b/js/FeedTree.js
@@ -101,8 +101,9 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dojo/_base/array", "dojo/co
menu.addChild(new dijit.MenuItem({
label: __("Debug feed"),
onClick: function() {
- window.open("backend.php?op=feeds&method=update_debugger&feed_id=" + this.getParent().row_id +
- "&csrf_token=" + App.getInitParam("csrf_token"));
+ /* global __csrf_token */
+ App.postOpenWindow("backend.php", {op: "feeds", method: "update_debugger",
+ feed_id: this.getParent().row_id, csrf_token: __csrf_token});
}}));
}