mirror of
https://github.com/zhayujie/chatgpt-on-wechat.git
synced 2026-07-19 04:37:28 +08:00
Merge pull request #2927 from shunfeng8421/fix/eval-ast-literal-eval
security: replace eval() with ast.literal_eval + document pickle risk
This commit is contained in:
21
config.py
21
config.py
@@ -307,6 +307,12 @@ class Config(dict):
|
|||||||
self.user_datas[user] = {}
|
self.user_datas[user] = {}
|
||||||
return 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):
|
def load_user_datas(self):
|
||||||
try:
|
try:
|
||||||
with open(os.path.join(get_appdata_dir(), "user_datas.pkl"), "rb") as f:
|
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):
|
def save_user_datas(self):
|
||||||
try:
|
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:
|
with open(os.path.join(get_appdata_dir(), "user_datas.pkl"), "wb") as f:
|
||||||
pickle.dump(self.user_datas, f)
|
pickle.dump(self.user_datas, f)
|
||||||
logger.info("[Config] User datas saved.")
|
logger.info("[Config] User datas saved.")
|
||||||
@@ -415,11 +423,16 @@ def load_config():
|
|||||||
if name in available_setting:
|
if name in available_setting:
|
||||||
logger.info("[INIT] override config by environ args: {}={}".format(name, value))
|
logger.info("[INIT] override config by environ args: {}={}".format(name, value))
|
||||||
try:
|
try:
|
||||||
config[name] = eval(value)
|
# SECURITY: Use ast.literal_eval instead of eval().
|
||||||
except Exception:
|
# ast.literal_eval only parses Python literals (strings, numbers,
|
||||||
if value == "false":
|
# 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
|
config[name] = False
|
||||||
elif value == "true":
|
elif value.lower() == "true":
|
||||||
config[name] = True
|
config[name] = True
|
||||||
else:
|
else:
|
||||||
config[name] = value
|
config[name] = value
|
||||||
|
|||||||
Reference in New Issue
Block a user