mirumee / ariadne

Python library for implementing GraphQL servers using schema-first approach.
https://ariadnegraphql.org
BSD 3-Clause "New" or "Revised" License
2.23k stars 179 forks source link

Ability to disable file uploads with Starlette integration #417

Open mcho421 opened 4 years ago

mcho421 commented 4 years ago

Would it be possible to have an option to disable file uploads with the Starlette integration (regardless of whether python-multipart is installed or not)?

I was reading https://ariadnegraphql.org/docs/other-integrations and was wondering whether it safe to allow GraphQL requests with a content type of multipart/form-data, since it mentions that only application/json should be allowed.

For example, if you have pip install python-multipart installed, and Starlette application main.py like:

from ariadne import QueryType, make_executable_schema, MutationType
from ariadne.asgi import GraphQL
from starlette.applications import Starlette

type_defs = """
    type Query {
        hello: String!
    }
    type Mutation {
        changeState: String!
    }
"""

query = QueryType()
mutation = MutationType()

counter = 0

@query.field("hello")
def resolve_hello(*_):
    return "Hello world!"

@mutation.field("changeState")
def resolve_change_state(*_):
    # Do some change to a database
    global counter
    counter += 1
    return counter

# Create executable schema instance
schema = make_executable_schema(type_defs, [query, mutation])

app = Starlette(debug=True)
app.mount("/graphql", GraphQL(schema, debug=True))
# run with $ uvicorn main:app

You could be tricked to click a button defined like this on a different website which could cause an unintended state change:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8"/>
  <title>upload</title>
</head>
<body>
<form action="http://127.0.0.1:8000/graphql/" method="post" enctype="multipart/form-data">
  <p><input type="text" name="operations" value='{"query": "mutation {\n  changeState\n}\n"}'>
  <p><input type="text" name="map" value='{"file1": ["path1"]}'>
  <p><input type="file" name="file1">
  <p><button type="submit">Submit</button>
</form>
</body>
</html>
rafalp commented 1 year ago

We could have enable_multipart or disable_multipart configuration knob on GraphQL app from asgi and wsgi modules.