fix(api): refactors the SQL LIKE pattern escaping logic to use a centralized utility function, ensuring consistent and secure handling of special characters across all database queries. - #7
fix(api): refactors the SQL LIKE pattern escaping logic to use a centralized utility function, ensuring consistent and secure handling of special characters across all database queries.#7
Conversation
…ralized utility function, ensuring consistent and secure handling of special characters across all database queries. Signed-off-by: NeatGuyCoding <15627489+NeatGuyCoding@users.noreply.github.com>
…logic Signed-off-by: NeatGuyCoding <15627489+NeatGuyCoding@users.noreply.github.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 5 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
| if not pattern: | ||
| return pattern | ||
| # Escape backslash first, then percent and underscore | ||
| return pattern.replace("%", "\\%").replace("_", "\\_").replace("\\", "\\\\") |
There was a problem hiding this comment.
Escape order is wrong in escape_like_pattern function
High Severity
The escape_like_pattern function escapes characters in the wrong order. The comment says "Escape backslash first, then percent and underscore" but the code does the opposite - it escapes % and _ first, then \\ last. This causes already-escaped characters to be double-escaped. For example, input test\%_value produces test\\\\%\\_value instead of test\\\%\_value.
| query = query.where( | ||
| or_( | ||
| DocumentSegment.content.ilike(f"%{keyword}%"), | ||
| DocumentSegment.content.ilike(f"%{keyword}%", escape="\\"), |
There was a problem hiding this comment.
Unescaped keyword used in LIKE pattern
High Severity
The code creates escaped_keyword by calling escape_like_pattern(keyword) but then uses the original unescaped keyword variable in DocumentSegment.content.ilike(f"%{keyword}%", escape="\\"). This defeats the purpose of the escaping and leaves the query vulnerable to SQL injection via LIKE wildcards.
| case "end with": | ||
| filters.append(json_field.like(f"%{value}")) | ||
| escaped_value = escape_like_pattern(str(value)) | ||
| filters.append(json_field.like(f"%{value}", escape="\\")) |
There was a problem hiding this comment.
Unescaped value used in "end with" LIKE pattern
High Severity
The "end with" case creates escaped_value by calling escape_like_pattern(str(value)) but then uses the original unescaped value variable in json_field.like(f"%{value}", escape="\\"). This bypasses the escaping protection entirely for the "end with" metadata filter condition.
|
|
||
| # Escape special characters in keyword to prevent SQL injection via LIKE wildcards | ||
| escaped_keyword = escape_like_pattern(keyword[:30]) | ||
| keyword_like_val = f"%{keyword[:30]}%" |
There was a problem hiding this comment.
Escaped keyword created but never used
High Severity
The code creates escaped_keyword by calling escape_like_pattern(keyword[:30]) but then constructs keyword_like_val using the original unescaped keyword[:30]. The escaped_keyword variable is never used, completely bypassing the escaping intended to prevent SQL injection via LIKE wildcards.
| from libs.helper import escape_like_pattern | ||
|
|
||
| escaped_query = escape_like_pattern(query).replace("'", "''") | ||
| filter_clauses.append(f"{Field.CONTENT_KEY} LIKE '%{escaped_query}%' ESCAPE '\\\\'") |
There was a problem hiding this comment.
ClickZetta ESCAPE clause has extra backslash
Medium Severity
The SQL ESCAPE clause uses ESCAPE '\\\\' which produces ESCAPE '\\' in SQL (two backslashes), but escape_like_pattern produces escapes using a single backslash (e.g., \%). Since ClickZetta is configured with quote mode where backslash is literal, this mismatch means the LIKE pattern escaping won't work correctly. The ESCAPE clause should use ESCAPE '\\' in Python to produce ESCAPE '\' in SQL.
Benchmark PR from qodo-benchmark#173
Note
Strengthens search safety/consistency by standardizing SQL LIKE escaping and updating related queries.
libs.helper.escape_like_patternand applies it to search filters in conversations, datasets segments, annotations, apps, tags, workflow logs, and metadata filteringESCAPE '\'escape_like_pattern; integration tests verifying literal matching of%,_, and\across annotations, apps, tags, and workflow logsAppServiceimports to avoid circular dependenciesWritten by Cursor Bugbot for commit 0806191. Configure here.