1
0
Fork 0
mirror of https://github.com/wallabag/wallabag.git synced 2025-06-27 16:36:00 +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,
.results-item,
.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;
}

View file

@ -12,6 +12,7 @@
background: initial;
}
& button > i.material-icons.theme-toggle-icon,
& > a > i.material-icons.theme-toggle-icon {
float: none;
margin-left: 0;
@ -22,6 +23,7 @@
margin: 0;
}
&.fixed button,
&.fixed a {
font-size: 13px;
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;
}

View file

@ -14,6 +14,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\Translation\TranslatorInterface;
use Wallabag\CoreBundle\Entity\Entry;
@ -400,12 +401,16 @@ class EntryController extends AbstractController
* Reload an entry.
* 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
*/
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->updateEntry($entry, 'entry_reloaded');

View file

@ -56,10 +56,14 @@
</li>
<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">
<i class="material-icons small">refresh</i>
<span>{{ 'entry.view.left_menu.re_fetch_content'|trans }}</span>
</a>
<form action="{{ path('reload_entry', {'id': entry.id}) }}" method="post">
<input type="hidden" name="token" value="{{ csrf_token('reload-entry') }}"/>
<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>
</li>

View file

@ -509,7 +509,9 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->getEntityManager()->flush();
$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());
@ -530,7 +532,9 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->getEntityManager()->persist($entry);
$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());