• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rwjdk / TrelloDotNet / 6393576553

03 Oct 2023 01:20PM UTC coverage: 67.061% (-0.4%) from 67.435%
6393576553

push

github

web-flow
Implement webhook signature validation (#26)

* implement webhook signature validation

* Requested changes and some optimizations

- add webhook signature validation to AutomationController
- add Secret to TrelloClientOptions
- reduce memory allocations in WebhookSignatureValidator.ValidateSignature from ~15KB to ~5KB

* WebhookSignatureValidator: try to validate signatures when signature or webhookUrl is set. Throw an exception if one of signature, webhookUrl, secret is missing

871 of 1623 branches covered (0.0%)

Branch coverage included in aggregate %.

37 of 37 new or added lines in 5 files covered. (100.0%)

2246 of 3025 relevant lines covered (74.25%)

60.93 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/TrelloDotNet/TrelloDotNet/Control/Webhook/WebhookSignatureValidator.cs
1
using System;
2
using System.Linq;
3
using System.Security.Cryptography;
4
using System.Text;
5

6
namespace TrelloDotNet.Control.Webhook
7
{
8
    internal static class WebhookSignatureValidator
9
    {
10
        private static byte[] Digest(byte[] data, int dataIndex, int dataLength, string secret)
11
        {
12
            var hmac = new HMACSHA1(Encoding.UTF8.GetBytes(secret));
×
13
            return hmac.ComputeHash(data, dataIndex, dataLength);
×
14
        }
15

16
        internal static bool ValidateSignature(string json, string signature, string webhookUrl, string secret)
17
        {
18
            if (json == null)
×
19
                throw new ArgumentNullException(nameof(json));
×
20
            if (signature == null)
×
21
                throw new ArgumentNullException(nameof(signature));
×
22
            if (webhookUrl == null)
×
23
                throw new ArgumentNullException(nameof(webhookUrl));
×
24
            if (secret == null)
×
25
                throw new ArgumentNullException(nameof(secret), "You must provide an API secret to use Webhook Signature Validation. Please set TrelloClientOptions.Secret");
×
26
            
27
            var payloadLength = Encoding.UTF8.GetByteCount(json) + Encoding.UTF8.GetByteCount(webhookUrl);
×
28
            var payloadBytes = new byte[payloadLength];
×
29
            var payloadBytesWritten = Encoding.UTF8.GetBytes(json, 0, json.Length, payloadBytes, 0);
×
30
            payloadBytesWritten += Encoding.UTF8.GetBytes(webhookUrl, 0, webhookUrl.Length, payloadBytes, payloadBytesWritten);
×
31
            var hashBytes = Digest(payloadBytes, 0, payloadBytesWritten, secret);
×
32
            var signatureBytes = Convert.FromBase64String(signature);
×
33
            return hashBytes.SequenceEqual(signatureBytes); 
×
34
        }
35
    }
36
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc