1
0
Fork 0
mirror of https://github.com/wallabag/wallabag.git synced 2025-06-27 16:36:00 +00:00

Protect star_entry with a CSRF token

This commit is contained in:
Yassine Guedidi 2025-03-21 23:28:08 +01:00
parent edffef8375
commit 00d0e6f951
6 changed files with 47 additions and 13 deletions

View file

@ -10,7 +10,7 @@ $(document).ready(() => {
/* mark as favorite */ /* mark as favorite */
Mousetrap.bind('f', () => { Mousetrap.bind('f', () => {
$('ul.side-nav a.favorite i')[0].click(); $('ul.side-nav button.favorite i')[0].click();
}); });
/* mark as read */ /* mark as read */

View file

@ -467,12 +467,16 @@ class EntryController extends AbstractController
/** /**
* Changes starred status for an entry. * Changes starred status for an entry.
* *
* @Route("/star/{id}", requirements={"id" = "\d+"}, name="star_entry") * @Route("/star/{id}", name="star_entry", methods={"POST"}, requirements={"id" = "\d+"})
* *
* @return RedirectResponse * @return RedirectResponse
*/ */
public function toggleStarAction(Request $request, Entry $entry) public function toggleStarAction(Request $request, Entry $entry)
{ {
if (!$this->isCsrfTokenValid('star-entry', $request->request->get('token'))) {
throw new BadRequestHttpException('Bad CSRF token.');
}
$this->checkUserAction($entry); $this->checkUserAction($entry);
$entry->toggleStar(); $entry->toggleStar();

View file

@ -23,7 +23,13 @@
</form> </form>
</li> </li>
<li> <li>
<a title="{{ 'entry.list.toogle_as_star'|trans }}" class="tool grey-text" href="{{ path('star_entry', {'id': entry.id, redirect: current_path}) }}" data-action="star" data-entry-id="{{ entry.id }}"><i class="material-icons">{% if entry.isStarred == 0 %}star_border{% else %}star{% endif %}</i></a> <form action="{{ path('star_entry', {'id': entry.id, redirect: current_path}) }}" method="post" class="inline-block">
<input type="hidden" name="token" value="{{ csrf_token('star-entry') }}"/>
<button type="submit" class="btn-link tool grey-text" title="{{ 'entry.list.toogle_as_star'|trans }}">
<i class="material-icons">{% if entry.isStarred == 0 %}star_border{% else %}star{% endif %}</i>
</button>
</form>
</li> </li>
<li> <li>
<a title="{{ 'entry.list.delete'|trans }}" onclick="return confirm('{{ 'entry.confirm.delete'|trans|escape('js') }}')" data-action-confirm="{{ 'entry.confirm.delete'|trans }}" class="tool grey-text delete" href="{{ path('delete_entry', {'id': entry.id, redirect: current_path}) }}" data-action="delete" data-entry-id="{{ entry.id }}"><i class="material-icons">delete</i></a> <a title="{{ 'entry.list.delete'|trans }}" onclick="return confirm('{{ 'entry.confirm.delete'|trans|escape('js') }}')" data-action-confirm="{{ 'entry.confirm.delete'|trans }}" class="tool grey-text delete" href="{{ path('delete_entry', {'id': entry.id, redirect: current_path}) }}" data-action="delete" data-entry-id="{{ entry.id }}"><i class="material-icons">delete</i></a>

View file

@ -22,7 +22,13 @@
<i class="material-icons">{% if entry.isArchived == 0 %}done{% else %}unarchive{% endif %}</i> <i class="material-icons">{% if entry.isArchived == 0 %}done{% else %}unarchive{% endif %}</i>
</button> </button>
</form> </form>
<a title="{{ 'entry.list.toogle_as_star'|trans }}" class="tool grey-text" href="{{ path('star_entry', {'id': entry.id, redirect: current_path}) }}"><i class="material-icons">{% if entry.isStarred == 0 %}star_border{% else %}star{% endif %}</i></a> <form action="{{ path('star_entry', {'id': entry.id, redirect: current_path}) }}" method="post" class="inline-block">
<input type="hidden" name="token" value="{{ csrf_token('star-entry') }}"/>
<button type="submit" class="btn-link tool grey-text" title="{{ 'entry.list.toogle_as_star'|trans }}">
<i class="material-icons">{% if entry.isStarred == 0 %}star_border{% else %}star{% endif %}</i>
</button>
</form>
<a title="{{ 'entry.list.delete'|trans }}" onclick="return confirm('{{ 'entry.confirm.delete'|trans|escape('js') }}')" class="tool grey-text delete" href="{{ path('delete_entry', {'id': entry.id, redirect: current_path}) }}"><i class="material-icons">delete</i></a> <a title="{{ 'entry.list.delete'|trans }}" onclick="return confirm('{{ 'entry.confirm.delete'|trans|escape('js') }}')" class="tool grey-text delete" href="{{ path('delete_entry', {'id': entry.id, redirect: current_path}) }}"><i class="material-icons">delete</i></a>
</li> </li>
</ul> </ul>

View file

@ -35,9 +35,13 @@
</form> </form>
</li> </li>
<li> <li>
<a class="waves-effect" title="{{ 'entry.view.left_menu.set_as_starred'|trans }}" href="{{ path('star_entry', {'id': entry.id, redirect: current_path}) }}" id="setFav"> <form action="{{ path('star_entry', {'id': entry.id, redirect: current_path}) }}" method="post" class="inline-block">
<input type="hidden" name="token" value="{{ csrf_token('star-entry') }}"/>
<button type="submit" class="waves-effect" title="{{ 'entry.view.left_menu.set_as_starred'|trans }}">
<i class="material-icons small">{% if entry.isStarred == 0 %}star_outline{% else %}star{% endif %}</i> <i class="material-icons small">{% if entry.isStarred == 0 %}star_outline{% else %}star{% endif %}</i>
</a> </button>
</form>
</li> </li>
</ul> </ul>
</div> </div>
@ -89,10 +93,14 @@
</li> </li>
<li class="bold hide-on-med-and-down"> <li class="bold hide-on-med-and-down">
<a class="waves-effect collapsible-header favorite" title="{{ 'entry.view.left_menu.set_as_starred'|trans }}" href="{{ path('star_entry', {'id': entry.id, redirect: current_path}) }}" id="setFav"> <form action="{{ path('star_entry', {'id': entry.id, redirect: current_path}) }}" method="post">
<input type="hidden" name="token" value="{{ csrf_token('star-entry') }}"/>
<button type="submit" class="waves-effect collapsible-header favorite" title="{{ 'entry.view.left_menu.set_as_starred'|trans }}">
<i class="material-icons spall">{% if entry.isStarred == 0 %}star_outline{% else %}star{% endif %}</i> <i class="material-icons spall">{% if entry.isStarred == 0 %}star_outline{% else %}star{% endif %}</i>
<span>{{ 'entry.view.left_menu.set_as_starred'|trans }}</span> <span>{{ 'entry.view.left_menu.set_as_starred'|trans }}</span>
</a> </button>
</form>
<div class="collapsible-body"></div> <div class="collapsible-body"></div>
</li> </li>
<li class="bold border-bottom"> <li class="bold border-bottom">
@ -321,7 +329,15 @@
</button> </button>
</form> </form>
</li> </li>
<li><a class="btn-floating" href="{{ path('star_entry', {'id': entry.id, redirect: current_path}) }}"><i class="material-icons">{% if entry.isStarred == 0 %}star_outline{% else %}star{% endif %}</i></a></li> <li>
<form action="{{ path('star_entry', {'id': entry.id, redirect: current_path}) }}" method="post" class="inline-block">
<input type="hidden" name="token" value="{{ csrf_token('star-entry') }}"/>
<button type="submit" class="btn-floating">
<i class="material-icons">{% if entry.isStarred == 0 %}star_outline{% else %}star{% endif %}</i>
</button>
</form>
</li>
<li><a class="btn-floating" href="{{ path('delete_entry', {'id': entry.id, redirect: current_path}) }}" onclick="return confirm('{{ 'entry.confirm.delete'|trans|escape('js') }}')"><i class="material-icons">delete</i></a></li> <li><a class="btn-floating" href="{{ path('delete_entry', {'id': entry.id, redirect: current_path}) }}" onclick="return confirm('{{ 'entry.confirm.delete'|trans|escape('js') }}')"><i class="material-icons">delete</i></a></li>
</ul> </ul>
</div> </div>

View file

@ -670,7 +670,9 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->getEntityManager()->flush(); $this->getEntityManager()->flush();
$this->getEntityManager()->clear(); $this->getEntityManager()->clear();
$client->request('GET', '/star/' . $entry->getId()); $crawler = $client->request('GET', '/view/' . $entry->getId());
$client->submit($crawler->filter('.left-bar')->selectButton('entry.view.left_menu.set_as_starred')->form());
$this->assertSame(302, $client->getResponse()->getStatusCode()); $this->assertSame(302, $client->getResponse()->getStatusCode());