aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/app
diff options
context:
space:
mode:
authorAlexandre Alapetite <alexandre@alapetite.fr>2025-04-05 23:15:37 +0200
committerGitHub <noreply@github.com>2025-04-05 23:15:37 +0200
commitd858053a7c70b3fee0fe407420ff8bd1466d5de2 (patch)
tree68e6237aff1f290361e21024a2a35476a6a88888 /app
parent711a14fd9ccea0a5b3c68dfa20fc34e558823f40 (diff)
downloadfreshrss-d858053a7c70b3fee0fe407420ff8bd1466d5de2.tar.gz
freshrss-d858053a7c70b3fee0fe407420ff8bd1466d5de2.zip
Use HTTP POST for logout (#7489)
* Use HTTP POST for logout To avoid potential CSRF risks * Fixed button font issue * Minor whitespace
Diffstat (limited to 'app')
-rw-r--r--app/Controllers/authController.php10
-rw-r--r--app/layout/aside_configure.phtml8
-rw-r--r--app/layout/header.phtml7
-rw-r--r--app/layout/simple.phtml10
4 files changed, 24 insertions, 11 deletions
diff --git a/app/Controllers/authController.php b/app/Controllers/authController.php
index 9bad837f9..4de8d01f1 100644
--- a/app/Controllers/authController.php
+++ b/app/Controllers/authController.php
@@ -223,9 +223,13 @@ class FreshRSS_auth_Controller extends FreshRSS_ActionController {
* This action removes all accesses of the current user.
*/
public function logoutAction(): void {
- invalidateHttpCache();
- FreshRSS_Auth::removeAccess();
- Minz_Request::good(_t('feedback.auth.logout.success'), [ 'c' => 'index', 'a' => 'index' ]);
+ if (Minz_Request::isPost()) {
+ invalidateHttpCache();
+ FreshRSS_Auth::removeAccess();
+ Minz_Request::good(_t('feedback.auth.logout.success'), [ 'c' => 'index', 'a' => 'index' ]);
+ } else {
+ Minz_Error::error(403);
+ }
}
/**
diff --git a/app/layout/aside_configure.phtml b/app/layout/aside_configure.phtml
index d107e7f63..9824e7fa8 100644
--- a/app/layout/aside_configure.phtml
+++ b/app/layout/aside_configure.phtml
@@ -2,6 +2,9 @@
declare(strict_types=1);
?>
<nav class="nav nav-list aside" id="aside_feed">
+ <form id="post-csrf" method="post">
+ <input type="hidden" name="_csrf" value="<?= FreshRSS_Auth::csrfToken() ?>" />
+ </form>
<a class="toggle_aside" href="#close"><?= _i('close') ?></a>
<ul>
@@ -19,9 +22,8 @@
<a href="<?= _url('user', 'profile') ?>"><?= _t('gen.menu.user_profile') ?></a>
</li>
<li class="item">
- <a class="signout" href="<?= FreshRSS_auth_Controller::getLogoutUrl() ?>">
- <?php
- echo _t('gen.auth.logout'); ?> <?= _i('logout') ?></a>
+ <button class="as-link signout" form="post-csrf" formaction="<?=
+ FreshRSS_auth_Controller::getLogoutUrl() ?>"><?= _t('gen.auth.logout'); ?><?= _i('logout') ?></button>
</li>
</ul>
</li>
diff --git a/app/layout/header.phtml b/app/layout/header.phtml
index b152ed78a..1e4290f98 100644
--- a/app/layout/header.phtml
+++ b/app/layout/header.phtml
@@ -50,6 +50,9 @@
<?php if (FreshRSS_Auth::hasAccess()) { ?>
<nav class="item configure">
+ <form id="post-csrf" method="post">
+ <input type="hidden" name="_csrf" value="<?= FreshRSS_Auth::csrfToken() ?>" />
+ </form>
<div class="dropdown">
<div id="dropdown-configure" class="dropdown-target"></div>
<a class="btn dropdown-toggle" href="#dropdown-configure"><?= _i('configure') ?></a>
@@ -63,7 +66,9 @@
<ul>
<li class="item"><a href="<?= _url('user', 'profile') ?>"><?= _t('gen.menu.user_profile') ?></a></li>
<?php if (FreshRSS_Auth::accessNeedsAction()): ?>
- <li class="item"><a class="signout" href="<?= _url('auth', 'logout') ?>"><?= _t('gen.auth.logout'); ?><?= _i('logout') ?></a></li>
+ <li class="item">
+ <button class="as-link signout" form="post-csrf" formaction="<?= _url('auth', 'logout') ?>"><?= _t('gen.auth.logout'); ?><?= _i('logout') ?></button>
+ </li>
<?php else: ?>
<li class="item"><span class="signout">(<?= htmlspecialchars(Minz_User::name() ?? '', ENT_NOQUOTES, 'UTF-8') ?>)</span></li>
<?php endif; ?>
diff --git a/app/layout/simple.phtml b/app/layout/simple.phtml
index a79d102af..2a14682c9 100644
--- a/app/layout/simple.phtml
+++ b/app/layout/simple.phtml
@@ -60,13 +60,15 @@
<div class="item"></div>
+ <form id="post-csrf" method="post">
+ <input type="hidden" name="_csrf" value="<?= FreshRSS_Auth::csrfToken() ?>" />
+ </form>
+
<?php if (FreshRSS_Auth::accessNeedsAction()): ?>
<div class="item configure">
<?php if (FreshRSS_Auth::hasAccess()): ?>
- <a class="signout" href="<?= Minz_Url::display(['c' => 'auth', 'a' => 'logout'], 'html', 'root') ?>">
- <?= _i('logout') ?><?= _t('gen.auth.logout') ?>
- (<?= htmlspecialchars(Minz_User::name() ?? '', ENT_NOQUOTES, 'UTF-8') ?>)
- </a>
+ <button class="as-link signout" form="post-csrf" formaction="<?=
+ _url('auth', 'logout') ?>"><?= _t('gen.auth.logout'); ?><?= _i('logout') ?></button>
<?php else: ?>
<a class="signin" href="<?= Minz_Url::display(['c' => 'auth', 'a' => 'login'], 'html', 'root') ?>">
<?= _i('login') ?><?= _t('gen.auth.login') ?>