You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Check for RSQL support by sending harmless probes like `?filter=id==test`, `?q==test` or malformed operators `=foo=`; verbose APIs often leak parser errors ("Unknown operator" / "Unknown property").
587
+
-`rsql-parser`-style grammars reserve `" ' ( ) ; , = ! ~ < >`; if a selector/value containing one of those characters only works once quoted (for example `name=='a,b'`), you have a useful fingerprint and a hint that input validation is happening on only part of the expression.
588
+
- Don't stop at `filter[users]`: Elide-style JSON:API backends may accept both type-specific filters such as `filter[user]=role==admin` and a global `filter=authors.name=='Null Ned';title=='Life with Null Ned'` that traverses relationships.
589
+
- Probe operator support to fingerprint the translator layer, not just the parser: `==*foo*`, `=ini=*foo*`, `=isnull=true`, `=isempty=true`, `=between=(1,10)` or `=hasmember=` usually reveal Elide/custom JPA translators with a much larger attack surface. In Elide 5+ the default FIQL behavior is case-sensitive, so comparing `name==admin` with `name=ini=*ADMIN*` is also a useful fingerprint.
590
+
- Pull `/doc`, `/swagger` or the OpenAPI document when present. Elide documents filter parameters for each primitive attribute plus `include`, `sort` and pagination support, which is an easy way to recover valid selectors without brute-forcing field names.
587
591
- Many implementations double-parse URL parameters; try double-encoding `(`, `)`, `*`, `;` (e.g., `%2528admin%2529`) to bypass naive blocklists and WAFs.
588
592
- Boolean exfil with wildcards: `filter[users]=email==*%@example.com;status==ACTIVE` and flip logic with `,` (OR) to compare response sizes.
589
593
- Range/proximity leaks: `filter[users]=createdAt=rng=(2024-01-01,2025-01-01)` quickly enumerates by year without knowing exact IDs.
- Elide and many Spring Data REST projects translate RSQL directly to JPA Criteria. When developers add custom operators (e.g., `=ilike=`) and build predicates via string concatenation instead of prepared parameters, you can pivot to SQLi (classic payload: `name=ilike='%%' OR 1=1--'`).
593
-
- Elide analytic data store accepts parameterized columns; combining user-controlled analytic params with RSQL filters was the root cause of SQLi in CVE-2022-24827. Even if patched versions parameterize correctly, similar bespoke code often remains—hunt for `@JoinFilter`/`@ReadPermission` SpEL expressions containing `${}` and try injecting `';sleep(5);'` or logical tautologies.
594
-
- JSON:API backends commonly expose both `include` and `filter`. Filtering on related resources `filter[orders]=customer.email==*admin*` may bypass top-level ACLs because relation-level filters execute before ownership checks.
596
+
-`rsql-parser` only parses the grammar and explicitly supports custom operators. If you see non-standard operators such as `=like=`, `=ilike=`, `=all=` or `=notAssigned=`, focus your review on the translation layer because that is where unsafe string concatenation usually appears.
597
+
- Elide JSON:API supports both type-specific `filter[TYPE]` parameters and a single global `filter`, and selectors can traverse related models with dotted paths such as `author.books.price.total`. Test the same predicate on root collections and related collections because authorization bugs often exist on only one path.
598
+
-`rsql-jpa-specification` supports public-to-internal property remapping (for example `compCode` -> `company.code`, `compId` -> `company.id`). If the UI or docs expose friendly aliases, fuzz both the alias and the canonical dotted path to discover hidden joins or allow-list gaps.
599
+
- The same library documents direct SQL `LIKE` translation plus configurable escape characters. If the target exposes `=like=`-style operators, test `%`, `_` and the escape character because custom predicates often forget to escape wildcards consistently across MySQL/PostgreSQL/SQL Server.
600
+
- Newer `rsql-jpa-specification` releases also support PostgreSQL `jsonb` traversal (`data.user.id==1`, `data.roles.id==1`) and optional stored-procedure syntax such as `@upper[code]==HELLO` when procedures are whitelisted. If an API exposes either feature, you can often pivot from a simple field filter into nested JSON documents or function-backed selectors that were never meant to be attacker reachable.
601
+
- Elide analytic queries added field arguments/parameterized columns to the RSQL grammar; this was the precondition behind CVE-2022-24827, where a `TEXT` parameter containing `--` could strip the generated authorization `WHERE` clause. On analytics endpoints, always test whether filter operands or field arguments are copied into SQL fragments before server-side auth filters are applied.
595
602
596
603
## Automation helpers
597
604
-**rsql-parser CLI (Java)**: `java -jar rsql-parser.jar "name=='*admin*';status==ACTIVE"` validates payloads locally and shows the abstract syntax tree—useful to craft balanced parentheses and custom operators.
0 commit comments