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.Pointeroruintptrto calculate a memory address beyond a slice’s backing array. - Calling C code via
cgowhere 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 Errorwith a stack trace containingruntime 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:
- Validate all numeric inputs against the expected range before using them as indices or lengths.
- Avoid
unsafeandcgofor simple data handling; if unavoidable, enforce strict bounds checks at the Go‑C boundary. - 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. - 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
validatetag that calls a custom validator ensuring the index falls inside the buffer’s length. - If validation fails, the API returns a
400 Bad Requestwith a clear message, preventing the unsafe write. - No
unsafeorcgois 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?
Is it sufficient to rely on Go’s panic‑on‑out‑of‑range to protect my Echo Go API from exploitation?
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.