用途
该技能用于处理文件上传与云存储相关任务,覆盖 S3、Cloudflare R2、预签名 URL、分片上传以及图片优化,并关注大文件上传时不阻塞的处理方式。其角色定位为文件上传专家,强调安全与性能,不信任文件扩展名,认为大文件需要特殊处理,并优先采用预签名 URL 而非服务器代理。
主要能力
技能围绕文件上传与存储的安全和性能展开,包含以下原则:
- 永不信任客户端声明的文件类型
- 使用预签名 URL 进行直传
- 大文件采用流式处理,绝不整体缓冲
- 上传时进行校验,之后再优化
技能还列出了若干“锋利边缘”(常见陷阱),每项包含严重级别、场景、症状、原因与推荐修复:
-
信任客户端提供的文件类型(严重级别:CRITICAL)。场景:用户上传将 malware.exe 重命名为 image.jpg,仅检查扩展名后存储并提供服务,其他用户下载并执行。症状包括恶意软件以图片形式上传、提供错误的 content-type。原因是文件扩展名和 Content-Type 头可被伪造。推荐修复为检查魔数(magic bytes),示例使用 file-type 库的 fileTypeFromBuffer 与 fileTypeFromStream,并限定允许类型为 image/jpeg、image/png、image/webp。
-
无上传大小限制(严重级别:HIGH)。场景:无文件大小限制,攻击者上传 10GB 文件,导致服务器内存或磁盘耗尽、拒绝服务或产生巨额存储账单。症状包括大文件上传时服务器崩溃、巨额存储账单、内存耗尽。原因是无限制时攻击者可耗尽资源,合法用户也可能误传超大文件。推荐修复为设置大小限制,示例包括 Formidable 的 maxFileSize、Multer 的 limits.fileSize、客户端提前检查,以及带 ContentLength 的预签名 URL。
-
用户可控文件名导致路径穿越(严重级别:CRITICAL)。场景:用户上传名为 ../../../etc/passwd 的文件,直接使用文件名导致文件保存到上传目录之外,系统文件被覆盖。症状包括文件出现在上传目录之外、系统文件被访问。原因是用户输入不应直接用于文件路径,路径穿越序列可逃逸预期目录。推荐修复为净化文件名,示例使用 path.basename、正则替换、白名单扩展名,或直接生成 crypto.randomUUID() + ext 的新名称,并强调不要使用 "uploads/" + req.body.filename。
-
预签名 URL 共享或缓存不当(严重级别:MEDIUM)。场景:私有文件的预签名 URL 在 API 响应中返回,响应被 CDN 缓存,任何持有缓存 URL 的人可在数小时内访问私有文件。症状包括私有文件可通过缓存 URL 访问、过期后仍可访问。原因是预签名 URL 授予临时访问权限,若被缓存或共享,访问范围会超出预期。推荐修复为控制预签名 URL 的分发,示例包括敏感文件使用短过期时间(如 300 秒)、响应设置 Cache-Control: no-store, max-age=0,或使用 CloudFront 签名 URL 获得更多控制。
技能还包含验证检查项:仅检查文件扩展名(严重级别:CRITICAL,消息:检查魔数而非仅扩展名,修复动作:使用 file-type 库验证实际类型);用户文件名直接用于路径(严重级别:CRITICAL,消息:净化文件名防止路径穿越,修复动作:使用 path.basename() 并生成安全名称)。
使用方式
当用户提及或暗示以下内容时使用该技能:file upload、S3、R2、presigned URL、multipart、image upload、cloud storage。示例用户请求为:Use @file-uploads for this task: Expert at handling file uploads and cloud storage.
技能还包含协作与委派触发条件:图片优化 CDN 委派给 performance-optimization(图片交付);存储文件元数据委派给 postgres-wizard(数据库模式)。
适用场景
适用于需要处理文件上传、云存储、预签名 URL、分片上传、图片上传与优化的开发任务,尤其关注上传安全(类型校验、大小限制、文件名净化、预签名 URL 分发控制)与性能(流式处理、不阻塞)。
限制
仅当任务明确匹配上述范围时使用该技能。不要将输出视为环境特定验证、测试或专家审查的替代。如果缺少必要输入、权限、安全边界或成功标准,应停止并请求澄清。