codeant-ai-for-open-source[bot] commented on code in PR #40130:
URL: https://github.com/apache/superset/pull/40130#discussion_r3501647542


##########
superset/daos/base.py:
##########
@@ -81,9 +81,15 @@ def apply(self, column: Any, value: Any) -> Any:
         return op_func(column, value)
 
 
-def _escape_like(value: str) -> str:
-    """Escape LIKE/ILIKE wildcards to prevent wildcard injection."""
-    return value.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_")
+def _escape_like(value: Any) -> str:
+    """Escape LIKE/ILIKE wildcards to prevent wildcard injection.
+
+    ``ColumnOperator.value`` is typed ``Any``, so a non-string payload (e.g. a
+    numeric JSON value) can reach a LIKE-family operator. Coerce to ``str`` so
+    such input degrades to a literal match instead of raising 
``AttributeError``.
+    """
+    text = "" if value is None else str(value)
+    return text.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_")

Review Comment:
   **Suggestion:** Converting `None` to an empty string makes LIKE-family 
filters generate wildcard-only patterns (`%`, `%%`, etc.), so a request with a 
null filter value can unintentionally match almost all rows. Treat `None` as an 
invalid value for LIKE operators (or convert it to the literal string `"None"`) 
instead of collapsing it to `""`. [incorrect condition logic]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ❌ Dataset MCP list filters with null values match all datasets.
   - ⚠️ Generic DAO LIKE filters can misbehave on missing values.
   - ⚠️ Chart and dashboard DAO filters may return overly broad results.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Start Superset with this PR code and focus on the MCP dataset listing 
tool defined at
   `superset/mcp_service/dataset/tool/list_datasets.py:1-33`, which calls
   `ModelListCore.run_tool()` (see `superset/mcp_service/mcp_core.py:41-52`) 
and in turn
   `_call_dao_list()` (lines 16-39) to invoke `DatasetDAO.list()` with 
`filters` forwarded as
   `column_operators`.
   
   2. Craft a DatasetFilter-like object (or JSON) where `opr` is a LIKE-family 
operator such
   as `"sw"` (starts-with) and `value` is null/omitted, e.g. `{"col": 
"table_name", "opr":
   "sw"}`; when parsed to a `ColumnOperator` (base model at 
`superset/daos/base.py:7-10` with
   `value: Any = Field(None, ...)`), this produces an instance with `c.value is 
None`.
   
   3. When `ModelListCore._call_dao_list()` calls 
`DatasetDAO.list(column_operators=filters)`
   (see `superset/mcp_service/mcp_core.py:30-39`), `BaseDAO.list()` at
   `superset/daos/base.py:11-23, 63-79` eventually calls 
`cls.apply_column_operators(query,
   column_operators)`; inside `apply_column_operators` (lines 16-64), the 
`ColumnOperator` is
   processed and `operator_enum.apply(column, value)` is invoked with 
`value=None`.
   
   4. `ColumnOperatorEnum.sw` is mapped in `operator_map` (see 
`superset/daos/base.py:37-47`)
   to `lambda col, val: col.like(f"{_escape_like(val)}%", escape="\\")`; 
`_escape_like`
   (lines 25-33) sees `value is None`, sets `text = ""`, and returns an empty 
string, so the
   pattern becomes `"%"`, which in SQL LIKE matches almost every row, causing 
the filter
   intended to be empty/invalid to act as a match-all and return an unfiltered 
dataset list.
   ```
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=88f092378ef943d5abd0614045b6f4c9&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=88f092378ef943d5abd0614045b6f4c9&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset/daos/base.py
   **Line:** 91:92
   **Comment:**
        *Incorrect Condition Logic: Converting `None` to an empty string makes 
LIKE-family filters generate wildcard-only patterns (`%`, `%%`, etc.), so a 
request with a null filter value can unintentionally match almost all rows. 
Treat `None` as an invalid value for LIKE operators (or convert it to the 
literal string `"None"`) instead of collapsing it to `""`.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F40130&comment_hash=0eb32009e835bbfe1fb594460fd3829b6c5580c15217c58a99f8e6564f37efdf&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F40130&comment_hash=0eb32009e835bbfe1fb594460fd3829b6c5580c15217c58a99f8e6564f37efdf&reaction=dislike'>👎</a>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to