Skip to content

Unable to verify signature for testing purposes #453

@gotchahn

Description

@gotchahn

Issue Summary

I'm trying to do some tests in rails to check if my sendgrid webhook endpoint is working. I'm in using the same values for PUBLIC KEY and SIGNATURE key shared on the fixtures page:

PUBLIC_KEY = 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE83T4O/n84iotIvIW4mdBgQ/7dAfSmpqIM8kF9mN1flpVKS3GRqe62gw+2fNNRaINXvVpiglSI8eNEc6wEA3F+g=='.freeze
FAILING_PUBLIC_KEY = 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqTxd43gyp8IOEto2LdIfjRQrIbsd4SXZkLW6jDutdhXSJCWHw8REntlo7aNDthvj+y7GjUuFDb/R1NGe1OPzpA=='.freeze
SIGNATURE = 'MEUCIGHQVtGj+Y3LkG9fLcxf3qfI10QysgDWmMOVmxG0u6ZUAiEAyBiXDWzM+uOe5W0JuG+luQAbPIqHh89M15TluLtEZtM='.freeze
FAILING_SIGNATURE = 'MEUCIQCtIHJeH93Y+qpYeWrySphQgpNGNr/U+UyUlBkU6n7RAwIgJTz2C+8a8xonZGi6BpSzoQsbVRamr2nlxFDWYNH3j/0='.freeze
TIMESTAMP = '1600112502'.freeze
PAYLOAD = "#{[
{
email: 'hello@world.com',
event: 'dropped',
reason: 'Bounced Address',
sg_event_id: 'ZHJvcC0xMDk5NDkxOS1MUnpYbF9OSFN0T0doUTRrb2ZTbV9BLTA',
sg_message_id: 'LRzXl_NHStOGhQ4kofSm_A.filterdrecv-p3mdw1-756b745b58-kmzbl-18-5F5FC76C-9.0',
'smtp-id': '<LRzXl_NHStOGhQ4kofSm_A@ismtpd0039p1iad1.sendgrid.net>',
timestamp: 1_600_112_492
}
].to_json}\r\n".freeze # Be sure to include the trailing carriage return and newline!

But overall the verify method returns false to me.

Code Snippet

If I do this manually in the console, using the same values, the verify returns false:

irb(main):003:0> 
irb(main):004:0> ew = SendGrid::EventWebhook.new
=> #<SendGrid::EventWebhook:0x00007faa52aab758>
irb(main):005:0> 
irb(main):006:0> 
irb(main):007:0> public_key = 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE83T4O/n84iotIvIW4mdBgQ/7dAfSmpqIM8kF9mN1flpVKS3GRqe62gw+2fNNRaINXvVpiglSI8eNEc6wEA3F+g=='.freeze
=> "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE83T4O/n84iotIvIW4mdBgQ/7dAfSmpqIM8kF9mN1flpVKS3GRqe62gw+2fNNRaINXvVpiglSI8eNEc6wEA3F+g=="
irb(main):008:0> 
irb(main):009:0> signature = 'MEUCIGHQVtGj+Y3LkG9fLcxf3qfI10QysgDWmMOVmxG0u6ZUAiEAyBiXDWzM+uOe5W0JuG+luQAbPIqHh89M15TluLtEZtM='.freeze
=> "MEUCIGHQVtGj+Y3LkG9fLcxf3qfI10QysgDWmMOVmxG0u6ZUAiEAyBiXDWzM+uOe5W0JuG+luQAbPIqHh89M15TluLtEZtM="
irb(main):010:0> 
irb(main):011:0> timestamp = '1600112502'.freeze
=> "1600112502"
irb(main):012:0> 
irb(main):013:0> payload = "#{[
irb(main):014:1>       {
irb(main):015:2>         email: 'hello@world.com',
irb(main):016:2>         event: 'dropped',
irb(main):017:2>         reason: 'Bounced Address',
irb(main):018:2>         sg_event_id: 'ZHJvcC0xMDk5NDkxOS1MUnpYbF9OSFN0T0doUTRrb2ZTbV9BLTA',
irb(main):019:2>         sg_message_id: 'LRzXl_NHStOGhQ4kofSm_A.filterdrecv-p3mdw1-756b745b58-kmzbl-18-5F5FC76C-9.0',
irb(main):020:2>         'smtp-id': '<LRzXl_NHStOGhQ4kofSm_A@ismtpd0039p1iad1.sendgrid.net>',
irb(main):021:2>         timestamp: 1_600_112_492
irb(main):022:2>       }
irb(main):023:1>     ].to_json}\r\n".freeze
=> "[{\"email\":\"hello@world.com\",\"event\":\"dropped\",\"reason\":\"Bounced Address\",\"sg_event_id\":\"ZHJvcC0xMDk5NDkxOS1MUnpYbF9OSFN0T0doUTRrb2ZTbV9BLTA\",\"sg_message_id\":\"LRzXl_NHStOGhQ4kofSm_A.filterdrecv-p3mdw1-756b745b58-kmzbl-18-5F5FC76C-9.0\",\"smtp-id\":\"\\u003cLRzXl_NHStOGhQ4kofSm_A@ismtpd0039p1iad1.sendgrid.net\\u003e\",\"timestamp\":1600112492}]\r\n"
irb(main):024:0> 
irb(main):025:0> ec_public_key = ew.convert_public_key_to_ecdsa(public_key)
=> #<OpenSSL::PKey::EC:0x00007faa52ab8160>
irb(main):026:0> 
irb(main):027:0> ew.verify_signature(ec_public_key, payload, signature, timestamp)
=> false
irb(main):028:0> 

Also this is my rspec that I was coding:

require "rails_helper"

ENV["SENDGRID_EVENT_HOOK_KEY"] = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEc1xJU2qhLFMxcOLdKWQIA2OZdmUTlNRT5xFEipLDnGkO0uhW8aJiIQxJGglBRiKWxNqm3jjRbUpaAaDH9WHkng==".freeze

describe Webhooks::SendgridController, type: "request" do
  describe "POST 'create'" do

    let(:example_sendrid_payload) do
      "#{[
        {
          email: 'hello@world.com',
          event: 'dropped',
          reason: 'Bounced Address',
          sg_event_id: 'ZHJvcC0xMDk5NDkxOS1MUnpYbF9OSFN0T0doUTRrb2ZTbV9BLTA',
          sg_message_id: 'LRzXl_NHStOGhQ4kofSm_A.filterdrecv-p3mdw1-756b745b58-kmzbl-18-5F5FC76C-9.0',
          'smtp-id': '<LRzXl_NHStOGhQ4kofSm_A@ismtpd0039p1iad1.sendgrid.net>',
          timestamp: 1_600_112_492
        }
      ].to_json}\r\n".freeze
    end

    let(:sendgrid_signed_header) do
      {
          "#{SendGrid::EventWebhookHeader::SIGNATURE}" => "MEYCIQCxfnpzX3CftRSaaA4wHWHOKEyHbCf5jbwL/z/QQpncqQIhANu8Ug7FTuQhgGzhSVQvDSIS64rp+fXz2AloRnV5qcTL".freeze,
          "#{SendGrid::EventWebhookHeader::TIMESTAMP}" => "1600112502".freeze
      }
    end

    it "responds with success when provided signature matches" do
      post webhooks_sendgrid_path, params: example_sendrid_payload, headers: sendgrid_signed_header

      expect(response).to have_http_status(200)
    end
end

Exception/Log

 1) Webhooks::SendgridController POST 'create' responds with success when provided signature matches
     Failure/Error: expect(response).to have_http_status(200)
       expected the response to have status code 200 but it was 401

Technical details:

  • sendgrid-ruby version: 6.3.8
  • ruby version: 2.6.5

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions