M
M
midia212021-10-22 14:55:47
go
midia21, 2021-10-22 14:55:47

How to allow calling api controller to only one server by ip (which sends a webhook)?

I am writing a small project in golang. In this project, a webhook is subscribed, which, upon a certain event, sends a request to the url specified when registering the hook. Basically a security issue. How do I make it so that only the server sending the webhook can access my webhook controller. After all, potentially, if you don’t think about it, anyone can send myserver / webhook-handler via postman and inject left data.

The github manuals (I just came across a description of working with their webhooks) describe a good way to solve the problem: when registering a webhook, send a secret key that will come to my controller with a payload every time the hook fires. This key will also be stored on my server, and then you can simply check the one that came and the one that is available.
https://docs.github.com/en/developers/webhooks-and...

However, there is one problem - the api I am working with does not support secret keys. Does anyone know of other ways to solve this problem? Thanks in advance.

PS Also, the github manuals describe another option - to give access to the handler only to certain IP addresses. But I have no idea how to implement it in order to avoid address forgery. Is it configured on the webserver side (eg Apache) or directly in the code? I would also be happy with examples in any languages.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
E
Evgeny Mamonov, 2021-10-22
@midia21

Most often, in such cases, they use a secret key, which is passed either in the request parameters (it’s better not to do this, because the secret key will be visible in the logs of intermediate proxies and servers) or in the HTTP header (this option is safer than passing in request parameters).
Less commonly used option with a digital signature of the request. This option is significantly more secure than passing the private key in the clear. With this option, you not only know that the request was sent by the server you need, but also that the request was not modified by anyone (for example, by a proxy server).
But both of these options require refinement on the part of the server sending the request.
As far as I understand, this option is not available to you.
In principle, the option of protection by IP address is quite normal.
The easiest way is to set up a firewall, i.e. block access to your service for everyone and open only for the IP of the server that makes requests.
If the firewall option is not suitable, you can provide protection on the Go side.
IP can be obtained from an HTTP request https://pkg.go.dev/net/http#Request
Here is a finished example

package main

import (
    "fmt"
    "log"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Your IP is %s", r.RemoteAddr)
}

func main() {
    http.HandleFunc("/", handler)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

Sometimes (depending on the web server settings) the real IP can come in HTTP request headers
ip := r.Header.Get("X-Forwarded-For")
// или
ip := r.Header.Get("X-Real-IP")

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question