- 应用安全
- 网络安全
- 渗透测试
- 逆向工程
【免费下载链接】Mobile-Security-Framework-MobSF
Mobile Security Framework (MobSF) is an automated, all-in-one mobile application (Android/iOS/Windows) pen-testing, malware analysis and security assessment framework capable of performing static and dynamic analysis.
Mobile Security Framework(MobSF)是一个面向 Android / iOS / Windows 移动应用的自动化渗透测试、恶意软件分析与安全评估框架,支持静态与动态双重分析。正因其每一个代码路径都会处理来自已认证但可能怀有恶意的用户所提交的 APK、ZIP、IPA、Manifest 等攻击者可控输入,MobSF 将"安全默认优先"(Security must be the default, not an afterthought)确立为底层工程准则,并以仓库根目录的 AGENTS.md 固化成一套可执行的开发规范。
本文以 AGENTS.md 为骨架,结合mobsf/MobSF/security.py、mobsf/StaticAnalyzer/forms.py、tox.ini、.github/SECURITY.md 等仓库源码,系统拆解 MobSF 的安全架构、输入信任模型、Django 安全特性、归档解压防护与提交前检查清单。读者读完可掌握一套可直接复用的"处理不可信输入"的防御性编码方法,也能理解 MobSF 各类安全告警背后的设计意图。
一、前置门槛:提交前必须通过tox -e lint
AGENTS.md 的第一条硬性要求是:任何任务收尾前必须运行 lint 并修复全部错误,且不能留下非零退出码。具体命令为:
tox -e lint从 tox.ini 的[testenv:lint]配置可以看到,这一命令并非单一检查器,而是组合了autopep8(自动格式化)、flake8及flake8-bugbear、flake8-import-order、flake8-docstrings、pep8-naming、radon等系列插件,外加codespell拼写检查。关键约束包括:
flake8-import-order:要求每组 import 保持字母序,分组顺序为 stdlib → 第三方 → Django → 本地 MobSF;- 行宽上限
max-line-length = 88,圈复杂度上限max-complexity = 42; - 对
mobsf/uploads、mobsf/downloads、mobsf/static、mobsf/templates等目录排除检查。
同时 tox 环境列表为py312, py313,与 pyproject.toml 中python = "^3.12"的要求一致——这直接决定了下文 TAR 解压可依赖 Python 3.12 的内置安全过滤机制。
二、集中式安全架构:mobsf/MobSF/security.py
AGENTS.md 明确规定:新增安全检查时优先放入集中式安全助手模块mobsf/MobSF/security.py。部分历史遗留校验器仍存在于mobsf/MobSF/utils.py,对于已经确立的助手应优先复用。这种"单点收口"的架构使全框架的安全逻辑可审计、可复用,而不是散落在各个 view 中各自实现。
实际源码证实了这一点:security.py内的函数可分为四类。
2.1 路径安全
from mobsf.MobSF.security import ( is_path_traversal, # 检查原始字符串中的 .. 序列、绝对路径、URL 编码技巧 is_safe_path, # 路径构造后通过 realpath() 做包含关系检查 )is_path_traversal(user_input)(security.py):同时按 POSIX 与 Windows 语义检查,对输入做双层 URL 解码(防%252e→%2e→.的双重编码绕过),并拒绝\x00空字节、/、\开头的绝对路径、盘符(drive)以及任何包含..的路径;is_safe_path(safe_root, check_path, raw_file)(security.py):对安全根目录与目标路径都做normpath→realpath→normcase归一化后,用os.path.commonpath判断目标是否被包含在安全根内。
值得注意的历史教训:.github/SECURITY.md 中记录的 Windows-only path traversal via root-relative paths bypasses is_path_traversal()(影响<=4.5.3)正是"仅靠单一平台语义判断"导致的漏洞,因此现实现同时覆盖posixpath与ntpath。
2.2 输入验证
is_attack_pattern, # 检测 shell 注入:;、$()、||、&& cmd_injection_check, # 检测 OS 命令注入字符 is_pipe_or_link, # 读取文件前检测符号链接与命名管道(FIFO)is_attack_pattern使用正则;|\$\(|\|\||&&匹配典型 RCE 载荷,命中即记录Possible RCE attack detected日志并返回结果供调用方拦截;cmd_injection_check来自 Commix 思路的断字符清单,覆盖;、&、|、||及其 URL 编码变体(%3B、%26、%7C等)与%0a、%0d%0a换行注入;is_pipe_or_link(path)通过os.path.islink(path) or stat.S_ISFIFO(...)在读取文件前拒绝符号链接与命名管道,防止通过特殊文件类型读取任意内容。
2.3 输出净化
sanitize_filename, # 用于 Content-Disposition 头部的安全文件名 sanitize_for_logging,# 记录用户输入前剔除换行与控制字符 sanitize_redirect, # 重定向只允许相对路径 sanitize_svg, # 基于 bleach 剔除 SVG 中的 XSS 载荷 clean_filename, # Windows 安全文件名(Unicode 归一化)sanitize_filename将非[a-zA-Z0-9._-]字符替换为_并合并连续下划线;sanitize_for_logging(filename, max_length=255)将\n、\r、\t替换为_,再按白名单清洗并截断到 255 字符——这是防日志注入的关键手段(配合后端日志系统防止伪造日志行);sanitize_redirect仅放行以/开头的站内相对路径,//开头的协议相对 URL 与任意外部地址一律回落为根路径/,对应历史 Open Redirect 漏洞(GHSA-8m9j-2f32-2vx4,<=4.0.4);sanitize_svg基于bleach.clean白名单机制,只保留svg/g/path/rect/circle/text/image/use/filter/linearGradient/radialGradient等安全标签及其有限属性集,strip=True剥离脚本与事件处理器,对应历史恶意 SVG 图标存储型 XSS(GHSA-mwfg-948f-2cc5,<=4.3.2);clean_filename仅对 Windows 生效:先做 NFKD Unicode 归一化并转 ASCII,再按-_.() 字母数字白名单过滤,规避 Windows 保留字符与文件系统差异。
2.4 网络 / SSRF 防护
valid_host, # DNS 解析主机;拒绝私网/环回/组播 IPvalid_host是 SSRF 防护的第一道门,其底层实现远比名字复杂(security.py):
- 拒绝清单覆盖
127.0.0.0/8、169.254.0.0/16、172.16.0.0/12、192.168.0.0/16、10.0.0.0/8及 RFC 6598 共享地址段100.64.0.0/10; - 对 IPv6 做去映射与隧道解包:
::ffff:127.0.0.1先还原为 IPv4 再判定,sixtofour、teredo、64:ff9b::/96等翻译/隧道地址也会提取内嵌 IPv4 递归检查; - 主机名校验拒绝
localhost、无点号单标签名以及.home.arpa、.internal、.lan、.local、.localdomain等内网后缀; safe_stream_request/safe_request(security.py)更进一步:先解析全部 DNS 答案、确认均为公网地址,再连接字面 IP 并保留原 Host/SNI(通过_PinnedTLSAdapter),从根本上切断 DNS Rebinding 窗口,且上游代理会 fail-closed(代理做 DNS 即拒绝),响应大小默认限制 1 MiB。
这些实现正是对 SECURITY.md 中一系列 SSRF 历史漏洞(DNS Rebinding、Host 头注入、assetlinks_check 端口绕过等)的体系化回应。
三、以史为鉴:.github/SECURITY.md与"修复不完整反模式"
AGENTS.md 要求开发者阅读 .github/SECURITY.md 了解本代码库的安全问题完整历史,作为"哪些 Bug 类别值得警惕、哪些模式曾被利用过"的对照表。该文件按影响版本列出近 30 条已披露漏洞,高频出现的类别恰好对应前文四类助手:
| 漏洞类别 | 典型记录 | 对应防护函数 |
|---|---|---|
| 路径遍历 / Zip Slip / AR-Slip | GHSA-c8g7-42qj-frj3、GHSA-8j49-mmcx-4mp5、GHSA-9gh8-9r95-3fc3 | is_path_traversal+is_safe_path |
| SSRF / DNS Rebinding | GHSA-fcfq-m8p6-gw56、GHSA-wpff-wm84-x5cx | valid_host/safe_stream_request |
| CSRF(GET 触发状态变更) | GHSA-hh7q-v28p-p55m、GHSA-3p54-567p-2wpr | @require_http_methods+ CSRF 中间件 |
| 存储型 XSS(SVG、Manifest 字段) | GHSA-mwfg-948f-2cc5、GHSA-8hf7-h89p-3pqj | sanitize_svg+ 模板自动转义 |
| 命令注入 | CVE-2024-21633(apktool 任意文件覆写) | is_attack_pattern/cmd_injection_check |
| 压缩炸弹 DoS | GHSA-cvhc-xjjc-c4p3、GHSA-c5vg-26p8-q8cr | 解压前尺寸预算校验 |
| 开放重定向 | GHSA-8m9j-2f32-2vx4 | sanitize_redirect |
AGENTS.md 特别强调"Incomplete Fix Anti-Pattern"(修复不完整反模式):本代码库安全回归最常见的根源,是修复了某一条代码路径却漏掉了它的"兄弟路径"。关闭任何安全修复前必须:
- 搜索所有执行相同操作的函数/模式(例如每一处解析图标路径、每一处解压归档条目);
- 确认修复在全部等价路径上一致生效;
- 同时检查APK 二进制流程与源码 ZIP 流程——它们是独立代码路径、独立调用点,历史上曾发生过分化。
四、输入信任模型:默认一切不可信
AGENTS.md 给出了一份明确的"信任分级"表,这是所有校验逻辑的设计前提:
request.GET/request.POST:不可信,用表单或显式检查校验,输出时转义;- 文件上传:不可信,校验 magic bytes、大小限制与扩展名白名单;
- 归档条目(
zip/tar/ar):不可信,解压前逐条目检查; AndroidManifest.xml中的值:不可信,在用于文件系统操作或渲染前一律视为攻击者可控;Info.plist中的值:不可信,与 Manifest 值同等对待(对应 SECURITY.md 中"未校验 CFBundleExecutable 导致 iOS IPA 图标路径穿越"的 GHSA-m83p-3cgp-6p8c);md5/hashURL 参数:仅在校验后半可信,必须先经is_md5()(utils.py,正则匹配 32 位十六进制)再用于路径;- 设备标识符:不可信,需命令注入检查加格式校验。
五、Django 层安全特性:表单、装饰器、转义、ORM 与 CSRF
5.1 表单校验——首要输入净化层
AGENTS.md 规定新请求校验优先使用 Django Form;若某视图不用表单,则每个request.GET[...]/request.POST[...]都必须在使用前显式校验。项目采用mixin 组合模式而非在视图里写临时校验(StaticAnalyzer/forms.py):
# StaticAnalyzer/forms.py — 可组合的 mixin AttackDetect # 'file' 参数:is_path_traversal + 扩展名白名单 APIChecks # 'hash' 参数:MD5 格式校验(API 模式) WebChecks # 'md5' 参数:MD5 格式校验(HTML 模式) AndroidChecks # Android 扫描类型 ChoiceField 白名单 IOSChecks # iOS 扫描类型 ChoiceField 白名单AttackDetect.clean_file()先调is_path_traversal(file),再以正则^\.(kt|java|smali|xml|plist|m|swift|db|sqlitedb|sqlite|txt|json)$校验扩展名,任一失败即raise forms.ValidationError;APIChecks/WebChecks用min_length=32, max_length=32的CharField配合clean_hash()/clean_md5()调用is_md5();- 组合示例:
class ViewSourceAndroidApiForm(AttackDetect, AndroidChecks, APIChecks)一条类声明即完成"路径穿越 + 扫描类型 + 哈希格式"三层校验。
关键原则两条:自定义字段校验器必须写在clean_<field>()中并在拒绝时抛出forms.ValidationError,绝不能"返回部分结果再在视图里二次检查";失败时用FormUtil.errors_message(form)生成标准错误响应。
尤其重要的一条:凡取值集合有限的参数一律使用ChoiceField(如AndroidChecks的 eclipse/studio/java/smali/xml/apk/jar/aar/so/a 十个取值,IOSChecks的 ipa/dylib/ios),在表单层就消灭整类注入风险;严禁用CharField再在视图里手工比对白名单。
5.2 视图装饰器——三层齐备
处理敏感操作的视图应同时应用三个装饰器:
@login_required @permission_required(Permissions.SCAN) # 或 DELETE、SUPPRESS 等 @require_http_methods(['POST']) # 或 ['GET']——绝不能省略 def my_view(request, api=False): ...@login_required拦截未认证访问;@permission_required在认证之上再实施基于角色的访问控制(角色权限定义见 mobsf/MobSF/management/commands/create_roles.py);@require_http_methods在任何业务逻辑执行前拒绝错误 HTTP 动词,从机制上杜绝"GET 触发 CSRF"与 HTTP 方法混淆(method confusion)问题。
5.3 模板自动转义与 DOM 安全
Django 模板引擎默认转义变量。AGENTS.md 明令:对任何源自扫描数据、Manifest 或用户输入的值,禁用{% autoescape off %}与|safe过滤器;在模板之外手工拼接 JSON 等用户可控字符串时,必须显式调用django.utils.html.escape()。同时强调模板自动转义保护不了 JavaScript DOM 落点:绝不把扫描、任务或用户派生字符串赋给innerHTML,应使用textContent(示例见 templates/general/tasks.html)。
5.4 ORM——禁止原生 SQL
所有数据库访问必须走 Django ORM,禁止.raw()或字符串拼接 SQL。用户输入参与过滤时以关键字参数传入,让 ORM 自动参数化:
# 正确——参数化 RecentScansDB.objects.filter(MD5=checksum) # 错误——拼接导致 SQL 注入 RecentScansDB.objects.raw(f'SELECT * FROM ... WHERE MD5 = "{checksum}"')这条规则直接对应 SECURITY.md 中 GHSA-hqjr-43r5-9q58(SQLite 数据库查看器 SQL 注入,<=4.4.5)。
5.5 CSRF
Django 的CsrfViewMiddleware全局开启。任何修改状态的视图禁用@csrf_exempt;唯一合法例外是已确立模式的 API 端点(携带X-Csrftoken头或基于 Token 认证)。所有变更操作——包括动态分析的启动/停止/流式输出——必须使用携带 CSRF Token 的 POST,不能用 GET;当一个页面既要渲染又要流式输出(如 logcat)时,应将 GET 渲染与 POST 流式拆分为两个入口。
六、归档解压安全:TAR 与 ZIP 的差异化防护
6.1 TAR:必须用 Python 3.12 的filter='data'
AGENTS.md 用一个具体攻击链说明为何"手写 name-only 检查"不可靠:符号链接 + 嵌套条目组合可以绕过os.path.abspath名字检查——名为escape的符号链接成员先通过检查并落盘,随后名为escape/pwned.txt的文件成员经由该符号链接被写入任意位置。
技术要点:
os.path.abspath会归一化..但不解析符号链接;os.path.realpath两者都解析,但提取前执行的 realpath 检查仍存在TOCTOU 时间窗口;- 正确做法是利用 Python 3.12 内置过滤器(MobSF 要求
python = "^3.12"):
# 正确——逐成员、类型感知、符号链接感知 tar.extractall(dest, members=safe_members_generator, filter='data') # 错误——基于 abspath 的名字检查,对符号链接不可见 for member in tar.getmembers(): if not os.path.abspath(join(dest, member.name)).startswith(dest): raise ... tar.extractall(dest, members=...)filter='data'会在提取前、逐成员地拒绝:指向目标外的符号链接、目标外的硬链接、绝对路径、路径穿越以及设备文件。对于必须兼容 Python < 3.12 的代码,回退方案为:先跳过全部符号链接与硬链接成员(member.issym()/member.islnk()),再用realpath做边界检查,并且逐成员"校验后立即提取",而非"批量校验后再 extractall"。
6.2 ZIP:逐成员路径验证 + 解压预算
Pythonzipfile不会把 Unix 符号链接条目落成真实文件系统符号链接,而是将链接目标当作普通文件字节写入,因此 TAR 符号链接攻击对 ZIP 不适用。ZIP 场景的规范是:用is_path_traversal+is_safe_path校验成员名,并在调用zip_ref.extract(member, dest)之前逐成员验证。
仓库实现可作范例:mobsf/StaticAnalyzer/views/common/shared_func.py的解压循环(约 shared_func.py)完整落地了这一模型:
- 先对成员文件名做解码与"保留文件名冲突"(
is_reserved_file_conflict)处理; if (is_path_traversal(file_path) or not is_safe_path(ext_path, destination, file_path))命中即记录Zip slip detected并跳过该成员;- 解压前统计
file_size与累计总量,超出settings.ZIP_MAX_UNCOMPRESSED_FILE_SIZE单文件上限或ZIP_MAX_UNCOMPRESSED_TOTAL_SIZE总量上限即跳过或中止——这是对压缩炸弹 DoS(GHSA-c5vg-26p8-q8cr、GHSA-x768-8642-mmq9)的工程化防御; - 落盘文件强制
external_attr为rw-r--r--(644),避免解压出可执行权限位。
七、任何涉及文件 I/O 或用户输入改动的提交前清单
AGENTS.md 以一份可直接打勾的 checklist 收尾,覆盖了上文全部主题。它同时可作为其他安全敏感项目的通用验收模板:
- 原始输入在构造路径前先经
is_path_traversal校验 - 存在安全根时,构造出的文件系统路径用
is_safe_path复核 - 文件读取前用
is_pipe_or_link拒绝符号链接与 FIFO - Shell 参数以列表形式传递,而非格式化字符串
- 用户可控字符串渲染前用
django.utils.html.escape转义 - SVG 内容经过
sanitize_svg清洗 - 出站 URL 经
valid_host检查 - 重定向包裹
sanitize_redirect - 日志语句对任何用户派生值使用
sanitize_for_logging - TAR 解压使用
filter='data',而非手写abspath检查 - ZIP 解压在
extract()前用realpath逐成员校验路径 - 每个安全守卫都必须有
continue/return/raise——仅记日志不算拦截 - 修复对称地应用到所有等价代码路径
tox -e lint以退出码 0 通过
结语:把安全做成默认值
从 AGENTS.md 可以看出,MobSF 的安全工程并非依赖某个单一防护点,而是一条完整防线:表单层用ChoiceField与 mixin 消灭注入类别,视图层用三层装饰器收敛认证/授权/方法混淆,输出层用模板自动转义与sanitize_*系列封堵 XSS/重定向/日志注入,归档层用filter='data'与逐成员校验对抗 Zip Slip 与解压炸弹,网络层用 DNS 全量解析 + IP 固定连接对抗 SSRF 与 DNS Rebinding,而.github/SECURITY.md的历史漏洞清单则持续为这条防线提供"哪些模式曾经被攻破"的实证输入。任何为 MobSF 贡献代码、或借鉴其架构构建同类安全分析平台的开发者,都可以把这条"默认不可信、单点收口、对称修复、守卫必须中断执行"的规范直接落地为团队的编码纪律。
- 应用安全
- 网络安全
- 渗透测试
- 逆向工程
【免费下载链接】Mobile-Security-Framework-MobSF
Mobile Security Framework (MobSF) is an automated, all-in-one mobile application (Android/iOS/Windows) pen-testing, malware analysis and security assessment framework capable of performing static and dynamic analysis.
相关推荐
PhotoPrism 安全编码实践指南:归档解压与 HTTP 下载的安全防护规范(pkg/AGENTS.md 解读)
PhotoPrism 安全编码实践指南:归档解压与 HTTP 下载的安全防护规范(pkg/AGENTS.md 解读) 本篇技术指南以 PhotoPrism 仓库
后端前端图像处理人工智能AI 应用YOLOv5 仓库协作与 AI 编码 Agent 实践指南:基于 AGENTS.md 的工程规范解读
YOLOv5 仓库协作与 AI 编码 Agent 实践指南:基于 AGENTS.md 的工程规范解读 导读 本文围绕 YOLOv5 仓库根目录下的 AGENTS
人工智能深度学习计算机视觉预训练微调MobSF 安全开发指南:面向 AI 编码助手与安全工程师的攻击面防护规范
MobSF 安全开发指南:面向 AI 编码助手与安全工程师的攻击面防护规范 MobSF(Mobile Security Framework)是一款自动化的移动应
应用安全网络安全渗透测试逆向工程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考