Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error authenticating POST requests from browser session behind Oathkeeper #270

Closed
jrykr opened this issue Feb 27, 2020 · 4 comments · Fixed by #283 or #329
Closed

Error authenticating POST requests from browser session behind Oathkeeper #270

jrykr opened this issue Feb 27, 2020 · 4 comments · Fixed by #283 or #329
Assignees
Labels
bug Something is not working. feat New feature or request. upstream Issue is caused by an upstream dependency.

Comments

@jrykr
Copy link

jrykr commented Feb 27, 2020

Adding a bug report here per @aeneasr request on Discord.

Describe the bug

In the following situation, Kratos responds with a 400 error with a message about a missing CSRF token:

  • Browser app makes a POST request to an API protected by Oathkeeper.
  • Oathkeeper is configured with authenticators.cookie_session.config.check_session_url referring to Kratos /sessions/whoami as detailed below.
  • On the other hand, when the browser app makes a GET request to the same API, Kratos returns 200, and Oathkeeper passes along the request as expected.

Reproducing the bug

Steps to reproduce the behavior:

  1. Issue a POST request to a service fronted by Oathkeeper while relying upon Kratos cookie_session. For example:
POST http://127.0.0.1:4455/myresource/stuff
Cookie: ory_kratos_session=abc123; myservice_session=def456

Resulting in a 400 error from Kratos => 401 error from Oathkeeper.

(Trimmed) Server logs

oathkeeper | started handling POST /myresource/stuff
kratos     | started handling POST public#{{kratos}} request=/sessions/whoami
kratos     | missing or invalid csrf_token; expected_token="xzy098" received_token= received_token_form= 
kratos     | error reason="CSRF token is missing or invalid."
kratos     | completed handling POST public#{{kratos}} request=/sessions/whoami status=400 
oathkeeper | error; cookie_session; granted=false POST http://127.0.0.1:4455/myresource/stuff
oathkeeper | completed status=401 text_status=Unauthorized

Server configuration

.oathkeeper.yml

authenticators:
  cookie_session:
    enabled: true
    config:
      check_session_url: http://kratos:4433/sessions/whoami
      only:
        - ory_kratos_session
      preserve_path: true
      extra_from: "@this"
      subject_from: "identity.id"

access-rules.yml

- id: myservice
  upstream:
    url: "http://myservice:8000"
    preserve_host: true
  match:
    url: "http://127.0.0.1:4455/myresource<.*>"
    methods:
      - GET
      - POST
  authenticators:
    - handler: cookie_session
  authorizer:
    handler: allow
  mutators:
    - handler: noop

Expected behavior

Given a valid ory_kratos_session cookie, expected POST requests to reach the protected API.

Environment

Docker latest images as of 2020-02-27

oryd/oathkeeper
sha256:5f5099ba754180103dae6f4cd827d8d2f6fcc451a2635ed83ab896c5414dea38

oryd/kratos
sha256:e7482ee40663b7f63ca2b5fe0826c01444cf3c2e289480ab1afdc812361f72e3

Additional context

None.

@aeneasr
Copy link
Member

aeneasr commented Feb 28, 2020

Thank you for the detailed report! We will probably have to make some changes in oathkeeper instead but we can track the issue here :)

@aeneasr aeneasr added bug Something is not working. feat New feature or request. upstream Issue is caused by an upstream dependency. labels Feb 28, 2020
@aeneasr aeneasr added this to the v0.1.2-alpha.1 milestone Feb 28, 2020
@jdelgadoalfonso
Copy link

jdelgadoalfonso commented Mar 11, 2020

I have found the error:

the bug is in oathkeeper project.

authenticator cookie_session has a function which send a request to CheckSessionURL asking if the session_id in the cookie is valid or not.

This function, forwardRequestToSessionStore, receives as a first parameter the original request from the user and then makes a new request to the CheckSessionURL. The problem is that this function is using the original request Method to make the new request to CheckSessionURL, however, kratos API REST just accepts GET method.

authenticator_cookie_session.patch.txt

@norilt
Copy link

norilt commented Apr 6, 2020

The problem still exists.

The Problem is that no CSRF token is send with the request, but nosurf.CSRFHandler protects the /sessions/whoami route.

One possible fix could be to set n.ExemptPath("/sessions/whoami") in x/nosurf.gowhen creating the handler:

) *nosurf.CSRFHandler {
    n := nosurf.New(router)
    n.ExemptPath("/sessions/whoami")

@vuurpyl
Copy link

vuurpyl commented Nov 2, 2022

Still have the problem with kratos oryd/kratos:v0.10.1 and oathkeeper oryd/oathkeeper:v0.40.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something is not working. feat New feature or request. upstream Issue is caused by an upstream dependency.
Projects
None yet
6 participants