Skip to content

[panic]: slice OOB caused by illegal uri #4775

Closed
@secsys-go

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]

Metadata

Assignees

Labels

bug 🐞Something isn't working

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions