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

One time use project upload token #6935

Closed
wants to merge 114 commits into from

Conversation

rachelcipkins
Copy link

Created a one time user scoped token for project uploads. Implemented as a caveat. #6378

@woodruffw woodruffw mentioned this pull request Nov 18, 2019
except InvalidMacaroon:
raise HTTPUnauthorized()
user = macaroon_service.find_userid(
request.master_key
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that this master_key attribute gets mocked in the tests, but I can't find where it actually appears in the (real) request object. Does it get set anywhere, or is this WIP?

@woodruffw
Copy link
Member

This PR now contains a few different features:

@woodruffw
Copy link
Member

Some notes:

  • The API endpoint should return an HTTP 400 (or 403, as appropriate) + JSON body on errors, but it currently returns HTML when authentication fails (e.g., when a macaroon fails caveat checks). This is probably happening somewhere further up in the auth policy and needs to be special cased; I need to look into this.

  • The semantics around one-time tokens and project version tokens need some discussion: the project/file upload API is currently designed to take one upload at a time, meaning that a version release that includes multiple distributions (one sdist, a couple of bdist-*) will need N one-time tokens for N uploads. Similarly, a release is considered "created" once the first file associated with it is uploaded, meaning that macaroons bound to a single release will only work for the first uploaded file.

@brainwane
Copy link
Contributor

@rcipkins @woodruffw I suspect this is the kind of feature that could use a sentence of explanation in https://pypi.org/help/#apitoken .

@merwok
Copy link
Contributor

merwok commented Jan 17, 2020

The API endpoint should return an HTTP 400 (or 403, as appropriate) + JSON body on errors, but it currently returns HTML when authentication fails […]. This is probably happening somewhere further up in the auth policy and needs to be special cased

Could be coming from the generic forbidden view:
https://github.com/pypa/warehouse/blob/master/warehouse/views.py#L94

A more specific view_config (using a specific exception as context or if not possible a custom predicate) could do what you want.

macaroon_service = request.find_service(IMacaroonService, context=None)

form = CreateMacaroonForm(
**payload,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passing ** from attacker provided JSON is a risky move. It lets the attacker control which args are provided. If CreateMacaroonForm adds a new optional argument this can turn into a vulnerability. It ought to be passed as data=payload or explicitly unpacked.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, excellent point. This PR needs a decent amount of reworking (and discussion, w/r/t to the semantics of "one time use" for uploads of multiple files per release).

@woodruffw
Copy link
Member

I'm going to pick the core functionality out of this PR and include it in #10888. Closing.

@woodruffw woodruffw closed this Mar 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants