【问题标题】:How do I avoid distributing sensitive information in my MSI by accident?如何避免意外在我的 MSI 中分发敏感信息?
【发布时间】:2018-06-26 22:02:39
【问题描述】:

如何避免意外在我的 WiX/MSI 中分发敏感信息?

  • 我不小心将密码、机器名称或登录凭据与我的 MSI 文件一起分发。我该如何最好地处理这个问题?
  • 部署后,我的应用程序错误地连接到我的 QA/UAT 系统而不是我的生产系统 - 因为我的设置的自定义操作代码中的调试构造错误。如何检测和避免这种情况?
  • 我一般如何避免分发此类信息?

这是一个问答式的问题,采用最简单的方法来避免意外通过您的 MSI 传播敏感信息

【问题讨论】:

  • 为什么不用InstallShield、Advanced Installer等标签?这适用于任何创建 MSI 文件的工具。
  • 好的,我会按照你的建议添加一些标签。

标签: wix windows-installer installshield advanced-installer wise


【解决方案1】:

Super Condensed:安装 Orca,让其他人参与帮助并按顺序检查原始表,然后是任何自定义操作代码。


所有这一切都是显而易见的 - 如果这发生在您身上并且您在野外有敏感信息:您所能做的就是撤回 MSI(希望从下载 - 在光学时代甚至更糟媒体),更改任何密码或任何其他泄露的内容 - 然后确保您不会再次遇到它。现在是重要的部分,未来如何避免它。

除了以下有关敏感信息的信息外,还请记住,您要包含在您的设置中的某些文件可能无法合法地再分发。典型示例是来自 Microsoft 的调试工具或来自第三方 SDK 工具包的调试工具。请仔细阅读文档并避免在您的自定义操作中使用此类“hacky 工具”。


短版

更新:让我记下,在我忘记之前,您应该从所有设置文件中删除“downloaded file blocking flag”(通常也是只读标志)。

下面的建议基本上是 1) 使用 Orca 扫描您的最终 MSI,2) 查看已安装的设置文件以及任何 模板与您的 MSI 一起提供的安装脚本。此外,3) 仔细检查您编译的自定义操作源,并可能改进发布构建配置实践(例如#ifdef _DEBUG,见下文)。 4) 通过检查 MSI 中的实际内容(提取它们)查看您的脚本自定义操作。至关重要的是:5)从其他人那里获得一些帮助以进行所有手动测试 - 获得一些同谋:-)。 说真的:设置与应用程序一样重要 - 要使您的解决方案成功,您有责任让 QA 人员和其他人参与测试 - 并告诉他们测试什么以及如何测试。

我会避免自己尝试自动进行此类检查。没有什么可以替代对数据的真实关注。也许社区解决方案将有助于长期。它可以成为验证套件的一部分吗?半自动的帮助可能会起作用,但全自动的魔法:算了吧。有太多的方法可以用你必须用的所有绳子在脚上开枪。

敏感数据可能是错误的术语,也许“无效内容”更合适。问题可能是由于您的应用程序在启动时指向您的测试服务器而不是生产服务器。自定义操作可能会弹出意外的消息框(有时会泄露敏感数据),并且会出现类似的发布错误,而不仅仅是暴露纯敏感数据。


质量检查 - 错误探索

检查意外包含的敏感数据显然与您的包裹的一般 QA 相关。它应该与一般测试同时进行。 QA 人员忙于应用程序测试,您真的必须推动这个部署测试,并制定测试计划。没什么特别的,但要测试所有安装模式(installreinstallrepairself-repairupgradepatchinguninstalladministrative installresume / suspended install(设置重启问题)你也应该做publishingadvertisement - 如果你有设备和网络来测试这个)并测试所有自定义操作功能(彻底)。实际上,您必须测试安装、重新安装、卸载和升级,但请测试所有模式。

如果您是本地化,请在所有版本的所有核心区域进行测试。还在德国地区运行英语,反之亦然,仅用于烟雾测试。事实上,在所有地区测试英语 - 我猜很明显。自定义操作很容易在由该机器上的随机状态触发的本地化机器上失败(例如,CA 试图访问硬编码的英文路径和异常结果),或者在异常处理程序代码或类似代码中显示一些被遗忘的英文消息框从未在英文盒子上触发。不好,哦,是的,而且我经常看到它应该被记录为一个问题。

而且我想应该提到一位经验丰富的开发人员的话:“...在发现的每个错误都是真正的惊喜之前,不要对太多人进行测试”。而且 - 他更有趣的建议 - 预发布会留下几个已知的错误,并告诉 QA 人员有这样那样数量的错误要找到 - 只是为了一些集中注意力的动力:-)。 P.S:我喜欢称这位经验丰富的开发人员为“​​老蚱蜢”,或者更常见的是“素食男孩”。孔子说:“永远不要相信可以用(有机)胡萝卜收买的人!

题外话,回到真正的主题:错误包含敏感数据。


检查 MSI 文件

在检查我的 MSI 文件中是否有敏感信息时,我会保持简单。

  1. 首先快速浏览一遍源文件(WiX、Installshield、Advanced Installer 或您使用的任何工具),以解决硬编码的开发盒问题
  2. 然后特别注意检查已完成的候选版本 MSI 文件。真正的麦考伊。所有表格,还提取一些嵌入内容以供验证(脚本、自定义操作 dll 等...)。
  3. 所有安装模式下的实际安装,如上所述。敏感内容可能会被泄露,但许多其他问题也可能会被泄露 - 例如弹出的意外消息框 - 有时会显示敏感的调试信息(自定义操作测试焦点)。

如何检查?一些脚本检查可能很有用,但从经验来看,我并不喜欢它。如果我是诚实的,我更喜欢第二双眼睛而不是花哨的脚本检查。真正的发布工作只是我的两分钱。

  1. 安装 Orca
    • Orca 与 MSI 一样精确 - 其他工具经常显示虚假的专有表格。 Orca 是文件内容的直接视图。
    • 如果您安装了 Visual Studio,请搜索“Orca”here 以快速找到安装程序 - 或者告诉安装了 Visual Studio 的人员向您发送安装程序 MSI。
    • 您也可以尝试“Super Orca” - 但建议使用 Orca。
  2. 现在只需使用 Orca 打开您的候选发布 MSI - 并浏览表格
    • 简单地说:
      • 在真实源中强制执行任何更改,不要修补已完成的 MSI。
      • 如果您问我,根本不需要现场修补程序 - 在我看来,您需要从源头进行修复并重建完整的 MSI 文件。然后你给你的源代码贴上标签(如果你有适当的、老式的源代码控制,带有美味的修订和标签)。
    • 最容易受到攻击的表可能是:RegistryPropertyIniFile- 但其他几个位置也可能存在问题。
    • 如果您实际使用 MSI GUI:tables relating to GUI 也容易受到攻击。
      • 很多人只是使用标准的 GUI 而不做任何修改。这应该可以消除大部分风险。
      • 如果您有自定义 GUI,那么 there are quite a few tables involved in the MSI GUI declaration。我会盯着他们所有人看。
      • 也许特别关注:ListBoxComboBoxUITextDialog
      • 显然要特别关注您自己的自定义对话框 - 如果有的话。
    • 第三方工具为诸如 XML 文件更新之类的事情提供易受攻击的自定义表。眼球这些也是。
      • 任何看起来像 XMLFile、SQLUpdates 等的东西......
      • 来自不同供应商的此类自定义表格越来越多。它们现在涉及到各种各样的东西,而不仅仅是配置文件(防火墙规则、SQL 脚本等......)
    • 检查所有包含的脚本。
      • 签入源代码管理,但也...
      • CustomAction table 或 Binary table - 后者要求您输出任何脚本 - 或在其源位置检查它们。
  3. 检查应用程序安装的所有设置文件(通过 MSI 的文件表)。
    • 可以通过文件表安装具有硬编码设置的 INI 文件,因此它们的值在 Orca 中不可见(与显示要写入的 INI 的所有字段的 INIFile 表相反)。
      • 这里的区别本质上是文件是作为文件处理还是作为一组组值对处理以写入 INI。后一种方法是“正确”的方法。
      • 请注意,如果某些 INI 文件具有非标准格式(与正常键值对格式相反的额外字段和各种奇怪),甚至更常见,则可能需要将其安装为文件:INI 文件可能有很大的 cmets 部分,其中包含您想要保留的帮助信息(通常用于开发人员工具) - 而您不能通过 INI 文件表。然后可以选择将其安装为文件。
    • 其他设置文件(如 XML 文件)可以以相同的方式安装。事实上很多时候。
      • 如上所述,第三方工具通常支持从 Orca 中可查看的自定义表写入更新。
      • 可以有许多这样不同的表(加密字段?里面有什么?)
    • 像这样包含的文件通常由开发人员维护,但检查仍然是发布责任。为您的 MSI 创建一个administrative installation(链接答案中的更多链接)并检查创建的网络映像中提取的设置文件。 msiexec.exe /a "Your.msi"、或setup.exe /a(安装屏蔽)或setup.exe /extract(高级安装程序)。 Some setup.exe info
  4. 检查支持批量安装脚本Powershell脚本其他形式的脚本随您的设置提供 - 以执行实际操作软件的安装。
    • 有时您会看到带有一些设置的现成脚本可帮助自动部署,通常某种形式的硬编码信息会潜入此处(UNC 路径,甚至 IP 地址或其他类型的测试数据)。李>
    • 根据我的经验,这些脚本有时作为单独的下载提供,可能是事后才想到的,最终被 QA 忽略了。
    • 在 QA 和测试期间积极使用这些脚本(如果可用,或者更好):改为在单页 PDF 中记录大规模部署(更通用且不易出错)。
  5. 警告:已编译的自定义操作 仍然可能包含敏感内容,即使在 Orca 中什么都看不到 - 很明显。有时一时冲动很容易忘记。这是非常重要的(新宠词)——回到源代码。
    • 已编译的自定义操作不能直接“查看”,因此任何硬编码的敏感内容“暴露程度较低”。
    • 但是,错误的硬编码 IP 地址可能会导致您的所有用户尝试连接到您的测试服务器或您自己想要的任何其他服务器...我怀疑这不会在设置期间发生,但在第一次应用启动。
    • 再次:获得帮助 - 第二双眼睛会为您省去麻烦,但这次也让他们阅读实际的源代码。告诉他们专注于意想不到的、硬编码的值和奇怪的定义——任何看起来“实验性”的东西。
      • 这种“白盒”或“透明”质量检查在这里可能很好。招聘另一位开发人员?我会只关注“奇怪的东西”的代码,而不是测试实际功能(即用于黑盒测试)。
      • 显然,该代码仅适用于用户输入或在命令行中设置的值的 MSI PUBLIC PROPERTIES。任何硬编码的东西都不应该真的存在。然而,在现实世界中,大多数开发人员最终都会在调试版本中设置硬编码。
      • QA 专业人员 应该被告知如何测试相同的自定义操作“black box” - 以及第一个应用程序启动以测试正确的值被写入到任何地方.
      • 您能否为 QA 人员提供一些方便的应用程序级日志记录,他们知道存在并且知道如何使用(并且需要他们进行检查?)。然后,您应该在他们发现您的发布应用程序访问您的内部测试服务器而不是您的生产服务器之前几分钟。
    • 对于已编译的 C++ 自定义操作,如果您坚持硬编码,我建议您使用良好的挑剔调试实践。使用#ifdef _DEBUG 包装debugging message boxes 和任何hard coded test variables。请参阅下面的 C++ sn-p。这意味着发布版本中根本没有实验值(预处理器将删除所有调试结构)。
    • 也许也将NOMB 添加到您的发布版本中?请参阅下面的示例 - 应该防止杂散的发布构建消息框 - 定义本质上是“禁止” 他们(其他,可能的定义:How to tame the Windows headers (useful defines)?)。
      • 我只是简单地测试了这个。不过,我在发布版本中弹出了相当多的被遗忘的 C++ 消息框——我不得不承认——幸运的是没有灾难(敲木头等等等等)。
      • 请记住,这样的消息框可能会在没有任何警告或明确原因(通常没有日志消息)的情况下神秘地停止以静默模式远程运行的安装程序。
      • 此类消息通常由某种错误条件或异常触发,大多数安装通常不会触发 - 所以它突然出现在某些 PC 上。远程部署时无法恢复。设置没有正确回滚,它只是卡住了。如果没有用户在本地登录,则也无法在机器上将其关闭。不完全是关于敏感信息,而是相关的(确切地说是在盒子上显示的内容?),以及在测试自定义操作时需要查看的内容。
      • 一个自然的问题是,是否有办法让消息框自动超时?我简要地对这个建议的MessageBoxTimeout 方法(来自user32.dll)进行了烟雾测试,它似乎甚至支持上述NOMB 功能以及超时。换句话说,您可以将消息框设置为在发布版本中禁止和在调试版本中超时。未经彻底测试。
    • C++ 不是我的菜,请使用贵公司定义的发布版本的最佳实践。也许寻找定义和字符串变量。或者所有设置都可能位于仅包含在调试版本中的设置文件中(但奇怪的东西往往会到处蔓延)。
    • 对于托管代码,我问自己的问题是:这个托管二进制文件的反编译能力如何?我在这里的经验很少。我从来没有花时间反编译托管二进制文件。
      • 无论如何,代码中不应该有任何敏感内容 - 除非您有隐藏的私钥、许可证密钥或类似奇怪的东西 - 我绝对不会这样做,让应用程序去做。
      • 对于为您的应用程序设置试用期等功能,我想您可能希望更好地“隐藏实施”。某种混淆可能很常见,我没有跟上速度。也许这是 .NET 世界中更大的问题之一? 该主题的专家:请教育我们
      • 我将关注与上述相同的问题:调试错误地包含在发布模式二进制文件中的构造以及设置为测试服务器和测试资源的错误链接和路径。
  6. 在您的官方版本中意外包含调试构建二进制文件
    • 在某些情况下很容易发生的另一个问题:您在 MSI 中包含自定义操作 DLL 的调试版本
    • 这显然会发生在您设置中的任何文件上,不仅仅是您的自定义操作 DLL,而且自定义操作 DLL 在构建后特别“隐藏”在您的包中(嵌入在 MSI 的二进制表中 - 验证它)。李>
    • 也许确保在您编译的自定义操作 dll 或任何其他文件的文件名中添加d?即使这会给您带来一些额外的工作?
    • 我不确定调试 dll 到底有多“敏感”(必须由适当的 C++ 专家详细说明)——但我肯定不想在我的设置中无意中分发此类文件。我有时(很少)为 QA 团队制作调试构建 MSI 文件,仅包含用于测试目的的调试二进制文件和符号,在我看来,这些设置应该在一两个月后过期,并且永远不容易安装并且永远不会在您的 QA 团队之外使用.可以添加要安装的密码,但 MSI 是一种开放格式,仍然可以提取。没有戏剧性,我想只是需要记住和管理的事情。
  7. 现在这有点推动“敏感数据”这个话题了,但是对您打算数字签名并公开发布的任何内容进行一次彻底的恶意软件扫描怎么样? ?签名的恶意软件不是您想要体验的东西。
    • 验证您在发布文件(如果有)上的数字签名。使用 UAC 等进行测试...
    • 可以使用 Virustotal.com 或等效的恶意软件扫描服务/解决方案来扫描您的最终 MSI 文件中的恶意软件(或误报)。
    • 测试安装后使用procexp64.exe(直接下载Sysinternals Process Explorer)扫描所有正在运行的进程。 See some suggested usage steps for the tool here
    • 使用这些工具还可以帮助您消除误报。随着安全软件加强安全性和恶意软件变得更加普遍,一个可怕的问题似乎变得越来越严重。
      • False-positives may cause endless self-repair(请参阅该链接中的问题 7)用于您部署的包,因为文件被反复隔离,然后由 Windows 安装程序通过自我修复放回。
      • 误报讽刺对于真正的恶意软件,您告诉用户重建他们的计算机。 对于误报,您面临与安全软件供应商解决问题的压力。现在如何为数十种安全工具和套件做到这一点?

仅调试 C++ 自定义操作中的消息框:

我使用消息框将调试器附加到 C++ 自定义操作代码。如何避免这些小动物出现在发布版本中?这里有一个建议:

#ifdef _DEBUG //Display Debug information only for debug builds
     MessageBox(NULL, "Text", "Caption", MB_OK|MB_SYSTEMMODAL);
#endif

高级 C++ 人员会立即发现他们应该为此创建一个更好的宏 - 将所有内容都包含在内 - 我不是 C++ 专家,所以我暂时将其省略(SafeMessageBox?DeploymentMessageBox?)。

stdafx.h 中,可以另外启用NOMB(应该防止MessageBox 编译,除非用#ifdef _DEBUG 包裹 - 使MessageBoxes 仅在调试版本中可用):

#ifndef _DEBUG // Forbid MessageBox in Release builds
    #define NOMB
#endif

公平的赌注,这可能会成为你最讨厌的定义之一 :-)。谁闻到了注释掉的部分?我不会使用#undef 来添加临时发布消息框——它会破坏整个保护功能——很可能会导致您希望避免的事情:一个杂散的消息框。如果必须的话,也许只需注释掉stdafx.h 中的#define,然后再次启用定义 - 通过构建过程自动 - 对于真正的公开发布构建,触发任何杂散消息框的编译错误

如上所述,您可以尝试新的MessageBoxTimeout 方法(来自user32.dll,显然自XP 起可用)来显示不会“卡住”但在指定秒数后超时的消息框。不用于发布,但可能对调试和 QA 有用。

一些上下文#ifdef DEBUG versus #if DEBUG。真正了解 C++ 的人,可以根据需要随时澄清或详细说明。以上来自一个非常古老的 C++ 项目。

基本上就是这样 - 几乎不是火箭科学 - 只是“咬人的小事”。关于以下主题的进一步讨论,但恕我直言,此手动扫描无法替代。我的诚实建议,抓住一些人(经理很好 :-) - 将他们作为同谋拉进来!),为他们安装 Orca,然后告诉他们点击表格并查看所有设置文件- 并让开发人员帮助编译自定义操作代码。仅仅查看原始的 Orca 表甚至可以有效地发现其他错误或缺陷。


敏感信息

在开发过程中有很多机会在您的 MSI 源中意外包含敏感信息:login credentialspasswordsdatabase connection stringsuser namesshare nameIP-addressmachine names、@ 987654385@、web host login credentialsother sensitive data

您的 MSI 显然根本不应该包含任何此类敏感信息 - 当然,除非您想指向您自己的网站,或者提供 联系电子邮件电话号码。然而,其他任何事情几乎总是不受欢迎的 - 由于开发实验(通常在 脚本自定义操作 - 或 编译自定义与此相关的操作 - 更糟糕的是,上面建议的 Orca 审查方法无法检测到,但用户通常无法查看,除非它通过意外消息框显示 - 或者如果 .NET 托管代码被反汇编) .

如果安装确实需要,此类“敏感”信息应该是最终用户在安装时设置的参数(属性),可以通过设置的交互式 GUI 设置,也可以通过 PUBLIC PROPERTIES 设置或在命令行转换时正在安装设置。这里有一些关于使用转换和公共属性的信息:How to make better use of MSI files 用于 MSI 文件的静默企业部署(链接的答案还提供了对更一般意义上的 MSI 问题和好处的相当特别的描述)。

【讨论】:

    猜你喜欢
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    相关资源
    最近更新 更多