Low severityNVD Advisory· Published Apr 4, 2019· Updated Aug 5, 2024
CVE-2019-1003063
CVE-2019-1003063
Description
Jenkins Amazon SNS Build Notifier Plugin stores credentials unencrypted in its global configuration file on the Jenkins master where they can be viewed by users with access to the master file system.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.jenkins-ci.plugins:snsnotifyMaven | < 2.37 | 2.37 |
Affected products
1- Range: all versions as of 2019-04-03
Patches
1874db1f2882aUpdate AWS SDK + Fix clear text AWS secret key
10 files changed · +126 −52
CHANGELOG.md+48 −0 added@@ -0,0 +1,48 @@ +Changelog +=== + +### 2.0 + +Release date: _Apr ??, 2021_ + +* Fixed clear text persistence of AWS secret key +* Updated parent pom to 4.18 +* Set min Jenkins version to 2.263.1 +* Added dependency to plugin aws-java-sdk 1.11.995 +* Removed dependency to included aws-java-sdk-sns +* Removed dependency to included httpcore +* Added docs +* Added changelog + +### 1.13 + +Release date: _Mar 9, 2016_ + +* Added support for IAM Roles +* Ability to disable notifications on every build. + +### 1.10 + +Release date: _Jan 19, 2016_ + +* Cleaned up dependencies. + +### 1.9 + +Release date: _May 21, 2015_ + +* Containing support for more BUILD_* variables. + +### 1.8 + +Release date: _Oct 12, 2014_ + +* Allow to send out SNS notifications also on build start. + +### 1.7 + +Release date: _Aug 25, 2014_ + +* Update to current LTS version +* Send SNS notification for all build return types +* Allow to specify template for subject and message notification.
docs/images/snsnotify-global-config.png+0 −0 addeddocs/images/snsnotify-post-build-config.png+0 −0 added.gitignore+1 −0 modified@@ -4,6 +4,7 @@ release.properties pom.xml.releaseBackup # IntelliJ project files +.idea/ *.ipr *.iml *.iws
pom.xml+16 −13 modified@@ -5,15 +5,21 @@ <parent> <groupId>org.jenkins-ci.plugins</groupId> <artifactId>plugin</artifactId> - <version>1.565.1</version> + <version>4.18</version> <!-- or whatever the newest version available is --> + <relativePath /> </parent> <artifactId>snsnotify</artifactId> - <version>1.14-SNAPSHOT</version> + <version>2.0-SNAPSHOT</version> <packaging>hpi</packaging> <name>Amazon SNS Build Notifier</name> <description>Publish build notifications to an AWS SNS Topic</description> - <url>https://wiki.jenkins-ci.org/display/JENKINS/Amazon+SNS+Notifier</url> + <url>https://github.com/jenkinsci/snsnotify-plugin</url> + + <properties> + <jenkins.version>2.263.1</jenkins.version> + <java.level>8</java.level> + </properties> <developers> <developer> @@ -28,6 +34,10 @@ <id>nikos</id> <name>Niko Schmuck</name> </developer> + <developer> + <id>lenslord</id> + <name>Michael Meissner</name> + </developer> </developers> <scm> @@ -38,19 +48,12 @@ <dependencies> <dependency> - <groupId>com.amazonaws</groupId> - <artifactId>aws-java-sdk-sns</artifactId> - <version>RELEASE</version> - </dependency> - - <dependency> - <groupId>org.apache.httpcomponents</groupId> - <artifactId>httpcore</artifactId> - <version>4.4.1</version> + <groupId>org.jenkins-ci.plugins</groupId> + <artifactId>aws-java-sdk</artifactId> + <version>1.11.995</version> </dependency> </dependencies> - <repositories> <repository> <id>repo.jenkins-ci.org</id>
README.md+4 −2 modified@@ -13,7 +13,7 @@ Create an installable artifact: 1. `mvn clean install` 2. (wait for mvn to download the internet) 3. Manage Jenkins > Plugins > Advanced > Upload ```./target/snsnotify.hpi``` -4. Restart Jenkins ([$JENKINS_URL]/restart) +4. Restart Jenkins ([$JENKINS_URL]/safeRestart) Now, login to AWS and do the following: @@ -24,11 +24,13 @@ Finally, back to Jenkins... 1. Manage Jenkins > Configure Jenkins to use AWS creds and newly created Topic ARN. You can also specify the default bevaiour in case you want to send out also an - SNS notification when the build is started (off by default). + SNS notification when the build is started (off by default). +  2. As part of your job: add post-build step for SNS notification, optionally configure subject and message (you can make use of build and environment variables, which do get substituted), resp. override Topic ARN (if you do not want to stick with globally configured one). +  ## helpfull aws snippets
src/main/java/org/jenkinsci/plugins/snsnotify/AmazonSNSNotifier.java+47 −30 modified@@ -1,8 +1,8 @@ package org.jenkinsci.plugins.snsnotify; -import com.amazonaws.auth.AWSCredentials; -import com.amazonaws.auth.DefaultAWSCredentialsProviderChain; -import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.auth.*; +import com.amazonaws.client.builder.AwsClientBuilder; +import com.amazonaws.services.sns.AmazonSNS; import com.amazonaws.services.sns.AmazonSNSClient; import com.amazonaws.services.sns.model.PublishRequest; import hudson.EnvVars; @@ -16,6 +16,7 @@ import hudson.tasks.BuildStepMonitor; import hudson.tasks.Notifier; import hudson.tasks.Publisher; +import hudson.util.Secret; import net.sf.json.JSONObject; import org.apache.commons.lang.StringUtils; import org.kohsuke.stapler.DataBoundConstructor; @@ -105,7 +106,7 @@ public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListen private void send(AbstractBuild build, TaskListener listener, BuildPhase phase) { String awsAccessKey = getDescriptor().getAwsAccessKey(); - String awsSecretKey = getDescriptor().getAwsSecretKey(); + Secret awsSecretKey = getDescriptor().getAwsSecretKey(); String publishTopic = isEmpty(projectTopicArn) ? getDescriptor().getDefaultTopicArn() : projectTopicArn; boolean useLocalCredential = getDescriptor().isDefaultLocalCredential(); @@ -115,23 +116,24 @@ private void send(AbstractBuild build, TaskListener listener, BuildPhase phase) return; } - if (!(useLocalCredential) && (isEmpty(awsAccessKey) || isEmpty(awsSecretKey))) { + if (!(useLocalCredential) && (isEmpty(awsAccessKey) || isEmpty(awsSecretKey.getPlainText()))) { listener.error("AWS credentials not configured; cannot send SNS notification"); return; } - String snsApiEndpoint = getSNSApiEndpoint(publishTopic); - if (isEmpty(snsApiEndpoint)) { + AwsClientBuilder.EndpointConfiguration snsApiEndpoint = getSNSApiEndpoint(publishTopic); + if (snsApiEndpoint == null) { listener.error("Could not determine SNS API Endpoint from topic ARN: " + publishTopic); return; } // ~~ prepare subject (incl. variable replacement) String subject; if (StringUtils.isEmpty(subjectTemplate)) { + Result buildResult = build.getResult(); subject = truncate( String.format("Build %s: %s", - phase == BuildPhase.STARTED ? "STARTED" : build.getResult().toString(), + phase == BuildPhase.STARTED || buildResult == null? "STARTED" : buildResult.toString(), build.getFullDisplayName()), 100); } else { subject = replaceVariables(build, listener, phase, subjectTemplate); @@ -142,22 +144,24 @@ private void send(AbstractBuild build, TaskListener listener, BuildPhase phase) isEmpty(messageTemplate) ? getDescriptor().getDefaultMessageTemplate() : messageTemplate); LOG.info("Setup SNS client '" + snsApiEndpoint + "' ..."); - AWSCredentials awsCredentials; + AWSCredentialsProvider awsCredentialsProvider; try { if (useLocalCredential) { - awsCredentials = new DefaultAWSCredentialsProviderChain().getCredentials(); + awsCredentialsProvider = new DefaultAWSCredentialsProviderChain(); } else { - awsCredentials = new BasicAWSCredentials(awsAccessKey, awsSecretKey); + awsCredentialsProvider = new AWSStaticCredentialsProvider(new BasicAWSCredentials(awsAccessKey, awsSecretKey.getPlainText())); } } catch (Exception e) { listener.error("Failed to send SNS notification: " + e.getMessage()); return; } - AmazonSNSClient snsClient = new AmazonSNSClient(awsCredentials); - snsClient.setEndpoint(snsApiEndpoint); + AmazonSNS snsClient = AmazonSNSClient.builder() + .withEndpointConfiguration(snsApiEndpoint) + .withCredentials(awsCredentialsProvider) + .build(); try { String summary = String.format("subject=%s topic=%s", subject, publishTopic); @@ -216,18 +220,27 @@ private boolean isEmpty(String s) { */ private String replaceVariables(AbstractBuild build, TaskListener listener, BuildPhase phase, String tmpl) { + String resultString = tmpl; + try { EnvVars envVars = build.getEnvironment(listener); + Result buildResult = build.getResult(); + envVars.put("BUILD_PHASE", phase.name()); envVars.put("BUILD_ARTIFACT_PATHS", artifactPaths(build.getArtifacts())); - envVars.put("BUILD_RESULT", phase == BuildPhase.STARTED ? "STARTED" : build.getResult().toString()); + envVars.put("BUILD_RESULT", phase == BuildPhase.STARTED || buildResult == null ? "STARTED" : buildResult.toString()); envVars.put("BUILD_DURATION", Long.toString(build.getDuration())); String result = Util.replaceMacro(tmpl, build.getBuildVariableResolver()); - return Util.replaceMacro(result, envVars); - } catch (Exception e) { + resultString = Util.replaceMacro(result, envVars); + } + catch (RuntimeException e) { + LOG.warning("Unable to get environment while trying to replace variables on " + tmpl); + } + catch (Exception e) { LOG.warning("Unable to get environment while trying to replace variables on " + tmpl); - return tmpl; } + + return resultString; } /** @@ -244,7 +257,7 @@ private String artifactPaths(List<Artifact> artifacts) { * Determine the SNS API endpoint to make API calls to, based on the region * included in the topic ARN. */ - private String getSNSApiEndpoint(String topicArn) { + private AwsClientBuilder.EndpointConfiguration getSNSApiEndpoint(String topicArn) { // This is probably not a recommended way to pick the API endpoint, but // it seems to be a reasonably safe assumption, and avoids extra @@ -256,7 +269,17 @@ private String getSNSApiEndpoint(String topicArn) { } String region = arnParts[3]; - return "sns." + region + ".amazonaws.com"; + + String apiEndpoint = ""; + if (region.startsWith("cn-")){ + apiEndpoint = "sns." + region + ".amazonaws.com.cn"; + } else { + apiEndpoint = "sns." + region + ".amazonaws.com"; + } + + AwsClientBuilder.EndpointConfiguration conf = new AwsClientBuilder.EndpointConfiguration (apiEndpoint, region); + + return conf; } @@ -266,7 +289,7 @@ private String getSNSApiEndpoint(String topicArn) { public static final class DescriptorImpl extends BuildStepDescriptor<Publisher> { private String awsAccessKey; - private String awsSecretKey; + private Secret awsSecretKey; private String defaultTopicArn; private String defaultMessageTemplate; private boolean defaultSendNotificationOnStart; @@ -290,22 +313,16 @@ public boolean isApplicable(Class<? extends AbstractProject> aClass) { @Override public boolean configure(StaplerRequest req, JSONObject formData) throws FormException { - awsAccessKey = formData.getString("awsAccessKey"); - awsSecretKey = formData.getString("awsSecretKey"); - defaultTopicArn = formData.getString("defaultTopicArn"); - defaultMessageTemplate = formData.getString("defaultMessageTemplate"); - defaultSendNotificationOnStart = formData.getBoolean("defaultSendNotificationOnStart"); - defaultLocalCredential = formData.getBoolean("defaultLocalCredential"); - defaultNotifyOnConsecutiveSuccesses = formData.getBoolean("defaultNotifyOnConsecutiveSuccesses"); + req.bindJSON(this, formData); save(); - return super.configure(req, formData); + return true; } public String getAwsAccessKey() { return awsAccessKey; } - public String getAwsSecretKey() { + public Secret getAwsSecretKey() { return awsSecretKey; } @@ -333,7 +350,7 @@ public void setAwsAccessKey(String awsAccessKey) { this.awsAccessKey = awsAccessKey; } - public void setAwsSecretKey(String awsSecretKey) { + public void setAwsSecretKey(Secret awsSecretKey) { this.awsSecretKey = awsSecretKey; }
src/main/resources/index.jelly+1 −0 modified@@ -1,3 +1,4 @@ +<?jelly escape-by-default='true'?> <div> Send build notifications to an Amazon SNS Topic </div>
src/main/resources/org/jenkinsci/plugins/snsnotify/AmazonSNSNotifier/config.jelly+1 −0 modified@@ -1,3 +1,4 @@ +<?jelly escape-by-default='true'?> <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form"> <f:entry title="Topic ARN (overrides global default)" field="projectTopicArn">
src/main/resources/org/jenkinsci/plugins/snsnotify/AmazonSNSNotifier/global.jelly+8 −7 modified@@ -1,3 +1,4 @@ +<?jelly escape-by-default='true'?> <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form"> <f:section title="Amazon SNS Notification"> @@ -6,55 +7,55 @@ help="/plugin/snsnotify/help-awsAccessKey.html" field="awsAccessKey"> - <f:textbox name="snsnotify.awsAccessKey" /> + <f:textbox /> </f:entry> <f:entry title="AWS Secret Key" help="/plugin/snsnotify/help-awsSecretKey.html" field="awsSecretKey"> - <f:password name="snsnotify.awsSecretKey" /> + <f:password /> </f:entry> <f:entry title="Use Local Credentials" help="/plugin/snsnotify/help-defaultCredential.html" field="defaultLocalCredential"> - <f:booleanRadio name="snsnotify.defaultLocalCredential" /> + <f:booleanRadio /> </f:entry> <f:entry title="Default notification topic ARN" help="/plugin/snsnotify/help-defaultTopicArn.html" field="defaultTopicArn"> - <f:textbox name="snsnotify.defaultTopicArn" /> + <f:textbox /> </f:entry> <f:entry title="Default message (default: {BUILD_URL})" help="/plugin/snsnotify/help-defaultMessageTemplate.html" field="defaultMessageTemplate"> - <f:textbox name="snsnotify.defaultMessageTemplate" /> + <f:textbox /> </f:entry> <f:entry title="Send notification also on start of build?" help="/plugin/snsnotify/help-defaultSendNotificationOnStart.html" field="defaultSendNotificationOnStart"> - <f:booleanRadio name="snsnotify.defaultSendNotificationOnStart" /> + <f:booleanRadio /> </f:entry> <f:entry title="Send notifications on every build?" help="/plugin/snsnotify/help-defaultNotifyOnConsecutiveSuccesses.html" field="defaultNotifyOnConsecutiveSuccesses"> - <f:booleanRadio name="snsnotify.defaultNotifyOnConsecutiveSuccesses" /> + <f:booleanRadio /> </f:entry> </f:section> </j:jelly>
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-84p4-7mxc-7phjghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2019-1003063ghsaADVISORY
- www.openwall.com/lists/oss-security/2019/04/12/2ghsamailing-listx_refsource_MLISTWEB
- www.securityfocus.com/bid/107790mitrevdb-entryx_refsource_BID
- github.com/jenkinsci/snsnotify-plugin/commit/874db1f2882aebb452c6d9dc0ad59efa6fd336dbghsaWEB
- jenkins.io/security/advisory/2019-04-03/ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.