security: replace unsafe eval() with ast.literal_eval()#7379
security: replace unsafe eval() with ast.literal_eval()#7379thesohamdatta wants to merge 2 commits into
Conversation
Greptile SummaryThis PR replaces bare
Confidence Score: 1/5Not safe to merge — every function touched by this PR will crash at runtime due to a missing import. The fix correctly swaps eval() for ast.literal_eval(), but neither changed file imports the ast module. Every Redis read path that was modified — including app reviews, usage counts, geolocation cache, and transcript segments — will throw NameError: name 'ast' is not defined on the first call. The try_catch_decorator wrapping most of these functions will silently swallow the error and return None, so callers will get empty or null data rather than an explicit failure, making this regression easy to miss without careful testing. Both backend/database/redis_db.py and plugins/db.py need import ast added to their top-level imports before this can be merged. Important Files Changed
Reviews (1): Last reviewed commit: "security: replace unsafe eval() with ast..." | Re-trigger Greptile |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: be34b72c2c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if not count: | ||
| return None | ||
| return eval(count) | ||
| return ast.literal_eval(count) |
There was a problem hiding this comment.
Decode Redis bytes before literal_eval
This Redis client is constructed without decode_responses=True, so r.get(...) returns bytes; eval accepted byte strings, but ast.literal_eval(b'123') raises ValueError. On any existing cache hit for usage counts/money/reviews, these getters now fail instead of returning the cached value, so decode the Redis value before passing it to literal_eval.
Useful? React with 👍 / 👎.
| segments = [] | ||
| else: | ||
| segments = eval(segments) | ||
| segments = ast.literal_eval(segments) |
There was a problem hiding this comment.
Decode transcript cache values before literal_eval
The Redis client here also returns bytes, and ast.literal_eval does not accept byte strings even though the previous eval did. When a transcript key already exists, append_segment_to_transcript and the plugin transcript upsert path will raise instead of appending segments, so the value needs decoding before literal_eval.
Useful? React with 👍 / 👎.
| if not count: | ||
| return None | ||
| return eval(count) | ||
| return ast.literal_eval(count) |
There was a problem hiding this comment.
Missing
import ast — all changed functions will raise NameError at runtime
ast is never imported in this file, so every call to ast.literal_eval() introduced by this PR will immediately throw NameError: name 'ast' is not defined. That means get_app_usage_count_cache, get_app_money_made_amount_cache, set_app_review_cache, get_specific_user_review, get_app_reviews, get_apps_reviews, and get_cached_user_geolocation are all broken. Add import ast to the top-level imports (alongside import json, import os, etc.).
| return ast.literal_eval(count) | |
| import ast | |
| import base64 | |
| import json | |
| import os | |
| from typing import List, Union, Optional | |
| from datetime import datetime, timedelta, timezone | |
| import redis | |
| import logging |
…es before literal_eval
|
I've pushed an update that fully addresses the Greptile and Codex feedback. beyond fixing the missing ast imports and decoding the Redis bytes, I also audited the migration scripts and replaced some unsafe eval() calls there with |
replaces unsafe eval() with ast.literal_eval() to prevent rce in redis handlers. minimal fix following repo standards