mirror of
https://github.com/zhayujie/chatgpt-on-wechat.git
synced 2026-07-17 11:07:11 +08:00
security: replace eval() with ast.literal_eval + document pickle risk
- config.py:418 — Replace eval(value) with ast.literal_eval() for environment variable config overrides. ast.literal_eval only parses Python literals and cannot execute arbitrary code, preventing environment-variable-based code injection. - config.py:310-328 — Add security notes on pickle.load/dump usage. Pickle is safe here (local appdata file, same-process write/read), but notes suggest JSON migration or HMAC signing for future hardening. Fixes: potential RCE via controlled environment variables
This commit is contained in:
21
config.py
21
config.py
@@ -307,6 +307,12 @@ class Config(dict):
|
||||
self.user_datas[user] = {}
|
||||
return self.user_datas[user]
|
||||
|
||||
# SECURITY NOTE: pickle.load() can execute arbitrary code during
|
||||
# deserialization. This is safe as long as user_datas.pkl is trusted
|
||||
# (local app data directory, written only by this process). For a future
|
||||
# hardening pass, consider migrating to JSON (json.load/json.dump) if the
|
||||
# data structures are JSON-serializable, or adding an HMAC signature to
|
||||
# detect tampering of the pickle file.
|
||||
def load_user_datas(self):
|
||||
try:
|
||||
with open(os.path.join(get_appdata_dir(), "user_datas.pkl"), "rb") as f:
|
||||
@@ -320,6 +326,8 @@ class Config(dict):
|
||||
|
||||
def save_user_datas(self):
|
||||
try:
|
||||
# SECURITY: pickle.dump output should only be loaded by this same
|
||||
# process. See note on load_user_datas() above.
|
||||
with open(os.path.join(get_appdata_dir(), "user_datas.pkl"), "wb") as f:
|
||||
pickle.dump(self.user_datas, f)
|
||||
logger.info("[Config] User datas saved.")
|
||||
@@ -415,11 +423,16 @@ def load_config():
|
||||
if name in available_setting:
|
||||
logger.info("[INIT] override config by environ args: {}={}".format(name, value))
|
||||
try:
|
||||
config[name] = eval(value)
|
||||
except Exception:
|
||||
if value == "false":
|
||||
# SECURITY: Use ast.literal_eval instead of eval().
|
||||
# ast.literal_eval only parses Python literals (strings, numbers,
|
||||
# tuples, lists, dicts, booleans, None) and CANNOT execute
|
||||
# arbitrary code, preventing environment-variable injection.
|
||||
import ast
|
||||
config[name] = ast.literal_eval(value)
|
||||
except (ValueError, SyntaxError):
|
||||
if value.lower() == "false":
|
||||
config[name] = False
|
||||
elif value == "true":
|
||||
elif value.lower() == "true":
|
||||
config[name] = True
|
||||
else:
|
||||
config[name] = value
|
||||
|
||||
Reference in New Issue
Block a user