Android WebView 中网页被挟制的缘故原由及办理方案

打印 上一主题 下一主题

主题 866|帖子 866|积分 2608

在 Android 应用开发中,WebView 是一个常用的组件,用于在应用内显示网页内容。然而,有时用户可能会发现网页被挟制到另一个不安全的网页。这种情况不仅影响用户体验,还可能带来安全隐患。本文将探讨导致网页被挟制的可能缘故原由,并提供相应的办理方案。
一、缘故原由分析


  • JavaScript 重定向
    某个网页中包罗以下 JavaScript 代码:
    1. window.location.href = "http://malicious-site.com";
    复制代码
    这段代码会在页面加载时将用户重定向到恶意网站。
  • 恶意网页
    用户点击了一个链接,访问了一个看似正常的网站,但该网站现实上是一个垂纶网站,包罗重定向代码,试图引导用户输入敏感信息。
  • WebView 设置不当
    开发者在 WebView 中未设置 WebViewClient,导致 WebView 默认行为是打开全部链接,而不是在应用内处理。这可能导致用户被重定向到外部浏览器,增加了被恶意网站挟制的风险。
  • 拦截 URL 加载
    在 shouldOverrideUrlLoading 方法中,开发者没有精确处理 URL,例如:
    1. @Override
    2. public boolean shouldOverrideUrlLoading(WebView view, String url) {
    3.     // 没有验证 URL,直接加载
    4.     view.loadUrl(url);
    5.     return true;
    6. }
    复制代码
    这可能导致用户被重定向到不安全的网站。
  • 广告或跟踪脚本
    某些网页可能嵌入了广告或跟踪脚本,这些脚本会在用户访问时自动重定向到广告商的网站,乃至可能是恶意网站。
  • 中间人攻击
    在公共 Wi-Fi 网络中,攻击者可能通过中间人攻击拦截用户的网络请求,并将其重定向到恶意网站,伪装成合法网站。
  • DNS 挟制
    用户的 DNS 请求被挟制,导致访问某个合法网站时,现实上被重定向到攻击者控制的 IP 地址。例如,用户输入 www.example.com,但由于 DNS 挟制,现实访问的是 malicious-site.com。
二、办理方案一览

为了淘汰网页被挟制的风险,开发者可以接纳以下步调:


  • 利用 HTTPS:确保访问的网页利用 HTTPS,这样可以淘汰中间人攻击的风险。
  • 验证 URL:在 shouldOverrideUrlLoading 方法中,验证即将加载的 URL,确保它是安全的。
  • 禁用 JavaScript:如果不需要 JavaScript,可以思量禁用它,淘汰潜在的重定向风险。
  • 利用安全的 WebView 设置:确保 WebView 的设置是安全的,例如启用安全的内容加载计谋。
  • 监控网络请求:利用网络监控工具,检察 WebView 中的网络请求,辨认潜在的恶意重定向。
  • 利用安全的 DNS:思量利用安全的 DNS 服务(如 DNS over HTTPS),以淘汰 DNS 挟制的风险。
三、办理方案代码案例

以下是针对办理方案中提到的每个步调的代码案例,以帮助开发者更好地理解如安在 Android WebView 中实现这些安全步调。
3.1 利用 HTTPS

确保加载的网页利用 HTTPS。可以在加载 URL 进步行检查:
  1. private void loadUrl(WebView webView, String url) {
  2.     if (url.startsWith("https://")) {
  3.         webView.loadUrl(url);
  4.     } else {
  5.         // 提示用户或处理不安全的 URL
  6.         Toast.makeText(context, "不安全的链接,无法加载!", Toast.LENGTH_SHORT).show();
  7.     }
  8. }
复制代码
3.2 验证 URL

在 shouldOverrideUrlLoading 方法中验证即将加载的 URL:
  1. @Override
  2. public boolean shouldOverrideUrlLoading(WebView view, String url) {
  3.     if (isSafeUrl(url)) {
  4.         view.loadUrl(url);
  5.     } else {
  6.         // 提示用户或处理不安全的 URL
  7.         Toast.makeText(context, "不安全的链接,无法加载!", Toast.LENGTH_SHORT).show();
  8.     }
  9.     return true;
  10. }
  11. private boolean isSafeUrl(String url) {
  12.     // 这里可以添加更复杂的 URL 验证逻辑
  13.     return url.startsWith("https://") || url.startsWith("http://trusted-site.com");
  14. }
复制代码
3.3 禁用 JavaScript

如果不需要 JavaScript,可以在 WebView 设置中禁用它:
  1. WebView webView = findViewById(R.id.webview);
  2. WebSettings webSettings = webView.getSettings();
  3. webSettings.setJavaScriptEnabled(false); // 禁用 JavaScript
复制代码
3.4 利用安全的 WebView 设置

确保 WebView 的设置是安全的,例如启用安全的内容加载计谋:
  1. webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_NEVER_ALLOW); // 禁止混合内容
  2. webSettings.setDomStorageEnabled(true); // 启用 DOM 存储
复制代码
3.5 监控网络请求

利用 WebViewClient 监控网络请求,辨认潜在的恶意重定向:
  1. webView.setWebViewClient(new WebViewClient() {
  2.     @Override
  3.     public void onPageStarted(WebView view, String url, Bitmap favicon) {
  4.         super.onPageStarted(view, url, favicon);
  5.         // 监控页面加载
  6.         Log.d("WebView", "Loading URL: " + url);
  7.     }
  8.     @Override
  9.     public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
  10.         super.onReceivedError(view, request, error);
  11.         // 处理加载错误
  12.         Toast.makeText(context, "加载错误: " + error.getDescription(), Toast.LENGTH_SHORT).show();
  13.     }
  14. });
复制代码
3.6 利用安全的 DNS

在 Java 层,DNS 解析由 AddressCache 管理。当未掷中缓存时,会调用 Libcore.os.android_getaddrinfo 方法进行域名解析。通过阅读源码发现,解析逻辑由 libc.so 中的 getaddrinfo 方法实现,而 WebView 中的域名解析逻辑也是通过 libwebviewchromium.so 调用这个底层方法。
为了优化 DNS 解析,我们可以利用 inline hook 的方式(详细方案可以参考 ShadowHook)来 hook getaddrinfo 方法。这样可以先查询我们维护的缓存,再进行相应的优化和兜底处理。
以下是一个简单的示例,展示怎样利用 ShadowHook 来 hook getaddrinfo 方法:
  1. import com.github.shadowhook.ShadowHook;
  2. public class DnsHook {
  3.     public static void hookGetAddrInfo() {
  4.         ShadowHook.hook("libc.so", "getaddrinfo", new ShadowHook.HookCallback() {
  5.             @Override
  6.             public Object invoke(Object... args) {
  7.                 String hostname = (String) args[0];
  8.                 // 查询自定义缓存
  9.                 String cachedIp = queryCustomDnsCache(hostname);
  10.                 if (cachedIp != null) {
  11.                     // 返回缓存的 IP 地址
  12.                     return cachedIp;
  13.                 }
  14.                 // 调用原始的 getaddrinfo 方法
  15.                 return ShadowHook.callOriginal(args);
  16.             }
  17.         });
  18.     }
  19.     private static String queryCustomDnsCache(String hostname) {
  20.         // 实现自定义 DNS 缓存查询逻辑
  21.         return null; // 返回 null 表示未命中缓存
  22.     }
  23. }
复制代码
四、案例深入分析

4.1 问题

用户点击链接A,会跳转到不良网站链接B。这个问题在用户手机上必现。
4.2 分析


  • 因为用户在任何网络情况都能复现,猜疑是用户android端的系统DNS解析被挟制了。
    验证方法:android端打开华佗诊断的DNS检测页面,发现解析结果为空。在其他浏览器打开链接A,也不会调解到链接B。说明系统的DNS解析没有被挟制。
    检测页面链接:https://itango.tencent.com/app/data/huatuo

  • 通过抓包工具分析,发现没有A域名的请求包。虽然界面上打开的是链接A,但是现实上Webview直接发起了B的请求。
    通过这一点,猜疑是Webview缓存了之前在某个网络情况下的DNS解析结果,默认跳转到了链接B。
    其中抓包工具利用的是:Reqable
    下载链接是:https://reqable.com/zh-CN/android/

  • 删除应用的【缓存】(不需要清除数据),用户恢复正常。验证了确实是Webview在应用沙箱中缓存相识析结果。
五、结论

在 Android WebView 中,网页被挟制的情况可能由多种因素引起,包括 JavaScript 重定向、恶意网页、设置不当等。通过接纳恰当的安全步调,开发者可以有效降低这些风险,保护用户的浏览体验和数据安全。确保在开发过程中关注这些潜在的安全隐患,将有助于提升应用的整体安全性和用户信任度。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

泉缘泉

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表