You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by bn...@apache.org on 2026/10/19 21:15:20 UTC
(trafficserver) 17/22: doc: correct the regex matching contract where sites enforce full match
This is an automated email from the ASF dual-hosted git repository.
bneradt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit a5a7a8aa2ad81d773f21b1de86dd650bff8a95b9
Author: Evan Zelkowitz <e_...@apple.com>
AuthorDate: Tue Sep 1 13:28:16 2026 -0600
doc: correct the regex matching contract where sites enforce full match
The matching contract section stated that the matcher never requires a
pattern to consume the whole subject, and illustrated it with a host
regex — the one site where that stopped being true when regex_map was
anchored at both ends. sni.yaml's fqdn was missing from the per-site
list for the same reason, and remap.config told operators an unanchored
host pattern matches more inputs than intended when it now matches
fewer.
Point the example at map_with_referer, which is still substring, name
the two always-anchored sites, add the sni.yaml entry, and replace the
remap.config note with the rewrite operators actually need. Anchor the
geoip_acl and maxmind_acl examples so the plugin docs stop teaching the
unanchored form their own best-practices guide warns against.
(cherry picked from commit 83d56545049807aeae9171c5b9a32a12a192a09e)
---
.../configuration/regex-best-practices.en.rst | 30 +++++++++++++++++++---
doc/admin-guide/files/remap.config.en.rst | 15 ++++++++---
doc/admin-guide/plugins/geoip_acl.en.rst | 8 +++---
doc/admin-guide/plugins/maxmind_acl.en.rst | 4 +--
4 files changed, 45 insertions(+), 12 deletions(-)
diff --git a/doc/admin-guide/configuration/regex-best-practices.en.rst b/doc/admin-guide/configuration/regex-best-practices.en.rst
index 66ce7742aa..95deefaec2 100644
--- a/doc/admin-guide/configuration/regex-best-practices.en.rst
+++ b/doc/admin-guide/configuration/regex-best-practices.en.rst
@@ -52,13 +52,20 @@ possibly the whole subject, possibly a prefix, possibly a fragment in
the middle. The matcher does not, by default, require the pattern to
consume the entire subject.
+Two sites depart from that default and always require the pattern to
+match the entire subject: ``regex_map`` in :file:`remap.config` and
+``fqdn`` in :file:`sni.yaml`. Both are noted in their entries below.
+:ts:cv:`proxy.config.regex.anchor_policy_rules` extends the same
+requirement to the sites listed in `Requiring whole-subject matches`_.
+
This is the standard PCRE behavior. It has security implications when
the subject is influenced by a client (a request URL, a host header,
an SNI value, a Referer header, etc.). An operator who writes the
-pattern ``cdn\.example\.com`` as a host regex thinking *"match this
-exact host"* will find the rule firing on client-supplied hosts like
-``cdn.example.com.other.org``, because the substring
-``cdn.example.com`` appears at position 0 of the longer subject.
+pattern ``cdn\.example\.com`` as a ``map_with_referer`` referer regex
+thinking *"match this exact host"* will find the rule firing on
+client-supplied ``Referer`` values like
+``http://cdn.example.com.other.org/``, because the substring
+``cdn.example.com`` appears within the longer subject.
The fix at the operator level is to anchor patterns explicitly so the
pattern says exactly what it should match:
@@ -228,6 +235,11 @@ remap.config — ``regex_map``
For URL ``http://cdn.example.com:8080/path``, the regex sees the
subject ``cdn.example.com``.
+Patterns at this site are compiled anchored at both ends, so a match
+must consume the whole host. A substring-style pattern such as
+``example\.com`` therefore does not match ``cdn.example.com``, and
+``cdn\.example\.com`` does not match ``cdn.example.com.other.org``.
+
remap.config — ``map_with_referer``
-----------------------------------
@@ -263,6 +275,16 @@ splitdns.config — ``url_regex``
**Subject:** the full request URL — same as ``parent.config``'s
``url_regex``.
+sni.yaml — ``fqdn``
+-------------------
+
+**Subject:** the SNI value from the inbound TLS ClientHello.
+
+Each ``*`` in an ``fqdn`` is expanded to a wildcard group before the
+value is compiled as a regex, and matching is case-insensitive. A
+match must consume the entire SNI value, so a pattern for
+``example.com`` does not match ``example.com.other.org``.
+
url_sig — ``excl_regex``
------------------------
diff --git a/doc/admin-guide/files/remap.config.en.rst b/doc/admin-guide/files/remap.config.en.rst
index fcde8b34dd..d34438ac6a 100644
--- a/doc/admin-guide/files/remap.config.en.rst
+++ b/doc/admin-guide/files/remap.config.en.rst
@@ -325,11 +325,20 @@ limitations below:
.. seealso::
The ``host`` regex is matched against the request host (no scheme,
- port, or path). Operator-written patterns can match more inputs
- than intended when unanchored. For per-site subject definitions,
- common pitfalls, and recommended pattern shapes, see
+ port, or path), and is anchored at both ends: a match must consume
+ the whole host. A substring-style pattern such as ``example\.com``
+ therefore does not match ``cdn.example.com``. For per-site subject
+ definitions, common pitfalls, and recommended pattern shapes, see
:ref:`admin-regex-best-practices`.
+.. note::
+ Both-ends anchoring of the ``host`` regex arrived in 10.1.4 and
+ 10.2.0. A deployed pattern that relied on matching only part of the
+ host stops matching entirely under it, so the rule becomes inert
+ rather than matching more loosely. Rewrite such a pattern by adding
+ ``.*`` at each end that was not anchored — ``\.example\.com``
+ becomes ``^.*\.example\.com.*$``.
+
Examples
--------
diff --git a/doc/admin-guide/plugins/geoip_acl.en.rst b/doc/admin-guide/plugins/geoip_acl.en.rst
index 8c64e51610..07feeb0e10 100644
--- a/doc/admin-guide/plugins/geoip_acl.en.rst
+++ b/doc/admin-guide/plugins/geoip_acl.en.rst
@@ -63,10 +63,12 @@ The three typical use cases are as follows:
@pparam=regex::/etc/music.regex
where music.regex is a format with PCRE (perl compatible) regular
-expressions, and unique rules for match. E.g.::
+expressions, and unique rules for match. Anchor each pattern so it
+matches only what it is meant to — an unanchored pattern matches any
+path merely containing it. E.g.::
- .*\.mp3 allow US
- .*\.ogg deny US
+ ^.*\.mp3$ allow US
+ ^.*\.ogg$ deny US
Note that the default in the case of no matches on the regular
expressions is to "allow" the request. This can be overridden, see next
diff --git a/doc/admin-guide/plugins/maxmind_acl.en.rst b/doc/admin-guide/plugins/maxmind_acl.en.rst
index 7943778c59..cde2a535e0 100644
--- a/doc/admin-guide/plugins/maxmind_acl.en.rst
+++ b/doc/admin-guide/plugins/maxmind_acl.en.rst
@@ -51,8 +51,8 @@ An example configuration ::
ip:
- 127.0.0.1
regex:
- - [US, ".*\\.txt"] # Because these get parsed you must escape the escape of the ``.`` in order to have it be escaped in the regex, resulting in ".*\.txt"
- - [US, ".*\\.mp3"]
+ - [US, "^.*\\.txt$"] # Because these get parsed you must escape the escape of the ``.`` in order to have it be escaped in the regex, resulting in "^.*\.txt$"
+ - [US, "^.*\\.mp3$"]
In order to load an updated configuration while ATS is running you will have to touch or modify the remap.config file in order to initiate a plugin reload to pull in any changes.