Skip to content

Kratos CSRF issue on self hosted setup #3316

@Imtinan1996

Description

@Imtinan1996

Preflight checklist

Describe the bug

Hi I am using the Kratos CLI to run a self hosted instance.

The issue is with logging in to sessions and logging out. When i first create the Browser Login Flow, a CSRF token Cookie is set

image

This is okay, and it logs me in and I can successfully log out as well with the Browser Logout Flow

Now when I try to log back in, it gives me the "security_csrf_violation" error. This is due to the fact that the older CSRF token still resides in the cookies and both the new and old cookies are sent over, but the older one is utilized which leads to an error

image

Am i doing something wrong? I am using a SSR framework (Remix) and i have even tried to clear the cookie from the server, but nothing seems to work. This is limiting the functionality, and i have to continuously clear cookies when trying to develop and has become a hindrance, moreover i cant go to production with this current limitation so any help will be greatly appreciated
self-hosted

Reproducing the bug

  1. Create a Browser Login Flow
  2. Login
  3. Create Browser Logout Flow
  4. Logout
  5. Create Browser Login Flow
  6. Login - Error

Relevant log output

{
   "audience":"application",
   "error":{
      "debug":"",
      "details":{
         "docs":"https://www.ory.sh/kratos/docs/debug/csrf",
         "hint":"The anti-CSRF cookie was found but the CSRF token was not included in the HTTP request body (csrf_token) nor in the HTTP Header (X-CSRF-Token).",
         "reject_reason":"The HTTP Cookie Header was set and a CSRF token was sent but they do not match. We recommend deleting all cookies for 
this domain and retrying the flow."
      },
      "message":"the request was rejected to protect you from Cross-Site-Request-Forgery",
      "reason":"Please retry the flow and optionally clear your cookies. The request was rejected to protect you from Cross-Site-Request-Forgery (CSRF) which could cause account takeover, leaking personal information, and other serious security issues.",
      "stack_trace":"\ngithub.com/ory/kratos/selfservice/flow.EnsureCSRF\n\t/project/selfservice/flow/request.go:70\ngithub.com/ory/kratos/selfservice/strategy/password.(*Strategy).Login\n\t/project/selfservice/strategy/password/login.go:66\ngithub.com/ory/kratos/selfservice/flow/login.(*Handler).updateLoginFlow\n\t/project/selfservice/flow/login/handler.go:720\ngithub.com/ory/kratos/x.NoCacheHandle.func1\n\t/project/x/nocache.go:21\ngithub.com/ory/kratos/x.NoCacheHandle.func1\n\t/project/x/nocache.go:21\ngithub.com/julienschmidt/httprouter.(*Router).ServeHTTP\n\t/go/pkg/mod/github.com/julienschmidt/[email protected]/router.go:387\ngithub.com/ory/nosurf.(*CSRFHandler).handleSuccess\n\t/go/pkg/mod/github.com/ory/[email protected]/handler.go:234\ngithub.com/ory/nosurf.(*CSRFHandler).ServeHTTP\n\t/go/pkg/mod/github.com/ory/[email protected]/handler.go:185\ngithub.com/urfave/negroni.Wrap.func1\n\t/go/pkg/mod/github.com/urfave/[email protected]/negroni.go:46\ngithub.com/urfave/negroni.HandlerFunc.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/[email protected]/negroni.go:29\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/[email protected]/negroni.go:38\ngithub.com/ory/kratos/x.glob..func1\n\t/project/x/clean_url.go:15\ngithub.com/urfave/negroni.HandlerFunc.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/[email protected]/negroni.go:29\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/[email protected]/negroni.go:38\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2109\ngithub.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerResponseSize.func1\n\t/go/pkg/mod/github.com/prometheus/[email protected]/prometheus/promhttp/instrument_server.go:284\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2109\ngithub.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerCounter.func1\n\t/go/pkg/mod/github.com/prometheus/[email protected]/prometheus/promhttp/instrument_server.go:142\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2109\ngithub.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerDuration.func1\n\t/go/pkg/mod/github.com/prometheus/[email protected]/prometheus/promhttp/instrument_server.go:92\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2109\ngithub.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerDuration.func2\n\t/go/pkg/mod/github.com/prometheus/[email protected]/prometheus/promhttp/instrument_server.go:104\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2109\ngithub.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerRequestSize.func1\n\t/go/pkg/mod/github.com/prometheus/[email protected]/prometheus/promhttp/instrument_server.go:234\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2109\ngithub.com/ory/x/prometheusx.Metrics.instrumentHandlerStatusBucket.func1\n\t/go/pkg/mod/github.com/ory/[email protected]/prometheusx/metrics.go:115\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2109\ngithub.com/ory/x/prometheusx.(*MetricsManager).ServeHTTP\n\t/go/pkg/mod/github.com/ory/[email protected]/prometheusx/middleware.go:41\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/[email protected]/negroni.go:38\ngithub.com/ory/x/metricsx.(*Service).ServeHTTP\n\t/go/pkg/mod/github.com/ory/[email protected]/metricsx/middleware.go:259\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/[email protected]/negroni.go:38\ngithub.com/ory/kratos/x.HTTPLoaderContextMiddleware.func1\n\t/project/x/httploadermiddleware.go:23",
      "status":"Forbidden",
      "status_code":403
   },
   "http_request":{
      "headers":{
         "accept":"application/json, text/plain, */*",
         "accept-encoding":"gzip, deflate, br",
         "accept-language":"en,en-GB;q=0.9,en-US;q=0.8",
         "connection":"keep-alive",
         "content-length":"179",
         "content-type":"application/json",
         "cookie":[
            "csrf_token_e04715253caff9a793925fcba527cfabdd2d2de981eacada031790de22126f26=hUI8kGMtEEjJ+k9toUxI+VGvdfDYW/1NoUMg+M2IO8A=; csrf_token_e04715253caff9a793925fcba527cfabdd2d2de981eacada031790de22126f26=TzHksZJR5qZ2/9OVeTyIWoH3rVfb2nczcl06UcpNdYw=; my_session_token=asessiontoken"
         ],
         "origin":"http://localhost:3000",
         "referer":"http://localhost:3000/",
         "sec-ch-ua":"\"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"114\", \"Google Chrome\";v=\"114\"",
         "sec-ch-ua-mobile":"?0",
         "sec-ch-ua-platform":"\"Windows\"",
         "sec-fetch-dest":"empty",
         "sec-fetch-mode":"cors",
         "sec-fetch-site":"same-site",
         "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
      },
      "host":"localhost:4433",
      "method":"POST",
      "path":"/self-service/login",
      "query":"flow=684086e6-1fa1-4464-a44e-166a790ac7b0",
      "remote":"[::1]:55948",
      "scheme":"http"
   },
   "http_response":{
      "status_code":403
   },
   "level":"info",
   "msg":"An error 
occurred while handling a request",
   "service_name":"Ory Kratos",
   "service_version":"v0.13.0",
   "time":"2023-06-14T13:12:57.0073414+04:00"
}

Relevant configuration

## Ory Kratos Configuration

identity:
  schemas:
    - id: users
      url: file://./user.schema.json

  default_schema_id: "users"

## Data Source Name ##
dsn: postgres://postgres:1234@localhost:5432/postgres

selfservice:
  default_browser_return_url: http://localhost:3000/auth/login/

  flows:
    logout:
      after:
        default_browser_return_url: http://localhost:3000/auth/login/

    login:
      lifespan: 5m
      after:
        password:
          default_browser_return_url: http://localhost:3000/auth/logged-in/
        default_browser_return_url: http://localhost:3000/auth/login/
      ui_url: http://localhost:3000/auth/login/

    ## Account Recovery Configuration ##
    #
    recovery:
      ui_url: http://localhost:3000/auth/recovery/
      lifespan: 1h
      use: code
      notify_unknown_recipients: true
      enabled: true

    settings:
      lifespan: 10m
      privileged_session_max_age: 1h
      required_aal: aal1
      ui_url: http://localhost:3000/auth/settings/password

    error:
      ui_url: http://localhost:3000/auth/error

  methods:
    link:
      config:
        lifespan: 1h
        base_url: http://localhost:3000/auth/password/reset/confirm
      enabled: true

    password:
      config:
        haveibeenpwned_enabled: false
        max_breaches: 0
        ignore_network_errors: false
        min_password_length: 6
        identifier_similarity_check_enabled: false
        haveibeenpwned_host: ""
      enabled: true

    lookup_secret:
      enabled: false

    profile:
      enabled: false


session:
  lifespan: 168h
  cookie:
    persistent: false
    path: ""
    same_site: Strict
    domain: ""
  earliest_possible_extend: 168h
  whoami:
    required_aal: aal1

## The kratos version this config is written for. ##
version: v0.5.0-alpha.1
dev: true
help: true
sqa-opt-out: false
watch-courier: false
expose-metrics-port: 4434
config:
  - ""

serve:
  public:
    base_url: https://localhost:4433/
    port: 4433
    cors:
      allowed_origins:
        - https://localhost:3000/
        - http://localhost:3000
      allowed_methods:
        - POST
        - GET
        - PUT
        - PATCH
        - DELETE
        - OPTIONS
      allowed_headers:
        - Authorization
        - Cookie
        - Content-Type
      exposed_headers:
        - Content-Type
        - Set-Cookie
      allow_credentials: true
      options_passthrough: true
      max_age: 0
      debug: true
      enabled: true

  admin:
    base_url: https://localhost:4434/
    host: "localhost"
    port: 4434
    request_log:
      disable_for_health: false

clients:
  http:
    private_ip_exception_urls:
      - http://a.aaa
    disallow_private_ip_ranges: false

## Database related configuration ##
#
# Miscellaneous settings used in database related tasks (cleanup, etc.)
#
database:
  cleanup:
    sleep:
      tables: 0ns
    older_than: 0ns
    batch_size: 1

Version

v0.13.0

On which operating system are you observing this issue?

Windows

In which environment are you deploying?

Binary

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is not working.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions