1
0
Fork 0
mirror of https://github.com/wallabag/wallabag.git synced 2025-08-01 17:38:38 +00:00

Protect reload_entry with a CSRF token

This commit is contained in:
Yassine Guedidi 2025-03-19 01:31:35 +01:00
parent ed1acf59e1
commit 3817010e29
5 changed files with 55 additions and 10 deletions

View file

@ -62,7 +62,9 @@
.nav-panels .input-field input:focus, .nav-panels .input-field input:focus,
.results-item, .results-item,
.side-nav li > a, .side-nav li > a,
.side-nav li > a > i.material-icons { .side-nav li > a > i.material-icons,
.side-nav li button,
.side-nav li button > i.material-icons {
color: #dfdfdf; color: #dfdfdf;
} }

View file

@ -12,6 +12,7 @@
background: initial; background: initial;
} }
& button > i.material-icons.theme-toggle-icon,
& > a > i.material-icons.theme-toggle-icon { & > a > i.material-icons.theme-toggle-icon {
float: none; float: none;
margin-left: 0; margin-left: 0;
@ -22,6 +23,7 @@
margin: 0; margin: 0;
} }
&.fixed button,
&.fixed a { &.fixed a {
font-size: 13px; font-size: 13px;
line-height: 44px; line-height: 44px;
@ -41,7 +43,35 @@
} }
} }
.bold > a { // adapted from anchor styles from node_modules/materialize-css/sass/components/_sideNav.scss
.side-nav li button {
color: rgba(0 0 0 / 87%);
display: block;
font-size: 14px;
font-weight: 500;
height: 48px;
line-height: 48px;
padding: 0 (16px * 2);
width: 100%;
text-align: left;
&:hover {
background-color: rgba(0 0 0 / 5%);
}
& > i,
& > i.material-icons {
float: left;
height: 48px;
line-height: 48px;
margin: 0 (16px * 2) 0 0;
width: 24px;
color: rgba(0 0 0 / 54%);
}
}
.bold > a,
.bold > button {
font-weight: bold; font-weight: bold;
} }

View file

@ -14,6 +14,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorInterface;
use Wallabag\CoreBundle\Entity\Entry; use Wallabag\CoreBundle\Entity\Entry;
@ -400,12 +401,16 @@ class EntryController extends AbstractController
* Reload an entry. * Reload an entry.
* Refetch content from the website and make it readable again. * Refetch content from the website and make it readable again.
* *
* @Route("/reload/{id}", requirements={"id" = "\d+"}, name="reload_entry") * @Route("/reload/{id}", name="reload_entry", methods={"POST"}, requirements={"id" = "\d+"})
* *
* @return RedirectResponse * @return RedirectResponse
*/ */
public function reloadAction(Entry $entry) public function reloadAction(Request $request, Entry $entry)
{ {
if (!$this->isCsrfTokenValid('reload-entry', $request->request->get('token'))) {
throw new BadRequestHttpException('Bad CSRF token.');
}
$this->checkUserAction($entry); $this->checkUserAction($entry);
$this->updateEntry($entry, 'entry_reloaded'); $this->updateEntry($entry, 'entry_reloaded');

View file

@ -56,10 +56,14 @@
</li> </li>
<li class="bold"> <li class="bold">
<a class="waves-effect collapsible-header" onclick="return confirm('{{ 'entry.confirm.reload'|trans|escape('js') }}')" title="{{ 'entry.view.left_menu.re_fetch_content'|trans }}" href="{{ path('reload_entry', {'id': entry.id}) }}" id="reload"> <form action="{{ path('reload_entry', {'id': entry.id}) }}" method="post">
<i class="material-icons small">refresh</i> <input type="hidden" name="token" value="{{ csrf_token('reload-entry') }}"/>
<span>{{ 'entry.view.left_menu.re_fetch_content'|trans }}</span>
</a> <button type="submit" class="waves-effect collapsible-header" onclick="return confirm('{{ 'entry.confirm.reload'|trans|escape('js') }}')" title="{{ 'entry.view.left_menu.re_fetch_content'|trans }}">
<i class="material-icons small">refresh</i>
<span>{{ 'entry.view.left_menu.re_fetch_content'|trans }}</span>
</button>
</form>
<div class="collapsible-body"></div> <div class="collapsible-body"></div>
</li> </li>

View file

@ -509,7 +509,9 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->getEntityManager()->flush(); $this->getEntityManager()->flush();
$this->getEntityManager()->clear(); $this->getEntityManager()->clear();
$client->request('GET', '/reload/' . $entry->getId()); $crawler = $client->request('GET', '/view/' . $entry->getId());
$client->submit($crawler->selectButton('entry.view.left_menu.re_fetch_content')->form());
$this->assertSame(302, $client->getResponse()->getStatusCode()); $this->assertSame(302, $client->getResponse()->getStatusCode());
@ -530,7 +532,9 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->getEntityManager()->persist($entry); $this->getEntityManager()->persist($entry);
$this->getEntityManager()->flush(); $this->getEntityManager()->flush();
$client->request('GET', '/reload/' . $entry->getId()); $crawler = $client->request('GET', '/view/' . $entry->getId());
$client->submit($crawler->selectButton('entry.view.left_menu.re_fetch_content')->form());
$this->assertSame(302, $client->getResponse()->getStatusCode()); $this->assertSame(302, $client->getResponse()->getStatusCode());