VYPR
Moderate severityOSV Advisory· Published Dec 30, 2018· Updated Aug 5, 2024

CVE-2018-20594

CVE-2018-20594

Description

Reflected XSS in hsweb 3.0.4 due to missing type parameter validation in FlowableModelManagerController.export() allows arbitrary JavaScript execution.

AI Insight

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

Reflected XSS in hsweb 3.0.4 due to missing type parameter validation in FlowableModelManagerController.export() allows arbitrary JavaScript execution.

Vulnerability

A reflected cross-site scripting (XSS) vulnerability exists in hsweb 3.0.4 in the FlowableModelManagerController.export() method. The type path variable is accepted without validation and directly reflected in the HTTP response when the BPMN model has no main process, allowing an attacker to inject arbitrary JavaScript. The issue is located in org.hswebframework.web.workflow.web.FlowableModelManagerController [1][2][4].

Exploitation

An attacker can craft a URL such as .../export/{modelId}/ and trick a victim into clicking it. No authentication is required to trigger the reflected XSS; the attacker only needs to lure a user who has access to the hsweb application to visit the malicious link. The server returns the injected script in the response body, which executes in the victim's browser [1][2].

Impact

Successful exploitation allows an attacker to execute arbitrary JavaScript in the context of the victim's browser session. This can lead to session hijacking, cookie theft, defacement, or redirection to malicious sites. The impact is limited to the victim's browser and does not directly compromise the server [2][4].

Mitigation

The vulnerability is fixed in commit b72a2275 by adding proper type validation using the ModelType enum and handling exceptions with @SneakyThrows. Users should upgrade to a version of hsweb later than 3.0.4. No workaround is documented; the recommended mitigation is to apply the patch or update the dependency [1][4].

AI Insight generated on May 22, 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.hswebframework.web:hsweb-commonsMaven
<= 3.0.4

Affected products

2

Patches

1
b72a2275ed21

fix #107 修复反射型xss

2 files changed · +46 42
  • hsweb-system/hsweb-system-workflow/hsweb-system-workflow-local/src/main/java/org/hswebframework/web/workflow/enums/ModelType.java+9 0 added
    @@ -0,0 +1,9 @@
    +package org.hswebframework.web.workflow.enums;
    +
    +/**
    + * @author zhouhao
    + * @since 3.0.5
    + */
    +public enum ModelType {
    +    bpmn, json
    +}
    
  • hsweb-system/hsweb-system-workflow/hsweb-system-workflow-local/src/main/java/org/hswebframework/web/workflow/web/FlowableModelManagerController.java+37 42 modified
    @@ -8,6 +8,7 @@
     import io.swagger.annotations.Api;
     import io.swagger.annotations.ApiOperation;
     import io.swagger.annotations.ApiParam;
    +import lombok.SneakyThrows;
     import lombok.extern.slf4j.Slf4j;
     import org.activiti.bpmn.converter.BpmnXMLConverter;
     import org.activiti.bpmn.model.BpmnModel;
    @@ -33,6 +34,7 @@
     import org.hswebframework.web.commons.entity.PagerResult;
     import org.hswebframework.web.commons.entity.param.QueryParamEntity;
     import org.hswebframework.web.controller.message.ResponseMessage;
    +import org.hswebframework.web.workflow.enums.ModelType;
     import org.hswebframework.web.workflow.util.QueryUtils;
     import org.hswebframework.web.workflow.web.request.ModelCreateRequest;
     import org.springframework.beans.factory.annotation.Autowired;
    @@ -132,58 +134,51 @@ public ResponseMessage<Deployment> deployModel(@PathVariable String modelId) thr
         @GetMapping(value = "export/{modelId}/{type}")
         @ApiOperation("导出模型")
         @Authorize(action = "export")
    +    @SneakyThrows
         public void export(@PathVariable("modelId") @ApiParam("模型ID") String modelId,
    -                       @PathVariable("type") @ApiParam(value = "类型", allowableValues = "bpmn,json", example = "json") String type,
    +                       @PathVariable("type") @ApiParam(value = "类型", allowableValues = "bpmn,json", example = "json")
    +                               ModelType type,
                            @ApiParam(hidden = true) HttpServletResponse response) {
    -        try {
    -            Model modelData = repositoryService.getModel(modelId);
    -            BpmnJsonConverter jsonConverter = new BpmnJsonConverter();
    -            byte[] modelEditorSource = repositoryService.getModelEditorSource(modelData.getId());
    -
    -            JsonNode editorNode = new ObjectMapper().readTree(modelEditorSource);
    -            BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(editorNode);
    -
    -            // 处理异常
    -            if (bpmnModel.getMainProcess() == null) {
    -                response.setStatus(HttpStatus.UNPROCESSABLE_ENTITY.value());
    -                response.getOutputStream().println("no main process, can't export for dimension: " + type);
    -                response.flushBuffer();
    -                return;
    -            }
    -
    -            String filename = "";
    -            byte[] exportBytes = null;
    -
    -            String mainProcessId = bpmnModel.getMainProcess().getId();
    +        Model modelData = repositoryService.getModel(modelId);
    +        if (modelData == null) {
    +            throw new NotFoundException("模型不存在");
    +        }
    +        BpmnJsonConverter jsonConverter = new BpmnJsonConverter();
    +        byte[] modelEditorSource = repositoryService.getModelEditorSource(modelData.getId());
     
    -            if ("bpmn".equals(type)) {
    +        JsonNode editorNode = new ObjectMapper().readTree(modelEditorSource);
    +        BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(editorNode);
     
    -                BpmnXMLConverter xmlConverter = new BpmnXMLConverter();
    -                exportBytes = xmlConverter.convertToXML(bpmnModel);
    +        // 处理异常
    +        if (bpmnModel.getMainProcess() == null) {
    +            throw new UnsupportedOperationException("无法导出模型文件:" + type);
    +        }
     
    -                filename = mainProcessId + ".bpmn20.xml";
    -            } else if ("json".equals(type)) {
    +        String filename = "";
    +        byte[] exportBytes = null;
     
    -                exportBytes = modelEditorSource;
    -                filename = mainProcessId + ".json";
    +        String mainProcessId = bpmnModel.getMainProcess().getId();
     
    -            } else {
    -                throw new UnsupportedOperationException("不支持的格式:" + type);
    -            }
    +        if (type == ModelType.bpmn) {
    +            BpmnXMLConverter xmlConverter = new BpmnXMLConverter();
    +            exportBytes = xmlConverter.convertToXML(bpmnModel);
    +            filename = mainProcessId + ".bpmn20.xml";
    +        } else if (type == ModelType.json) {
    +            exportBytes = modelEditorSource;
    +            filename = mainProcessId + ".json";
     
    -            response.setCharacterEncoding("UTF-8");
    -            response.setContentType("application/octet-stream");
    -            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
    +        } else {
    +            throw new UnsupportedOperationException("不支持的格式:" + type);
    +        }
     
    -            /*创建输入流*/
    -            try (ByteArrayInputStream in = new ByteArrayInputStream(exportBytes)) {
    -                IOUtils.copy(in, response.getOutputStream());
    -                response.flushBuffer();
    -                in.close();
    -            }
    +        response.setCharacterEncoding("UTF-8");
    +        response.setContentType("application/octet-stream");
    +        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
     
    -        } catch (Exception e) {
    -            log.error("导出model的xml文件失败:modelId={}, type={}", modelId, type, e);
    +        /*创建输入流*/
    +        try (ByteArrayInputStream in = new ByteArrayInputStream(exportBytes)) {
    +            IOUtils.copy(in, response.getOutputStream());
    +            response.flushBuffer();
             }
         }
     
    

Vulnerability mechanics

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

References

4

News mentions

0

No linked articles in our index yet.