The "CSRF Protections" / "CSRF" sections in manuals/1.0/en/form.md:136 and manuals/1.0/ja/form.md:136 state:
A form that uses SetAntiCsrfTrait is wired with an AntiCsrfInterface, but the token is only verified on methods annotated with #[CsrfProtection]. Methods without #[CsrfProtection] perform no CSRF check even if the form has an AntiCsrf object set.
This does not match the implementation in ray/web-form-module 1.0.
What actually happens
SetAntiCsrfTrait::setAntiCsrf() is annotated with #[Inject], so DI populates $this->antiCsrf at construction. AbstractForm::postConstruct() then calls enableAntiCsrf() which adds the token field, and AbstractForm::apply() throws CsrfViolationException on token mismatch — regardless of whether the validated method has #[CsrfProtection].
This is exercised by AbstractFormTest::testAntiCsrfViolation (source), which sets antiCsrf directly on the form (no interceptor, no attribute) and asserts the throw.
Two independent opt-in paths
- Per-form:
use SetAntiCsrfTrait; on the form — always-on for that form.
- Per-action:
#[CsrfProtection] on the controller/resource method — AuraInputInterceptor injects antiCsrf before apply().
Either path enables enforcement.
Related fix upstream
The same wording in ray-di/Ray.WebFormModule README was corrected in ray-di/Ray.WebFormModule#30. The docs site needs the same correction in both EN and JA pages.
Proposed patch
git apply 可能なパッチ
--- a/manuals/1.0/en/form.md
+++ b/manuals/1.0/en/form.md
@@ -133,7 +133,12 @@
## CSRF Protections
-CSRF protection is **opt-in**. A form that uses `SetAntiCsrfTrait` is wired with an `AntiCsrfInterface`, but the token is only verified on methods annotated with `#[CsrfProtection]`. Methods without `#[CsrfProtection]` perform no CSRF check even if the form has an `AntiCsrf` object set.
+CSRF protection is **opt-in** and can be enabled through either of two independent paths:
+
+- **Per-form**: add `use SetAntiCsrfTrait;` to the form. `AntiCsrfInterface` is injected at construction time, the token field is added in `postConstruct()`, and every `apply()` call verifies the token.
+- **Per-action**: annotate the validated method with `#[CsrfProtection]`. `AuraInputInterceptor` then injects `AntiCsrfInterface` into the form before `apply()` runs.
+
+Either path causes `AbstractForm::apply()` to throw `CsrfViolationException` on token mismatch. Without either path, no CSRF check is performed.
```php
use BEAR\Resource\ResourceObject;
--- a/manuals/1.0/ja/form.md
+++ b/manuals/1.0/ja/form.md
@@ -133,7 +133,12 @@
## CSRF
-CSRF(クロスサイトリクエストフォージェリ)保護はopt-inです。フォームに`SetAntiCsrfTrait`を使うと`AntiCsrfInterface`が組み込まれますが、トークンの検証は`#[CsrfProtection]`アトリビュートを付けたメソッドでのみ実行されます。アトリビュートが無いメソッドでは、フォームが`AntiCsrf`オブジェクトを持っていてもCSRF検証は行われません。
+CSRF(クロスサイトリクエストフォージェリ)保護は**opt-in**で、独立した2つの経路のいずれかで有効化できます。
+
+- **フォーム単位**: フォームに`use SetAntiCsrfTrait;`を追加します。DIで`AntiCsrfInterface`が注入され、`postConstruct()`でトークンフィールドが追加され、`apply()`の呼び出しごとにトークンが検証されます。
+- **アクション単位**: バリデーション対象のメソッドに`#[CsrfProtection]`を付与します。`AuraInputInterceptor`が`apply()`実行前に`AntiCsrfInterface`をフォームへ注入します。
+
+どちらの経路でも、トークン不一致時には`AbstractForm::apply()`が`CsrfViolationException`をthrowします。どちらも使わない場合はCSRF検証は行われません。
```php
use BEAR\Resource\ResourceObject;
The "CSRF Protections" / "CSRF" sections in
manuals/1.0/en/form.md:136andmanuals/1.0/ja/form.md:136state:This does not match the implementation in
ray/web-form-module1.0.What actually happens
SetAntiCsrfTrait::setAntiCsrf()is annotated with#[Inject], so DI populates$this->antiCsrfat construction.AbstractForm::postConstruct()then callsenableAntiCsrf()which adds the token field, andAbstractForm::apply()throwsCsrfViolationExceptionon token mismatch — regardless of whether the validated method has#[CsrfProtection].This is exercised by
AbstractFormTest::testAntiCsrfViolation(source), which sets antiCsrf directly on the form (no interceptor, no attribute) and asserts the throw.Two independent opt-in paths
use SetAntiCsrfTrait;on the form — always-on for that form.#[CsrfProtection]on the controller/resource method —AuraInputInterceptorinjects antiCsrf beforeapply().Either path enables enforcement.
Related fix upstream
The same wording in
ray-di/Ray.WebFormModuleREADME was corrected in ray-di/Ray.WebFormModule#30. The docs site needs the same correction in both EN and JA pages.Proposed patch
git apply 可能なパッチ