marcdel

marcdel

Validating webhook payloads from GitHub

I’m trying to validate github webhooks with a secret. The example documentation is in Ruby and I’m trying to figure out the corresponding Elixir. So far I have not been successful, but I’m not sure if it’s the decoding bit that’s wrong or if I’m using the wrong thing for the body.

My attempt:

  def create(conn, params) do
    [event_id] = get_req_header(conn, "x-github-delivery")
    [event_name] = get_req_header(conn, "x-github-event")

    verify_signature(conn)

    json(conn, %{success: true, message: "event received"})
  end

  def verify_signature(conn) do
    secret = "super secret"
    [signature] = get_req_header(conn, "x-hub-signature")

    body = inspect(Plug.Conn.read_body(conn))
    # {:ok, body, _conn} = Plug.Conn.read_body(conn)

    expected_signature =
      :crypto.hmac(:sha, secret, body)
      |> Base.encode16
      |> String.downcase()
      |> fn sig -> "sha1=" <> sig end.()

      unless Plug.Crypto.secure_compare(expected_signature, signature), do: raise "signature didn't match"
  end

Ruby:

post '/payload' do
  request.body.rewind
  payload_body = request.body.read
  verify_signature(payload_body)
  push = JSON.parse(params[:payload])
  "I got some JSON: #{push.inspect}"
end

def verify_signature(payload_body)
  signature = 'sha1=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), ENV['SECRET_TOKEN'], payload_body)
  return halt 500, "Signatures didn't match!" unless Rack::Utils.secure_compare(signature, request.env['HTTP_X_HUB_SIGNATURE'])
end

Marked As Solved

maartenvanvliet

maartenvanvliet

Might want to have a look at gh_webhook_plug | Hex and gh_webhook_plug/lib/gh_webhook_plug.ex at master · emilsoman/gh_webhook_plug · GitHub
in particular.

Also note that you need to call this plug before Plug.Parsers is called.

Also Liked

marcdel

marcdel

Ooooooh, that totally makes sense. I realized I must be getting to the body too late because it was already an elixir map, but didn’t really put two and two together. I’ll give that a shot tomorrow, thank you!

Last Post!

marcdel

marcdel

Ooooooh, that totally makes sense. I realized I must be getting to the body too late because it was already an elixir map, but didn’t really put two and two together. I’ll give that a shot tomorrow, thank you!

Where Next?

Popular in Questions Top

nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

Other popular topics Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 44167 214
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 42576 114
New

We're in Beta

About us Mission Statement