Skip to content

v0.27.1

Latest

Choose a tag to compare

@applied-ai-release-bot applied-ai-release-bot released this 04 Sep 12:44

Release Notes

This is a security release. Upgrade if any filter value in your application comes from user input.

Every filter class rendered a caller's value into its RediSearch clause without containing it, so a crafted value could close that clause and append its own syntax. Under DIALECT 2 an injected | lifts to the root of the query, which means a surrounding tenant or visibility filter stopped applying and the query returned records outside its scope. Tag, Text, Num and Geo were each reachable by a different route, and all four now validate the value where it is supplied. Detail in GHSA-932c-v3f4-cwxp.

Filter expressions are also parenthesised now wherever they combine with another clause, which fixes three broken query shapes.

Results change, with no error raised

Check these before you upgrade.

Call Before Now
Text("f") != value, quote in the value excluded nothing excludes correctly
GeoRadius(lon, lat, 1.9, "km") queried 1 km queries 1.9 km
MCP text filters eq, ne, in, multi-word value matched nothing work as intended

A | in a tag value is now escaped, so Tag("f") == "a|b" matches that one literal value rather than either a or b. Pass a list for a union: Tag("f") == ["a", "b"] is unchanged.

A VectorRangeQuery with a raw-string filter containing a top-level | returned documents outside the vector range, because the union bound across the intersection rather than inside the filter. It now returns fewer, correctly filtered results.

Values that used to build a broken query now raise

  • Num(field).between(start, end) raises TypeError unless both bounds are real numbers, so coerce a numeric string or a Decimal first. int, float and numpy scalars are unaffected.
  • Geo coordinates raise TypeError for a str or Decimal, and ValueError outside their range.
  • A zero, negative or infinite geo radius raises ValueError.

Queries that used to fail now run

A VectorQuery whose filter_expression holds more than one clause, and a MultiVectorQuery given an explicit wildcard filter, both raised a syntax error.

Query strings change shape

A filtered MultiVectorQuery no longer groups its vector-range clauses in parentheses, and a filtered VectorRangeQuery no longer wraps the whole query. Same meaning, different string. Tests asserting on exact query strings may need updating.

Unchanged by design

The pattern operators still interpolate their input raw, which is what makes *, %% and | work: Text(field) % pattern, Tag(field) % pattern and TextQuery(text=...) all behave as before. Do not pass untrusted input to them; use == for a value you did not construct.


🐛 Bug Fix

🏠 Internal

  • chore(deps): bump mistune from 3.3.0 to 3.3.3 in the uv group across 1 directory #719 (@dependabot)