GitLab recently introduced Releases, a way to present tags in the user interface of GitLab. These releases are currently managed via the API.
Releases are closely tight to ordinary git tags, and therefore also present similar information.
However, guest users, who do not have access to the code, also have access to these releases and therefore have also access to this information related to the code.
Steps to reproduce
Tested on GitLab 11.7.0-rc4-ee
Create a private, push some code, create a git tag, and a new release via the API. (In these steps the project is accessible via the namespace joe/test-releases)
Add a guest user to the project
As the guest user open the following page: https://gitlab.com/joe/test-releases/releases
Here, you can observe that the sidebar is not showing the releases page. However, you can access this page and retrieve the list of releases.
Similarly, you can also as a guest user you can retrieve the release via the API. Therefore, perform the following API call:
curl --request GET --header"PRIVATE-TOKEN: <GUEST-USER-TOKEN>" https://example.gitlab.com/api/v4/<project-id>/releases
This will return all releases including information like the tag, description, committing details, etc as shown below in the JSON output.
[{"tag_name":"secret-tag","description":"This is a secret security release mitigating vulnerabilities","name":"Secret Release","description_html":"<p dir=\"auto\">This is a secret security release mitigating vulnerabilities</p>","created_at":"2019-01-11T12:30:06.503Z","author":{"id":1,"name":"joe","username":"joe","state":"active","avatar_url":"https://secure.gravatar.com/avatar/6466f73ed21b9d1624dee906821e9176?s=80&d=identicon","web_url":"https://example.gitlab.com/joe"},"commit":{"id":"9acaed88330c5fcb7cd119e7b10af49d3a9a48ab","short_id":"9acaed88","title":"Add new file","created_at":"2019-01-11T12:25:04.000Z","parent_ids":[],"message":"Add new file","author_name":"joe","author_email":"test@bar.com","authored_date":"2019-01-11T12:25:04.000Z","committer_name":"joe","committer_email":"test@bar.com","committed_date":"2019-01-11T12:25:04.000Z"},"assets":{"count":4,"sources":[{"format":"zip","url":"https://example.gitlab.com/joe/test-releases/-/archive/secret-tag/test-releases-secret-tag.zip"},{"format":"tar.gz","url":"https://example.gitlab.com/joe/test-releases/-/archive/secret-tag/test-releases-secret-tag.tar.gz"},{"format":"tar.bz2","url":"https://example.gitlab.com/joe/test-releases/-/archive/secret-tag/test-releases-secret-tag.tar.bz2"},{"format":"tar","url":"https://example.gitlab.com/joe/test-releases/-/archive/secret-tag/test-releases-secret-tag.tar"}],"links":[]}}]
Similar to that, also the endpoint https://example.gitlab.com/api/v4/<project-id>/releases/:tag_name is vulnerable to this.
Steps to mitigate
Perform proper authorization in the API and for the release page. Guests should have access to this information.
Impact
Guest users have access to private information like release details, etc...
Attachments
Warning: Attachments received through HackerOne, please exercise caution!
@darbyfrey can you take a look? Releases should respect the privacy of the project (i.e., private projects should have private releases, public projects should have public releases.)
@asaba @jlenny Checked. Release does respect the privacy of the project. We all agreed upon that guest users can read releases. FYI, guest can do the following things today
Guests can read projects, borads, wiki, issues, milesones, etc, but why they are forbidden to see releases? I think Release's secrecy level won't be different from the other areas.
@dosuken123 to confirm, guest users can read projects, boards, issues, wiki, etc. on private projects? If so, then yes - I think this is working as designed. Releases are not more secure or secret than any of those other things.
Assuming above is true, the one thing that seems unusual here is that the sidebar does not show releases for the guest user, but they are able to navigate there using the URL. Why would the navigation be hidden for these users?
Thanks @dosuken123. Can you add a release to your project? I want to see if I can download the source code even though I don't have access to the source.
Thank you @dosuken123 ! So I've confirmed, as guest:
I cannot create a release
I do not have permissions to download source that's linked to
This seems to be working fine to me, except for the missing link to the releases page. @asaba I propose we remove the security tag and convert into a fix to add the link in the sidebar nav. Are you good with this?
Checked. Release does respect the privacy of the project. We all agreed upon that guest users can read releases. FYI, guest can do the following things today
@jlenny @dosuken123 Does anyone have a reference for this we can point the reporter to? Updating the documentation (adding Releases the main permissions table and noting the visibility in the Release specific information) should also be a part of the fix.
This seems to be working fine to me, except for the missing link to the releases page. @asaba I propose we remove the security tag and convert into a fix to add the link in the sidebar nav. Are you good with this?
With the addition of clarifying the documentation, that LGTM. cc @estrike
As guest: I do not have permissions to download source that's linked to
@jlenny Should we not display the Download links, then?
I don't understand why Releases, which represent repository data, would be available to Guests while the repository itself isn't.
We are also exposing the commit SHA, commit title, and tag name, to a user who is not actually allowed to list or view commits or tags, which seems inconsistent, if not incorrect.
If we want Releases to be available to Guests, I think we should make sure we remove the commit sha and message, tag, and download links.
@dosuken123 can you please take another look at permissions given @DouweM's comments above? Releases shouldn't bypass any existing permissions. Maybe we just need to hide SHA, commit title, tag name, source download links for guest users who shouldn't have access to them.
@DouweM @jlenny Releases do not bypass any existing permissions. Downloading source code is always evaluated by the deticated permission category *_download_code.
Actually, Releases is stuck in the same situation with Pipelines. Guest users can see pipelines with SHAs but they don't have access to the associated SHA.
This is more like up to UX or PM decision though, I feel what @DouweM mentioned above makes sense that if a user doesn't have an ability to download, then the link should not be in the first place, it should be hidden.
Now, an interesting question is that if guest doesn't have access to source code and Release assets(links, etc), then should we hide the "Releases" section from the sidebar? Or showing Releases title and description only still makes sense to guests?
The original issue here was that it was possible to access a release as a guest, even though the section was not visible in the sidebar. I'm more convinced that we should just block the endpoint for guest users in private projects, as well as hide the menu. I think in some cases a private project will want to make public releases (for example, closed source projects) but they probably don't want any references to the source code returned by the release API.
My suggestion here is to remove access to releases for guest users in private projects completely, update the docs to reflect this, and wait for demand for someone with an actual use case for private project/public releases to solve that problem.
Anyone disagree with this approach to resolve this issue?
@jlenny Maybe Guest users would want to download aritfacts or Release assets only. In my previous company, we released obfuscated binary to clients but never disclosed source code unless our clients payed for it. So it makes sense to have such a role, IMO.
Interestingly, for Pipelines/Builds/Artifacts, we have Public pipelines setting
This actually controls if guest can download artifacts or not. If it's disabled, guests cannot download artifacts. So probably it makese sense that Releases follows the artifacts download rule with the option.
Yes, there is a use case @dosuken123, I'm just not sure anyone needs it yet and it would be good to build the feature in discussion with someone who actively needs it.
I'm with @dosuken123 on this. I wonder if it would make sense to split the Public Pipelines setting into the ability to view logs and the ability to download artifacts, with the latter governing the ability to access releases?
@afontaine I think that there is a potential use case for closed source projects who want to make public releases. I don't think we support that very well in the MVC, though, and I don't necessarily want to make fixing that a part of solving this security issue.
Since there hasn't been strong objection to the idea discussed yesterday, let's move forward with the plan to:
remove access to releases for guest users in private projects completely, update the docs to reflect this, and wait for demand for someone with an actual use case for private project/public releases to solve that problem.
@marcia @jlenny Technically, we should fix Guest user's permission first, before we update the documentation => https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/24766. Still, guest users can see Release pages today by directly putting the link, admitting that guest users are prohibited to access it makes this issue escalated to a real security issue.
@dosuken123 I think, since we are already tracking it in this security ~P2, we can document our intent. But @marcia I'm curious what our documentation policy is there?
@marcia @dosuken123 is saying we should not update the docs until he makes a change. If we document that guests are prohibited access before we make guest access prohibited, then we create an actual security issue.
Setting to %11.9 since it was a priority for %11.8 with a due date of Feb 23. @darbyfrey can you please help ensure a backend engineer is assigned ASAP? Since it's past the due date now we could consider including this in a security patch.
@asaba this unfortunately wasn't completed in time for the due date. Is it OK if this goes into the %11.10 release, or should we go through the security patch process? cc @dosuken123.
To my understanding this is working as expected, it covers the use case of a closed source development team that want to release binaries.
This is my understanding as well. We have artifacts where you need to access sources. We have releases which can be detached from the source. You want to distribute binaries, not source code. Thus why you allow Guests to access it.
I would say that this actually falls under Permissions > Releases separate access, similar as we do for Repository. This seems like a fully valid workflow: allow external (guests) to access Releases.
@nolith@ayufan we did discuss this, you can see https://gitlab.com/gitlab-org/gitlab-ce/issues/56402#note_135513519 for the last decision made. @DouweM and security had raised concerns that the releases feature was still exposing bits that we shouldn't, so we were going to just hide it in the sidebar for guest access to private users to address the immediate security concern and then wait for an actual user to request the use case of publishing binaries from a private project in order to implement that as a follow up:
The original issue here was that it was possible to access a release as a guest, even though the section was not visible in the sidebar. I'm more convinced that we should just block the endpoint for guest users in private projects, as well as hide the menu. I think in some cases a private project will want to make public releases (for example, closed source projects) but they probably don't want any references to the source code returned by the release API.
My suggestion here is to remove access to releases for guest users in private projects completely, update the docs to reflect this, and wait for demand for someone with an actual use case for private project/public releases to solve that problem.
Anyone disagree with this approach to resolve this issue?
Because of a snafu where the issue was accidentally not assigned to anyone who would deliver it, the feedback that there was an objection to that approach didn't come until a few days ago. It's not too late to revisit, but we are dealing with a overdue security issue now so should treat it with some urgency (pending confirmation from @asaba that this would be OK to move into %11.10). I'm certainly open to different ideas, but to me removing guest access for private users until we have a customer demand for that feature seems like the easiest and most obvious.. but maybe from the backend it's not the case.
@DouweM and security had raised concerns that the releases feature was still exposing bits that we shouldn't, so we were going to just hide it in the sidebar for guest access to private users to address the immediate security concern
No, what @DouweM pointed out was if the guest user cannot download the source code, then should we hide the links for the source code, which is tottaly legitimate as UX improvements. We've not exposed source code to users who don't have a permission from the beginning.
This is my understanding as well. We have artifacts where you need to access sources. We have releases which can be detached from the source. You want to distribute binaries, not source code. Thus why you allow Guests to access it.
We are also exposing the commit SHA, commit title, and tag name, to a user who is not actually allowed to list > or view commits or tags, which seems inconsistent, if not incorrect.
If we want Releases to be available to Guests, I think we should make sure we remove the commit sha and message, tag, and download links.
I think these properties require the same authoriztion checks of :download_code.
Yes. I think that if we want to implement that correctly, we should think about releases_access_level that works similar to all other subsystems for Permissions, and this is where we define who can download Releases.
Releases technically is detached from CI, and I think that ideally it should stay like this.
Yes. I think that if we want to implement that correctly, we should think about releases_access_level that works similar to all other subsystems for Permissions, and this is where we define who can download Releases.
Makes sense. Something like Protected environment. We can create an issue for that and follow-up later.
@dosuken123 your steps above seem correct. Regarding point 3,
Create an issue "Hide links to source in Release page if the user doesn't have permission to download source"
My understanding from a month back was that this was the issue, after discussion, to make that specific change. Do we need to close this one and open a different one to do that?
@marcia the documentation update needed here is to instead of saying guest users cannot access releases, we should say "Guest users can access Release pages for downloading assets, except for items related to source code." Is this something you can please take a look at? This would be a small modification to https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/24766.
Tl;dr; We'll close this issue by disallowing guest users from accessing Releases.
After some discussions with @ayufan, we've found an issue on the Releases API architecture that it takes tag_name for the primary key. For example, users can fetch a single Release entry via GET api/v4/projects/:project_id/releases/:tag_name. This means we cannot completely disallow guests from accessing repository information because they can brute-force to the API for finding existing tag name in the repository.
In the future, we'd come up with a concrete plan to support guest users to access Releases safely, but in the meantime, we should fix this issue by disallowing them to access entire Release domain. As the severity of this issue is relatively low, we should not spend much time on this issue. I'll prepare an MR shortly.
Lastly, sorry for the confusion and long back-and-force discussions, and thank you for kind advices.