Skip to content

Commit b7b7fd4

Browse files
jonas-jonasory-bot
authored andcommitted
fix: return correct CSRF errors
GitOrigin-RevId: cab70529e9041391cd406fb96b8ce0b53b1a657f
1 parent 68bea59 commit b7b7fd4

13 files changed

Lines changed: 146 additions & 75 deletions

File tree

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ require (
5858
github.com/ory/client-go v0.0.0-00010101000000-000000000000
5959
github.com/ory/dockertest/v3 v3.12.0
6060
github.com/ory/graceful v0.1.4-0.20230301144740-e222150c51d0
61-
github.com/ory/herodot v0.10.7
61+
github.com/ory/herodot v0.10.8
6262
github.com/ory/hydra-client-go/v2 v2.2.1
6363
github.com/ory/jsonschema/v3 v3.0.9-0.20250317235931-280c5fc7bf0e
6464
github.com/ory/mail/v3 v3.0.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -607,8 +607,8 @@ github.com/ory/go-oidc/v3 v3.0.0-20250124100243-69986dfaf891 h1:HjpfYsY85wpheyMw
607607
github.com/ory/go-oidc/v3 v3.0.0-20250124100243-69986dfaf891/go.mod h1:Jxfv2TPRvdJuLfmkvokss8dkguhMmer2UvARU6SWy0Y=
608608
github.com/ory/graceful v0.1.4-0.20230301144740-e222150c51d0 h1:VMUeLRfQD14fOMvhpYZIIT4vtAqxYh+f3KnSqCeJ13o=
609609
github.com/ory/graceful v0.1.4-0.20230301144740-e222150c51d0/go.mod h1:hg2iCy+LCWOXahBZ+NQa4dk8J2govyQD79rrqrgMyY8=
610-
github.com/ory/herodot v0.10.7 h1:CETBRP4LboLlQCSVTkyQix/a2bVh1rmNhhfxd45khCI=
611-
github.com/ory/herodot v0.10.7/go.mod h1:j6i246U6iX8TStYNKIVQxb2waweQvtOLi+b/9q+OULg=
610+
github.com/ory/herodot v0.10.8 h1:uUPsXd4FKTsNHHU+OS5gYrRNEMraU36st0kBeWiXsno=
611+
github.com/ory/herodot v0.10.8/go.mod h1:j6i246U6iX8TStYNKIVQxb2waweQvtOLi+b/9q+OULg=
612612
github.com/ory/hydra-client-go/v2 v2.2.1 h1:m1821pIX6ybG/3oSAn2wtrbBKNwe9q5A8fLljYuLpBk=
613613
github.com/ory/hydra-client-go/v2 v2.2.1/go.mod h1:K83R+iK40+5uF2uQ34yRUrf9izRvFsza9pG2Se5qMmk=
614614
github.com/ory/jsonschema/v3 v3.0.9-0.20250317235931-280c5fc7bf0e h1:4tUrC7x4YWRVMFp+c64KACNSGchW1zXo4l6Pa9/1hA8=

internal/driver.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func NewConfigurationWithDefaults(t testing.TB, opts ...configx.OptionModifier)
6363
func NewFastRegistryWithMocks(t *testing.T, opts ...configx.OptionModifier) (*config.Config, *driver.RegistryDefault) {
6464
conf, reg := NewRegistryDefaultWithDSN(t, "", opts...)
6565
reg.WithCSRFTokenGenerator(nosurfx.FakeCSRFTokenGenerator)
66-
reg.WithCSRFHandler(nosurfx.NewFakeCSRFHandler(""))
66+
reg.WithCSRFHandler(nosurfx.NewFakeCSRFHandler(reg))
6767
reg.WithHooks(map[string]func(config.SelfServiceHook) interface{}{
6868
"err": func(c config.SelfServiceHook) interface{} {
6969
return &hook.Error{Config: c.Config}

internal/registrationhelpers/helpers.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,23 +174,25 @@ func AssertCSRFFailures(t *testing.T, reg *driver.RegistryDefault, flows []strin
174174
skipIfNotEnabled(t, flows, "browser")
175175

176176
browserClient := testhelpers.NewClientWithCookies(t)
177+
browserClient.Jar.SetCookies(nosurfx.WithFakeCSRFCookie(t, reg, publicTS.URL))
177178
f := testhelpers.InitializeRegistrationFlowViaBrowser(t, browserClient, publicTS, false, false, false)
178179

179180
actual, res := testhelpers.RegistrationMakeRequest(t, false, false, f, browserClient, values.Encode())
180181
assert.EqualValues(t, http.StatusOK, res.StatusCode)
181-
assertx.EqualAsJSON(t, nosurfx.ErrInvalidCSRFToken,
182+
assertx.EqualAsJSON(t, nosurfx.ErrInvalidCSRFTokenServerTokenMismatch,
182183
json.RawMessage(actual), "%s", actual)
183184
})
184185

185186
t.Run("case=should fail because of missing CSRF token/type=spa", func(t *testing.T) {
186187
skipIfNotEnabled(t, flows, "spa")
187188

188189
browserClient := testhelpers.NewClientWithCookies(t)
190+
browserClient.Jar.SetCookies(nosurfx.WithFakeCSRFCookie(t, reg, publicTS.URL))
189191
f := testhelpers.InitializeRegistrationFlowViaBrowser(t, browserClient, publicTS, true, false, false)
190192

191193
actual, res := testhelpers.RegistrationMakeRequest(t, false, true, f, browserClient, values.Encode())
192194
assert.EqualValues(t, http.StatusForbidden, res.StatusCode)
193-
assertx.EqualAsJSON(t, nosurfx.ErrInvalidCSRFToken,
195+
assertx.EqualAsJSON(t, nosurfx.ErrInvalidCSRFTokenAJAXTokenMismatch,
194196
json.RawMessage(gjson.Get(actual, "error").Raw), "%s", actual)
195197
})
196198

internal/testhelpers/selfservice_login.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ func LoginMakeRequestCtx(
281281
req := NewPostRequest(t, isAPI, f.Ui.Action, bytes.NewBufferString(values))
282282
if isSPA && !isAPI {
283283
req.Header.Set("Accept", "application/json")
284+
req.Header.Set("Sec-Fetch-Mode", "cors")
284285
}
285286
for _, o := range opt {
286287
o(req)

internal/testhelpers/selfservice_registration.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ func RegistrationMakeRequestCtx(
138138
req := NewPostRequest(t, isAPI, f.Ui.Action, bytes.NewBufferString(values))
139139
if isSPA {
140140
req.Header.Set("Accept", "application/json")
141+
req.Header.Set("Sec-Fetch-Mode", "cors")
141142
}
142143
req = req.WithContext(ctx)
143144

internal/testhelpers/selfservice_settings.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,9 @@ func SettingsMakeRequest(
225225
if isSPA || isAPI {
226226
req.Header.Set("Accept", "application/json")
227227
}
228+
if isSPA {
229+
req.Header.Set("Sec-Fetch-Mode", "cors")
230+
}
228231

229232
res, err := hc.Do(req)
230233
require.NoError(t, err, "action: %s", f.Ui.Action)

selfservice/strategy/idfirst/strategy_login_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,21 +216,23 @@ func TestCompleteLogin(t *testing.T) {
216216

217217
t.Run("case=should fail because of missing CSRF token/type=browser", func(t *testing.T) {
218218
browserClient := testhelpers.NewClientWithCookies(t)
219+
browserClient.Jar.SetCookies(nosurfx.WithFakeCSRFCookie(t, reg, publicTS.URL))
219220
f := testhelpers.InitializeLoginFlowViaBrowser(t, browserClient, publicTS, false, false, false, false)
220221

221222
actual, res := testhelpers.LoginMakeRequest(t, false, false, f, browserClient, values.Encode())
222223
assert.EqualValues(t, http.StatusOK, res.StatusCode)
223-
assertx.EqualAsJSON(t, nosurfx.ErrInvalidCSRFToken,
224+
assertx.EqualAsJSON(t, nosurfx.ErrInvalidCSRFTokenServerTokenMismatch,
224225
json.RawMessage(actual), "%s", actual)
225226
})
226227

227228
t.Run("case=should fail because of missing CSRF token/type=spa", func(t *testing.T) {
228229
browserClient := testhelpers.NewClientWithCookies(t)
230+
browserClient.Jar.SetCookies(nosurfx.WithFakeCSRFCookie(t, reg, publicTS.URL))
229231
f := testhelpers.InitializeLoginFlowViaBrowser(t, browserClient, publicTS, false, true, false, false)
230232

231233
actual, res := testhelpers.LoginMakeRequest(t, false, true, f, browserClient, values.Encode())
232234
assert.EqualValues(t, http.StatusForbidden, res.StatusCode)
233-
assertx.EqualAsJSON(t, nosurfx.ErrInvalidCSRFToken,
235+
assertx.EqualAsJSON(t, nosurfx.ErrInvalidCSRFTokenAJAXTokenMismatch,
234236
json.RawMessage(gjson.Get(actual, "error").Raw), "%s", actual)
235237
})
236238

selfservice/strategy/password/login_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,21 +247,23 @@ func TestCompleteLogin(t *testing.T) {
247247

248248
t.Run("case=should fail because of missing CSRF token/type=browser", func(t *testing.T) {
249249
browserClient := testhelpers.NewClientWithCookies(t)
250+
browserClient.Jar.SetCookies(nosurfx.WithFakeCSRFCookie(t, reg, publicTS.URL))
250251
f := testhelpers.InitializeLoginFlowViaBrowser(t, browserClient, publicTS, false, false, false, false)
251252

252253
actual, res := testhelpers.LoginMakeRequest(t, false, false, f, browserClient, values.Encode())
253254
assert.EqualValues(t, http.StatusOK, res.StatusCode)
254-
assertx.EqualAsJSON(t, nosurfx.ErrInvalidCSRFToken,
255+
assertx.EqualAsJSON(t, nosurfx.ErrInvalidCSRFTokenServerTokenMismatch,
255256
json.RawMessage(actual), "%s", actual)
256257
})
257258

258259
t.Run("case=should fail because of missing CSRF token/type=spa", func(t *testing.T) {
259260
browserClient := testhelpers.NewClientWithCookies(t)
261+
browserClient.Jar.SetCookies(nosurfx.WithFakeCSRFCookie(t, reg, publicTS.URL))
260262
f := testhelpers.InitializeLoginFlowViaBrowser(t, browserClient, publicTS, false, true, false, false)
261263

262264
actual, res := testhelpers.LoginMakeRequest(t, false, true, f, browserClient, values.Encode())
263265
assert.EqualValues(t, http.StatusForbidden, res.StatusCode)
264-
assertx.EqualAsJSON(t, nosurfx.ErrInvalidCSRFToken,
266+
assertx.EqualAsJSON(t, nosurfx.ErrInvalidCSRFTokenAJAXTokenMismatch,
265267
json.RawMessage(gjson.Get(actual, "error").Raw), "%s", actual)
266268
})
267269

selfservice/strategy/password/settings_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ func TestSettings(t *testing.T) {
102102
publicTS, _ := testhelpers.NewKratosServer(t, reg)
103103

104104
browserUser1 := testhelpers.NewHTTPClientWithIdentitySessionCookie(t.Context(), t, reg, browserIdentity1)
105+
browserUser1.Jar.SetCookies(nosurfx.WithFakeCSRFCookie(t, reg, publicTS.URL))
105106
browserUser2 := testhelpers.NewHTTPClientWithIdentitySessionCookie(t.Context(), t, reg, browserIdentity2)
107+
browserUser2.Jar.SetCookies(nosurfx.WithFakeCSRFCookie(t, reg, publicTS.URL))
106108
apiUser1 := testhelpers.NewHTTPClientWithIdentitySessionToken(t.Context(), t, reg, apiIdentity1)
107109
apiUser2 := testhelpers.NewHTTPClientWithIdentitySessionToken(t.Context(), t, reg, apiIdentity2)
108110

@@ -442,7 +444,7 @@ func TestSettings(t *testing.T) {
442444
assert.Equal(t, http.StatusOK, res.StatusCode)
443445
assert.Contains(t, res.Request.URL.String(), conf.GetProvider(t.Context()).String(config.ViperKeySelfServiceErrorUI))
444446

445-
assertx.EqualAsJSON(t, nosurfx.ErrInvalidCSRFToken, json.RawMessage(actual), "%s", actual)
447+
assertx.EqualAsJSON(t, nosurfx.ErrInvalidCSRFTokenServerTokenMismatch, json.RawMessage(actual), "%s", actual)
446448
})
447449

448450
t.Run("case=should pass even without CSRF token/type=spa", func(t *testing.T) {
@@ -455,7 +457,7 @@ func TestSettings(t *testing.T) {
455457
assert.Equal(t, http.StatusForbidden, res.StatusCode)
456458

457459
assert.Contains(t, res.Request.URL.String(), publicTS.URL+settings.RouteSubmitFlow)
458-
assertx.EqualAsJSON(t, nosurfx.ErrInvalidCSRFToken, json.RawMessage(gjson.Get(actual, "error").Raw), "%s", actual)
460+
assertx.EqualAsJSON(t, nosurfx.ErrInvalidCSRFTokenAJAXTokenMismatch, json.RawMessage(gjson.Get(actual, "error").Raw), "%s", actual)
459461
})
460462

461463
t.Run("case=should pass even without CSRF token/type=api", func(t *testing.T) {

0 commit comments

Comments
 (0)