安全修复(High): 文件创建时设置权限 0o600

- 锁文件创建时设置权限 0o600
- 临时文件创建时设置权限 0o600
- 数据文件写入后确保权限为 0o600
- 防止未授权访问敏感统计数据
This commit is contained in:
2026-03-09 15:18:22 +08:00
parent 65ef23de5d
commit 3b5f728efe
+14 -9
View File
@@ -45,7 +45,9 @@ def _acquire_lock(lock_file_path: Path):
"""
try:
lock_file_path.parent.mkdir(parents=True, exist_ok=True)
lock_fd = open(lock_file_path, 'w')
# 使用 os.open 创建文件并设置权限
fd = os.open(lock_file_path, os.O_WRONLY | os.O_CREAT, 0o600)
lock_fd = os.fdopen(fd, 'w')
fcntl.flock(lock_fd.fileno(), fcntl.LOCK_EX)
return lock_fd
except (OSError, IOError) as e:
@@ -116,19 +118,22 @@ def _atomic_write(data: Dict[str, Any]):
try:
lock_fd = _acquire_lock(LOCK_FILE)
# 写入临时文件
with tempfile.NamedTemporaryFile(
mode='w',
encoding='utf-8',
dir=STATS_DIR,
suffix='.tmp',
delete=False
) as temp_file:
# 写入临时文件(使用 os.open 设置权限)
fd = os.open(
tempfile.mktemp(suffix='.tmp', dir=STATS_DIR),
os.O_WRONLY | os.O_CREAT | os.O_EXCL,
0o600
)
temp_path = f"/proc/self/fd/{fd}"
with os.fdopen(fd, 'w', encoding='utf-8') as temp_file:
json.dump(data, temp_file, ensure_ascii=False, indent=2)
temp_path = temp_file.name
# 原子重命名
os.replace(temp_path, STATS_FILE)
# 确保最终文件权限正确
os.chmod(STATS_FILE, 0o600)
temp_path = None # 防止在 finally 中再次删除
except (OSError, IOError) as e:
logger.error(f"写入统计文件失败: {e}")