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

Protect changeLocale with a CSRF token

This commit is contained in:
Yassine Guedidi 2025-03-19 00:40:30 +01:00
parent e162408139
commit ed1acf59e1
3 changed files with 36 additions and 12 deletions

View file

@ -672,12 +672,16 @@ class ConfigController extends AbstractController
*
* @param string $language
*
* @Route("/locale/{language}", name="changeLocale")
* @Route("/locale/{language}", name="changeLocale", methods={"POST"})
*
* @return RedirectResponse
*/
public function setLocaleAction(Request $request, ValidatorInterface $validator, $language = null)
{
if (!$this->isCsrfTokenValid('change-locale', $request->request->get('token'))) {
throw new BadRequestHttpException('Bad CSRF token.');
}
$errors = $validator->validate($language, (new LocaleConstraint()));
if (0 === \count($errors)) {

View file

@ -16,9 +16,23 @@
{% endblock fos_user_content %}
</div>
<div class="center">
<a href="{{ path('changeLocale', {'language': 'de'}) }}">Deutsch</a>
<a href="{{ path('changeLocale', {'language': 'en'}) }}">English</a>
<a href="{{ path('changeLocale', {'language': 'fr'}) }}">Français</a>
<form action="{{ path('changeLocale', {'language': 'de'}) }}" method="post" class="inline-block">
<input type="hidden" name="token" value="{{ csrf_token('change-locale') }}"/>
<button type="submit" class="btn-link">Deutsch</button>
</form>
<form action="{{ path('changeLocale', {'language': 'en'}) }}" method="post" class="inline-block">
<input type="hidden" name="token" value="{{ csrf_token('change-locale') }}"/>
<button type="submit" class="btn-link">English</button>
</form>
<form action="{{ path('changeLocale', {'language': 'fr'}) }}" method="post" class="inline-block">
<input type="hidden" name="token" value="{{ csrf_token('change-locale') }}"/>
<button type="submit" class="btn-link">Français</button>
</form>
</div>
</div>
</main>

View file

@ -1133,19 +1133,21 @@ class ConfigControllerTest extends WallabagCoreTestCase
{
$client = $this->getTestClient();
$client->request('GET', '/locale/de');
$client->followRedirect();
$crawler = $client->request('POST', '/locale/de');
$this->assertSame('de', $client->getRequest()->getLocale());
$this->assertSame('de', $client->getContainer()->get(SessionInterface::class)->get('_locale'));
$this->assertSame(400, $client->getResponse()->getStatusCode());
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
$this->assertStringContainsString('Bad CSRF token.', $body[0]);
}
public function testChangeLocaleWithReferer()
{
$client = $this->getTestClient();
$client->request('GET', '/login');
$client->request('GET', '/locale/de');
$crawler = $client->request('GET', '/login');
$client->submit($crawler->selectButton('Deutsch')->form());
$client->followRedirect();
$this->assertSame('de', $client->getRequest()->getLocale());
@ -1156,8 +1158,12 @@ class ConfigControllerTest extends WallabagCoreTestCase
{
$client = $this->getTestClient();
$client->request('GET', '/login');
$client->request('GET', '/locale/yuyuyuyu');
$crawler = $client->request('GET', '/login');
$token = $crawler->filter('form[action="/locale/de"] input[name=token]')->attr('value');
$client->request('POST', '/locale/yuyuyuyu', [
'token' => $token,
]);
$client->followRedirect();
$this->assertNotSame('yuyuyuyu', $client->getRequest()->getLocale());