Skip to content

fix(homeserver): escaped chars in sql like - #531

Open
MCarlomagno wants to merge 2 commits into
mainfrom
fix/unescaped-sql-like
Open

fix(homeserver): escaped chars in sql like#531
MCarlomagno wants to merge 2 commits into
mainfrom
fix/unescaped-sql-like

Conversation

@MCarlomagno

@MCarlomagno MCarlomagno commented Jul 30, 2026

Copy link
Copy Markdown
Member

Summary

Uses Postgres starts_with for literal prefix queries.
Previously, LIKE metacharacters such as _ and % could widen contains_directory, shallow-listing, and deep-listing matches, exposing lookalike sibling paths. Prefixes are now matched literally, with regression coverage in the existing repository tests.

@SeverinAlexB

Copy link
Copy Markdown
Collaborator

AI input that I find intriguing: Instead of using a LIKE which can be dangerous, should we just use the Postgres native starts_with function? This avoids needing to escape anything.

Since the intended operation is literal prefix matching, PostgreSQL’s native starts_with(string, prefix) (https://www.postgresql.org/docs/current/functions-string.html) avoids LIKE escaping entirely:
starts_with(entries.path, $1)
SeaQuery 0.32 does not provide a dedicated helper, but supports custom functions:
use sea_query::{Alias, Expr, Func, SimpleExpr};

fn starts_with_path(prefix: &str) -> SimpleExpr {
    Func::cust(Alias::new("starts_with"))
        .arg(Expr::col((ENTRY_TABLE, EntryIden::Path)))
        .arg(prefix)
        .into()
}
Then:
.and_where(Self::starts_with_path(&full_path))
This is preferable to escaped_like_prefix() because:
%, _, and \ are automatically literal.
It directly expresses the intended operation.
PostgreSQL has supported starts_with() since version 11; CI uses PostgreSQL 18.
PostgreSQL provides planner/index support for this function, similar to prefix LIKE.
If retaining LIKE, the PR’s manual escaping is necessary: SeaQuery’s LikeExpr::escape('\\') only emits ESCAPE '\'; it does not escape the supplied pattern. So I would recommend replacing the helper and all three LIKE expressions with starts_with(), while keeping the regression tests.

@MCarlomagno

Copy link
Copy Markdown
Member Author

@SeverinAlexB yes I think that makes sense, it makes the implementation more coupled to Postgres but I assume that's fine

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants