VYPR
Moderate severityNVD Advisory· Published Jun 11, 2019· Updated Aug 4, 2024

CVE-2019-10335

CVE-2019-10335

Description

A stored cross site scripting vulnerability in Jenkins ElectricFlow Plugin 1.1.5 and earlier allowed attackers able to configure jobs in Jenkins or control the output of the ElectricFlow API to inject arbitrary HTML and JavaScript in the plugin-provided output on build status pages.

AI Insight

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

Jenkins ElectricFlow Plugin 1.1.5 and earlier had a stored XSS vulnerability allowing attackers to inject arbitrary HTML/JavaScript via job configuration or API output.

Vulnerability

Overview

The Jenkins ElectricFlow Plugin, in versions 1.1.5 and earlier, contains a stored cross-site scripting (XSS) vulnerability. The root cause is insufficient escaping of user-controlled data when rendering output on build status pages. The plugin directly appended parameters, names, and values from job configurations or ElectricFlow API responses into HTML without proper encoding, as shown by the fix that introduced HtmlUtils.encodeForHtml() calls [4].

Exploitation and

Attack Surface

An attacker can exploit this by either having the ability to configure jobs in Jenkins (e.g., as a user with Job/Configure permission) or by controlling the output of the ElectricFlow API, which the plugin displays. This does not require authentication to the ElectricFlow service directly, but rather leverages Jenkins' own permissions or external API manipulation. The attack is low-complexity, requires no special privileges beyond job configuration, and is network-based [1][2].

Impact

Successful exploitation allows the attacker to inject arbitrary HTML and JavaScript into the build status page. When other users or administrators view the affected build status page, the injected script executes in their browser session within the Jenkins context. This can lead to session hijacking, credential theft, defacement, or further malicious actions against the Jenkins instance. The vulnerability is classified as medium severity with a CVSSv3 score of 6.1 [1][2].

Mitigation

Status

The vulnerability was fixed in ElectricFlow Plugin version 1.1.7, released on June 11, 2019 [3]. Users should upgrade to version 1.1.7 or later immediately. As of now, there is no evidence of active exploitation in the wild, and the vulnerability is not listed on the CISA Known Exploited Vulnerabilities (KEV) catalog.

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.jenkins-ci.plugins:electricflowMaven
< 1.1.71.1.7

Affected products

2

Patches

1
1a90ee7727f8

[SECURITY-1412]

https://github.com/jenkinsci/electricflow-pluginOlexii VasilkovskyMay 29, 2019via ghsa
11 files changed · +76 37
  • pom.xml+10 0 modified
    @@ -95,5 +95,15 @@
           <artifactId>jackson-xml-databind</artifactId>
           <version>0.6.2</version>
         </dependency>
    +    <dependency>
    +      <groupId>org.owasp.encoder</groupId>
    +      <artifactId>encoder</artifactId>
    +      <version>1.2.2</version>
    +    </dependency>
    +    <dependency>
    +      <groupId>com.googlecode.owasp-java-html-sanitizer</groupId>
    +      <artifactId>owasp-java-html-sanitizer</artifactId>
    +      <version>20190503.1</version>
    +    </dependency>
       </dependencies>
     </project>
    
  • src/main/java/org/jenkinsci/plugins/electricflow/ElectricFlowDeployApplication.java+3 2 modified
    @@ -28,6 +28,7 @@
     import org.apache.commons.logging.Log;
     import org.apache.commons.logging.LogFactory;
     import org.jenkinsci.plugins.electricflow.ui.FieldValidationStatus;
    +import org.jenkinsci.plugins.electricflow.ui.HtmlUtils;
     import org.jenkinsci.plugins.electricflow.ui.SelectFieldUtils;
     import org.jenkinsci.plugins.electricflow.ui.SelectItemValidationWrapper;
     import org.kohsuke.stapler.DataBoundConstructor;
    @@ -224,12 +225,12 @@ private String getSummaryHtml(
                     + "<table cellspacing=\"2\" cellpadding=\"4\"> \n"
                     + "  <tr>\n"
                     + "    <td>Application Name:</td>\n"
    -                + "    <td><a href='" + applicationUrl + "'>" + applicationName
    +                + "    <td><a href='" + HtmlUtils.encodeForHtml(applicationUrl) + "'>" + HtmlUtils.encodeForHtml(applicationName)
                     + "</a></td>   \n"
                     + "  </tr>\n"
                     + "  <tr>\n"
                     + "    <td>Deploy run URL:</td>\n"
    -                + "    <td><a href='" + deployRunUrl + "'>" + deployRunUrl
    +                + "    <td><a href='" + HtmlUtils.encodeForHtml(deployRunUrl) + "'>" + HtmlUtils.encodeForHtml(deployRunUrl)
                     + "</a></td>   \n"
                     + "  </tr>";
     
    
  • src/main/java/org/jenkinsci/plugins/electricflow/ElectricFlowGenericRestApi.java+7 6 modified
    @@ -15,6 +15,7 @@
     
     import javax.annotation.Nonnull;
     
    +import org.jenkinsci.plugins.electricflow.ui.HtmlUtils;
     import org.kohsuke.stapler.DataBoundConstructor;
     import org.kohsuke.stapler.DataBoundSetter;
     
    @@ -130,12 +131,12 @@ private String getSummaryHtml(
                     + "<table cellspacing=\"2\" cellpadding=\"4\"> \n"
                     + "  <tr>\n"
                     + "    <td style='width:20%;'>URL Path:</td>\n"
    -                + "    <td><a href='" + url + "'>" + url
    +                + "    <td><a href='" + HtmlUtils.encodeForHtml(url) + "'>" + HtmlUtils.encodeForHtml(url)
                     + "</a></td>   \n"
                     + "  </tr>\n"
                     + "  <tr>\n"
                     + "    <td>HTTP Method:</td>\n"
    -                + "    <td>" + httpMethod + "</td>   \n"
    +                + "    <td>" + HtmlUtils.encodeForHtml(httpMethod) + "</td>   \n"
                     + "  </tr>\n";
     
             if (!HttpMethod.GET.equals(HttpMethod.valueOf(httpMethod))) {
    @@ -151,10 +152,10 @@ private String getSummaryHtml(
                     for (Pair pair : parameters) {
                         strBuilder.append("  <tr>\n"
                                           + "    <td>&nbsp;&nbsp;&nbsp;&nbsp;")
    -                              .append(pair.getKey())
    +                              .append(HtmlUtils.encodeForHtml(pair.getKey()))
                                   .append(":</td>\n"
                                       + "    <td>")
    -                              .append(pair.getValue())
    +                              .append(HtmlUtils.encodeForHtml(pair.getValue()))
                                   .append("</td>    \n"
                                       + "  </tr>\n");
                     }
    @@ -164,14 +165,14 @@ private String getSummaryHtml(
                 else if (!body.isEmpty()) {
                     summaryText = summaryText + "  <tr>\n"
                             + "    <td>Body:</td>\n"
    -                        + "    <td>" + formatJsonOutput(body) + "</td>    \n"
    +                        + "    <td>" + HtmlUtils.encodeForHtml(formatJsonOutput(body)) + "</td>    \n"
                             + "  </tr>\n";
                 }
             }
     
             summaryText = summaryText + "  <tr>\n"
                     + "    <td>Result:</td>\n"
    -                + "    <td><pre>" + formatJsonOutput(result)
    +                + "    <td><pre>" + HtmlUtils.encodeForHtml(formatJsonOutput(result))
                     + "</pre></td>    \n"
                     + "  </tr>\n";
             summaryText = summaryText + "</table>";
    
  • src/main/java/org/jenkinsci/plugins/electricflow/ElectricFlowPipelinePublisher.java+4 3 modified
    @@ -21,6 +21,7 @@
     import org.apache.commons.logging.LogFactory;
     
     import org.jenkinsci.plugins.electricflow.ui.FieldValidationStatus;
    +import org.jenkinsci.plugins.electricflow.ui.HtmlUtils;
     import org.jenkinsci.plugins.electricflow.ui.SelectFieldUtils;
     import org.jenkinsci.plugins.electricflow.ui.SelectItemValidationWrapper;
     import org.kohsuke.stapler.DataBoundConstructor;
    @@ -284,16 +285,16 @@ private String getSummaryHtml(
                     + "<table cellspacing=\"2\" cellpadding=\"4\"> \n"
                     + "  <tr>\n"
                     + "    <td>Pipeline URL:</td>\n"
    -                + "    <td><a href='" + url + "'>" + url + "</a></td>   \n"
    +                + "    <td><a href='" + HtmlUtils.encodeForHtml(url) + "'>" + HtmlUtils.encodeForHtml(url) + "</a></td>   \n"
                     + "  </tr>\n"
                     + "  <tr>\n"
                     + "    <td>Pipeline Name:</td>\n"
    -                + "    <td><a href='" + url + "'>" + pipelineName
    +                + "    <td><a href='" + HtmlUtils.encodeForHtml(url) + "'>" + HtmlUtils.encodeForHtml(pipelineName)
                     + "</a></td>   \n"
                     + "  </tr>\n"
                     + "  <tr>\n"
                     + "    <td>Project Name:</td>\n"
    -                + "    <td>" + projectName + "</td>    \n"
    +                + "    <td>" + HtmlUtils.encodeForHtml(projectName) + "</td>    \n"
                     + "  </tr>";
     
             summaryText = Utils.getParametersHTML(parameters, summaryText,
    
  • src/main/java/org/jenkinsci/plugins/electricflow/ElectricFlowPublishApplication.java+6 6 modified
    @@ -26,6 +26,7 @@
     import org.apache.commons.logging.Log;
     import org.apache.commons.logging.LogFactory;
     
    +import org.jenkinsci.plugins.electricflow.ui.HtmlUtils;
     import org.kohsuke.stapler.DataBoundConstructor;
     import org.kohsuke.stapler.QueryParameter;
     import org.kohsuke.stapler.StaplerRequest;
    @@ -210,7 +211,7 @@ private String getSummaryHtml(
                     + "<table cellspacing=\"2\" cellpadding=\"4\"> \n"
                     + "  <tr>\n"
                     + "    <td>Application URL:</td>\n"
    -                + "    <td><a href='" + url + "'>" + url + "</a></td>   \n"
    +                + "    <td><a href='" + HtmlUtils.encodeForHtml(url) + "'>" + HtmlUtils.encodeForHtml(url) + "</a></td>   \n"
                     + "  </tr>\n";
     
             if (!zipFiles.isEmpty()) {
    @@ -238,8 +239,7 @@ private String getSummaryHtml(
                             byte[] encoded = Files.readAllBytes(Paths.get(
                                         manifestPath));
     
    -                        jsonContent = "<pre>" + new String(encoded, "UTF-8")
    -                                + "</pre>";
    +                        jsonContent = new String(encoded, "UTF-8");
                         }
                         catch (IOException e) {
                             logger.println(
    @@ -253,7 +253,7 @@ private String getSummaryHtml(
     
                     strBuilder.append("  <tr>\n"
                                       + "    <td>&nbsp;&nbsp;&nbsp;&nbsp;")
    -                          .append(fileName)
    +                          .append(HtmlUtils.encodeForHtml(fileName))
                               .append("</td>\n"
                                   + "    <td>")
                               .append("</td>    \n"
    @@ -263,10 +263,10 @@ private String getSummaryHtml(
                 if (!jsonContent.isEmpty()) {
                     strBuilder.append("  <tr>\n"
                                       + "    <td>&nbsp;&nbsp;&nbsp;&nbsp;")
    -                          .append(MANIFEST_NAME)
    +                          .append(HtmlUtils.encodeForHtml(MANIFEST_NAME))
                               .append("</td>\n"
                                   + "    <td>")
    -                          .append(jsonContent)
    +                          .append("<pre>").append(HtmlUtils.encodeForHtml(jsonContent)).append("</pre>")
                               .append("</td>    \n"
                                   + "  </tr>\n");
                 }
    
  • src/main/java/org/jenkinsci/plugins/electricflow/ElectricFlowRunProcedure.java+2 1 modified
    @@ -28,6 +28,7 @@
     import org.apache.commons.logging.Log;
     import org.apache.commons.logging.LogFactory;
     import org.jenkinsci.plugins.electricflow.ui.FieldValidationStatus;
    +import org.jenkinsci.plugins.electricflow.ui.HtmlUtils;
     import org.jenkinsci.plugins.electricflow.ui.SelectFieldUtils;
     import org.jenkinsci.plugins.electricflow.ui.SelectItemValidationWrapper;
     import org.kohsuke.stapler.DataBoundConstructor;
    @@ -166,7 +167,7 @@ private String getSummaryHtml(
                     + "<table cellspacing=\"2\" cellpadding=\"4\"> \n"
                     + "  <tr>\n"
                     + "    <td>Procedure Name:</td>\n"
    -                + "    <td><a href='" + jobUrl + "'>" + procedureName + "</a></td>   \n"
    +                + "    <td><a href='" + HtmlUtils.encodeForHtml(jobUrl) + "'>" + HtmlUtils.encodeForHtml(procedureName) + "</a></td>   \n"
                     + "  </tr>";
     
             summaryText = Utils.getParametersHTML(parameters, summaryText,
    
  • src/main/java/org/jenkinsci/plugins/electricflow/ElectricFlowTriggerRelease.java+6 5 modified
    @@ -27,6 +27,7 @@
     import org.apache.commons.logging.Log;
     import org.apache.commons.logging.LogFactory;
     import org.jenkinsci.plugins.electricflow.ui.FieldValidationStatus;
    +import org.jenkinsci.plugins.electricflow.ui.HtmlUtils;
     import org.jenkinsci.plugins.electricflow.ui.SelectFieldUtils;
     import org.jenkinsci.plugins.electricflow.ui.SelectItemValidationWrapper;
     import org.kohsuke.stapler.DataBoundConstructor;
    @@ -210,28 +211,28 @@ private String getSummaryHtml(
                     + "<table cellspacing=\"2\" cellpadding=\"4\"> \n"
                     + "  <tr>\n"
                     + "    <td>Release Name:</td>\n"
    -                + "    <td><a href='" + urlRelease + "'>" + releaseName
    +                + "    <td><a href='" + HtmlUtils.encodeForHtml(urlRelease) + "'>" + HtmlUtils.encodeForHtml(releaseName)
                     + "</a></td>   \n"
                     + "  </tr>\n"
                     + "  <tr>\n"
                     + "    <td>Pipeline URL:</td>\n"
    -                + "    <td><a href='" + urlPipeline + "'>" + urlPipeline
    +                + "    <td><a href='" + HtmlUtils.encodeForHtml(urlPipeline) + "'>" + HtmlUtils.encodeForHtml(urlPipeline)
                     + "</a></td>   \n"
                     + "  </tr>\n"
                     + "  <tr>\n"
                     + "    <td>Pipeline Name:</td>\n"
    -                + "    <td><a href='" + urlPipeline + "'>" + pipelineName
    +                + "    <td><a href='" + HtmlUtils.encodeForHtml(urlPipeline) + "'>" + HtmlUtils.encodeForHtml(pipelineName)
                     + "</a></td>   \n"
                     + "  </tr>\n"
                     + "  <tr>\n"
                     + "    <td>Project Name:</td>\n"
    -                + "    <td>" + projectName + "</td>    \n"
    +                + "    <td>" + HtmlUtils.encodeForHtml(projectName) + "</td>    \n"
                     + "  </tr>";
     
             if (!startingStage.isEmpty()) {
                 summaryText = summaryText + "  <tr>\n"
                         + "    <td>Starting stage:</td>\n"
    -                    + "    <td>" + startingStage + "</td>    \n"
    +                    + "    <td>" + HtmlUtils.encodeForHtml(startingStage) + "</td>    \n"
                         + "  </tr>";
             }
     
    
  • src/main/java/org/jenkinsci/plugins/electricflow/ElectricFlowUploadArtifactPublisher.java+5 4 modified
    @@ -19,6 +19,7 @@
     import org.apache.commons.logging.Log;
     import org.apache.commons.logging.LogFactory;
     
    +import org.jenkinsci.plugins.electricflow.ui.HtmlUtils;
     import org.kohsuke.stapler.DataBoundConstructor;
     import org.kohsuke.stapler.QueryParameter;
     import org.kohsuke.stapler.StaplerRequest;
    @@ -211,19 +212,19 @@ private String getSummaryHtml(
                 + "<table cellspacing=\"2\" cellpadding=\"4\">\n"
                 + "  <tr>\n"
                 + "    <td>Artifact URL:</td>\n"
    -            + "    <td><a href ='" + url + "'>" + url + "</a></td> \n"
    +            + "    <td><a href ='" + HtmlUtils.encodeForHtml(url) + "'>" + HtmlUtils.encodeForHtml(url) + "</a></td> \n"
                 + "  </tr>\n"
                 + "  <tr>\n"
                 + "    <td>Artifact Name:</td>\n"
    -            + "    <td><a href ='" + url + "'>" + artifactName + "</a></td> \n"
    +            + "    <td><a href ='" + HtmlUtils.encodeForHtml(url) + "'>" + HtmlUtils.encodeForHtml(artifactName) + "</a></td> \n"
                 + "  </tr>\n"
                 + "  <tr>\n"
                 + "    <td>Artifact Version:</td>\n"
    -            + "    <td>" + newArtifactVersion + "</td> \n"
    +            + "    <td>" + HtmlUtils.encodeForHtml(newArtifactVersion) + "</td> \n"
                 + "  </tr>\n"
                 + "  <tr>\n"
                 + "    <td>Repository Name:</td>\n"
    -            + "    <td>" + repository + "</td> \n"
    +            + "    <td>" + HtmlUtils.encodeForHtml(repository) + "</td> \n"
                 + "  </tr>\n"
                 + "</table>";
         }
    
  • src/main/java/org/jenkinsci/plugins/electricflow/SummaryTextAction.java+4 3 modified
    @@ -18,6 +18,8 @@
     
     import jenkins.tasks.SimpleBuildStep;
     
    +import static org.jenkinsci.plugins.electricflow.ui.HtmlUtils.getHtmlPolicy;
    +
     public class SummaryTextAction
         implements Action,
             SimpleBuildStep.LastBuildAction
    @@ -66,9 +68,8 @@ public SummaryTextAction(
             return this.run;
         }
     
    -    public String getSummaryText()
    -    {
    -        return this.summaryText;
    +    public String getSummaryText() {
    +        return getHtmlPolicy().sanitize(this.summaryText);
         }
     
         @Override public String getUrlName()
    
  • src/main/java/org/jenkinsci/plugins/electricflow/ui/HtmlUtils.java+21 0 added
    @@ -0,0 +1,21 @@
    +package org.jenkinsci.plugins.electricflow.ui;
    +
    +import org.owasp.encoder.Encode;
    +import org.owasp.html.HtmlPolicyBuilder;
    +import org.owasp.html.PolicyFactory;
    +
    +public class HtmlUtils {
    +    public static PolicyFactory getHtmlPolicy() {
    +        return new HtmlPolicyBuilder()
    +                .allowElements("h3", "table", "tr", "td", "a", "b", "pre")
    +                .allowAttributes("href").onElements("a")
    +                .allowAttributes("cellspacing", "cellpadding").onElements("table")
    +                .allowStyling()
    +                .allowStandardUrlProtocols()
    +                .toFactory();
    +    }
    +
    +    public static String encodeForHtml(String input) {
    +        return Encode.forHtml(input);
    +    }
    +}
    
  • src/main/java/org/jenkinsci/plugins/electricflow/Utils.java+8 7 modified
    @@ -27,6 +27,7 @@
     
     import jenkins.model.GlobalConfiguration;
     import org.jenkinsci.plugins.electricflow.ui.FieldValidationStatus;
    +import org.jenkinsci.plugins.electricflow.ui.HtmlUtils;
     import org.jenkinsci.plugins.electricflow.ui.SelectFieldUtils;
     import org.jenkinsci.plugins.electricflow.ui.SelectItemValidationWrapper;
     
    @@ -196,7 +197,7 @@ public static String getParametersHTML(
                 for (String param : parameters) {
                     strBuilder.append("  <tr>\n"
                                       + "    <td>&nbsp;&nbsp;&nbsp;&nbsp;")
    -                          .append(param)
    +                          .append(HtmlUtils.encodeForHtml(param))
                               .append("</td>\n")
                               .append("  </tr>\n");
                 }
    @@ -229,10 +230,10 @@ public static String getParametersHTML(
     
                     strBuilder.append("  <tr>\n"
                                       + "    <td>&nbsp;&nbsp;&nbsp;&nbsp;")
    -                          .append(name)
    +                          .append(HtmlUtils.encodeForHtml(name))
                               .append(":</td>\n"
                                   + "    <td>")
    -                          .append(value)
    +                          .append(HtmlUtils.encodeForHtml(value))
                               .append("</td>    \n"
                                   + "  </tr>\n");
                 }
    @@ -347,17 +348,17 @@ public static String getValidationComparisonRow(String parameterName, Object old
             if (!newValue.equals(oldValue)) {
                 rowStyleAttr = "style=\"background-color: #e2db0c;\"";
             }
    -        return "<tr " + rowStyleAttr + "><td>" + parameterName + "</td><td>" + oldValue + "</td><td>" + newValue + "</td></tr>";
    +        return "<tr " + rowStyleAttr + "><td>" + HtmlUtils.encodeForHtml(parameterName) + "</td><td>" + HtmlUtils.encodeForHtml(String.valueOf(oldValue)) + "</td><td>" + HtmlUtils.encodeForHtml(String.valueOf(newValue)) + "</td></tr>";
         }
     
         public static String getValidationComparisonRowOldParam(String parameterName, Object oldValue) {
             String rowStyleAttr = "style=\"background-color: #fa9a76;\"";
    -        return "<tr " + rowStyleAttr + "><td>" + parameterName + "</td><td>" + oldValue + "</td><td></td></tr>";
    +        return "<tr " + rowStyleAttr + "><td>" + HtmlUtils.encodeForHtml(parameterName) + "</td><td>" + HtmlUtils.encodeForHtml(String.valueOf(oldValue)) + "</td><td></td></tr>";
         }
     
         public static String getValidationComparisonRowNewParam(String parameterName, Object newValue) {
             String rowStyleAttr = "style=\"background-color: #82dc84;\"";
    -        return "<tr " + rowStyleAttr + "><td>" + parameterName + "</td><td></td><td>" + newValue + "</td></tr>";
    +        return "<tr " + rowStyleAttr + "><td>" + HtmlUtils.encodeForHtml(parameterName) + "</td><td></td><td>" + HtmlUtils.encodeForHtml(String.valueOf(newValue)) + "</td></tr>";
         }
     
         public static String getValidationComparisonRowsForExtraParameters(String sectionName, Map<String, String> oldParamsMap, Map<String, String> newParamsMap) {
    @@ -367,7 +368,7 @@ public static String getValidationComparisonRowsForExtraParameters(String sectio
     
             StringBuilder rows = new StringBuilder();
             rows.append("<tr><td></td><td></td><td></td></tr>");
    -        rows.append("<tr><td>" + sectionName + "</td><td></td><td></td></tr>");
    +        rows.append("<tr><td>" + HtmlUtils.encodeForHtml(sectionName) + "</td><td></td><td></td></tr>");
     
             Set<String> oldKeysSet = new HashSet<String>(oldParamsMap.keySet());
             oldKeysSet.removeAll(newParamsMap.keySet());
    

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.