Skip to content

Commit

Permalink
feat: add fuzzing tests (#171)
Browse files Browse the repository at this point in the history
  • Loading branch information
btfhernandez authored Dec 5, 2024
1 parent c3dc9d5 commit 6d63ba2
Show file tree
Hide file tree
Showing 5 changed files with 251 additions and 0 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,12 @@ top
# go inside of function memory usage
list main.callPasswordSafeAPI
```

## Fuzzing Testing

Run Fuzz Tests

```bash
go test -fuzz=FuzzGetManagedAccount -fuzztime=10s ./fuzzing//managed_accounts
go test -fuzz=FuzzGetSecret -fuzztime=10s ./fuzzing/secrets
```
5 changes: 5 additions & 0 deletions api/managed_account/managed_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package managed_accounts
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"net/url"
Expand Down Expand Up @@ -54,6 +55,10 @@ func (managedAccountObj *ManagedAccountstObj) ManageAccountFlow(secretsToRetriev
secretDictionary := make(map[string]string)
var saveLastErr error = nil

if len(secretsToRetrieve) == 0 {
return secretDictionary, errors.New("empty managed account list")
}

for _, secretToRetrieve := range secretsToRetrieve {
retrievalData := strings.Split(secretToRetrieve, separator)
systemName := retrievalData[0]
Expand Down
4 changes: 4 additions & 0 deletions api/secrets/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ func (secretObj *SecretObj) GetSecretFlow(secretsToRetrieve []string, separator
secretDictionary := make(map[string]string)
var saveLastErr error = nil

if len(secretsToRetrieve) == 0 {
return secretDictionary, errors.New("empty secret list")
}

for _, secretToRetrieve := range secretsToRetrieve {
retrievalData := strings.Split(secretToRetrieve, separator)
secretTitle := retrievalData[len(retrievalData)-1]
Expand Down
123 changes: 123 additions & 0 deletions fuzzing/managed_accounts/get_managed_accounts_fuzz_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package fuzzing_managed_account

import (
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"time"

"github.com/BeyondTrust/go-client-library-passwordsafe/api/authentication"
"github.com/BeyondTrust/go-client-library-passwordsafe/api/logging"
managed_accounts "github.com/BeyondTrust/go-client-library-passwordsafe/api/managed_account"
"github.com/BeyondTrust/go-client-library-passwordsafe/api/utils"
backoff "github.com/cenkalti/backoff/v4"
"go.uber.org/zap"
)

type TestConfig struct {
name string
server *httptest.Server
response string
}

func FuzzGetManagedAccount(f *testing.F) {

testConfig := TestConfig{
name: "FuzzGetManagedAccount",
server: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Mocking Response according to the endpoint path
switch r.URL.Path {

case "/Auth/SignAppin":
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"Felipe"}`))
if err != nil {
f.Error("Test case Failed")
}

case "/Auth/Signout":
_, err := w.Write([]byte(``))
if err != nil {
f.Error("Test case Failed")
}

case "/ManagedAccounts":
_, err := w.Write([]byte(`{"SystemId":1,"AccountId":10}`))
if err != nil {
f.Error("Test case Failed")
}

case "/Requests":
_, err := w.Write([]byte(`124`))
if err != nil {
f.Error("Test case Failed")
}

case "/Credentials/124":
_, err := w.Write([]byte(`"fake_credential"`))
if err != nil {
f.Error("Test case Failed")
}

case "/Requests/124/checkin":
_, err := w.Write([]byte(``))
if err != nil {
f.Error("Test case Failed")
}

default:
http.NotFound(w, r)
}
})),
response: "fake_credential",
}

logger, _ := zap.NewDevelopment()

// create a zap logger wrapper
zapLogger := logging.NewZapLogger(logger)

httpClientObj, _ := utils.GetHttpClient(5, false, "", "", zapLogger)

backoffDefinition := backoff.NewExponentialBackOff()
backoffDefinition.MaxElapsedTime = time.Second

// instantiating authenticate obj, injecting httpClient object
var authenticate, _ = authentication.Authenticate(*httpClientObj, backoffDefinition, "https://fake.api.com:443/BeyondTrust/api/public/v3/", "fakeone_a654+9sdf7+8we4f", "fakeone_aasd156465sfdef", zapLogger, 300)

apiUrl, _ := url.Parse(testConfig.server.URL + "/")
authenticate.ApiUrl = *apiUrl

// instantiating managed account obj
manageAccountObj, _ := managed_accounts.NewManagedAccountObj(*authenticate, zapLogger)

f.Add("fake1/account01", "/")
f.Add("fake2/account02", "#")
f.Add("fake3/account03", "*")
f.Add("fake4/account04", "-")
f.Add("fake5/account05", "/")

f.Add("fake6/account06/test/test", "*//")
f.Add("fake6/account06", "_")
f.Add("fake6/account06/test/test", "*//***************")

f.Fuzz(func(t *testing.T, a string, b string) {

managedAccount, err := manageAccountObj.GetSecret(a, b)
if err != nil {
if !strings.Contains(err.Error(), "empty managed account list") {
t.Errorf("Unexpected error: %s", err.Error())
}
}

if err != nil && managedAccount != "" {
t.Errorf("Unexpected error: %s", err.Error())
}

})

// signing out
_ = authenticate.SignOut()

}
110 changes: 110 additions & 0 deletions fuzzing/secrets/get_secrets_fuzz_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package fuzzing_secrets

import (
"net/http"
"net/http/httptest"
"net/url"
"testing"
"time"

"github.com/BeyondTrust/go-client-library-passwordsafe/api/authentication"
"github.com/BeyondTrust/go-client-library-passwordsafe/api/logging"
"github.com/BeyondTrust/go-client-library-passwordsafe/api/secrets"
"github.com/BeyondTrust/go-client-library-passwordsafe/api/utils"

"go.uber.org/zap"

backoff "github.com/cenkalti/backoff/v4"
)

type TestConfig struct {
name string
server *httptest.Server
response string
}

func FuzzGetSecret(f *testing.F) {

testConfig := TestConfig{
name: "FuzzGetSecret",
server: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Mocking Response according to the endpoint path
switch r.URL.Path {

case "/Auth/SignAppin":
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"Felipe"}`))
if err != nil {
f.Error("Test case Failed")
}

case "/Auth/Signout":
_, err := w.Write([]byte(``))
if err != nil {
f.Error("Test case Failed")
}

case "/secrets-safe/secrets":
_, err := w.Write([]byte(`[{"SecretType": "TEXT", "Password": "credential_in_sub_3_password","Id": "9152f5b6-07d6-4955-175a-08db047219ce","Title": "credential_in_sub_3"}]`))
if err != nil {
f.Error("Test case Failed")
}

case "/secrets-safe/secrets/9152f5b6-07d6-4955-175a-08db047219ce/file/download":
_, err := w.Write([]byte(`fake_password`))
if err != nil {
f.Error("Test case Failed")
}

default:
http.NotFound(w, r)
}
})),
response: "fake_password",
}

logger, _ := zap.NewDevelopment()

// create a zap logger wrapper
zapLogger := logging.NewZapLogger(logger)

httpClientObj, _ := utils.GetHttpClient(5, false, "", "", zapLogger)

backoffDefinition := backoff.NewExponentialBackOff()
backoffDefinition.MaxElapsedTime = time.Second

// instantiating authenticate obj, injecting httpClient object
var authenticate, _ = authentication.Authenticate(*httpClientObj, backoffDefinition, "https://fake.api.com:443/BeyondTrust/api/public/v3/", "fakeone_a654+9sdf7+8we4f", "fakeone_aasd156465sfdef", zapLogger, 300)

apiUrl, _ := url.Parse(testConfig.server.URL + "/")
authenticate.ApiUrl = *apiUrl
secretObj, _ := secrets.NewSecretObj(*authenticate, zapLogger, 4000)

f.Add("fake/Test1", "/")
f.Add("fake/Test2", "*")
f.Add("fake/Test3", "-")
f.Add("fake/Test4", "+")

f.Add("fake1/Test1/Test4", "//")
f.Add("fake1/Test2/Test5", "")
f.Add("fake1/Test1/Test4/Test5/Title", "-")
f.Add("fake1/Test4", "+")

f.Fuzz(func(t *testing.T, a string, b string) {

secret, err := secretObj.GetSecret(a, b)
if err != nil {
if err.Error() != "empty secret list" {
t.Errorf("Unexpected error: %s", err.Error())
}

if err != nil && secret != "" {
t.Errorf("Unexpected error: %s", err.Error())
}
}

})

// signing out
_ = authenticate.SignOut()

}

0 comments on commit 6d63ba2

Please sign in to comment.