<?php
- set_include_path(get_include_path() . PATH_SEPARATOR .
+ set_include_path(get_include_path() . PATH_SEPARATOR .
dirname(__FILE__) . "/include");
/* remove ill effects of magic quotes */
$op = $_REQUEST["op"];
@$method = $_REQUEST['subop'] ? $_REQUEST['subop'] : $_REQUEST["method"];
+ if (!$method)
+ $method = 'index';
+ else
+ $method = strtolower($method);
+
/* Public calls compatibility shim */
$public_calls = array("globalUpdateFeeds", "rss", "getUnread", "getProfiles", "share",
return;
}
+ $csrf_token = $_REQUEST['csrf_token'];
+
+ if (!$csrf_token)
+ error_log("[$op/$method] CSRF: [$csrf_token]\n", 3, "/tmp/csrf.log");
+
require_once "functions.php";
require_once "sessions.php";
require_once "sanity_check.php";
$handler = new $op($link, $_REQUEST);
if ($handler) {
- if ($handler->before($method)) {
- if ($method && method_exists($handler, $method)) {
- $handler->$method();
- } else if (method_exists($handler, 'index')) {
- $handler->index();
+ if (validate_csrf($csrf_token) || $handler->csrf_ignore($method)) {
+ if ($handler->before($method)) {
+ if ($method && method_exists($handler, $method)) {
+ $handler->$method();
+ }
+ $handler->after();
+ return;
}
- $handler->after();
+ } else {
+ header("Content-Type: text/plain");
+ print json_encode(array("error" => array("code" => 6)));
return;
}
}
<?php\r
class Article extends Protected_Handler {\r
\r
+ function csrf_ignore($method) {\r
+ $csrf_ignored = array("redirect");\r
+\r
+ return array_search($method, $csrf_ignored) !== false;\r
+ }\r
+\r
function redirect() {\r
$id = db_escape_string($_REQUEST['id']);\r
\r
<?php\r
class Feeds extends Protected_Handler {\r
\r
+ function csrf_ignore($method) {\r
+ $csrf_ignored = array("index");\r
+\r
+ return array_search($method, $csrf_ignored) !== false;\r
+ }\r
+\r
private function feedlist_init_cat($cat_id, $hidden = false) {\r
$obj = array();\r
$cat_id = (int) $cat_id;\r
$this->args = $args;
}
+ function csrf_ignore($method) {
+ return true;
+ }
+
function before() {
return true;
}
<?php
class Pref_Feeds extends Protected_Handler {
+
+ function csrf_ignore($method) {
+ $csrf_ignored = array("index", "getfeedtree", "add", "editcats", "editfeed");
+
+ return array_search($method, $csrf_ignored) !== false;
+ }
+
function batch_edit_cbox($elem, $label = false) {
print "<input type=\"checkbox\" title=\"".__("Check to enable field")."\"
onchange=\"dijit.byId('feedEditDlg').toggleField(this, '$elem', '$label')\">";
<?php
class Pref_Filters extends Protected_Handler {
+ function csrf_ignore($method) {
+ $csrf_ignored = array("index", "getfiltertree", "edit");
+
+ return array_search($method, $csrf_ignored) !== false;
+ }
+
function filter_test($filter_type, $reg_exp,
$action_id, $action_param, $filter_param, $inverse, $feed_id) {
<?php
class Pref_Instances extends Protected_Handler {
+ function csrf_ignore($method) {
+ $csrf_ignored = array("index", "edit");
+
+ return array_search($method, $csrf_ignored) !== false;
+ }
+
function before() {
if (parent::before()) {
if ($_SESSION["access_level"] < 10) {
<?php
class Pref_Labels extends Protected_Handler {
+ function csrf_ignore($method) {
+ $csrf_ignored = array("index", "getlabeltree", "edit");
+
+ return array_search($method, $csrf_ignored) !== false;
+ }
+
function edit() {
$label_id = db_escape_string($_REQUEST['id']);
<?php
class Pref_Prefs extends Protected_Handler {
+ function csrf_ignore($method) {
+ $csrf_ignored = array("index");
+
+ return array_search($method, $csrf_ignored) !== false;
+ }
+
function changepassword() {
$old_pw = $_POST["old_password"];
<?php
class Pref_Users extends Protected_Handler {
-
function before() {
if (parent::before()) {
if ($_SESSION["access_level"] < 10) {
return false;
}
+ function csrf_ignore($method) {
+ $csrf_ignored = array("index");
+
+ return array_search($method, $csrf_ignored) !== false;
+ }
+
function userdetails() {
header("Content-Type: text/xml");
<?php
class RPC extends Protected_Handler {
+ function csrf_ignore($method) {
+ $csrf_ignored = array("sanitycheck", "buttonplugin");
+
+ return array_search($method, $csrf_ignored) !== false;
+ }
+
function setprofile() {
$id = db_escape_string($_REQUEST["id"]);
$_SESSION["uid"] = db_fetch_result($result, 0, "id");
$_SESSION["name"] = db_fetch_result($result, 0, "login");
$_SESSION["access_level"] = db_fetch_result($result, 0, "access_level");
+ $_SESSION["csrf_token"] = sha1(uniqid(rand(), true));
db_query($link, "UPDATE ttrss_users SET last_login = NOW() WHERE id = " .
$_SESSION["uid"]);
}
}
+ function validate_csrf($csrf_token) {
+ return $csrf_token == $_SESSION['csrf_token'];
+ }
+
function validate_session($link) {
if (SINGLE_USER_MODE) return true;
$params["collapsed_feedlist"] = (int) get_pref($link, "_COLLAPSED_FEEDLIST");
+ $params["csrf_token"] = $_SESSION["csrf_token"];
+
return $params;
}
var notify_silent = false;
var loading_progress = 0;
var sanity_check_done = false;
+var init_params = {};
+
+Ajax.Base.prototype.initialize = Ajax.Base.prototype.initialize.wrap(
+ function (callOriginal, options) {
+
+ if (getInitParam("csrf_token") != undefined) {
+ Object.extend(options, options || { });
+
+ if (Object.isString(options.parameters))
+ options.parameters = options.parameters.toQueryParams();
+ else if (Object.isHash(options.parameters))
+ options.parameters = options.parameters.toObject();
+
+ options.parameters["csrf_token"] = getInitParam("csrf_token");
+ }
+
+ return callOriginal(options);
+ }
+);
/* add method to remove element from array */
var _active_feed_is_cat = false;
var hotkey_prefix = false;
var hotkey_prefix_pressed = false;
-var init_params = {};
var _force_scheduled_update = false;
var last_scheduled_update = false;