GWT-RPC:对请求有效负载的黑客攻击
Posted
技术标签:
【中文标题】GWT-RPC:对请求有效负载的黑客攻击【英文标题】:GWT-RPC: hacked attempt on request payload 【发布时间】:2015-07-23 03:30:37 【问题描述】:我的测试团队尝试入侵系统,他们发现 GWT-RPC 调用以响应格式“//EX”消息返回了敏感信息(文件名如下强调)。我很惊讶我找不到任何关于这个问题的帖子。
HTTP 请求(请求负载):
7|0|5|http:/localhost:8080/Test_Web/|14B8AB60CF9C73722670313BAE18D294|abc|abc|abc|1| 2|3|4|1|5|0|
HTTP 响应:
//EX[2,1,["com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException/3936916533","此应用程序已过期,请点击浏览器上的刷新按钮。(已阻止尝试访问 接口 'abc',不是由 'com.testProject.client.customerClassService' 实现的;这是配置错误或黑客尝试)"],0,7]
特别是说“配置错误或黑客尝试”的部分。在我的例子中是作为 HTTP 响应的 hack 尝试,因为异常表明 'abc' 不是由 'com.testProject.client.customerClassService' 实现的。
有什么想法可以在上面的错误消息中隐藏敏感信息(强调类名)吗?我尝试使用所有可用的浏览器,它不是来自浏览器。
【问题讨论】:
【参考方案1】:您的 gwt-rpc 服务接口的名称不应被视为敏感信息。在每个 gwt-rpc 调用上,所有方法名称和参数都使用 ajax 发送...它类似于您可以对它们执行的 rest 服务 API 资源名称和 crud 操作。
您遇到的异常是由 gwt-rpc 服务接口/方法/签名的无效名称引起的 - 调用被阻止。在这种情况下,重要的是要记住输入参数的服务器端验证。你永远不知道调用是由你的应用发出的还是被伪造的......
【讨论】:
感谢您的知识。【参考方案2】:这里收集的“敏感”信息非常少,因此我们必须假设您已启用所有其他混淆功能(删除类元数据、混淆 rpc 类型名称,并且已经检查了您自己生成的 JS 以确保没有toString()
曾经返回它自己的类名)。
在这种情况下,如果这个类没有实现所请求的接口(显然是abc
),那么这是从com.google.gwt.user.server.rpc.RPC#decodeRequest(String, Class<?>, SerializationPolicyProvider)
发出的标准RPC 错误。如果有这样的界面,我会感到非常惊讶!有人可能会争辩说,如果这样的接口不存在,甚至不应该进行此检查,但即使进行该检查也会泄露有关您的服务器上不存在哪些类的信息,这也可能被认为是“敏感的”。
如果这是一个问题,我的建议是阻止 any IncompatibleRemoteServiceException
到达客户。这将有效地阻止对客户端的任何调试,但只需给它一个空白的“您的错误请求出现问题”。在一些合法的情况下,客户可能应该从这样的异常中获取信息,但从您的角度来看,这可能仍然是敏感的。如果您的问题中没有详细说明敏感的确切含义,这很难说。
话虽如此,下面是我将如何覆盖此行为:首先,查看 RemoveServiceServlet.processCall,通常通过将其记录给用户来处理该故障:
/**
* Process a call originating from the given request. This method calls
* @link RemoteServiceServlet#checkPermutationStrongName() to prevent
* possible XSRF attacks and then decodes the <code>payload</code> using
* @link RPC#decodeRequest(String, Class, SerializationPolicyProvider)
* to do the actual work.
* Once the request is decoded @link RemoteServiceServlet#processCall(RPCRequest)
* will be called.
* <p>
* Subclasses may optionally override this method to handle the payload in any
* way they desire (by routing the request to a framework component, for
* instance). The @link HttpServletRequest and @link HttpServletResponse
* can be accessed via the @link #getThreadLocalRequest() and
* @link #getThreadLocalResponse() methods.
* </p>
* This is public so that it can be unit tested easily without HTTP.
*
* @param payload the UTF-8 request payload
* @return a string which encodes either the method's return, a checked
* exception thrown by the method, or an
* @link IncompatibleRemoteServiceException
* @throws SerializationException if we cannot serialize the response
* @throws UnexpectedException if the invocation throws a checked exception
* that is not declared in the service method's signature
* @throws RuntimeException if the service method throws an unchecked
* exception (the exception will be the one thrown by the service)
*/
public String processCall(String payload) throws SerializationException
// First, check for possible XSRF situation
checkPermutationStrongName();
RPCRequest rpcRequest;
try
rpcRequest = RPC.decodeRequest(payload, delegate.getClass(), this);
catch (IncompatibleRemoteServiceException ex)
log(
"An IncompatibleRemoteServiceException was thrown while processing this call.",
ex);
return RPC.encodeResponseForFailedRequest(null, ex);
return processCall(rpcRequest);
我们不想捕获IncompatibleRemoteServiceException
并按原样将其注销,而是想写一个不起眼的“您的请求有问题,请提交给技术支持”之类的答案。请务必使用RPC.encodeResponseForFailedRequest
或RPC.encodeResponseForFailure
方法来确保将其编写为您的客户端代码和阅读并理解为故意模棱两可的异常。
【讨论】:
以上是关于GWT-RPC:对请求有效负载的黑客攻击的主要内容,如果未能解决你的问题,请参考以下文章