Skip to content

v2.36.1 — a number is a number

Choose a tag to compare

@sean-e-dietrich sean-e-dietrich released this 01 Oct 06:34
· 19 commits to 2.x since this release
db2ee74

v2.36.1

Equality on a number compares as a number.

Some variables resolve to a number: port, query_count (new in 2.36.0), asn, and GeoLocation's database fields. Every value a rule compares against them is text, whether written in YAML or substituted from a rule source. So equals, not_equals and in compared a number with text and never matched, and not_equals matched every request.

PHP 8.1–8.5 supported. No new configuration keys. This changes what some existing rules do, so read What changes on upgrade.

What changes on upgrade

  • Equality rules on a number start matching. port:8443, port@in:8443,9443 and query_count.f@equals:4 never matched before. A block rule written that way starts blocking.
  • not_equals on a number stops matching everything. It used to match every request, including the value it named. A block rule such as query_count.f@not_equals:0 refused every visitor; now it refuses only requests that carry the parameter. Check any not_equals rule on port or query_count.
  • Text variables are unchanged. Two strings still compare exactly, so query.page:01 does not match ?page=1.

Fixed

  • Numbers against text (#443, #444). On v2.36.0:

    Rule Request Before After
    port:8443 port 8443 no match match
    port@in:8443,9443 port 8443 no match match
    port@not_equals:8443 port 8443 match no match
    query_count.f@equals:4 four f values no match match
    query_count.f@not_equals:0 no f match (blocked everyone) no match
    rule source port:{value} with 8443 port 8443 no match match

    When the value from the request is a number and the rule's value is numeric text, equals and not_equals now compare them as numbers. in is covered too, because each of its values is checked as equals. That includes values from a rule source, which are filled in after the config is built, so a host couldn't convert them itself. GeoLocation's numeric database fields, such as location.latitude and the geoname_id fields, compare the same way. A value that isn't a number, such as port@equals:abc, behaves as before. ASN rules already worked this way since 2.35.0, AS prefix included.

    The facet-crawling recipe from 2.36.0 uses greater_than, which always worked, so a site that followed it is unaffected.

  • ChallengeRequiredException's render context type (#442, #444). It was declared array<string, string>, but notices (2.35.0) is a list. Static analysis therefore told a host's correct is_array($context['notices']) check that it could never be true, which is how kanopi/firewall-laravel found it. The type is now array<string, mixed>, as it already was on the provider interface. Docblock only; no runtime change.

  • A flaky test. Three MemcachedStorageTest assertions compared a stored timestamp with a later time() call, and could fail by one second on a slow CI run. Test only.

Full changelog: v2.36.0...v2.36.1