选择 Crashlytics 时会植入一个在后续构建中运行的下载脚本
原文依据:2 处当产品名包含 `FirebaseCrashlytics` 时,工具向项目加入 `/bin/sh` 构建阶段,执行 Firebase 包检出目录中的 `Crashlytics/run`。该脚本源码不在所提供材料中,因此无法从本次审计确认其完整行为。构建阶段还明确授予它读取 dSYM、可执行文件和 GoogleService plist 的输入路径。
后续构建会以开发者的本地权限运行来自所解析 Firebase SDK 的代码,并让它接触应用二进制、调试符号及配置文件。若依赖来源或解析版本遭到破坏,这会成为代码执行及敏感构建资料泄露的入口。
选择名称含 `FirebaseCrashlytics` 的产品时,工具会把一个 `/bin/sh` 构建阶段写入项目;以后构建会执行 Firebase SDK 检出目录中的 `Crashlytics/run`,并向该阶段声明 dSYM、应用可执行文件和 GoogleService plist 等输入。该脚本不在所给源码中,因此其具体网络或数据处理行为无法确认。用户可要求作者说明并固定 Firebase 依赖版本,或限制该构建阶段的输入与执行环境。
var inputPaths = [ "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}", "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${PRODUCT_NAME}", "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist", "$(TARGET_BUILD_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/GoogleService-Info.plist", "$(TARGET_BUILD_DIR)/$(EXECUTABLE_PATH)" ] if isUserScriptSandboxingEnabled(project: project) { inputPaths.append("${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${PRODUCT_NAME}.debug.dylib") } let phase = PBXShellScriptBuildPhase( files: [], inputPaths: inputPaths, outputPaths: [], shellPath: "/bin/sh", shellScript: "\"${BUILD_DIR%/Build/*}/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run\"\n", runOnlyForDeploymentPostprocessing: false查看另外 1 个位置
if products.contains(where: { $0.contains("FirebaseCrashlytics")}) { print("Setting the debug format to DWARF with dSYMs") setDwarfWithDsymDebugInformationFormat(project: pbxproj) print("Adding the Crashlytics Run Script Build phase") if !hasCrashlyticsRunScriptBuildPhase(project: pbxproj) { addCrashlyticsRunScriptBuildPhase(project: pbxproj) } else { print("Crashlytics Run Script Build phase already exists") } }