VYPR
Low severity3.5NVD Advisory· Published Jun 2, 2026

CVE-2026-10567

CVE-2026-10567

Description

Stored XSS vulnerability in CordysCRM v1.4.1 allows remote attackers to inject malicious scripts via the Description argument.

AI Insight

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

Stored XSS vulnerability in CordysCRM v1.4.1 allows remote attackers to inject malicious scripts via the Description argument.

Vulnerability

A stored cross-site scripting (XSS) vulnerability exists in 1Panel-dev CordysCRM up to version 1.4.1. The vulnerability resides in the Save function of the ModuleFormService.java file, specifically within the ModuleFormController component. It is triggered by manipulating the Description argument, allowing for remote exploitation.

Exploitation

An attacker can exploit this vulnerability by sending a crafted POST request to the /module/form/save interface. The malicious payload, such as `, can be injected into the Description` field. This payload will execute in the victim's browser when the form editing function is accessed, even before the save action is confirmed [1].

Impact

Successful exploitation of this vulnerability allows an attacker to execute arbitrary JavaScript code in the context of the victim's browser. This can lead to session hijacking, data theft, or redirection to malicious websites, compromising the user's interaction with the application.

Mitigation

This vulnerability is fixed in CordysCRM version 1.7.0, released on 2026-05-29 [4]. Upgrading to this version or later is recommended. The patch identifier is c87682afa8df79853299f75489c9d333f7bc5fce [2].

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

Affected products

1

Patches

1
c87682afa8df

fix: Implement XSS protection with configurable URL filtering

https://github.com/1Panel-dev/CordysCRMzhaoMay 22, 2026via nvd-ref
3 files changed · +58 23
  • backend/app/src/main/resources/commons.properties+2 2 modified
    @@ -89,5 +89,5 @@ dashboard.whitelist.enabled=false
     # Enable whitelist functionality, if not enabled, access will not be restricted.
     dashboard.whitelist.allowed=
     
    -# Full HTML escaping switch. When enabled, all tags will be escaped (may affect content display), only enable for special scenarios.
    -xss.escape.all.enabled=false
    \ No newline at end of file
    +# List of URLs that require XSS filtering, supports Ant-style path matching, e.g., /api/**. If no URLs need to be filtered, it can be left empty.
    +# xss.protection.url.list=/account/follow/**,/announcement/add
    \ No newline at end of file
    
  • backend/framework/src/main/java/cn/cordys/config/RequestParamTrimConfig.java+54 19 modified
    @@ -3,14 +3,19 @@
     import com.fasterxml.jackson.core.JsonParser;
     import com.fasterxml.jackson.databind.DeserializationContext;
     import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
    +import jakarta.servlet.http.HttpServletRequest;
     import org.apache.commons.lang3.StringUtils;
     import org.springframework.beans.factory.annotation.Value;
     import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
     import org.springframework.context.annotation.Bean;
     import org.springframework.context.annotation.Configuration;
    +import org.springframework.util.AntPathMatcher;
    +import org.springframework.web.context.request.RequestContextHolder;
    +import org.springframework.web.context.request.ServletRequestAttributes;
     import org.springframework.web.util.HtmlUtils;
     
     import java.io.IOException;
    +import java.util.Arrays;
     
     /**
      * 配置类,用于定制 Jackson 的反序列化过程。
    @@ -23,8 +28,13 @@
     @Configuration
     public class RequestParamTrimConfig {
     
    -    @Value("${xss.escape.all.enabled:false}")
    -    private boolean escape;
    +    /**
    +     * 需要开启 XSS 过滤的 URL 列表(Ant 风格,逗号分隔)。
    +     * 示例:/account/follow/**,/announcement/**
    +     * 留空表示不对任何请求做 HTML 转义。
    +     */
    +    @Value("${xss.protection.url.list:}")
    +    private String xssFilterUrlList;
     
         /**
          * 定义一个 {@link Jackson2ObjectMapperBuilderCustomizer} Bean,
    @@ -37,24 +47,49 @@ public class RequestParamTrimConfig {
          */
         @Bean
         public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
    -        return jacksonObjectMapperBuilder -> {
    -            // 为 String 类型字段定义自定义的反序列化操作
    -            jacksonObjectMapperBuilder
    -                    .deserializerByType(String.class, new StdScalarDeserializer<String>(String.class) {
    -                        @Override
    -                        public String deserialize(JsonParser jsonParser, DeserializationContext ctx)
    -                                throws IOException {
    -                            // 在反序列化时去除前后空格
    -                            String value = StringUtils.trim(jsonParser.getValueAsString());
    -
    -                            // 进一步清理可能的 XSS 攻击内容,开启后可能会导致一些特殊字符被转义,如 <、>、& 等
    -                            if (escape) {
    -                                return HtmlUtils.htmlEscape(value);
    -                            }
    -                            return value;
    +        AntPathMatcher pathMatcher = new AntPathMatcher(); // 线程安全,可复用
    +
    +        return builder -> builder
    +                .deserializerByType(String.class, new StdScalarDeserializer<String>(String.class) {
    +                    @Override
    +                    public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
    +                        String rawValue = p.getValueAsString();
    +                        String trimmedValue = StringUtils.trim(rawValue);
    +
    +                        // 判断是否需要对当前值进行 HTML 转义
    +                        if (shouldEscapeXss(pathMatcher)) {
    +                            return HtmlUtils.htmlEscape(trimmedValue);
                             }
    -                    });
    -        };
    +                        return trimmedValue;
    +                    }
    +                });
    +    }
    +
    +    /**
    +     * 判断当前请求是否命中 XSS 过滤白名单(命中 → 执行转义)。
    +     */
    +    private boolean shouldEscapeXss(AntPathMatcher pathMatcher) {
    +        // 未配置过滤列表
    +        if (StringUtils.isBlank(xssFilterUrlList)) {
    +            return false;
    +        }
    +
    +        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    +        if (attributes == null) {
    +            return false; // 非 Web 上下文(定时任务等)不处理
    +        }
    +
    +        HttpServletRequest request = attributes.getRequest();
    +        String requestURI = request.getRequestURI();
    +        if (StringUtils.isBlank(requestURI)) {
    +            return false;
    +        }
    +
    +        // 逗号分隔的 Ant 路径列表,任一匹配即需要转义
    +        return Arrays.stream(xssFilterUrlList.split(","))
    +                .map(String::trim)
    +                .filter(StringUtils::isNotBlank)   // 过滤掉空白配置项
    +                .anyMatch(pattern -> pathMatcher.match(pattern, requestURI));
         }
     
     }
    
  • installer/conf/cordys-crm.properties+2 2 modified
    @@ -39,5 +39,5 @@ dashboard.whitelist.enabled=false
     # Enable whitelist functionality, if not enabled, access will not be restricted.
     dashboard.whitelist.allowed=
     
    -# Full HTML escaping switch. When enabled, all tags will be escaped (may affect content display), only enable for special scenarios.
    -xss.escape.all.enabled=false
    \ No newline at end of file
    +# List of URLs that require XSS filtering, supports Ant-style path matching, e.g., /api/**. If no URLs need to be filtered, it can be left empty.
    +xss.protection.url.list=/account/follow/**,/announcement/add
    \ No newline at end of file
    

Vulnerability mechanics

Root cause

"The application failed to properly sanitize user-supplied input in the Description field, allowing for the injection of malicious scripts."

Attack vector

An attacker can remotely initiate an attack by manipulating the Description argument in the Save function. This manipulation involves injecting script payloads that are then reflected in the application, leading to cross-site scripting. The attack may be initiated by a user with low privileges, as indicated by the CVSS vector [ref_id=1].

Affected code

The vulnerability resides in the `ModuleFormService.java` file, specifically within the `Save` function of the `ModuleFormController` component. The issue stems from the handling of the `Description` argument, which is susceptible to cross-site scripting attacks due to insufficient sanitization [ref_id=1].

What the fix does

The patch introduces a configurable URL filtering mechanism for XSS protection. Instead of globally escaping all string inputs, the application now checks if the current request URI matches a configured list of Ant-style patterns. If a match is found, the input string is HTML-escaped using `HtmlUtils.htmlEscape()`; otherwise, it is only trimmed. This change limits XSS protection to specific endpoints, addressing the vulnerability by ensuring that potentially malicious input in the Description field is sanitized when it is processed by the relevant endpoints [patch_id=4437616].

Preconditions

  • authThe attacker has low privileges.

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

References

8

News mentions

0

No linked articles in our index yet.