@marcel91200 / caddy Mirror · read-only / commits / 2dc747cf
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 13, 13:00 UTC

Limit unclosed placeholder tolerance (fix #4170)

Matthew Holt committed Sep 15, 2022 at 13:36 UTC 2dc747cf2d7dd4e7337c1d7665042b896f3b4445
1 file changed +12 -1
replacer.go
+12 -1
@@ -144,9 +144,11 @@ func (r *Replacer) replace(input, empty string,
144 // iterate the input to find each placeholder
145 var lastWriteCursor int
146
147 + // fail fast if too many placeholders are unclosed
148 + var unclosedCount int
149 +
150 scan:
151 for i := 0; i < len(input); i++ {
149 -
152 // check for escaped braces
153 if i > 0 && input[i-1] == phEscape && (input[i] == phClose || input[i] == phOpen) {
154 sb.WriteString(input[lastWriteCursor : i-1])
@@ -158,9 +160,17 @@ scan:
160 continue
161 }
162
163 + // our iterator is now on an unescaped open brace (start of placeholder)
164 +
165 + // too many unclosed placeholders in absolutely ridiculous input can be extremely slow (issue #4170)
166 + if unclosedCount > 100 {
167 + return "", fmt.Errorf("too many unclosed placeholders")
168 + }
169 +
170 // find the end of the placeholder
171 end := strings.Index(input[i:], string(phClose)) + i
172 if end < i {
173 + unclosedCount++
174 continue
175 }
176
@@ -168,6 +178,7 @@ scan:
178 for end > 0 && end < len(input)-1 && input[end-1] == phEscape {
179 nextEnd := strings.Index(input[end+1:], string(phClose))
180 if nextEnd < 0 {
181 + unclosedCount++
182 continue scan
183 }
184 end += nextEnd + 1