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


##########
superset/utils/core.py:
##########
@@ -2088,6 +2088,60 @@ def create_zip(files: dict[str, Any]) -> BytesIO:
     return buf
 
 
+# Matches a safe, opaque token suitable for use as a cookie name. Restricting 
the
+# allowed characters prevents client-controlled input from injecting unexpected
+# cookie attributes or control characters.
+COOKIE_TOKEN_RE = re.compile(r"^[A-Za-z0-9_-]{1,128}$")
+
+
+def sanitize_cookie_token(token: str | None) -> str | None:
+    """Return the token if it is a valid cookie name, otherwise None.
+
+    The export endpoints echo a client-provided ``token`` query parameter back 
as
+    a cookie name to signal download completion. Validate it against a strict
+    allow-list before trusting it.
+
+    :param token: the client-provided token value
+    :return: the token if valid, else None
+    """
+    if token and COOKIE_TOKEN_RE.match(token):
+        return token

Review Comment:
   **Suggestion:** `$` accepts a final newline, so a token ending in `%0A` 
passes validation and `set_cookie` raises on the control character, turning the 
export into a 500 response. [error handling]
   
   **Assessment:** 🟠 `Major` Β· πŸ” `Occurrence: Sometimes`
   
   [![Use CodeAnt 
Skill](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/use-codeant-skill-flat-v2.svg)](https://docs.codeant.ai/cli/resolve-pr-comments-skill)
 [![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=8f202ea209234253ad05d2bdfea6077d&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=8f202ea209234253ad05d2bdfea6077d&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   <details>
   <summary><b>Prompt for AI Agent πŸ€– </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset/utils/core.py
   **Line:** 2094:2108
   **Comment:**
        *Error Handling: `$` accepts a final newline, so a token ending in 
`%0A` passes validation and `set_cookie` raises on the control character, 
turning the export into a 500 response.
   
   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%2F44311&comment_hash=69acc041223943c29db4f3467da858ac75b694a761eeafb9d90c55033375c06f&reaction=like'>πŸ‘</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F44311&comment_hash=69acc041223943c29db4f3467da858ac75b694a761eeafb9d90c55033375c06f&reaction=dislike'>πŸ‘Ž</a>



##########
superset/utils/core.py:
##########
@@ -2088,6 +2088,60 @@ def create_zip(files: dict[str, Any]) -> BytesIO:
     return buf
 
 
+# Matches a safe, opaque token suitable for use as a cookie name. Restricting 
the
+# allowed characters prevents client-controlled input from injecting unexpected
+# cookie attributes or control characters.
+COOKIE_TOKEN_RE = re.compile(r"^[A-Za-z0-9_-]{1,128}$")
+
+
+def sanitize_cookie_token(token: str | None) -> str | None:
+    """Return the token if it is a valid cookie name, otherwise None.
+
+    The export endpoints echo a client-provided ``token`` query parameter back 
as
+    a cookie name to signal download completion. Validate it against a strict
+    allow-list before trusting it.
+
+    :param token: the client-provided token value
+    :return: the token if valid, else None
+    """
+    if token and COOKIE_TOKEN_RE.match(token):
+        return token
+    return None
+
+
+def send_export_zip(buf: BytesIO, filename: str) -> Response:
+    """Build a non-cacheable ZIP attachment response for the export endpoints.
+
+    Export bundles are generated per request from live metadata, so they must 
never
+    be cached. Flask applies ``SEND_FILE_MAX_AGE_DEFAULT`` (one year in 
Superset's
+    config) to every ``send_file`` response that does not opt out, which made
+    browsers and intermediate proxies serve stale export archives. Passing
+    ``max_age=0`` and marking the response ``no-store``/``no-cache`` keeps the
+    behavior of genuine static assets untouched while forcing exports to be 
fetched
+    fresh every time.
+
+    The optional client-provided ``token`` query parameter is echoed back as a
+    cookie so the UI can detect that the download finished.
+
+    :param buf: an in-memory ZIP archive, positioned at the start
+    :param filename: the download file name advertised to the client
+    :return: the response to return from the export endpoint
+    """
+    response = send_file(
+        buf,
+        mimetype="application/zip",
+        as_attachment=True,
+        download_name=filename,
+        max_age=0,
+    )
+    response.cache_control.no_store = True
+    response.cache_control.no_cache = True
+    response.cache_control.must_revalidate = True
+    if token := sanitize_cookie_token(request.args.get("token")):
+        response.set_cookie(token, "done", max_age=600)

Review Comment:
   **Suggestion:** A caller can pass `token=session`, so this response 
overwrites Flask’s authentication session cookie with `done`, logging the user 
out or corrupting session state. [security]
   
   **Assessment:** 🟠 `Major` Β· πŸ” `Occurrence: Sometimes`
   
   [![Use CodeAnt 
Skill](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/use-codeant-skill-flat-v2.svg)](https://docs.codeant.ai/cli/resolve-pr-comments-skill)
 [![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=7a1be0def0f14bcb8ac61cef021dafa4&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=7a1be0def0f14bcb8ac61cef021dafa4&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   <details>
   <summary><b>Prompt for AI Agent πŸ€– </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset/utils/core.py
   **Line:** 2140:2141
   **Comment:**
        *Security: A caller can pass `token=session`, so this response 
overwrites Flask’s authentication session cookie with `done`, logging the user 
out or corrupting session state.
   
   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%2F44311&comment_hash=0cc0527557d2670d5783885c6f78c08e9b82efad22fad2ec6c14fdf4ebe294e0&reaction=like'>πŸ‘</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F44311&comment_hash=0cc0527557d2670d5783885c6f78c08e9b82efad22fad2ec6c14fdf4ebe294e0&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