VYPR
Critical severityNVD Advisory· Published May 1, 2023· Updated Oct 15, 2024

Apache StreamPark (incubating): Logic error causing any account reset

CVE-2022-46365

Description

Apache StreamPark 1.0.0 before 2.0.0 When the user successfully logs in, to modify his profile, the username will be passed to the server-layer as a parameter, but not verified whether the user name is the currently logged user and whether the user is legal, This will allow malicious attackers to send any username to modify and reset the account, Users of the affected versions should upgrade to Apache StreamPark 2.0.0 or later.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Apache StreamPark before 2.0.0 lacks server-side verification when a logged-in user modifies their profile, allowing arbitrary account takeover.

Vulnerability

Description

CVE-2022-46365 describes a privilege escalation and authorization bypass in Apache StreamPark versions 1.0.0 through 2.0.0 (exclusive). The root cause is that when a logged-in user submits a profile modification request, the server accepts a username parameter from the client without verifying that the supplied username matches the currently authenticated user or that the user is authorized to modify that account [1]. This design flaw means the server relies solely on the client-provided username to perform profile updates, such as password changes.

Exploitation

Conditions

An attacker who has successfully authenticated to any StreamPark account—even a low-privileged one—can exploit this vulnerability by crafting a request that includes a different target username in the profile update endpoint. The server does not validate that the requester is the same as the user being modified [1][2]. No additional privileges or network position are needed beyond a valid session cookie or token. The attack surface is exposed through the user profile API, as evidenced by the fix that changed the updatePassword method signature to accept a User object instead of separate username and password parameters, enabling server-side identity checks [2].

Impact

Successful exploitation allows an attacker to modify the profile—including resetting the password—of any other user on the StreamPark instance. This can lead to full account takeover, unauthorized access to sensitive streaming application configurations, and potential lateral movement within the platform. The impact is particularly severe in multi-tenant environments because a single compromised session can compromise the entire user base.

Mitigation

The vulnerability is fixed in Apache StreamPark version 2.0.0. The commit resolving the issue enforces server-side user validation by passing the entire User object to the service layer, which can then authenticate that the operation is permitted [2][3]. Users of affected versions should upgrade immediately, as no workaround is documented [1].

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.apache.streampark:streamparkMaven
>= 1.0.0, < 2.0.02.0.0

Affected products

2

Patches

1
4f39d7f422d7

[Bug] update password bug fixed (#2123)

8 files changed · +47 19
  • streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/system/controller/UserController.java+2 4 modified
    @@ -137,11 +137,9 @@ public RestResponse checkPassword(
         }
     
         @PutMapping("password")
    -    public RestResponse updatePassword(
    -        @NotBlank(message = "{required}") String username,
    -        @NotBlank(message = "{required}") String password)
    +    public RestResponse updatePassword(User user)
             throws Exception {
    -        userService.updatePassword(username, password);
    +        userService.updatePassword(user);
             return RestResponse.success();
         }
     
    
  • streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/system/entity/User.java+2 0 modified
    @@ -85,6 +85,8 @@ public class User implements Serializable {
     
         private String avatar;
     
    +    private transient String oldPassword;
    +
         private transient String sortField;
     
         private transient String sortOrder;
    
  • streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/system/service/impl/UserServiceImpl.java+14 4 modified
    @@ -35,6 +35,7 @@
     import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
     import lombok.extern.slf4j.Slf4j;
     import org.apache.commons.collections.CollectionUtils;
    +import org.apache.commons.lang3.StringUtils;
     import org.springframework.beans.factory.annotation.Autowired;
     import org.springframework.stereotype.Service;
     import org.springframework.transaction.annotation.Propagation;
    @@ -137,14 +138,23 @@ public void updateAvatar(String username, String avatar) {
     
         @Override
         @Transactional(rollbackFor = Exception.class)
    -    public void updatePassword(String username, String password) {
    -        User user = new User();
    +    public void updatePassword(User userParam) {
    +        User user = getById(userParam.getUserId());
    +        if (user == null) {
    +            throw new ApiAlertException("update password failed, user is null");
    +        }
    +
    +        String saltPassword = ShaHashUtils.encrypt(user.getSalt(), userParam.getOldPassword());
    +        if (!StringUtils.equals(user.getPassword(), saltPassword)) {
    +            throw new ApiAlertException("update password failed, old password error");
    +        }
    +
             String salt = ShaHashUtils.getRandomSalt();
    -        password = ShaHashUtils.encrypt(salt, password);
    +        String password = ShaHashUtils.encrypt(salt, userParam.getPassword());
             user.setSalt(salt);
             user.setPassword(password);
             LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<User>()
    -            .eq(User::getUsername, username);
    +            .eq(User::getUserId, user.getUserId());
             this.baseMapper.update(user, queryWrapper);
         }
     
    
  • streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/system/service/UserService.java+3 4 modified
    @@ -94,11 +94,10 @@ public interface UserService extends IService<User> {
     
         /**
          * update password
    -     *
    -     * @param username user
    -     * @param password password
    +     * @param user
    +     * @throws Exception
          */
    -    void updatePassword(String username, String password) throws Exception;
    +    void updatePassword(User user) throws Exception;
     
         /**
          * reset password
    
  • streampark-console/streampark-console-webapp/src/api/system/user.ts+2 1 modified
    @@ -146,7 +146,8 @@ export function fetchUserTypes() {
      * @param {String} password password
      */
     export function fetchUserPasswordUpdate(data: {
    -  username: string;
    +  userId: string | number;
    +  oldPassword: string;
       password: string;
     }): Promise<boolean> {
       return defHttp.put({
    
  • streampark-console/streampark-console-webapp/src/layouts/default/header/components/user-dropdown/PasswordModal.vue+15 4 modified
    @@ -45,13 +45,23 @@
             component: 'Input',
             render: () => h(Alert, { type: 'info', message: userStore.getUserInfo?.username }),
           },
    +      {
    +        field: 'oldPassword',
    +        label: t('sys.login.oldPassword'),
    +        component: 'InputPassword',
    +        itemProps: { hasFeedback: true },
    +        rules: [
    +          { required: true, message: t('sys.login.oldPasswordPlaceholder'), trigger: 'blur' },
    +          { min: 8, message: t('system.user.form.passwordHelp'), trigger: 'blur' },
    +        ],
    +      },
           {
             field: 'password',
    -        label: t('sys.login.password'),
    +        label: t('sys.login.newPassword'),
             component: 'InputPassword',
             itemProps: { hasFeedback: true },
             rules: [
    -          { required: true, message: t('sys.login.passwordPlaceholder'), trigger: 'blur' },
    +          { required: true, message: t('sys.login.newPasswordPlaceholder'), trigger: 'blur' },
               { min: 8, message: t('system.user.form.passwordHelp'), trigger: 'blur' },
             ],
           },
    @@ -84,15 +94,16 @@
           changeOkLoading(true);
           const formValue = await validate();
           await fetchUserPasswordUpdate({
    -        username: userStore.getUserInfo?.username,
    +        userId: userStore.getUserInfo?.userId,
    +        oldPassword: formValue.oldPassword,
             password: formValue.password,
           });
     
           createConfirm({
             iconType: 'success',
             title: t('sys.modifyPassword.title'),
             content: t('sys.modifyPassword.success'),
    -        okText: t('sys.logoutNow'),
    +        okText: t('sys.modifyPassword.logout'),
             okType: 'danger',
             onOk: () => {
               userStore.logout(true);
    
  • streampark-console/streampark-console-webapp/src/locales/lang/en/sys.ts+5 2 modified
    @@ -115,15 +115,18 @@ export default {
         // placeholder
         accountPlaceholder: 'Please input username',
         passwordPlaceholder: 'Please input password',
    +    oldPasswordPlaceholder: 'Please input old password',
    +    newPasswordPlaceholder: 'Please input new password',
         confirmPasswordPlaceholder: 'Please input confirm password',
         smsPlaceholder: 'Please input sms code',
         mobilePlaceholder: 'Please input mobile',
         policyPlaceholder: 'Register after checking',
         diffPwd: 'The two passwords are inconsistent',
    -
         userName: 'Username',
         password: 'Password',
    -    confirmPassword: 'Confirm Password',
    +    oldPassword: 'Old password',
    +    newPassword: 'New password',
    +    confirmPassword: 'Confirm password',
         email: 'Email',
         smsCode: 'SMS code',
         mobile: 'Mobile',
    
  • streampark-console/streampark-console-webapp/src/locales/lang/zh-CN/sys.ts+4 0 modified
    @@ -108,6 +108,8 @@ export default {
         // placeholder
         accountPlaceholder: '请输入账号',
         passwordPlaceholder: '请输入密码',
    +    oldPasswordPlaceholder: '请输入当前密码',
    +    newPasswordPlaceholder: '请输入新密码',
         confirmPasswordPlaceholder: '请输入确认密码',
         smsPlaceholder: '请输入验证码',
         mobilePlaceholder: '请输入手机号码',
    @@ -116,6 +118,8 @@ export default {
     
         userName: '账号',
         password: '密码',
    +    oldPassword: '当前密码',
    +    newPassword: '新密码',
         confirmPassword: '确认密码',
         email: '邮箱',
         smsCode: '短信验证码',
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.