Skip to content

Insecure way to handle json requests #2174

Closed
@fduxiao

Description

Long story short

BaseRequest.json coroutine returns request body directly, whose Content-Type should have been checked.

Expected behaviour

Content-Type should be ensured to be application/json so that one can make sure it is sent by ajax, since there are always csrf attacks while ajax can not be forged cross site.

Actual behaviour

Content-Type is not checked.

Steps to reproduce

I setup the server using following code.

#!/usr/bin/env python3

from aiohttp import web
import asyncio


app = web.Application()


async def index(request):
    if request.method == 'GET':
        return web.Response(text='Hello Aiohttp!')
    elif request.method == 'POST':
        j = await request.json()
        return web.json_response(j)


def setup_routes(app):
    app.router.add_route('*', '/', index)


if __name__ == '__main__':
    setup_routes(app)
    web.run_app(app, host='127.0.0.1', port=8080)

And I request the server with following command.

# both of the following will work
curl -v -d '{"abc":2}' -H "Content-Type: application/json" http://127.0.0.1:8080
curl -v -d '{"abc":2}' http://127.0.0.1:8080  # This should fail.

Actually flask handles json requests only with Content-Type: application/json

Environment

> uname -a
Darwin bogon 16.7.0 Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64 x86_64

> python3 --version  # installed with homebrew
Python 3.6.2

> python3 -c 'import aiohttp; print(aiohttp.__version__)'
2.0.7

> brew --version 
Homebrew 1.3.0
Homebrew/homebrew-core (git revision 51fde5; last commit 2017-08-04)

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions