Отправить #913792: jaygajera17 E-commerce-project-springBoot 1.0 Authorization Bypass Through User-Controlled KeyИнформация

Названиеjaygajera17 E-commerce-project-springBoot 1.0 Authorization Bypass Through User-Controlled Key
Описание# E-commerce-project-springBoot-master — Vulnerability Assessment ## VULN-1: IDOR — Authorization Bypass in POST /updateuser ### Status: ✅ CONFIRMED (Dynamically Verified) ### Summary The `POST /updateuser` endpoint in `UserController` accepts a `userid` parameter directly from the HTTP request without verifying that the authenticated user is authorized to modify the target profile. Any authenticated user (including low-privilege `ROLE_NORMAL` users) can supply an arbitrary `userid` to change any other user's password, email, and address — including the administrator's account. This enables **full account takeover**: a normal customer can silently change the admin's password and seize control of the entire e-commerce platform. | Field | Value | |-------|-------| | **CWE** | CWE-639 (Authorization Bypass Through User-Controlled Key) | | **CVSS 3.1** | **8.8 (High)** — `AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H` | | **Attack Type** | Authenticated IDOR → Privilege Escalation | | **Impact** | Full admin account takeover | --- ### CVE 6-Gate Assessment | # | Criterion | Result | |---|-----------|--------| | 1 | Complete Source→Sink data flow | ✅ HTTP `userid` param → `UserController.updateUser()` → `userService.updateUserProfile()` → Hibernate `UPDATE CUSTOMER` | | 2 | Exploitable in default configuration | ✅ No custom config required — vulnerability exists in source code | | 3 | Successful dynamic PoC | ✅ Password changed admin→"hacked123", verified via BCrypt hash comparison | | 4 | Real security impact | ✅ Any user can change admin password → full system compromise | | 5 | Not a duplicate | ✅ Unique to this codebase | | 6 | Not a configuration error | ✅ Code-level authorization bypass — missing `userid` ownership check | --- ### Technical Details **Vulnerable Code** — `UserController.java:updateUser()`: ```java @PostMapping("/updateuser") public String updateUser( @RequestParam("userid") int userid, // ← USER-CONTROLLED, NO AUTH CHECK @RequestParam("username") String username, @RequestParam("email") String email, @RequestParam("password") String password, @RequestParam("address") String address) { userService.updateUserProfile(userid, username, email, password, address); return "redirect:/profileDisplay"; } ``` **Sink** — `userService.updateUserProfile()`: ```java public void updateUserProfile(int userid, String username, String email, String password, String address) { User user = this.userDao.getUser(userid); user.setEmail(email); user.setPassword(passwordEncoder.encode(password)); // BCrypt encodes attacker-supplied password user.setAddress(address); this.userDao.updateUser(user); } ``` The `userid` flows directly from HTTP request → controller → service → DAO without any authorization check. The service method blindly trusts the caller and updates whichever `userid` is provided. --- ### Attack Chain ``` Attacker (ROLE_NORMAL) │ ├─[1]─ Login as lisa/765 → gets JSESSIONID + CSRF token │ ├─[2]─ POST /updateuser │ Body: userid=1&username=admin&password=hacked123&... │ Cookie: JSESSIONID=<lisa's session> │ → Server updates admin (id=1) password to BCrypt("hacked123") │ └─[3]─ Admin password is now "hacked123" → Attacker can login as admin → Full system compromise ``` ### Dynamic PoC Verification | Step | Action | Result | |------|--------|--------| | 1 | Reset DB: admin=123, lisa=765 | ✅ | | 2 | Login as lisa (normal user) | ✅ 302 → / | | 3 | GET /profileDisplay (extract CSRF) | ✅ 200, userid=2 | | 4 | POST /updateuser userid=1 password=hacked123 | ✅ 302 → / (accepted) | | 5 | DB check: admin password | ✅ Now BCrypt hash (was plaintext "123") | | 6 | BCrypt comparison: checkpw("hacked123", hash) | ✅ **True** — verified | **PoC script**: `poc_idor_updateuser.py` — reproducible, self-resetting. --- ### Remediation Add authorization check before updating user profile: ```java @PostMapping("/updateuser") public String updateUser( @RequestParam("userid") int userid, @RequestParam("username") String username, // ... other params Principal principal) { // ← inject authenticated user // Get the authenticated user's ID from session/security context int authenticatedUserId = getAuthenticatedUserId(principal); // Authorization check: user can only modify their own profile if (userid != authenticatedUserId) { throw new AccessDeniedException("Not authorized to modify this user"); } // For admin override, check role: // if (!hasRole("ADMIN") && userid != authenticatedUserId) { throw ... } userService.updateUserProfile(userid, username, email, password, address); return "redirect:/profileDisplay"; } ``` --- ### Additional Notes - **PasswordEncoder**: The application uses `BCryptPasswordEncoder` (configured in `PasswordEncoderConfig.java`), so passwords are stored as BCrypt hashes. The IDOR bypasses this protection because the controller passes the raw password through the legitimate encoding pipeline. - **CSRF Protection**: Spring Security CSRF is enabled, but the CSRF token only prevents cross-site attacks — it does not prevent same-session IDOR. - **Dual Filter Chain**: The admin filter chain (`/admin/**`) has a configuration issue where admin login redirects to the user login page, but this does not affect the IDOR exploit — the password change is confirmed via database verification. - **Default Credentials**: `basedata.sql` ships with admin/123 and lisa/765 in plaintext, making exploitation trivial.
Источник⚠️ https://github.com/jaygajera17/E-commerce-project-springBoot/issues/172
Пользователь
 emiya (UID 100287)
Представление03.08.2026 07:53 (1 месяц назад)
Модерация12.09.2026 20:45 (1 month later)
Статуспринято
Запись VulDB403180 [jaygajera17 E-commerce-project-springBoot до 5e74a46b4b70623d0e4a0c9c4aee3bd1777185d2 UserController.java UserController.updateUser userid эскалация привилегий]
Баллы20

Interested in the pricing of exploits?

See the underground prices here!