Skip generating csrf token when csrf protection is turned off

This commit is contained in:
Kacper Kubacki 2025-09-01 13:02:15 +02:00 committed by Michał Kaczmarek
parent 868f7fc4f4
commit 93650735f5
21 changed files with 91 additions and 19 deletions

View file

@ -18,7 +18,7 @@
{{ form_widget(hookable_metadata.context.form.avatar) }}
{% if admin_user.id is not null and admin_user.avatar is not null and admin_user.avatar.path is not empty %}
<button
formaction="{{ path('sylius_admin_admin_user_remove_avatar', {'id': admin_user.id, '_csrf_token': csrf_token(admin_user.id)}) }}"
formaction="{{ path('sylius_admin_admin_user_remove_avatar', {'id': admin_user.id, '_csrf_token': sylius_csrf_protection_enabled() ? csrf_token(admin_user.id) : null}) }}"
type="submit"
class="btn btn-danger"
{{ sylius_test_html_attribute('delete-avatar-button') }}

View file

@ -4,7 +4,9 @@
{% if user != null %}
<form action="{{ path('sylius_admin_shop_user_delete', {'id': user.id, 'customerId': customer.id}) }}" method="POST">
<input type="hidden" name="_method" value="DELETE" />
<input type="hidden" name="_csrf_token" value="{{ csrf_token(user.id) }}" />
{% if sylius_csrf_protection_enabled() %}
<input type="hidden" name="_csrf_token" value="{{ csrf_token(user.id) }}" />
{% endif %}
<button type="submit" class="dropdown-item" {{ sylius_test_html_attribute('customer-actions-delete') }}>
{{ ux_icon('tabler:trash-x', {'class': 'icon dropdown-item-icon'}) }}
{{ 'sylius.ui.delete'|trans }}

View file

@ -5,7 +5,9 @@
{% if sylius_sm_can(order, constant('Sylius\\Component\\Order\\OrderTransitions::GRAPH'), constant('Sylius\\Component\\Order\\OrderTransitions::TRANSITION_CANCEL')) %}
<form action="{{ path('sylius_admin_order_cancel', {'id': order.id}) }}" method="POST" novalidate>
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_csrf_token" value="{{ csrf_token(order.id) }}" />
{% if sylius_csrf_protection_enabled() %}
<input type="hidden" name="_csrf_token" value="{{ csrf_token(order.id) }}" />
{% endif %}
<button type="submit" class="dropdown-item" {{ sylius_test_html_attribute('cancel-order') }}>
{{ ux_icon('tabler:circle-check', {'class': 'icon dropdown-item-icon'}) }}
{{ 'sylius.ui.cancel'|trans }}

View file

@ -3,7 +3,9 @@
{% if sylius_sm_can(order, constant('Sylius\\Component\\Order\\OrderTransitions::GRAPH'), constant('Sylius\\Component\\Order\\OrderTransitions::TRANSITION_CANCEL')) %}
<form action="{{ path('sylius_admin_order_cancel', {'id': order.id}) }}" method="POST" novalidate>
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_csrf_token" value="{{ csrf_token(order.id) }}" />
{% if sylius_csrf_protection_enabled() %}
<input type="hidden" name="_csrf_token" value="{{ csrf_token(order.id) }}" />
{% endif %}
<button type="submit" class="dropdown-item" {{ sylius_test_html_attribute('cancel-order') }}>
{{ ux_icon('tabler:circle-check', {'class': 'icon dropdown-item-icon'}) }}
{{ 'sylius.ui.cancel'|trans }}

View file

@ -1,7 +1,7 @@
{% set order = hookable_metadata.context.resource %}
{% if order.state in sylius_order_states_that_allows_to_resend_order_confirmation_email %}
{% set path = path('sylius_admin_order_resend_confirmation_email', {'id': order.id, '_csrf_token': csrf_token(order.id)}) %}
{% set path = path('sylius_admin_order_resend_confirmation_email', {'id': order.id, '_csrf_token': sylius_csrf_protection_enabled() ? csrf_token(order.id) : null}) %}
<a class="dropdown-item" href="{{ path }}" {{ sylius_test_html_attribute('resend-order-confirmation-email') }}>
{{ ux_icon('tabler:send', {'class': 'icon dropdown-item-icon flex-shrink-0'}) }}
<div class="pe-6">{{ 'sylius.ui.resend_the_order_confirmation_email'|trans }}</div>

View file

@ -3,7 +3,7 @@
{% set order = hookable_metadata.context.resource %}
{% if order.state in sylius_order_states_that_allows_to_resend_order_confirmation_email %}
{% set path = path('sylius_admin_order_resend_confirmation_email', {'id': order.id, '_csrf_token': csrf_token(order.id)}) %}
{% set path = path('sylius_admin_order_resend_confirmation_email', {'id': order.id, '_csrf_token': sylius_csrf_protection_enabled() ? csrf_token(order.id) : null}) %}
<a class="dropdown-item" href="{{ path }}" {{ sylius_test_html_attribute('resend-order-confirmation-email') }}>
{{ ux_icon('tabler:send', {'class': 'icon dropdown-item-icon flex-shrink-0'}) }}
<div class="pe-6">{{ 'sylius.ui.resend_the_order_confirmation_email'|trans }}</div>

View file

@ -4,7 +4,9 @@
{% if sylius_sm_can(payment, constant('Sylius\\Component\\Payment\\PaymentTransitions::GRAPH'), constant('Sylius\\Component\\Payment\\PaymentTransitions::TRANSITION_COMPLETE')) %}
<form action="{{ path('sylius_admin_order_payment_complete', {'orderId': order.id, 'id': payment.id}) }}" method="POST" novalidate>
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_csrf_token" value="{{ csrf_token(payment.id) }}" />
{% if sylius_csrf_protection_enabled() %}
<input type="hidden" name="_csrf_token" value="{{ csrf_token(payment.id) }}" />
{% endif %}
<button type="submit" class="btn" {{ sylius_test_html_attribute('complete-payment', payment.id) }}>
{{ ux_icon('tabler:check') }} {{ 'sylius.ui.complete'|trans }}
</button>

View file

@ -4,7 +4,9 @@
{% if sylius_sm_can(payment, constant('Sylius\\Component\\Payment\\PaymentTransitions::GRAPH'), constant('Sylius\\Component\\Payment\\PaymentTransitions::TRANSITION_REFUND')) %}
<form action="{{ path('sylius_admin_order_payment_refund', {'orderId': order.id, 'id': payment.id}) }}" method="POST" novalidate>
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_csrf_token" value="{{ csrf_token(payment.id) }}" />
{% if sylius_csrf_protection_enabled() %}
<input type="hidden" name="_csrf_token" value="{{ csrf_token(payment.id) }}" />
{% endif %}
<button type="submit" class="btn" {{ sylius_test_html_attribute('refund-payment', payment.id) }}>
{{ ux_icon('tabler:arrow-back-up-double') }} {{ 'sylius.ui.refund'|trans }}
</button>

View file

@ -1,7 +1,7 @@
{% set shipment = hookable_metadata.context.shipment %}
{% if shipment.state == 'shipped' %}
{% set resend_path = path('sylius_admin_shipment_resend_confirmation_email', {'id': shipment.id, '_csrf_token': csrf_token(shipment.id)}) %}
{% set resend_path = path('sylius_admin_shipment_resend_confirmation_email', {'id': shipment.id, '_csrf_token': sylius_csrf_protection_enabled () ? csrf_token(shipment.id) : null}) %}
<a href="{{ resend_path }}" class="btn btn-icon" data-bs-toggle="tooltip" data-bs-title="{{ 'sylius.ui.resend_the_shipment_confirmation_email'|trans }}" {{ sylius_test_html_attribute('resend-shipment-confirmation-email') }}>
{{ ux_icon('tabler:send') }}
</a>

View file

@ -1,7 +1,7 @@
<button class="btn primary"
{{ stimulus_controller('@sylius/admin-bundle/save-positions', {
url: path('sylius_admin_ajax_product_taxons_update_position', {taxonId: app.request.get('taxonId')}),
csrfToken: csrf_token('update-product-taxon-position'),
csrfToken: sylius_csrf_protection_enabled() ? csrf_token('update-product-taxon-position') : null,
inputSelector: '.sylius-product-taxon-position',
dataKey: 'productTaxons',
}) }}

View file

@ -1,7 +1,7 @@
<button class="btn primary"
{{ stimulus_controller('@sylius/admin-bundle/save-positions', {
url: path('sylius_admin_ajax_product_variants_update_position'),
csrfToken: csrf_token('update-product-variant-position'),
csrfToken: sylius_csrf_protection_enabled() ? csrf_token('update-product-variant-position') : null,
inputSelector: '.sylius-product-variant-position',
dataKey: 'productVariants',
}) }}

View file

@ -4,5 +4,7 @@
{{ form_start(form, {'action': path('sylius_admin_login_check'), 'attr': {'class': 'ui large loadable form', 'novalidate': 'novalidate'}}) }}
{% hook 'form' with { form } %}
<input type="hidden" name="_csrf_admin_security_token" value="{{ csrf_token('admin_authenticate') }}">
{% if sylius sylius_csrf_protection_enabled() %}
<input type="hidden" name="_csrf_admin_security_token" value="{{ csrf_token('admin_authenticate') }}">
{% endif %}
{{ form_end(form, {'render_rest': false}) }}

View file

@ -13,7 +13,9 @@
{% block footer %}
<form action="{{ path }}" method="post" {{ form_attr }}>
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_csrf_token" value="{{ csrf_token(id) }}" />
{% if sylius_csrf_protection_enabled() %}
<input type="hidden" name="_csrf_token" value="{{ csrf_token(id) }}" />
{% endif %}
{{ button.default({ text: 'sylius.ui.cancel'|trans, attr: 'data-bs-dismiss=modal' }) }}
{{ button.default({ text: label|trans, type: 'submit', class: 'btn-danger', attr: sylius_test_html_attribute('confirm-button') }) }}

View file

@ -3,7 +3,9 @@
{% if sylius_sm_can(data, options.graph, options.transition) %}
<form action="{{ path(options.link.route, options.link.parameters) }}" method="post" {{ sylius_test_html_attribute('action', action.name) }}>
<input type="hidden" name="_csrf_token" value="{{ csrf_token(data.id) }}">
{% if sylius_csrf_protection_enabled() %}
<input type="hidden" name="_csrf_token" value="{{ csrf_token(data.id) }}">
{% endif %}
<input type="hidden" name="_method" value="PUT">
<button class="btn {{ options.class|default }}" {% if labeled and 'btn-icon' in options.class|default %}data-bs-toggle="tooltip" data-bs-title="{{ action.label|trans }}"{% endif %}>
{% if action.icon %}{{ ux_icon(action.icon) }}{% endif %}

View file

@ -17,7 +17,9 @@
{% block footer %}
<form action="{{ path }}" method="POST" name="sylius_archivable">
<input type="hidden" name="_method" value="PATCH">
<input type="hidden" name="sylius_archivable[_token]" value="{{ csrf_token('sylius_archivable') }}" />
{% if sylius_csrf_protection_enabled() %}
<input type="hidden" name="sylius_archivable[_token]" value="{{ csrf_token('sylius_archivable') }}" />
{% endif %}
{{ button.default({ text: 'sylius.ui.cancel'|trans, attr: 'data-bs-dismiss=modal' }) }}
{{ button.default({ text: label, type: 'submit', class: 'btn-primary', attr: sylius_test_html_attribute('confirm-button') }) }}

View file

@ -15,6 +15,7 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
use Sylius\Bundle\CoreBundle\Twig\BundleLoadedCheckerExtension;
use Sylius\Bundle\CoreBundle\Twig\ChannelUrlExtension;
use Sylius\Bundle\CoreBundle\Twig\CsrfProtectionEnabledExtension;
use Sylius\Bundle\CoreBundle\Twig\PriceExtension;
use Sylius\Bundle\CoreBundle\Twig\ProductTranslationExtension;
use Sylius\Bundle\CoreBundle\Twig\VariantResolverExtension;
@ -59,4 +60,11 @@ return static function (ContainerConfigurator $container) {
->private()
->tag('twig.extension')
;
$services
->set('sylius.twig.extension.csrf_protection', CsrfProtectionEnabledExtension::class)
->args([service('service_container')])
->private()
->tag('twig.extension')
;
};

View file

@ -0,0 +1,38 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Sylius Sp. z o.o.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\Twig;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
final class CsrfProtectionEnabledExtension extends AbstractExtension
{
public function __construct(
private readonly ContainerInterface $container,
) {
}
public function getFunctions(): array
{
return [
new TwigFunction('sylius_csrf_protection_enabled', [$this, 'isCsrfProtectionEnabled']),
];
}
public function isCsrfProtectionEnabled(): bool
{
return $this->container->has('security.csrf.token_manager');
}
}

View file

@ -1 +1,3 @@
<input type="hidden" name="_csrf_shop_security_token" value="{{ csrf_token('shop_authenticate') }}">
{% if sylius_csrf_protection_enabled() %}
<input type="hidden" name="_csrf_shop_security_token" value="{{ csrf_token('shop_authenticate') }}">
{% endif %}

View file

@ -11,7 +11,9 @@
<input type="password" class="form-control" placeholder="{{ 'sylius.ui.password'|trans }}" {{ stimulus_target('@sylius/shop-bundle/api-login', 'password') }} {{ sylius_test_html_attribute('password-input') }}>
<button class="btn btn-primary" type="button" {{ stimulus_action('@sylius/shop-bundle/api-login', 'login') }} {{ sylius_test_html_attribute('login-button') }}>{{ 'sylius.ui.sign_in'|trans }}</button>
</div>
<input type="hidden" name="_csrf_shop_security_token" value="{{ csrf_token('shop_authenticate') }}" {{ stimulus_target('@sylius/shop-bundle/api-login', 'csrfToken') }}>
{% if sylius_csrf_protection_enabled() %}
<input type="hidden" name="_csrf_shop_security_token" value="{{ csrf_token('shop_authenticate') }}" {{ stimulus_target('@sylius/shop-bundle/api-login', 'csrfToken') }}>
{% endif %}
<div {{ stimulus_target('@sylius/shop-bundle/api-login', 'error') }} {{ sylius_test_html_attribute('login-validation-error') }}></div>
{% endif %}
</div>

View file

@ -57,6 +57,8 @@
<button class="btn btn-sm btn-icon btn-outline-danger w-full" type="submit" data-requires-confirmation {{ sylius_test_html_attribute('button', 'delete') }}>
{{ ux_icon('tabler:trash', {'class': 'icon icon-xs'})}} {{ ((message is empty and labeled) ? 'sylius.ui.delete' : message)|trans }}
</button>
<input type="hidden" name="_csrf_token" value="{{ csrf_token(resourceId) }}" />
{% if sylius_csrf_protection_enabled() %}
<input type="hidden" name="_csrf_token" value="{{ csrf_token(resourceId) }}" />
{% endif %}
</form>
{% endmacro %}

View file

@ -13,7 +13,9 @@
{% block footer %}
<form action="{{ path }}" method="post" {{ form_attr }}>
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_csrf_token" value="{{ csrf_token(id) }}" />
{% if sylius_csrf_protection_enabled() %}
<input type="hidden" name="_csrf_token" value="{{ csrf_token(id) }}" />
{% endif %}
<button type="button" class="btn btn-sm" data-bs-dismiss="modal">
{{ 'sylius.ui.cancel'|trans }}