Skip to content
GitLab
Next
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • GitLab GitLab
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 44,763
    • Issues 44,763
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
    • Requirements
  • Merge requests 1,330
    • Merge requests 1,330
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Container Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Metrics
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • GitLab.orgGitLab.org
  • GitLabGitLab
  • Issues
  • #29040
Closed
Open
Issue created May 28, 2019 by Jayson Salazar@jdsalaroDeveloper

User enumeration vectors /exists and /api/v4/users missing rate-limit

Summary

The permissions for some of our API endpoints make it too easy to mass-probe accounts once a potentially valid list of targets has been obtained.

This makes a scenario such as that detailed in https://about.gitlab.com/2019/05/14/git-ransom-campaign-incident-report-atlassian-bitbucket-github-gitlab/ [1] much more likely and easier to carry out.

https://www.owasp.org/index.php/Testing_for_User_Enumeration_and_Guessable_User_Account_(OWASP-AT-002) [2]

By virtue of # 1, # 2 shown below and https://gitlab.com/gitlab-org/gitlab-ce/issues/62493 it's easy for a malicious user to leverage GitLab as a source for valid user-data or a verify an already existing dataset.

/cc

@jritchey @estrike @jbroullon @dappelt for appsec feedback

@jarv @dawsmith for prod feedback

@northrup for infra feedback

@asaba for your involvement in [1]

@gitlab-com/gl-security/secops for visibility

1 /exists

Endpoint Authentication
https://gitlab.com/users/jsalazar-gitlab/exists none
{"exists":true}

2 /api/v4/users/id

Endpoint Authentication
https://gitlab.com/api/v4/users/33848217 none

For one user this would be the result:

https://gitlab.com/api/v4/users/33848217

```{"id":3355217,"name":"Jayson Salazar","username":"jsalazar-gitlab","state":"active","avatar_url":"https://assets.gitlab-static.net/uploads/-/system/user/avatar/3355217/avatar.png","web_url":"https://gitlab.com/jsalazar-gitlab","created_at":"2019-11-05T23:55:39.862Z","bio":"Security Engineer, Security Operations","location":"test","public_email":"","skype":"test","linkedin":"https://linkedin.com/in/jaysonsalazar","twitter":"test","website_url":"test","organization":"Gitlab Inc."}```

This endpoint can be iterated over. For multiple users the responses would look as follows:

shell:~/Desktop/WORK/gitlap.com$ for i in `seq 1 10000`; do echo -n $i ' '; curl -si https://gitlab.com/api/v4/users/$i | grep '{'; done
1  {"id":1,"name":"Si...}
2  {"message":"404 User Not Found"}
3  {"id":3,"name":"Tr...}
4  {"message":"404 User Not Found"}
5  {"id":5,"name":"Ch...}
6  {"id":6,"name":"ri...}
7  {"message":"404 User Not Found"}
8  {"message":"404 User Not Found"}
9  {"message":"404 User Not Found"}
10  {"message":"404 User Not Found"}
11  {"id":11,"name":"Bi...}
12  {"message":"404 User Not Found"}
13  {"message":"404 User Not Found"}
14  {"id":14,"name":"Ka...
15  {"id":15,"name":"JJ...
16  {"message":"404 User Not Found"}
17  {"message":"404 User Not Found"}
18  {"id":18,"name":"sw...}
19  {"message":"404 User Not Found"}
20  {"id":20,"name":"Gö...
21  {"message":"404 User Not Found"}
22  {"message":"404 User Not Found"}
23  {"message":"404 User Not Found"}
24  {"id":24,"name":"Ph...}

Some sort of rate-limit seems to be in place but is, for security purposes at least, ineffective.

shell:~$ for i in `seq 1 10000`; do echo -n $i ' '; curl -si https://gitlab.com/api/v4/users/$i | grep RateLimit-Remaining; done
1  RateLimit-Remaining: 598
2  RateLimit-Remaining: 599
3  RateLimit-Remaining: 598
4  RateLimit-Remaining: 597
5  RateLimit-Remaining: 599
6  RateLimit-Remaining: 598
7  RateLimit-Remaining: 597
8  RateLimit-Remaining: 596
9  RateLimit-Remaining: 599
10  RateLimit-Remaining: 598
11  RateLimit-Remaining: 597
Edited Sep 07, 2022 by Jayson Salazar
Assignee
Assign to
Time tracking