Skip to content

Commit

Permalink
Merge pull request #306 from pjbgf/fuzz
Browse files Browse the repository at this point in the history
Add fuzz testing for notifiers
  • Loading branch information
stefanprodan committed Jan 12, 2022
2 parents 0ece498 + 4f111d2 commit 2a728b0
Show file tree
Hide file tree
Showing 26 changed files with 1,109 additions and 6 deletions.
27 changes: 27 additions & 0 deletions .github/workflows/cifuzz.yaml
@@ -0,0 +1,27 @@
name: CIFuzz
on:
pull_request:
branches:
- main
jobs:
Fuzzing:
runs-on: ubuntu-latest
steps:
- name: Build Fuzzers
id: build
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
with:
oss-fuzz-project-name: 'fluxcd'
language: go
- name: Run Fuzzers
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
with:
oss-fuzz-project-name: 'fluxcd'
language: go
fuzz-seconds: 60
- name: Upload Crash
uses: actions/upload-artifact@v1
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts
path: ./out/artifacts
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -17,3 +17,5 @@
bin/
config/release/
config/crd/bases/gitrepositories.yaml

build/
21 changes: 21 additions & 0 deletions Makefile
Expand Up @@ -136,3 +136,24 @@ API_REF_GEN=$(GOBIN)/gen-crd-api-reference-docs
else
API_REF_GEN=$(shell which gen-crd-api-reference-docs)
endif

# Build fuzzers
fuzz-build:
rm -rf $(shell pwd)/build/fuzz/
mkdir -p $(shell pwd)/build/fuzz/out/

docker build . --tag local-fuzzing:latest -f tests/fuzz/Dockerfile.builder
docker run --rm -it \
-e FUZZING_LANGUAGE=go -e FUZZ_SECONDS=600 -e MODE=batch \
-e CIFUZZ_DEBUG='True' -e OSS_FUZZ_PROJECT_NAME=fluxcd \
-e SANITIZER=address \
-v "$(shell pwd)/build/fuzz/out":/out \
local-fuzzing:latest

# Run each fuzzer once to ensure they are working
fuzz-smoketest: fuzz-build
docker run --rm -ti \
-v "$(shell pwd)/build/fuzz/out":/out \
-v "$(shell pwd)/tests/fuzz/oss_fuzz_run.sh":/runner.sh \
gcr.io/oss-fuzz/fluxcd \
bash -c "/runner.sh"
5 changes: 3 additions & 2 deletions go.mod
Expand Up @@ -36,7 +36,7 @@ require (
)

require (
cloud.google.com/go v0.81.0 // indirect
cloud.google.com/go v0.97.0 // indirect
github.com/Azure/azure-sdk-for-go v53.4.0+incompatible // indirect
github.com/Azure/go-amqp v0.13.6 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
Expand Down Expand Up @@ -98,14 +98,15 @@ require (
go.uber.org/zap v1.19.1 // indirect
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
golang.org/x/net v0.0.0-20211215060638-4ddde0e984e9 // indirect
golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8 // indirect
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08 // indirect
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
Expand Down
60 changes: 56 additions & 4 deletions go.sum

Large diffs are not rendered by default.

File renamed without changes.
6 changes: 6 additions & 0 deletions tests/fuzz/Dockerfile.builder
@@ -0,0 +1,6 @@
FROM gcr.io/oss-fuzz-base/base-builder-go

COPY ./ $GOPATH/src/github.com/fluxcd/notification-controller/
COPY ./tests/fuzz/oss_fuzz_build.sh $SRC/build.sh

WORKDIR $SRC
54 changes: 54 additions & 0 deletions tests/fuzz/alertmanager_fuzzer.go
@@ -0,0 +1,54 @@
//go:build gofuzz
// +build gofuzz

/*
Copyright 2022 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package notifier

import (
"io"
"net/http"
"net/http/httptest"

fuzz "github.com/AdaLogics/go-fuzz-headers"
"github.com/fluxcd/pkg/runtime/events"
)

// FuzzAlertmanager implements a fuzzer that targets Alertmanager.Post().
func FuzzAlertmanager(data []byte) int {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
io.ReadAll(r.Body)
r.Body.Close()
}))
defer ts.Close()

alertmanager, err := NewAlertmanager(ts.URL, "", nil)
if err != nil {
return 0
}

f := fuzz.NewConsumer(data)
event := events.Event{}

if err := f.GenerateStruct(&event); err != nil {
return 0
}

_ = alertmanager.Post(event)

return 1
}
58 changes: 58 additions & 0 deletions tests/fuzz/azure_devops_fuzzer.go
@@ -0,0 +1,58 @@
//go:build gofuzz
// +build gofuzz

/*
Copyright 2022 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package notifier

import (
"io"
"net/http"
"net/http/httptest"

fuzz "github.com/AdaLogics/go-fuzz-headers"
"github.com/fluxcd/pkg/runtime/events"
)

// FuzzAzureDevOps implements a fuzzer that targets AzureDevOps.Post().
func FuzzAzureDevOps(data []byte) int {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
io.ReadAll(r.Body)
r.Body.Close()
}))
defer ts.Close()

f := fuzz.NewConsumer(data)
token, err := f.GetString()
if err != nil {
return 0
}

azureDevOps, err := NewAzureDevOps(ts.URL, token, nil)
if err != nil {
return 0
}

event := events.Event{}
if err := f.GenerateStruct(&event); err != nil {
return 0
}

_ = azureDevOps.Post(event)

return 1
}
58 changes: 58 additions & 0 deletions tests/fuzz/bitbucket_fuzzer.go
@@ -0,0 +1,58 @@
//go:build gofuzz
// +build gofuzz

/*
Copyright 2022 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package notifier

import (
"io"
"net/http"
"net/http/httptest"

fuzz "github.com/AdaLogics/go-fuzz-headers"
"github.com/fluxcd/pkg/runtime/events"
)

// FuzzBitbucket implements a fuzzer that targets Bitbucket.Post().
func FuzzBitbucket(data []byte) int {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
io.ReadAll(r.Body)
r.Body.Close()
}))
defer ts.Close()

f := fuzz.NewConsumer(data)
token, err := f.GetString()
if err != nil {
return 0
}

bitbucket, err := NewBitbucket(ts.URL, token, nil)
if err != nil {
return 0
}

event := events.Event{}
if err := f.GenerateStruct(&event); err != nil {
return 0
}

_ = bitbucket.Post(event)

return 1
}
63 changes: 63 additions & 0 deletions tests/fuzz/discord_fuzzer.go
@@ -0,0 +1,63 @@
//go:build gofuzz
// +build gofuzz

/*
Copyright 2022 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package notifier

import (
"io"
"net/http"
"net/http/httptest"

fuzz "github.com/AdaLogics/go-fuzz-headers"
"github.com/fluxcd/pkg/runtime/events"
)

// FuzzDiscord implements a fuzzer that targets Discord.Post().
func FuzzDiscord(data []byte) int {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
io.ReadAll(r.Body)
r.Body.Close()
}))
defer ts.Close()

f := fuzz.NewConsumer(data)
username, err := f.GetString()
if err != nil {
return 0
}

channel, err := f.GetString()
if err != nil {
return 0
}

discord, err := NewDiscord(ts.URL, "", username, channel)
if err != nil {
return 0
}

event := events.Event{}
if err := f.GenerateStruct(&event); err != nil {
return 0
}

_ = discord.Post(event)

return 1
}
54 changes: 54 additions & 0 deletions tests/fuzz/forwarder_fuzzer.go
@@ -0,0 +1,54 @@
//go:build gofuzz
// +build gofuzz

/*
Copyright 2022 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package notifier

import (
"io"
"net/http"
"net/http/httptest"

fuzz "github.com/AdaLogics/go-fuzz-headers"
"github.com/fluxcd/pkg/runtime/events"
)

// FuzzForwarder implements a fuzzer that targets Forwarder.Post().
func FuzzForwarder(data []byte) int {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
io.ReadAll(r.Body)
r.Body.Close()
}))
defer ts.Close()

forwarder, err := NewForwarder(ts.URL, "", nil)
if err != nil {
return 0
}

f := fuzz.NewConsumer(data)
event := events.Event{}

if err := f.GenerateStruct(&event); err != nil {
return 0
}

_ = forwarder.Post(event)

return 1
}

0 comments on commit 2a728b0

Please sign in to comment.