Skip to content

Commit

Permalink
Merge pull request #242 from ababushk/JENKINS_50154_unicode_payload
Browse files Browse the repository at this point in the history
[JENKINS-50154] Fix webhook payload signature generation when Unicode symbols are present in it
  • Loading branch information
KostyaSha committed Jan 3, 2021
2 parents e394f77 + a728333 commit c1aa272
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 7 deletions.
6 changes: 5 additions & 1 deletion pom.xml
Expand Up @@ -81,7 +81,11 @@
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>github-api</artifactId>
Expand Down
Expand Up @@ -2,6 +2,7 @@

import hudson.util.Secret;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.text.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -54,7 +55,10 @@ public String sha1() {
final SecretKeySpec keySpec = new SecretKeySpec(secret.getPlainText().getBytes(UTF_8), HMAC_SHA1_ALGORITHM);
final Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
mac.init(keySpec);
final byte[] rawHMACBytes = mac.doFinal(payload.getBytes(UTF_8));

final String unescapedPayload = StringEscapeUtils.unescapeJava(payload);
final String convertedUnicode = new String(unescapedPayload.getBytes("latin1"), UTF_8);
final byte[] rawHMACBytes = mac.doFinal(convertedUnicode.getBytes(UTF_8));

return Hex.encodeHexString(rawHMACBytes);
} catch (Exception e) {
Expand Down
@@ -1,4 +1,4 @@
package org.jenkinsci.plugins.github.extension;
package org.jenkinsci.plugins.github.webhook;

import hudson.util.Secret;
import org.junit.ClassRule;
Expand All @@ -14,28 +14,40 @@
*
* @author martinmine
*/
public class CryptoUtilTest {
public class GHWebhookSignatureTest {

private static final String SIGNATURE = "85d155c55ed286a300bd1cf124de08d87e914f3a";
private static final String PAYLOAD = "foo";
private static final String SECRET = "bar";

// Taken from real example of Pull Request update webhook payload
private static final String UNICODE_PAYLOAD = "{\"description\":\"foo\\u00e2\\u0084\\u00a2\"}";
private static final String UNICODE_SIGNATURE = "10e3cb05d27049775aeca89d84d9e6123d5ab006";

@ClassRule
public static JenkinsRule jRule = new JenkinsRule();

@Test
public void shouldComputeSHA1Signature() throws Exception {
assertThat("signature is valid", webhookSignature(
PAYLOAD,
PAYLOAD,
Secret.fromString(SECRET)
).sha1(), equalTo(SIGNATURE));
}

@Test
public void shouldMatchSignature() throws Exception {
assertThat("signature should match", webhookSignature(
PAYLOAD,
PAYLOAD,
Secret.fromString(SECRET)
).matches(SIGNATURE), equalTo(true));
}
}

@Test
public void shouldComputeSHA1SignatureWithUnicodePayload() throws Exception {
assertThat("signature is valid for unicode payload", webhookSignature(
UNICODE_PAYLOAD,
Secret.fromString(SECRET)
).sha1(), equalTo(UNICODE_SIGNATURE));
}
}

0 comments on commit c1aa272

Please sign in to comment.