fix: harden intranet CUPS setup

This commit is contained in:
2026-06-09 14:47:36 +08:00
parent 0878c71b5a
commit 2a688d2514
7 changed files with 158 additions and 112 deletions

View File

@@ -12,6 +12,7 @@ import tempfile
import shutil
import tarfile
import zipfile
import ipaddress
from pathlib import Path
from functools import wraps
@@ -29,6 +30,7 @@ ALLOWED_EXTENSIONS = {'deb', 'ppd', 'gz', 'tar', 'tgz', 'zip', 'rpm', 'sh', 'run
# 管理员凭据(可通过环境变量设置)
ADMIN_USERNAME = os.environ.get('DRIVER_MANAGER_USERNAME', 'admin')
ADMIN_PASSWORD = os.environ.get('DRIVER_MANAGER_PASSWORD', 'admin')
ALLOW_PRIVATE_ONLY = os.environ.get('DRIVER_MANAGER_ALLOW_PRIVATE_ONLY', '1').lower() not in ('0', 'false', 'no', 'off')
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = MAX_CONTENT_LENGTH
@@ -36,6 +38,46 @@ app.config['MAX_CONTENT_LENGTH'] = MAX_CONTENT_LENGTH
# 确保上传目录存在
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
@app.before_request
def limit_private_network():
"""默认只允许本机、链路本地和内网地址访问。"""
if not ALLOW_PRIVATE_ONLY:
return None
remote_addr = request.remote_addr or ''
try:
addr = ipaddress.ip_address(remote_addr)
except ValueError:
return Response('仅允许内网访问驱动管理器\n', 403)
if addr.is_loopback or addr.is_private or addr.is_link_local:
return None
return Response('仅允许内网访问驱动管理器\n', 403)
def _is_within_directory(base_dir, target_path):
base = os.path.realpath(base_dir)
target = os.path.realpath(target_path)
return os.path.commonpath([base, target]) == base
def safe_extract_tar(tar, path):
"""防止恶意 tar 包写出解压目录。"""
for member in tar.getmembers():
target_path = os.path.join(path, member.name)
if not _is_within_directory(path, target_path):
raise ValueError(f'压缩包包含非法路径: {member.name}')
if member.issym() or member.islnk():
raise ValueError(f'压缩包包含链接文件: {member.name}')
tar.extractall(path)
def safe_extract_zip(zip_ref, path):
"""防止恶意 zip 包写出解压目录。"""
for member in zip_ref.infolist():
target_path = os.path.join(path, member.filename)
if not _is_within_directory(path, target_path):
raise ValueError(f'压缩包包含非法路径: {member.filename}')
zip_ref.extractall(path)
def check_auth(username, password):
"""验证用户名和密码"""
return username == ADMIN_USERNAME and password == ADMIN_PASSWORD
@@ -168,7 +210,7 @@ def install_tar_gz(filepath):
try:
# 解压
with tarfile.open(filepath, 'r:gz') as tar:
tar.extractall(extract_dir)
safe_extract_tar(tar, extract_dir)
results.append(('解压文件', {
'success': True,
'stdout': f'已解压到 {extract_dir}',
@@ -240,7 +282,7 @@ def install_zip(filepath):
try:
# 解压
with zipfile.ZipFile(filepath, 'r') as zip_ref:
zip_ref.extractall(extract_dir)
safe_extract_zip(zip_ref, extract_dir)
results.append(('解压文件', {
'success': True,
'stdout': f'已解压到 {extract_dir}',