如何避免意外地在WiX / MSI中分发敏感信息?
这是一个Q / A风格的问题,采用最简单的方法避免意外地通过MSI传播敏感信息
Super Condensed:安装Orca,让其他人参与帮助并按顺序浏览原始表,然后再安装任何自定义操作代码。
所有这一切都是显而易见的 - 如果这发生在你身上并且你有疯狂的敏感信息:所有你能做的就是撤回MSI(希望下载 - 在光学媒体时代更糟糕),更改任何密码或者其他任何被揭示的 - 然后确保你没有再次体验它。现在,重要的是,如何避免将来。
除了以下有关敏感信息的信息之外,还请记住,您希望包含在设置中的某些文件可能无法合法再分发。典型的例子是Microsoft的调试工具或第三方SDK工具包的调试工具。请仔细阅读文档,避免在自定义操作中使用此类“hacky工具”。
更新:在我忘记之前,让我记下你应该从所有安装文件中删除“downloaded file blocking flag”(通常也是只读标志)。
下面提出的所有建议主要是1)使用Orca扫描最终的MSI,2)查看已安装的设置文件以及随MSI提供的任何模板安装脚本。此外,3)非常好地检查您编译的自定义操作源,并可能改进发布版本配置实践(例如,#ifdef _DEBUG
,见下文)。 4)通过检查MSI中的实际内容(提取它们)来检查脚本自定义操作。至关重要的是:5)从其他人那里获得所有手动测试的帮助 - 得到一些帮凶:-)。说真的:设置和应用程序一样重要 - 为了让您的解决方案成功,您有责任让QA人员和其他人参与测试 - 并告诉他们测试的内容和方法。
我会避免尝试自动进行此类检查。对数据的真实眼球无可替代。也许社区解决方案有助于长期发展。它可能成为验证套件的一部分?半自动帮助可能有效,但完全自动魔术:忘了它。有太多的方法可以使用你必须在脚上射击的所有绳索。
敏感数据可能是错误的术语,也许“无效内容”更合适。应用程序在启动时指向测试服务器而不是生产服务器,可能会导致问题。可能会从自定义操作(有时会泄露敏感数据)中弹出意外的消息框,并且除了暴露的纯敏感数据之外,类似的版本错误也会出现。
检查事故中包含的敏感数据显然与您的包裹的一般质量保证有关。它应该与一般测试同时进行。 QA人员忙于应用程序测试,您必须推动此部署测试,并制定测试计划。没有什么花哨,但测试所有安装模式(install
,reinstall
,repair
,self-repair
,upgrade
,patching
,uninstall
,administrative install
,resume / suspended install
(安装重启问题),你还应该做publishing
和advertisement
- 如果你有设备和网络来测试这个)并测试所有自定义动作功能(彻底)。实际上和最低限度,你必须测试安装,重新安装,卸载和升级,但请测试所有模式。
如果您要进行本地化,请在所有版本的所有核心区域进行测试。也可以在德国地区运行英语,反之亦然,仅用于烟雾测试。事实上,在所有地区测试英语 - 显然我猜。自定义操作可能很容易在本机上的随机状态触发的本地化计算机上失败(CA尝试访问硬编码的英语路径,例如异常结果),或者在您的异常处理程序代码或类似内容中以英语显示一些被遗忘的消息框从未在英文盒子上触发过。糟糕,哦,是的,而且我经常看到它应该被认为是一个问题。
我想应该提到一位经验丰富的开发人员的话:“......在发现每个错误都是真正的惊喜之前,不要打太多人进行测试”。并且 - 他更有趣的建议 - 对于预发布会留下几个已知的错误,并告诉QA人们有这么多的错误可以找到 - 只是为了一些动力集中思想:-)。 P.S:我喜欢将这位经验丰富的开发人员称为“The Elder Grasshopper”,或者他更常被称为“Veggie Boy”。孔子说:“永远不要相信一个可以用(有机)胡萝卜贿赂的男人!”
一个大的题外话,回到真正的主题:错误地包含敏感数据。
在检查我的MSI文件以获取敏感信息时,我会保持简单。
怎么检查?一些脚本检查可能很有用,但从经验来看,我并不喜欢它。如果我是诚实的话,我更喜欢用花哨的脚本检查第二双眼睛。只是我的两分钱来自真正的发布工作。
Registry
,Property
,IniFile
-但在其他几个地方可能会出现问题。
如果您实际使用MSI GUI:tables relating to GUI
也很脆弱。
许多人只是使用标准GUI而无需修改。这应该消除大多数风险。
如果您有自定义GUI,那么there are quite a few tables involved in the MSI GUI declaration。我会全神贯注他们。
也许特别关注:ListBox
,ComboBox
,UIText
,Dialog
显然,如果有的话,更加关注自己的自定义对话框。
第三方工具为XML文件更新等功能提供易受攻击的自定义表。眼球这些也是。
任何看起来像XMLFile,SQLUpdates等的东西......
来自不同供应商的定制表越来越多。它们现在与各种事物有关,而不仅仅是配置文件(防火墙规则,SQL脚本等......)
检查所有包含的脚本。
签入源代码管理,但也......
CustomAction
表或Binary
表 - 后者要求您流出任何脚本 - 或在源位置检查它们。msiexec.exe /a "Your.msi"
,或setup.exe /a
(Installshield),或setup.exe /extract
(高级安装程序)。 Some setup.exe info。#ifdef _DEBUG
包装debugging message boxes
和任何hard coded test variables
。请参阅下面的C ++代码段。这意味着在发布版本中根本没有实验值(预处理器将删除所有调试构造)。
也许还将NOMB
添加到您的发布版本中?请参阅下面的示例 - 应该防止错误发布构建消息框 - 定义基本上“禁止”它们(其他,可能定义:How to tame the Windows headers (useful defines)?)。
我只是简单地测试过这个。我已经在发布版本中弹出了相当多的被遗忘的C ++消息框 - 我不得不承认 - 幸运的是没有灾难(敲木头等等等等等......)。
请记住,这样的消息框可以神秘地停止在其轨道中以静音模式远程进行的设置运行,而没有任何警告或明确原因(通常没有日志消息)。
这种消息通常可以通过某种错误条件或通常不会被大多数安装触发的异常触发 - 因此在某些PC上突然出现这种情况。在远程部署时无法恢复。设置没有正确回滚,它只是卡住了。如果没有用户在本地登录,则无法在计算机上将其关闭。不是严格意义上的敏感信息,而是相关的(确切地显示在框上的内容?),以及在测试自定义操作时要注意的事项。
一个自然的问题是,是否有办法让消息框自动超时?我简要地测试了这个建议的MessageBoxTimeout方法(来自user32.dll
),它似乎甚至支持上面的NOMB
功能以及超时。换句话说,您可以设置发布版本中禁止的消息框和调试版本中的超时。未彻底测试。
C ++不是我的事,使用公司定义的发布版本的最佳实践。也许寻找定义和字符串变量。或者所有设置都可能位于调试版本中仅包含的设置文件中(但奇怪的东西往往会在这里和那里蔓延)。
对于托管代码,我问自己的问题是:这个托管二进制文件如何解密?我这里的经验不多。我从来没有花时间去编译托管二进制文件。
代码中应该没有任何敏感 - 除非你有一个隐藏的私钥,许可证密钥或类似的东西 - 我肯定不会这样做,留给应用程序做。
对于诸如为应用程序设置试用期等功能,我想您可能希望更好地“隐藏实现”。某些混淆可能很常见,我无法加快速度。也许这是.NET世界中更大的问题之一?关于这个主题的专家:请教育我们。
我将重点关注与上述相同的问题:调试错误地包含在发布模式二进制文件中的构造以及设置为测试服务器和测试资源的错误链接和路径。d
添加到已编译的自定义操作dll的文件名中 - 或者其他任何文件?即使它会给你一些额外的工作?
我不确定调试DLL到底有多“敏感”(一个合适的C ++专家必须详细说明) - 但我确实不想在我的设置中无意中分发这些文件。我有时(很少)为QA团队制作调试构建MSI文件,仅包含用于测试目的的调试二进制文件和符号,在我看来,这些设置应该在一两个月后过期,并且从不易于安装,永远不会在QA团队之外使用。可以添加要安装的密码,但MSI是一种开放格式,仍然可以提取。没有戏剧性,我猜想要记住并管理。C ++自定义操作中的仅调试消息框:
我使用消息框将调试器附加到C ++自定义操作代码。如何避免这些小动物出现在发布版本中?这是一个建议:
#ifdef _DEBUG //Display Debug information only for debug builds
MessageBox(NULL, "Text", "Caption", MB_OK|MB_SYSTEMMODAL);
#endif
高级C ++人员会立即看到他们应该让自己成为一个更好的宏 - 包装一切 - 我不是C ++ wiz,所以我现在就把它留下来(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 credentials
,passwords
,database connection strings
,user names
,share name
,IP-address
,machine names
,ftp passwords
,web host login credentials
或other sensitive data
。
您的MSI显然不应包含任何此类敏感信息 - 除非您想指向您自己的网站,或提供联系电子邮件或电话号码。但是,其他任何事情几乎总是不受欢迎的 - 并且很快就会忘记从生产MSI文件中删除此类硬编码信息(由于开发实验(通常在脚本自定义操作中)或编译后的自定义操作 - 更糟糕且无法检测到通过上面提出的Orca审核方法,但通常用户无法查看,除非通过意外消息框显示 - 或者如果反汇编.NET托管代码)。
如果实际需要安装,这种“敏感”信息应该是最终用户在安装时设置的参数(属性),可以通过设置的交互式GUI或通过PUBLIC PROPERTIES设置,也可以在设置时通过命令行进行转换。正在安装。这里有一些关于使用变换和公共属性的信息:How to make better use of MSI files用于MSI文件的静默,公司部署(链接的答案还提供了更为一般意义上的MSI问题和优点的特别描述)。