Closed
Description
It occurs in modules/caddyhttp/rewrite/rewrite.go.
Specifically,this bug locates in func (rewr Rewrite) rewrite
func (rewr Rewrite) rewrite(r *http.Request, repl *caddy.Replacer, logger *zap.Logger) bool {
oldMethod := r.Method
oldURI := r.RequestURI
// method
if rewr.Method != "" {
r.Method = strings.ToUpper(repl.ReplaceAll(rewr.Method, ""))
}
// uri (path, query string and... fragment, because why not)
if uri := rewr.URI; uri != "" {
// find the bounds of each part of the URI that exist
pathStart, qsStart, fragStart := -1, -1, -1
pathEnd, qsEnd := -1, -1
for i, ch := range uri {
switch {
case ch == '?' && qsStart < 0:
pathEnd, qsStart = i, i+1
case ch == '#' && fragStart < 0:
qsEnd, fragStart = i, i+1
case pathStart < 0 && qsStart < 0 && fragStart < 0:
pathStart = i
}
}
if pathStart >= 0 && pathEnd < 0 {
pathEnd = len(uri)
}
if qsStart >= 0 && qsEnd < 0 {
qsEnd = len(uri)
}
// isolate the three main components of the URI
var path, query, frag string
if pathStart > -1 {
path = uri[pathStart:pathEnd]
}
if qsStart > -1 {
query = uri[qsStart:qsEnd]
}
if fragStart > -1 {
frag = uri[fragStart:]
}
...In this function, it parse the rewr.URI and attemps to find the bounds of each part of the URI that exist.
However, this implementation is too simple to handle unexpected scenarios.
If '#' appears in front of the '?' in rewr.URI, it makes that qsStart is larger than qsEnd,
which leads to a crash like 'panic: runtime error: slice bounds out of range' in slice accessing at query = uri[qsStart:qsEnd]