Fastapi: Dependecies are available as query params?

Created on 26 Nov 2020  Â·  12Comments  Â·  Source: tiangolo/fastapi

Example

Here is a code from the official Fastapi relational tutorial

@app.get("/users/", response_model=List[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    users = crud.get_users(db, skip=skip, limit=limit)
    return users

Description

db is supposed to be a SQLAlchemy session, but it will be also available to be set as a URL parameters. This seems like potentially a security issue. Basically one can pass GET /users/?db=foo which will cause an internal server error because "foo" does not have query or add attributes that are needed from a SQLAlchemy session. The question is if there can be a string that can be passed as db and gets de-serialized into a Python object that has the Session interface? How can the "db" dependency be inaccessible as a http query param?

Environment

  • OS: Linux
  • FastAPI Version 0.61.2

To know the FastAPI version use:

python -c "import fastapi; print(fastapi.__version__)"
  • Python version: 3.8.6
question

All 12 comments

Why do you think it will be accessible as a query parameter?

It showed up in the openapi docs as a parameter you can set.

Sep Dehpour

On Nov 26, 2020, at 5:15 AM, Elliana May notifications@github.com wrote:


Why do you think it will be accessible as a query parameter?

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or unsubscribe.

If it has shown up as a query parameter, that means you have implemented it incorrectly - perhaps you'd like to show us some code that demonstrates your issue?

Here is the actual code:

@app.post(
    "/projects/",
    response_model=ProjectSchemaFull,
    response_model_exclude_unset=True)
def patch_project(
        item: ProjectSchemaOptional,
        session: Session = Depends(get_session_for_fastapi)):

What does your get_session_for_fastapi function look like? This code alone won't cause the issue you describe

session_factory = sessionmaker(bind=engine)
Session = scoped_session(session_factory)


def get_session_for_fastapi(session=None):
    """
    A session context manager.

    Example usage:

    with get_session_for_fastapi() as session:
        ...
    """
    if session:
        yield session
    else:
        try:
            session = session_factory()
            yield session
        except Exception:
            session.rollback()
            raise
        else:
            if settings.TESTING:
                session.flush()
            else:
                session.commit()
        finally:
            session.close()

I'm going to stick only on the previous message.

settings.TESTING is not necessary. You can override your dependency: https://fastapi.tiangolo.com/advanced/testing-database/#create-the-new-database-session

Besides, based on your docstrings, you want this: https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/?h=+context+manager#using-context-managers-in-dependencies-with-yield

@Kludex is correct with all of the above.

Additionally, in your code sample, you have declared a query parameter, session. This isn't a bug.

I found the lines that cause the issue.

def get_session_for_mause_and_kludex(session=None):
    """
    Note: this is not a context manager.
    """
    if session:  # <---- THIS LINE
        yield session  # <---- AND THIS LINE
    try:
        session = session_factory()
        yield session
    except Exception:
        session.rollback()
        raise
    else:
        session.commit()
    finally:
        session.close()

With those 2 lines, the session (what is called in the FastAPI tutorial as "db") can be set as a URL parameter. Why?
If I comment those 2 lines, then session can not be set as a URL param. Please ignore the settings.TESTING and the mention of Context manager in the previous example. Those are not related to this bug.

Those two lines aren't your issue - the session=None parameter you have declared is.

That is how you declare URL parameters in FastAPI, even in subdependencies - this is not a bug

I see. It was not clear to me that the dependencies' parameters will end up as URL params. Is it mentioned in the docs? Perhaps I missed it. Thanks for the clarification.

It's the first example in the dependencies section of the documentation: https://fastapi.tiangolo.com/tutorial/dependencies/#create-a-dependency-or-dependable

Was this page helpful?
0 / 5 - 0 ratings