与敏感数据暴露相关的还有应用程序写入控制台或存储在 Splunk 或 Elasticsearch 等数据库中的日志信息 。我经常看到一些日志,这些日志披露了被开发人员遗忘的敏感数据 。
切勿记录非公开信息 。公开,我的意思是任何人都可以查看或访问该信息 。诸如私钥或证书之类的东西不是公开的,不应与您的错误,警告或信息消息一起记录 。下次您从应用程序中记录某些内容时,请确保所记录的内容与以下消息之一不同:
[error] The signature of the request is not correct. The correct key to be used should have been X.请注意服务器返回给客户端的内容,尤其是但不限于应用程序遇到异常的情况 。通常由于缺乏时间或经验,开发人员忘记实施所有此类情况 。这样(通常在错误的请求之后发生),应用程序将返回过多的细节以暴露实现 。
[warning] Login failed for username X and password Y. User with username X as password Z.
[info] A login was performed with success by user X with password Y.
此应用程序行为也是由于数据泄露而引起的漏洞 。如果您的应用由于请求错误(例如缺少一部分)而遇到NullPointerException,则该异常不应出现在响应的正文中 。同时,HTTP状态应该是400,而不是500 。类型为4XX的HTTP状态代码旨在表示客户端的问题 。最终,错误的请求是客户端问题,因此应用程序应相应地代表它 。类型为5XX的HTTP状态代码旨在通知您服务器上存在问题 。您是否在下一个代码段的响应中看到了问题?
{异常消息似乎正在公开一个IP地址 。攻击者可以使用此地址来了解网络配置,并最终找到一种方法来控制基础结构中的VM 。当然,仅凭这些数据,就不会造成任何伤害 。但是,收集不同的公开信息并将它们汇总在一起可以提供对系统产生不利影响所需的一切 。在响应中具有异常堆栈也不是一个好选择,例如:
"status": 500,
"error": "Internal Server Error",
"message": "Connection not found for IP Address 10.2.5.8/8080",
"path": "/product/add"
}
at JAVA.base/java.util.concurrent.ThreadPoolExecutor这种方法还公开了应用程序的内部结构 。从异常堆栈中,您可以看到命名符号以及用于特定操作的对象及其之间的关系 。但更糟糕的是,日志有时会泄露您的应用程序使用的依赖项版本 。(您是否在前面的异常堆栈中发现了 Tomcat 核心版本?)
? .runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker
? .run(ThreadPoolExecutor.java:628) ~[na:na]
at org.Apache.Tomcat.util.threads.TaskThread$WrappingRunnable
? .run(TaskThread.java:61) ~[tomcat-embed-core-9.0.26.jar:9.0.26]
at java.base/java.lang.Thread.run(Thread.java:830) ~[na:na]
我们应该避免使用易受攻击的依赖关系 。但是,如果我们发现自己错误地使用了易受攻击的依赖关系,则至少我们不想指出这个错误 。即使该依赖关系不是易受攻击的,也可能是因为还没有人发现该漏洞 。上一小节中的暴露可以激发攻击者寻找该特定版本中的漏洞,因为他们现在知道这就是您的系统使用的漏洞 。邀请他们破坏您的系统 。攻击者经常针对系统使用最小的细节,例如:
Response A:在此示例中,响应A和B是调用同一身份验证终结点的不同结果 。他们似乎没有透露任何与类设计或系统基础结构有关的信息,但这些隐藏了另一个问题 。如果消息公开了上下文信息,那么这些信息也可以隐藏漏洞 。基于提供给端点的不同输入的不同消息可用于理解执行的上下文 。在这种情况下,这些可以用来知道用户名何时正确但密码错误 。这会使系统更容易受到暴力攻击 。提供给客户的回复无助于确定对特定输入的可能猜测 。在这种情况下,它应该在两种情况下都提供相同的消息:
{
"status": 401,
"error": "Unauthorized",
"message": "Username is not correct",
"path": "/login "
}
Response B:
{
"status": 401,
"error": " Unauthorized",
"message": "Password is not correct",
"path": "/login "
}
{
"status": 401,
"error": " Unauthorized",
"message": "Username or password is not correct",
"path": "/login "
推荐阅读
- 游戏|玩家唤醒《艾尔登法环》中的巨型NPC:老龙发怒电脑也遭不住
- 电饼铛版煎翅中的做法
- 帮你彻底搞懂 JS 中的 prototype、__proto__与constructor
- ps中的滤镜制作炫酷的人物头像
- 茶艺中的盖置是什么,盖置是什么东西
- 算法:矩阵中的路径
- 莳萝在化妆品中的作用,莳萝在烹调中的作用及用法
- 移动WebApp高性能解决方案——MIP
- “白山黑水”中的黑水是指哪条江河?
- 推荐系统提供web服务的2种方式