nil pointer dereference panic in CancelRequest / ModifyRequest
Affected file: pkg/proxy/intercept/intercept.go
Description
CancelRequest calls ModifyRequest with a nil pointer as the modReq argument. Inside ModifyRequest, the code immediately dereferences that pointer before any nil check, causing a guaranteed runtime panic whenever a user cancels an intercepted request.
Steps to reproduce
- Enable request interception in Hetty.
- Trigger any proxied HTTP request so that it appears in the intercept queue.
- Click Cancel on the intercepted request in the admin UI.
- The server panics with
runtime error: invalid memory address or nil pointer dereference.
Root cause
CancelRequest is designed to send nil through the request channel as an abort signal, but it does so by routing through ModifyRequest, which unconditionally dereferences the pointer first:
// CancelRequest passes nil as modReq:
func (svc *Service) CancelRequest(reqID ulid.ULID) error {
return svc.ModifyRequest(reqID, nil, nil) // nil passed here
}
// ModifyRequest immediately dereferences it — PANIC:
func (svc *Service) ModifyRequest(reqID ulid.ULID, modReq *http.Request, modifyResponse *bool) error {
// ...
*modReq = *modReq.WithContext(req.req.Context()) // nil dereference
}Note that ClearRequests correctly sends nil directly to the channel without going through ModifyRequest, showing the intended pattern was known but not applied consistently.
Suggested fix
Add a nil guard in ModifyRequest before dereferencing the pointer:
if modReq != nil {
*modReq = *modReq.WithContext(req.req.Context())
if modifyResponse != nil {
*modReq = *modReq.WithContext(WithInterceptResponse(modReq.Context(), *modifyResponse))
}
}Alternatively, CancelRequest could bypass ModifyRequest entirely and send nil directly to the channel, as ClearRequests already does.
Source: dstotijn/hetty