部署调试符号(pdb文件)在生产环境中的风险是什么?

86
我有一个应用程序,记录异常堆栈跟踪,并希望在生产环境中部署时,这些堆栈跟踪包括文件名和行号。我找到了如何与程序集一起部署调试符号的方法,但在研究该问题的过程中,我遇到了this question,它暗示在生产环境中包含pdb文件不是一个好主意。对于接受的答案,有一个评论说:“...调试信息可能泄露敏感数据并成为攻击向量。这取决于你的应用程序是什么。”
那么可能会暴露哪些敏感数据?调试符号如何被用来危害应用程序?我对技术细节很感兴趣,但我真正想知道的是评估在任何给定应用程序和生产环境中包含调试符号的风险的实际方法。或者换句话说:最坏的情况会是什么?
编辑:后续问题/澄清

根据大家迄今为止的回答,似乎可以将这个问题在.NET应用程序中简化一些。链接到John Robbins博客Michael Maddox的答案的这段内容引起了我的注意:

.NET PDB仅包含两个部分的信息:源文件名及其行数、局部变量名。所有其他信息已经存在于.NET元数据中,因此不需要在PDB文件中重复存储相同的信息。

对我来说,这再次强调了其他人关于Reflector的说法,暗示真正的问题是访问程序集。一旦确定了这一点,关于PDB文件唯一需要决定的事情就是是否关心暴露文件名、行号和局部变量名(假设您一开始并不向最终用户显示堆栈跟踪)。或者我是否过于简化了这个问题?


@Matt:这是桌面应用程序、Web、紧凑型还是其他类型的应用程序? - Kb.
@Kb - 在这种特殊情况下,它是一个我们使用调度程序运行的控制台应用程序。它是为内部使用而自行开发的,因此任何能够看到pdb文件的人也将能够看到源代码,所以我对这个特定的应用程序不太担心。我更感兴趣的是一般/实际情况,这样我就可以决定是否冒险尝试其他应用程序,例如安装在偶尔连接到我们网络上敏感数据的笔记本电脑上的桌面应用程序。 - Matt
4个回答

60

这里有一个需要注意的问题:

在生产服务器上保留PDB调试文件是否存在安全问题?

还有更多关于PDB文件的信息:

PDB文件:每个开发人员都必须了解的内容

一般来说,我总是在我的部署中包含pdb文件,因为这样做可以获得很大的收益。

如果您从不向用户公开堆栈跟踪(通常情况下不应该),则在部署PDB文件时并没有任何额外的安全风险。

当用户出现可见的堆栈跟踪时,用户可以看到完整的堆栈跟踪,包括您的文件名和文件行号。这可能会让他们对您的应用程序架构有一些想法,从而可能帮助他们进行黑客攻击。

更大的安全威胁是像Reflector这样的工具,当它被用于您的DLL时,将允许其他人查看您的源代码,无论是否有pdb文件。


3
谢谢提供链接。因此,看起来方程式的至少一部分取决于应用程序被部署的位置(即桌面版还是Web服务器)。 - Matt

15
如果您在自己的组织中部署到生产环境,那么这不是一个安全问题。
如果您将软件销售给其他实体,则 .pdb 文件可能会为对反向工程感兴趣的人提供协助——这可能对您有利也可能不利。
但是(需要明确),无论 .pdbs 是否可用,都不希望客户端显示堆栈跟踪。但是,如果仅记录跟踪并向客户端呈现“漂亮”的错误页面,则没有问题。

我相信Matt在谈论.Net。通过PDB,有哪些额外的信息可以获得,而这些信息不像Lutz的Reflector工具那样已经可用? - Lars Truijens
源代码和行信息立即浮现在脑海中。我不认为本地变量名存在于元数据中。 - Michael
@Lars - 我从未说过它会有所帮助 :) 我认为围绕 PDB 和反向工程的整个恐惧是非常不合适的。能够使用 PDB 进行反向工程的人可以使用支持注释的良好反汇编器。 - Michael
1
我可以理解在非常长的方法中使用本地变量名称可能有助于逆向工程,但源文件名称和行信息呢?如果你问我,与 Reflector 等工具相比,这并不是真正的风险 :) - Lars Truijens
1
@Lars - 我认为表达Michael Maddox和我所说的另一种方式是,将.pdb文件提供给经常拥有这些程序集的人通常不会构成安全风险。将堆栈跟踪可用于没有这些程序集的人可能会构成风险。 - Michael Burr
所以,如果我理解正确的话,在Web应用程序中显示堆栈跟踪比在桌面应用程序中包含PDB(因为可以访问程序集)更危险。更大的教训是不应该在源代码中包含任何敏感内容吗? - Matt

11

拥有调试符号后,攻击者可以确定感兴趣的全局变量、函数偏移量等信息。

这样他就能看到您的系统有一个类似于以下的函数:

AddAdminUser(string name, string password);

了解它的偏移量。如果您的程序受到攻击,攻击者可以调用此函数以获得管理员特权。

或者类似于:

typedef enum {Basic, NTLM} AuthenticationMode;
AuthenticationMode g_authenticationMode;

它知道要翻转哪个比特位以将您的应用程序切换到不安全模式。

或者,这需要相当长的反向工程时间才能弄清楚。然而,并非不可逾越的时间。

但是......这都意味着您的攻击者已经处于可以危及您的程序的位置。如果是这种情况,您已经输了。

如果您有充分的商业理由部署pdb符号,请继续。部署PDB不会使您不安全。如果您没有部署的充分理由,则不应该这样做,因为会使攻击稍微容易一些。

您还可以创建公共PDB文件-这些文件剥离某些信息,但提供足够的符号来生成堆栈跟踪和进行基本调试。详情请参见这里。Microsoft在其符号服务器上部署公共PDB供所有人使用。

编辑:我所说的大多数内容都适用于部署原生代码的PDB的问题——我认为很多人也将这些担忧移到了.NET上,尽管装配元数据已经传达了其中很多。


6
我相信Matt在谈论.Net。即使没有PDB,您已经可以从像Lutz的Reflector这样的工具中获取所有源代码。 - Lars Truijens
@Lars - 我更新了我的评论以指出大多数代码都是本地代码。我认为很多人只是因为对PDB文件有一种无理的恐惧,认为攻击者不知道如何使用IDA Pro等反汇编工具,从而认为PDB会使逆向工程成为可能。我认为这些担忧也错误地引入到了托管代码中。 - Michael

2

有人可能会“恢复”您的应用程序的完整源代码。如果它是开源的,您不需要担心。如果它包含一些知识产权(算法、保护、许可),那么这可能不是一个好主意。

确实,像Reflector这样的工具甚至可以在没有PDB文件的情况下重建您代码的部分内容,但混淆可以帮助一点点(嗯,只是一点点)。


1
我相信Matt在谈论.Net。即使没有PDB,你已经可以从像Lutz Reflector这样的工具中获取所有源代码了。 - Lars Truijens
Lars,我完全同意,Reflector是逆向工程的好工具。但有时结果代码不太可读,特别是如果源代码被混淆了。PDB文件会让生活变得更美好。 - db_

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接