1.5 文件操作
1.5.1【必须】文件类型限制
- 通过白名单对上传或者下载的文件类型、大小进行严格校验。仅允许业务所需文件类型上传,避免上传木马、WebShell等文件。
import os
ALLOWED_EXTENSIONS = ['txt','jpg','png']
def allowed_file(filename):
if ('.' in filename and
'..' not in filename and
os.path.splitext(filename)[1].lower() in ALLOWED_EXTENSIONS):
return filename
return None
1.5.2 【必须】禁止外部文件存储于可执行目录
- 禁止外部文件存储于WEB容器的可执行目录(appBase)。建议使用 tempfile 库处理临时文件和临时目录。
1.5.3 【必须】避免路径穿越
- 保存在本地文件系统时,必须对路径进行合法校验,避免目录穿越漏洞
import os
upload_dir = '/tmp/upload/' # 预期的上传目录
file_name = '../../etc/hosts' # 用户传入的文件名
absolute_path = os.path.join(upload_dir, file_name) # /tmp/upload/../../etc/hosts
normalized_path = os.path.normpath(absolute_path) # /etc/hosts
if not normalized_path.startswith(upload_dir): # 检查最终路径是否在预期的上传目录中
raise IOError()
1.5.4 【建议】避免路径拼接
- 文件目录避免外部参数拼接。保存文件目录建议后台写死并对文件名进行校验(字符类型、长度)。
1.5.5 【建议】文件名hash化处理
import uuid
def random_filename(filename):
ext = os.path.splitext(filename)[1]
new_filename = uuid.uuid4().hex + ext
return new_filename