- 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
This commit is contained in:
parent
aeaafefa07
commit
8080c525fd
|
@ -20,7 +20,7 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@$csrf_token = $_REQUEST['csrf_token'];
|
@$csrf_token = $_POST['csrf_token'];
|
||||||
|
|
||||||
require_once "autoload.php";
|
require_once "autoload.php";
|
||||||
require_once "sessions.php";
|
require_once "sessions.php";
|
||||||
|
|
|
@ -751,7 +751,7 @@ class Feeds extends Handler_Protected {
|
||||||
|
|
||||||
$feed_id = (int)$_REQUEST["feed_id"];
|
$feed_id = (int)$_REQUEST["feed_id"];
|
||||||
@$do_update = $_REQUEST["action"] == "do_update";
|
@$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 = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ? AND owner_uid = ?");
|
||||||
$sth->execute([$feed_id, $_SESSION['uid']]);
|
$sth->execute([$feed_id, $_SESSION['uid']]);
|
||||||
|
@ -799,7 +799,7 @@ class Feeds extends Handler_Protected {
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>Feed Debugger: <?php echo "$feed_id: " . $this->getFeedTitle($feed_id) ?></h1>
|
<h1>Feed Debugger: <?php echo "$feed_id: " . $this->getFeedTitle($feed_id) ?></h1>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<form method="GET" action="">
|
<form method="post" action="">
|
||||||
<input type="hidden" name="op" value="feeds">
|
<input type="hidden" name="op" value="feeds">
|
||||||
<input type="hidden" name="method" value="update_debugger">
|
<input type="hidden" name="method" value="update_debugger">
|
||||||
<input type="hidden" name="xdebug" value="1">
|
<input type="hidden" name="xdebug" value="1">
|
||||||
|
|
|
@ -291,7 +291,7 @@ class Handler_Public extends Handler {
|
||||||
$uuid = clean($_REQUEST["key"]);
|
$uuid = clean($_REQUEST["key"]);
|
||||||
|
|
||||||
if ($uuid) {
|
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 = ?");
|
FROM ttrss_user_entries WHERE uuid = ?");
|
||||||
$sth->execute([$uuid]);
|
$sth->execute([$uuid]);
|
||||||
|
|
||||||
|
@ -366,7 +366,7 @@ class Handler_Public extends Handler {
|
||||||
}
|
}
|
||||||
body.css_loading * {
|
body.css_loading * {
|
||||||
display : none;
|
display : none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<link rel='shortcut icon' type='image/png' href='images/favicon.png'>
|
<link rel='shortcut icon' type='image/png' href='images/favicon.png'>
|
||||||
<link rel='icon' type='image/png' sizes='72x72' href='images/favicon-72px.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"]) {
|
if ($_SESSION["uid"]) {
|
||||||
|
|
||||||
$feed_url = trim(clean($_REQUEST["feed_url"]));
|
$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');
|
header('Content-Type: text/html; charset=utf-8');
|
||||||
?>
|
?>
|
||||||
|
|
35
js/App.js
35
js/App.js
|
@ -126,7 +126,33 @@ const App = {
|
||||||
return callOriginal(options);
|
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) {
|
urlParam: function(param) {
|
||||||
return String(window.location.href).parseQuery()[param];
|
return String(window.location.href).parseQuery()[param];
|
||||||
},
|
},
|
||||||
|
@ -986,8 +1012,11 @@ const App = {
|
||||||
};
|
};
|
||||||
this.hotkey_actions["feed_debug_update"] = () => {
|
this.hotkey_actions["feed_debug_update"] = () => {
|
||||||
if (!Feeds.activeIsCat() && parseInt(Feeds.getActive()) > 0) {
|
if (!Feeds.activeIsCat() && parseInt(Feeds.getActive()) > 0) {
|
||||||
window.open("backend.php?op=feeds&method=update_debugger&feed_id=" + Feeds.getActive() +
|
//window.open("backend.php?op=feeds&method=update_debugger&feed_id=" + Feeds.getActive());
|
||||||
"&csrf_token=" + this.getInitParam("csrf_token"));
|
|
||||||
|
/* global __csrf_token */
|
||||||
|
App.postOpenWindow("backend.php", {op: "feeds", method: "update_debugger", feed_id: Feeds.getActive(), csrf_token: __csrf_token});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
alert("You can't debug this kind of feed.");
|
alert("You can't debug this kind of feed.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,37 +131,11 @@ const Article = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
openInNewWindow: function (id) {
|
openInNewWindow: function (id) {
|
||||||
|
/* global __csrf_token */
|
||||||
|
App.postOpenWindow("backend.php",
|
||||||
|
{ "op": "article", "method": "redirect", "id": id, "csrf_token": __csrf_token });
|
||||||
|
|
||||||
const w = window.open("");
|
Headlines.toggleUnread(id, 0);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
},
|
||||||
render: function (article) {
|
render: function (article) {
|
||||||
App.cleanupMemory("content-insert");
|
App.cleanupMemory("content-insert");
|
||||||
|
|
|
@ -101,8 +101,9 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dojo/_base/array", "dojo/co
|
||||||
menu.addChild(new dijit.MenuItem({
|
menu.addChild(new dijit.MenuItem({
|
||||||
label: __("Debug feed"),
|
label: __("Debug feed"),
|
||||||
onClick: function() {
|
onClick: function() {
|
||||||
window.open("backend.php?op=feeds&method=update_debugger&feed_id=" + this.getParent().row_id +
|
/* global __csrf_token */
|
||||||
"&csrf_token=" + App.getInitParam("csrf_token"));
|
App.postOpenWindow("backend.php", {op: "feeds", method: "update_debugger",
|
||||||
|
feed_id: this.getParent().row_id, csrf_token: __csrf_token});
|
||||||
}}));
|
}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue