Webhook logs leak sensitive portions of the URL even after configuring a mask
HackerOne report #1793982 by joaxcar on 2022-12-05, assigned to @cmaxim:
Report
Summary
Note: I was requested to report this in a separate report. It was originally added as a comment here https://hackerone.com/reports/1791331
This is related to the fix for my reports https://hackerone.com/reports/1758126 and https://hackerone.com/reports/1757999 fixed in patch 15.6.1. After the 15.6 release there is an option to mask parts of a webhook URL to treat it as a secret value. See documentation link.
When this feature is used any secret string in the configured URL will be masked in the UI and in any logs in the UI. The values work the same as other tokens in that they are not even accessible by the user configuring it after it is first configured. It should not be possible for the initial user or any other users to retrieve these values. (see https://hackerone.com/reports/1758126)
There exists a problem with the current implementation where old log entries are not affected by a newly configured mask applied to the URL
According to the documentation, old log entries are removed after two days according to the docs. But they should probably be masked retroactively after adding a mask to a hook as the user updating the configured hook does this to make sure the data is not leaked.
Now if a hook have a record of events in its log when I add the mask, all old entries will still leak the unmasked URL for two days before the log entry is removed. If it is not impactful enough to warrant a fix, maybe there should at least be a doc update about this.
This change to the input field of the UI was made intentionally to hide the secret from other maintainers (as they do not necessarily have access to the receiving service). The leaked token (LOW confidentiality) gives an unauthorized other maintainer the ability to spoof requests to the receiving server (LOW integrity). And the impacted service is the receiving service (Scope changed). This was my rating of this, feel free to edit it as see fit!
Steps to reproduce
- Log in to gitlab
- Create a new project
- Go to https://gitlab.com/GROUP/PROJECT/-/hooks and configure a webhook. Put the URL like this
https://example.com?token=secret-token - Save the hook
- Scroll to the bottom of the page to the list of configured hooks.
- Click test to send a test request
- Click edit on the new hook
- There should be a log entry in the log list (this is the old entry)
- Click to add a mask, add the value
secret-tokenwith the replacementTOKEN. Click save for the webhook - Scroll to the bottom of the page to the list of configured hooks.
- Click edit on the new hook
- You can now see that the token is hidden in the UI. both in the config URL and in the mask field, there is no way to retrieve it
- Scroll down to the log entry list. Click the old log entry. The token will still be there.
- Make a new test request and look at the log entry list again. The new log entry will have a masked token, while the old one will keep the plain text token until the log entry expires. There is no way to remove the log entry manually.
What is the current bug behavior?
Masked values are kept in old log entries even after adding a mask to the hook URL
What is the expected correct behavior?
Adding a mask should remove old log entries or update them to mask the URL
Output of checks
This bug happens on GitLab.com
Impact
Secret parts of webhook URL are leaked to other maintainers in the UI of GitLab
Impact
Secret parts of webhook URL are leaked to other maintainers in the UI of GitLab
How To Reproduce
Please add reproducibility information to this section: