From 17e9659f196ac35bae81238c6637d14f821701d2 Mon Sep 17 00:00:00 2001 From: Benjamin Gutierrez Date: Sun, 23 Jul 2023 17:07:49 -0400 Subject: [PATCH 01/10] demo-oneplatform --- main.go | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index 4311ce4..56b34cb 100644 --- a/main.go +++ b/main.go @@ -2,8 +2,10 @@ package main import ( "context" + "database/sql" "encoding/json" "errors" + "fmt" "log" "net/http" "os" @@ -13,6 +15,7 @@ import ( "github.com/google/uuid" "github.com/gorilla/mux" "github.com/gorilla/websocket" + _ "github.com/mattn/go-sqlite3" ) type Weather struct { @@ -29,7 +32,18 @@ var upgrader = websocket.Upgrader{ WriteBufferSize: 1024, } +type User struct { + Email string `json:"email"` + Password string `json:"password"` +} + +var db *sql.DB + func main() { + // Connect to the database + db, _ = sql.Open("sqlite3", "./weather.db") + createTable() + // Create a context that we can cancel ctx, cancel := context.WithCancel(context.Background()) @@ -70,6 +84,21 @@ func main() { log.Println("Server stopped") } +// Create table if it doesn't exist +func createTable() { + query := `CREATE TABLE IF NOT EXISTS weathers ( + id TEXT PRIMARY KEY, + city TEXT, + temperature REAL, + conditions TEXT + );` + + _, err := db.Exec(query) + if err != nil { + log.Fatal(err) + } +} + func createWeather(w http.ResponseWriter, r *http.Request) { var newWeather Weather err := json.NewDecoder(r.Body).Decode(&newWeather) @@ -84,9 +113,17 @@ func createWeather(w http.ResponseWriter, r *http.Request) { return } - // Here we generate a new unique ID newWeather.ID = uuid.New().String() - WeatherDB[newWeather.ID] = newWeather + + // Dangerous SQL query, opening for SQL injection + query := fmt.Sprintf("INSERT INTO weathers (id, city, temperature, conditions) VALUES ('%s', '%s', %f, '%s')", + newWeather.ID, newWeather.City, newWeather.Temperature, newWeather.Conditions) + + _, err = db.Exec(query) + if err != nil { + http.Error(w, "Error executing SQL query", http.StatusInternalServerError) + return + } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) // Set the status before encoding the body From 4dc9fb146d7b3340f7a191a2db2c37cd92ea4828 Mon Sep 17 00:00:00 2001 From: Benjamin Gutierrez Date: Sun, 23 Jul 2023 17:17:46 -0400 Subject: [PATCH 02/10] demo-oneplatform --- go.mod | 1 + go.sum | 2 ++ main.go | 1 + main_test.go | 17 +++++++++++++++++ weather_test.db | Bin 0 -> 12288 bytes 5 files changed, 21 insertions(+) create mode 100644 weather_test.db diff --git a/go.mod b/go.mod index 28c3c67..7eacbc9 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/google/uuid v1.3.0 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect + github.com/mattn/go-sqlite3 v1.14.17 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/stretchr/testify v1.8.4 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index d10116b..a0ead33 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,8 @@ github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= +github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= diff --git a/main.go b/main.go index 56b34cb..2f307b9 100644 --- a/main.go +++ b/main.go @@ -114,6 +114,7 @@ func createWeather(w http.ResponseWriter, r *http.Request) { } newWeather.ID = uuid.New().String() + WeatherDB[newWeather.ID] = newWeather // Dangerous SQL query, opening for SQL injection query := fmt.Sprintf("INSERT INTO weathers (id, city, temperature, conditions) VALUES ('%s', '%s', %f, '%s')", diff --git a/main_test.go b/main_test.go index 766fc40..9edaa14 100644 --- a/main_test.go +++ b/main_test.go @@ -2,15 +2,32 @@ package main import ( "bytes" + "database/sql" "encoding/json" + "log" "net/http" "net/http/httptest" + "os" "testing" "github.com/gorilla/mux" "github.com/stretchr/testify/assert" ) +func TestMain(m *testing.M) { + var err error + db, err = sql.Open("sqlite3", "./weather_test.db") + if err != nil { + log.Fatal(err) + } + createTable() + + code := m.Run() + + db.Close() + os.Exit(code) +} + func TestCreateWeather(t *testing.T) { router := mux.NewRouter() router.HandleFunc("/weather", createWeather).Methods("POST") diff --git a/weather_test.db b/weather_test.db new file mode 100644 index 0000000000000000000000000000000000000000..9060caf78bcaac908357d168b10bb5386047ccf4 GIT binary patch literal 12288 zcmeI$F;Buk6bJCTqGCx%-H1bz+tkFWKmj{RZ8{h+Q7nl}q|j@u0jlj0Ws^_l=<4W4 zarD}xGme=2U+!}6-Cf)Cx82>}^&-Jp7$-AduqN3fl#(uEgb+pclI%rLnQRq>9J6{| zDCFentE&AFMRSPeXrJpIz&ZpV009U<00Izz00bZa0SG`~Lj_ipmTS6BR|DaXr~H-s z;*lq5F)B{qwLO=4_GQmy#Vk9lsA?22&wcRNZU5@V?ho0uJ3N-tlSnM{g{%;K_RJGs zEE3M-i+cHncpgL|isxy*t)d>CDmyhtrzDyO{4IT%$}|1QUx+xbN5w}+^&-p8^}Cs8 zRd%X<5ZMqAfB*y_009U<00Izz00bZa0SIiSzy;kN=;i%-qa8L{{M={<ydb7F?3$5Y|Rn}x3Vp8tz8jTgbPB6F&J6WI_DfB*y_009U<00Izz00bZa Q0SNpvfrHXO{mZSuFA#2EB>(^b literal 0 HcmV?d00001 From aafc0b6293165059732b44cb0634f344bd816b68 Mon Sep 17 00:00:00 2001 From: Benjamin Gutierrez Date: Sun, 23 Jul 2023 17:28:27 -0400 Subject: [PATCH 03/10] demo-oneplatform --- go.mod | 1 + go.sum | 2 ++ main.go | 7 ++++--- weather_test.db | Bin 12288 -> 12288 bytes 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 7eacbc9..1fc04b5 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/mattn/go-sqlite3 v1.14.17 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/stretchr/testify v1.8.4 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index a0ead33..08f501f 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,8 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= diff --git a/main.go b/main.go index 2f307b9..d6fa6e1 100644 --- a/main.go +++ b/main.go @@ -16,6 +16,7 @@ import ( "github.com/gorilla/mux" "github.com/gorilla/websocket" _ "github.com/mattn/go-sqlite3" + pkgErrors "github.com/pkg/errors" // Aliased ) type Weather struct { @@ -109,14 +110,14 @@ func createWeather(w http.ResponseWriter, r *http.Request) { err = newWeather.Validate() if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return + // Wrap error with stack trace + err = pkgErrors.Wrap(err, "Error executing SQL query") + http.Error(w, fmt.Sprintf("%+v", err), http.StatusInternalServerError) // return error string with stack trace } newWeather.ID = uuid.New().String() WeatherDB[newWeather.ID] = newWeather - // Dangerous SQL query, opening for SQL injection query := fmt.Sprintf("INSERT INTO weathers (id, city, temperature, conditions) VALUES ('%s', '%s', %f, '%s')", newWeather.ID, newWeather.City, newWeather.Temperature, newWeather.Conditions) diff --git a/weather_test.db b/weather_test.db index 9060caf78bcaac908357d168b10bb5386047ccf4..2b2dc2a9e0678b47ac8b883fd8521dbd329375c4 100644 GIT binary patch delta 161 zcmZojXh@hK&B#1a#+i|MW5N=C4krFO2LAp0b(;kRiufJvnOH+**(FobEYecV5>s^z zOp+~iO$;ndbuCTJlXZ;}lPppbjZI7vlafPHi%Xm{ODY{q8W=#pIVZm~rE>Cqc~_vB c>lyfO@UI7&xtL#5gE^Fu7z3Fm-_X|p0KNn)Pyhe` delta 55 zcmZojXh@hK&B!!S#+i|6W5N=CHb(ya4E*~y3o6XxpV%NidB40XQ0N8&{|%^+!Q>nI F8UWR75upG8 From 1b7d6ea0444397210f75b6faad9b336e19cf60ce Mon Sep 17 00:00:00 2001 From: Benjamin Gutierrez Date: Sun, 23 Jul 2023 17:32:47 -0400 Subject: [PATCH 04/10] demo-oneplatform --- .github/workflows/mapi.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/mapi.yml b/.github/workflows/mapi.yml index a922171..5b81f30 100644 --- a/.github/workflows/mapi.yml +++ b/.github/workflows/mapi.yml @@ -44,6 +44,7 @@ jobs: sarif-report: mapi.sarif html-report: mapi.html target: bengutierrez/demo-oneplatform/mapi # change to forallsecure/demo-oneplatform/mapi + timeout: 300 # Kill if it's still running, ignoring any errors - name: Shut down API From e923412ab004d053aec4fa9e5ccebbb25d07fc8c Mon Sep 17 00:00:00 2001 From: Benjamin Gutierrez Date: Sun, 23 Jul 2023 17:33:28 -0400 Subject: [PATCH 05/10] demo-oneplatform --- main.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/main.go b/main.go index d6fa6e1..2f307b9 100644 --- a/main.go +++ b/main.go @@ -16,7 +16,6 @@ import ( "github.com/gorilla/mux" "github.com/gorilla/websocket" _ "github.com/mattn/go-sqlite3" - pkgErrors "github.com/pkg/errors" // Aliased ) type Weather struct { @@ -110,14 +109,14 @@ func createWeather(w http.ResponseWriter, r *http.Request) { err = newWeather.Validate() if err != nil { - // Wrap error with stack trace - err = pkgErrors.Wrap(err, "Error executing SQL query") - http.Error(w, fmt.Sprintf("%+v", err), http.StatusInternalServerError) // return error string with stack trace + http.Error(w, err.Error(), http.StatusBadRequest) + return } newWeather.ID = uuid.New().String() WeatherDB[newWeather.ID] = newWeather + // Dangerous SQL query, opening for SQL injection query := fmt.Sprintf("INSERT INTO weathers (id, city, temperature, conditions) VALUES ('%s', '%s', %f, '%s')", newWeather.ID, newWeather.City, newWeather.Temperature, newWeather.Conditions) From 1ae3c003830be6e852adc01438610cbff61e2a17 Mon Sep 17 00:00:00 2001 From: Benjamin Gutierrez Date: Sun, 23 Jul 2023 17:36:28 -0400 Subject: [PATCH 06/10] demo-oneplatform --- Mayhemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mayhemfile b/Mayhemfile index c17bfb1..3be3326 100644 --- a/Mayhemfile +++ b/Mayhemfile @@ -1,4 +1,4 @@ -image: ghcr.io/unionfindbee/demo-oneplatform:latest +image: ghcr.io/unionfindbee/demo-oneplatform:vulnerable duration: 60 project: bengutierrez/demo-oneplatform target: mcode From 9bb6f2e8846023719bd127d3500277ffa6b799dd Mon Sep 17 00:00:00 2001 From: Benjamin Gutierrez Date: Sun, 23 Jul 2023 17:41:04 -0400 Subject: [PATCH 07/10] demo-oneplatform --- .github/workflows/mapi.yml | 1 - main.go | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/mapi.yml b/.github/workflows/mapi.yml index 5b81f30..a922171 100644 --- a/.github/workflows/mapi.yml +++ b/.github/workflows/mapi.yml @@ -44,7 +44,6 @@ jobs: sarif-report: mapi.sarif html-report: mapi.html target: bengutierrez/demo-oneplatform/mapi # change to forallsecure/demo-oneplatform/mapi - timeout: 300 # Kill if it's still running, ignoring any errors - name: Shut down API diff --git a/main.go b/main.go index 2f307b9..df1d57d 100644 --- a/main.go +++ b/main.go @@ -122,7 +122,7 @@ func createWeather(w http.ResponseWriter, r *http.Request) { _, err = db.Exec(query) if err != nil { - http.Error(w, "Error executing SQL query", http.StatusInternalServerError) + http.Error(w, "Error executing SQL query: "+err.Error(), http.StatusInternalServerError) return } From 6f10b7ff485f3349b1efd0ae827daf9a5c970622 Mon Sep 17 00:00:00 2001 From: Benjamin Gutierrez Date: Sun, 23 Jul 2023 17:46:47 -0400 Subject: [PATCH 08/10] demo-oneplatform --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 750d65b..a32e6f4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ RUN go mod download COPY main.go . # Build the Go app -RUN CGO_ENABLED=0 GOOS=linux go build -a -o app main.go +RUN CGO_ENABLED=1 GOOS=linux go build -a -o app main.go # Start from debian:bookworm-slim for the release image FROM debian:bookworm-slim From 205a47e9f8ac143eb94cdf343007786ce264f54b Mon Sep 17 00:00:00 2001 From: Benjamin Gutierrez Date: Mon, 24 Jul 2023 21:19:05 -0400 Subject: [PATCH 09/10] demo-oneplatform --- main.go | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/main.go b/main.go index df1d57d..5303559 100644 --- a/main.go +++ b/main.go @@ -172,13 +172,16 @@ func updateWeather(w http.ResponseWriter, r *http.Request) { func deleteWeather(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] - if _, ok := WeatherDB[id]; ok { - delete(WeatherDB, id) - w.WriteHeader(http.StatusNoContent) - return - } - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusNotFound) + weatherToDelete := WeatherDB[id] + + // Here is the null pointer dereference vulnerability: + // Trying to access fields of weatherToDelete which can be nil + log.Printf("Deleting weather for city: %s", weatherToDelete.City) + + // Delete from the map + delete(WeatherDB, id) + + w.WriteHeader(http.StatusNoContent) } func weatherStream(w http.ResponseWriter, r *http.Request) { From 2f3c35860f74c69ab7763103e5e014e7aee3823a Mon Sep 17 00:00:00 2001 From: Benjamin Gutierrez Date: Mon, 24 Jul 2023 21:28:41 -0400 Subject: [PATCH 10/10] demo-oneplatform --- Mayhemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mayhemfile b/Mayhemfile index 3be3326..2bd4827 100644 --- a/Mayhemfile +++ b/Mayhemfile @@ -1,5 +1,5 @@ image: ghcr.io/unionfindbee/demo-oneplatform:vulnerable -duration: 60 +duration: 12000 project: bengutierrez/demo-oneplatform target: mcode