Add env sanitation
Sanitize the environment variables when running webhooks and add ability to add custom environment variables per webhook.
This commit is contained in:
parent
a4e21288db
commit
46418bcf3a
2
Makefile
2
Makefile
|
@ -1,6 +1,8 @@
|
|||
default: all
|
||||
all: weblug
|
||||
|
||||
.PHONY: test
|
||||
|
||||
weblug: cmd/weblug/*.go
|
||||
go build -o weblug $^
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ type Hook struct {
|
|||
AllowAddresses []string `yaml:"allowed"` // Addresses that are explicitly allowed
|
||||
BlockedAddresses []string `yaml:"blocked"` // Addresses that are explicitly blocked
|
||||
HttpBasicAuth BasicAuth `yaml:"basic_auth"` // Optional requires http basic auth
|
||||
Env map[string]string `yaml:"env"` // Optional environment variables
|
||||
}
|
||||
|
||||
type BasicAuth struct {
|
||||
|
@ -89,6 +90,13 @@ func (hook *Hook) Run() error {
|
|||
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
||||
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(hook.UID), Gid: uint32(hook.GID)}
|
||||
}
|
||||
cmd.Env = make([]string, 0)
|
||||
if hook.Env != nil {
|
||||
// Build environment variable list as expected by cmd.Env
|
||||
for k, v := range hook.Env {
|
||||
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
}
|
||||
if hook.Output {
|
||||
buf, ret := cmd.Output()
|
||||
fmt.Println(string(buf))
|
||||
|
|
12
doc/weblug.8
12
doc/weblug.8
|
@ -1,6 +1,6 @@
|
|||
." Manpage for weblug
|
||||
." Contact felix@feldspaten.org to correct errors and/or typos.
|
||||
.TH weblug 8 "27 Apr 2023" "1.0" "weblug man page"
|
||||
." Write me an email <felix@feldspaten.org> if you find errors and/or typos. Thank you! :-)
|
||||
.TH weblug 8 "28 May 2023" "1.0" "weblug man page"
|
||||
.SH NAME
|
||||
weblug - Simple webhook receiver program
|
||||
|
||||
|
@ -52,6 +52,14 @@ See the following example configuration file:
|
|||
.br
|
||||
.B " concurrency: 2 # At most 2 parallel processes are allowed
|
||||
.br
|
||||
.B " env: # Define environment variables
|
||||
.br
|
||||
.B " KEY1: "VALUE1"
|
||||
.br
|
||||
.B " KEY2: "VALUE2"
|
||||
.br
|
||||
.br
|
||||
.br
|
||||
.br
|
||||
.B " - name: 'hook two'
|
||||
.br
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
#!/bin/bash -ex
|
||||
# Blackbox tests for weblug
|
||||
|
||||
cleanup() {
|
||||
|
@ -14,6 +14,8 @@ if [[ $EUID != 0 && $UID != 0 ]]; then
|
|||
sleep 3
|
||||
fi
|
||||
|
||||
# Secret environment variable, which must be removed by env sanitation.
|
||||
export SECRET1="top5ecret"
|
||||
|
||||
rm -f testfile
|
||||
../weblug test.yaml &
|
||||
|
@ -23,7 +25,7 @@ sleep 1
|
|||
|
||||
echo -e "\n\nChecking 'testfile' webhook ... "
|
||||
|
||||
curl http://127.0.0.1:2088/webhooks/touch
|
||||
curl --fail http://127.0.0.1:2088/webhooks/touch
|
||||
if [[ ! -f testfile ]]; then
|
||||
echo "Testfile doesn't exist after running webhook touch"
|
||||
exit 1
|
||||
|
@ -34,15 +36,15 @@ rm -f testfile
|
|||
|
||||
echo -e "\n\nChecking 'background' webhook ... "
|
||||
|
||||
timeout 2 curl http://127.0.0.1:2088/webhooks/background
|
||||
timeout 2 curl --fail http://127.0.0.1:2088/webhooks/background
|
||||
|
||||
## Check concurrency webhook, that allows only 2 requests at the same time (but sleeps for 5 seconds)
|
||||
|
||||
echo -e "\n\nChecking 'concurrency' webhook ... "
|
||||
|
||||
timeout 10 curl http://127.0.0.1:2088/3 &
|
||||
timeout 10 curl http://127.0.0.1:2088/3 &
|
||||
! timeout 2 curl http://127.0.0.1:2088/3
|
||||
timeout 10 curl --fail http://127.0.0.1:2088/3 &
|
||||
timeout 10 curl --fail http://127.0.0.1:2088/3 &
|
||||
! timeout 2 curl --fail http://127.0.0.1:2088/3
|
||||
|
||||
## Check UID and GID webhooks, but only if we're root
|
||||
|
||||
|
@ -50,10 +52,15 @@ echo -e "\n\nChecking 'uid/gid' webhook ... "
|
|||
|
||||
# Skip this test, if we're not root
|
||||
if [[ $EUID == 0 || $UID == 0 ]]; then
|
||||
curl http://127.0.0.1:2088/webhooks/uid
|
||||
curl http://127.0.0.1:2088/webhooks/gid
|
||||
curl --fail http://127.0.0.1:2088/webhooks/uid
|
||||
curl --fail http://127.0.0.1:2088/webhooks/gid
|
||||
else
|
||||
echo "Cannot UID and GID webhook tests, because we're not running as root"
|
||||
fi
|
||||
|
||||
## Check environment variables
|
||||
|
||||
|
||||
timeout 10 curl --fail 'http://127.0.0.1:2088/env'
|
||||
|
||||
echo -e "\n\nall good"
|
||||
|
|
30
test/checkenv
Executable file
30
test/checkenv
Executable file
|
@ -0,0 +1,30 @@
|
|||
#!/bin/bash -e
|
||||
# Script to test for environment variable sanitation
|
||||
|
||||
set -o pipefail
|
||||
|
||||
if [[ $PUBLIC1 != "one" ]]; then
|
||||
echo "PUBLIC1 variable not valid"
|
||||
exit 1
|
||||
fi
|
||||
if [[ $PUBLIC2 != "two" ]]; then
|
||||
echo "PUBLIC2 variable not valid"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if env | grep 'SECRET1' >/dev/null; then
|
||||
echo "SECRET1 variable is set but it should not be"
|
||||
echo "Environment sanitation failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# There must never be more than 10 variables set
|
||||
# Some variables will be set by bash at startup (e.g. PWD), so we are never in a
|
||||
# pristine environment. However, more than 10 variables indicates something's off
|
||||
# with the env sanitation
|
||||
if [[ `env | wc -l` -ge 10 ]]; then
|
||||
echo "More than 10 env variables detected"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "all good"
|
|
@ -25,3 +25,10 @@ hooks:
|
|||
uid: 10
|
||||
gid: 10
|
||||
output: True
|
||||
- name: 'environment variables'
|
||||
route: '/env'
|
||||
command: "bash ./checkenv"
|
||||
output: True
|
||||
env:
|
||||
PUBLIC1: "one"
|
||||
PUBLIC2: "two"
|
||||
|
|
|
@ -13,6 +13,9 @@ hooks:
|
|||
command: "sleep 5"
|
||||
background: True # Terminate http request immediately
|
||||
concurrency: 2 # At most 2 parallel processes are allowed
|
||||
env: # Define environment variables
|
||||
KEY1: "VALUE1"
|
||||
KEY2: "VALUE2"
|
||||
|
||||
- name: 'hook two'
|
||||
route: "/webhooks/2"
|
||||
|
|
Loading…
Reference in a new issue