Skip to content

content_type errors are broken, when combined with require_csrf #458

@DaineDanielson

Description

@DaineDanielson

Bottom line up front:
Somehow, the interaction of require_csrf and content_type causes a “Bad CSRF Token” error response when passed the wrong Content-Type into views with CSRF checking disabled.

Consider the following service (fully runnable):

from wsgiref.simple_server import make_server

from cornice import Service
from pyramid.config import Configurator
from pyramid.csrf import CookieCSRFStoragePolicy
from pyramid.request import Request
from pyramid.response import Response

CONTENT_TYPE = 'application/json'
HOST = 'localhost'

service = Service(name='service', path='/', content_type=CONTENT_TYPE)


@service.post(require_csrf=False)
def post(__: Request) -> Response:
    return Response("POSTed!")


if __name__ == '__main__':
    with Configurator() as config:
        # Turn on automatic CSRF checking.
        # NOTE: Our view disables CSRF checking, so this *should* be NOOP.
        config.set_csrf_storage_policy(
            CookieCSRFStoragePolicy(domain=HOST))
        config.set_default_csrf_options(require_csrf=True)

        config.include('cornice')
        config.add_cornice_service(service)

        app = config.make_wsgi_app()
    make_server(HOST, 6543, app).serve_forever()

However, when passed the wrong Content-Type, the POST in fact fails with:

<html>
    <head>
        <title>400 Bad CSRF Token</title>
    </head>
    <body>
        <h1>400 Bad CSRF Token</h1>
  Access is denied.  This server can not verify that your cross-site request forgery token belongs to your login session.  Either you supplied the wrong cross-site request forgery token or your session no longer exists.  This may be due to session timeout or because browser is not supplying the credentials required, as can happen when the browser has cookies turned off.
        <br/>
        <br/>
check_csrf_token(): Invalid token
    </body>
</html>

Since I’ve disabled require_csrf for the POST view, there should be no circumstance under which this error pops up. When Content-Type: application/json, everything works as intended.

I tried to debug this myself inside Cornice, but I ran out of time after going pretty deep, without luck.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions