# Patch Analysis: CVE-2026-23958 Fix Gap — Community Fallback Path Left Unpatched

## Fix Commit

- **Commit**: `cac165ee84bb296184b9be6f5fa695af0344fa05`
- **Author**: fit2cloud-chenyw
- **Date**: 2025-12-25
- **Message**: `fix: JWT Token 漏洞`

## Files Changed

Only one file was modified in the open-source repository:
- `sdk/common/src/main/java/io/dataease/auth/filter/CommunityTokenFilter.java`

Specifically, one line changed in the `else` branch:
```diff
-Method pwdMethod = DeReflectUtil.findMethod(o.getClass(), "getPwd");
+Method pwdMethod = DeReflectUtil.findMethod(o.getClass(), "getSecret");
```

## What the Fix Covers

The fix changes the JWT verification secret source in the **xpack/enterprise** code path (the `else` branch of `CommunityTokenFilter.doFilter`).

Before: `secret = userCacheBO.getPwd()` — returns `MD5(admin_password)`.
After: `secret = userCacheBO.getSecret()` — returns `MD5(admin_password) + RSA_public_key`.

This makes the HMAC secret unpredictable per-instance, preventing an unauthenticated attacker from forging admin JWTs when the xpack `loginServer` bean and `apisixCacheManage` bean are present (the standard Docker image configuration, which includes proprietary `xpack-*.jar` files).

## What the Fix Does NOT Cover

The fix **completely ignores** the community-edition fallback path in the same method:

```java
if (ObjectUtils.isEmpty(CommonBeanFactory.getBean("loginServer"))) {
    String pwd = SubstituleLoginConfig.getPwd();
    secret = Md5Utils.md5(pwd);
}
```

Additionally, the community login controller `SubstituleLoginServer` was **not changed** at all. It still signs JWTs with:

```java
String md5Pwd = Md5Utils.md5(pwd);
return generate(tokenUserBO, md5Pwd);
```

And `SubstituleLoginConfig.getPwd()` still defaults to the hardcoded string `DataEase@123456` when no `substitule.json` file exists.

## Fix Assumptions

The fix assumes:
1. All production deployments include the xpack `loginServer` bean.
2. The `apisixCacheManage` bean is always available in active deployments.
3. The community fallback path (`SubstituleLoginServer` + `SubstituleLoginConfig`) is only used in development or non-production scenarios.

## Why These Assumptions Are Wrong

1. **Open-source builds exclude xpack by default**: The `de-xpack` directory is a Git submodule pointing to a private repository (`git@github.com:dataease/de-xpack.git`). A clean clone/build from the public GitHub repository produces a JAR that does **not** contain `loginServer` or `apisixCacheManage` beans.

2. **The published Docker image includes xpack JARs**: `xpack-base.jar`, `xpack-permission.jar`, and `xpack-sync.jar` are placed in `/opt/apps` and loaded via `loader.path`. However, users who build from source or strip xpack JARs (e.g., for a fully open-source deployment) fall back to the unpatched community path.

3. **The default password remains hardcoded**: Even in v2.10.21, `SubstituleLoginConfig.getPwd()` falls back to `DataEase@123456`. There is no randomization or mandatory initialization flow.

## Target Threat Model / Security Policy

DataEase does not publish a formal `SECURITY.md` with a detailed threat model. However, the `README.md` and installer documentation position the project as an open-source data-visualization platform. The existence of a community fallback login controller (`SubstituleLoginServer`) indicates that the project is intended to be functional without proprietary xpack modules. A complete fix must protect **all** supported deployment modes, including pure open-source builds.

## Comparison: Before vs After

| Deployment Mode | v2.10.10 (Vulnerable) | v2.10.21 (With xpack JARs) | v2.10.21 (Without xpack JARs) |
|----------------|------------------------|----------------------------|-------------------------------|
| JWT Secret Source | `MD5(default_pwd)` | `MD5(pwd)+RSA_pubkey` | `MD5(default_pwd)` |
| Forgeable by attacker? | Yes | No | **Yes** |

## Verdict

The fix is **incomplete**. It patches the xpack path but leaves the community fallback path untouched. Any deployment built from the public source repository (or with xpack JARs removed) remains vulnerable to the same authentication bypass.
