fix(plugins): add regex length limit (#7802)

This commit is contained in:
Ville Vesilehto
2026-01-05 19:48:48 +02:00
committed by GitHub
parent adba778626
commit b723bd94d4
15 changed files with 117 additions and 3 deletions

View File

@@ -26,7 +26,8 @@ template CLASS TYPE [ZONE...] {
* **TYPE** the query type (A, PTR, ... can be ANY to match all types).
* **ZONE** the zone scope(s) for this template. Defaults to the server zones.
* `match` **REGEX** [Go regexp](https://golang.org/pkg/regexp/) that are matched against the incoming question name.
Specifying no regex matches everything (default: `.*`). First matching regex wins.
Specifying no regex matches everything (default: `.*`). First matching regex wins. Regex patterns
must not exceed 10000 characters.
* `answer|additional|authority` **RR** A [RFC 1035](https://tools.ietf.org/html/rfc1035#section-5) style resource record fragment
built by a [Go template](https://golang.org/pkg/text/template/) that contains the reply. Specifying no answer will result
in a response with an empty answer section.

View File

@@ -13,6 +13,10 @@ import (
"github.com/miekg/dns"
)
// maxRegexpLen is a hard limit on the length of a regex pattern to prevent
// OOM during regex compilation with malicious input.
const maxRegexpLen = 10000
func init() { plugin.Register("template", setupTemplate) }
func setupTemplate(c *caddy.Controller) error {
@@ -67,6 +71,9 @@ func templateParse(c *caddy.Controller) (handler Handler, err error) {
return handler, c.ArgErr()
}
for _, regex := range args {
if len(regex) > maxRegexpLen {
return handler, c.Errf("regex pattern too long: %d > %d", len(regex), maxRegexpLen)
}
r, err := regexp.Compile(regex)
if err != nil {
return handler, c.Errf("could not parse regex: %s, %v", regex, err)

View File

@@ -1,6 +1,8 @@
package template
import (
"fmt"
"strings"
"testing"
"github.com/coredns/caddy"
@@ -198,3 +200,19 @@ func TestSetupParse(t *testing.T) {
}
}
}
func TestSetupParseLargeRegex(t *testing.T) {
largeRegex := strings.Repeat("a", maxRegexpLen+1)
config := fmt.Sprintf(`template ANY A example.com {
match %s
}`, largeRegex)
c := caddy.NewTestController("dns", config)
_, err := templateParse(c)
if err == nil {
t.Fatal("Expected error for large regex, got nil")
}
if !strings.Contains(err.Error(), "too long") {
t.Errorf("Expected 'too long' error, got: %v", err)
}
}