HIGH out of bounds writeecho go

Out Of Bounds Write in Echo Go

How Out Of Bounds Write Manifests in Echo Go

Echo Go (the popular Echo web framework for Go) builds HTTP handlers around echo.Context. When a handler extracts a numeric value from the request — e.g., a query parameter, path variable, or JSON field — and uses that value directly as an index into a slice or array without validating the bounds, an out‑of‑bounds write can occur if the code later writes to that index.

Although Go’s memory safety prevents arbitrary memory corruption in pure Go code, out‑of‑bounds writes are still possible when:

  • Using unsafe.Pointer or uintptr to calculate a memory address beyond a slice’s backing array.
  • Calling C code via cgo where a Go slice is passed and the C side writes past the allocated length.
  • Leveraging reflection (unsafe.SliceData) to obtain a raw pointer and then performing pointer arithmetic.

In an Echo Go handler, a typical vulnerable pattern looks like this:

package main

import (
	"github.com/labstack/echo/v4"
	"strconv"
)

var buffer = make([]byte, 10) // fixed‑size buffer

func vulnerable(c echo.Context) error {
	// user supplies ?idx= via query string
	idxStr := c.QueryParam("idx")
	idx, err := strconv.Atoi(idxStr)
	if err != nil {
		return c.String(400, "invalid index")
	}
	// BUG: no bounds check before write
	buffer[idx] = 0xFF // out‑of‑bounds write if idx < 0 or idx >= len(buffer)
	return c.String(200, "ok")
}

func main() {
	e := echo.New()
	e.GET("/write", vulnerable)
	e.Start(":8080")
}

If an attacker supplies ?idx=100, the write accesses memory past the buffer’s allocation. In pure Go this triggers a panic (runtime error: index out of range), but when the slice is passed to C code or accessed via unsafe, the write can corrupt adjacent memory, leading to potential remote code execution or information disclosure — issues catalogued as CWE‑787: Out‑of‑bounds Write.

Echo Go-Specific Detection

middleBrick performs unauthenticated, black‑box scanning of API endpoints. For out‑of‑bounds write detection it:

  • Identifies numeric input parameters (query, path, JSON) that are used in calculations or array accesses.
  • Generates a series of progressively larger and smaller integer values (including negative numbers, zero, and values far beyond typical expected ranges) and injects them into each identified parameter.
  • Monitors the HTTP response for signs of a panic (500 Internal Server Error with a stack trace containing runtime error: index out of range), abrupt connection termination, or changes in response timing that suggest low‑level memory faults.
  • When the endpoint is suspected of invoking Cgo or unsafe code, middleBrick also checks for anomalous response bodies that may indicate memory leakage or corruption.

Example CLI usage to scan an Echo Go service:

# Install the middleBrick CLI (npm package)
npm i -g middlebrick

# Scan the target endpoint
middlebrick scan https://api.example.com/write

# Output (JSON) includes a finding like:
# {
#   "id": "OBW-001",
#   "name": "Potential Out‑of‑Bounds Write via slice index",
#   "severity": "high",
#   "description": "The handler writes to a slice using an unsanitized user‑supplied index without bounds checking.",
#   "remediation": "Validate the index against the slice length before performing the write."
# }

Because middleBrick does not require agents, credentials, or configuration, the test can be run against any publicly accessible Echo Go endpoint and will return a risk score (A–F) with the finding highlighted in the report.

Echo Go-Specific Remediation

Fixing an out‑of‑bounds write in Echo Go relies on proper input validation and avoiding unsafe memory manipulation. The recommended remediation steps are:

  1. Validate all numeric inputs against the expected range before using them as indices or lengths.
  2. Avoid unsafe and cgo for simple data handling; if unavoidable, enforce strict bounds checks at the Go‑C boundary.
  3. Use Go’s built‑in slicing syntax (slice[low:high:max]) which panics only if indices are out of range, making the error explicit and easier to catch in testing.
  4. Leverage Echo’s middleware or validation libraries (e.g., go-playground/validator/v10) to declaratively enforce constraints.

Here is the corrected version of the vulnerable handler:

package main

import (
	"github.com/labstack/echo/v4"
	"github.com/go-playground/validator/v10"
	"strconv"
)

var buffer = make([]byte, 10)

// custom validation tag for slice index
func sliceIndexValidator(fl validator.FieldLevel) bool {
	idx := fl.Field().Int()
	return idx >= 0 && idx < int64(len(buffer))
}

func init() {
	v := validator.New()
	v.RegisterValidation("sliceindex", sliceIndexValidator)
}

type WriteRequest struct {
	IDX int `validate:"required,sliceindex"` `json:"idx"`
}

func safe(c echo.Context) error {
	var req WriteRequest
	if err := c.Bind(&req); err != nil {
		return c.String(400, "invalid payload")
	}
	if err := validator.New().Struct(req); err != nil {
		return c.String(400, "index out of range")
	}
	// At this point req.IDX is guaranteed to be within [0, len(buffer)-1]
	buffer[req.IDX] = 0xFF
	return c.String(200, "ok")
}

func main() {
	e := echo.New()
	e.POST("/write", safe)
	e.Start(":8080")
}

Key points in the fix:

  • The handler now uses a struct with a validate tag that calls a custom validator ensuring the index falls inside the buffer’s length.
  • If validation fails, the API returns a 400 Bad Request with a clear message, preventing the unsafe write.
  • No unsafe or cgo is used, keeping the code within Go’s memory‑safe guarantees.

After applying this fix, a middleBrick rescan of the same endpoint will no longer trigger the out‑of‑bounds write finding, and the risk score will improve accordingly.

Frequently Asked Questions

Can middleBrick detect out‑of‑bounds writes that only manifest when the Echo Go handler calls Cgo code?
Yes. middleBrick’s active probing sends extreme numeric values to parameters that influence slice lengths or pointer arithmetic. If the handler passes a slice to Cgo, an out‑of‑bounds write from the C side often results in a 500 error, connection reset, or anomalous response timing, which middleBrick flags as a potential memory‑safety issue.
Is it sufficient to rely on Go’s panic‑on‑out‑of‑range to protect my Echo Go API from exploitation?
Relying solely on panics is not safe in production. A panic will cause the handler to return a 500 error, which can be used for denial‑of‑service, and if the slice is accessed via unsafe or cgo the panic may be bypassed, leading to silent memory corruption. Proper input validation, as shown in the remediation example, is required to eliminate the vulnerability.