Android WebView 中网页被劫持的原因及解决方案

文章目录

    • 一、原因分析
    • 二、解决方案一览
    • 三、解决方案代码案例
      • 3.1 使用 HTTPS
      • 3.2 验证 URL
      • 3.3 禁用 JavaScript
      • 3.4 使用安全的 WebView 设置
      • 3.5 监控网络请求
      • 3.6 使用安全的 DNS
    • 四、案例深入分析
      • 4.1 问题
      • 4.2 分析
    • 五、结论

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

一、原因分析

  1. JavaScript 重定向
    某个网页中包含以下 JavaScript 代码:

    window.location.href = "http://malicious-site.com";
    

    这段代码会在页面加载时将用户重定向到恶意网站。

  2. 恶意网页

    用户点击了一个链接,访问了一个看似正常的网站,但该网站实际上是一个钓鱼网站,包含重定向代码,试图引导用户输入敏感信息。

  3. WebView 设置不当

    开发者在 WebView 中未设置 WebViewClient,导致 WebView 默认行为是打开所有链接,而不是在应用内处理。这可能导致用户被重定向到外部浏览器,增加了被恶意网站劫持的风险。

  4. 拦截 URL 加载

    shouldOverrideUrlLoading 方法中,开发者没有正确处理 URL,例如:

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {// 没有验证 URL,直接加载view.loadUrl(url);return true;
    }
    

    这可能导致用户被重定向到不安全的网站。

  5. 广告或跟踪脚本

    某些网页可能嵌入了广告或跟踪脚本,这些脚本会在用户访问时自动重定向到广告商的网站,甚至可能是恶意网站。

  6. 中间人攻击

    在公共 Wi-Fi 网络中,攻击者可能通过中间人攻击拦截用户的网络请求,并将其重定向到恶意网站,伪装成合法网站。

  7. 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 前进行检查:

private void loadUrl(WebView webView, String url) {if (url.startsWith("https://")) {webView.loadUrl(url);} else {// 提示用户或处理不安全的 URLToast.makeText(context, "不安全的链接,无法加载!", Toast.LENGTH_SHORT).show();}
}

3.2 验证 URL

shouldOverrideUrlLoading 方法中验证即将加载的 URL:

@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {if (isSafeUrl(url)) {view.loadUrl(url);} else {// 提示用户或处理不安全的 URLToast.makeText(context, "不安全的链接,无法加载!", Toast.LENGTH_SHORT).show();}return true;
}private boolean isSafeUrl(String url) {// 这里可以添加更复杂的 URL 验证逻辑return url.startsWith("https://") || url.startsWith("http://trusted-site.com");
}

3.3 禁用 JavaScript

如果不需要 JavaScript,可以在 WebView 设置中禁用它:

WebView webView = findViewById(R.id.webview);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(false); // 禁用 JavaScript

3.4 使用安全的 WebView 设置

确保 WebView 的设置是安全的,例如启用安全的内容加载策略:

webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_NEVER_ALLOW); // 禁止混合内容
webSettings.setDomStorageEnabled(true); // 启用 DOM 存储

3.5 监控网络请求

使用 WebViewClient 监控网络请求,识别潜在的恶意重定向:

webView.setWebViewClient(new WebViewClient() {@Overridepublic void onPageStarted(WebView view, String url, Bitmap favicon) {super.onPageStarted(view, url, favicon);// 监控页面加载Log.d("WebView", "Loading URL: " + url);}@Overridepublic void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {super.onReceivedError(view, request, error);// 处理加载错误Toast.makeText(context, "加载错误: " + error.getDescription(), Toast.LENGTH_SHORT).show();}
});

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 方法:

import com.github.shadowhook.ShadowHook;public class DnsHook {public static void hookGetAddrInfo() {ShadowHook.hook("libc.so", "getaddrinfo", new ShadowHook.HookCallback() {@Overridepublic Object invoke(Object... args) {String hostname = (String) args[0];// 查询自定义缓存String cachedIp = queryCustomDnsCache(hostname);if (cachedIp != null) {// 返回缓存的 IP 地址return cachedIp;}// 调用原始的 getaddrinfo 方法return ShadowHook.callOriginal(args);}});}private static String queryCustomDnsCache(String hostname) {// 实现自定义 DNS 缓存查询逻辑return null; // 返回 null 表示未命中缓存}
}

四、案例深入分析

4.1 问题

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

4.2 分析

  1. 因为用户在任何网络环境都能复现,怀疑是用户android端的系统DNS解析被劫持了。
    验证方法:android端打开华佗诊断的DNS检测页面,发现解析结果为空。在其他浏览器打开链接A,也不会调整到链接B。说明系统的DNS解析没有被劫持。
    检测页面链接:https://itango.tencent.com/app/data/huatuo
    在这里插入图片描述

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

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

五、结论

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/8034.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux——网络(udp)

文章目录 目录 文章目录 前言 一、upd函数及接口介绍 1. 创建套接字 - socket 函数 2. 绑定地址和端口 - bind 函数 3. 发送数据 - sendto 函数 4. 接收数据 - recvfrom 函数 5. 关闭套接字 - close 函数 二、代码示例 1.服务端 2.客户端 总结 前言 Linux——网络基础&#xf…

C语言学习强化

前言 数据的逻辑结构包括: 常见数据结构: 线性结构:数组、链表、队列、栈 树形结构:树、堆 图形结构:图 一、链表 链表是物理位置不连续,逻辑位置连续 链表的特点: 1.链表没有固定的长度…

【ArcGIS微课1000例】0141:提取多波段影像中的单个波段

文章目录 一、波段提取函数二、加载单波段导出问题描述:如下图所示,img格式的时序NDVI数据有24个波段。现在需要提取某一个波段,该怎样操作? 一、波段提取函数 首先加载多波段数据。点击【窗口】→【影像分析】。 选择需要处理的多波段影像,点击下方的【添加函数】。 在多…

css3 svg制作404页面动画效果HTML源码

源码介绍 css3 svg制作404页面动画效果HTML源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果 效果预览 源码如下 <!doctype html> <html> <head> <meta charse…

R语言学习笔记之高效数据操作

一、概要 数据操作是R语言的一大优势&#xff0c;用户可以利用基本包或者拓展包在R语言中进行复杂的数据操作&#xff0c;包括排序、更新、分组汇总等。R数据操作包&#xff1a;data.table和tidyfst两个扩展包。 data.table是当前R中处理数据最快的工具&#xff0c;可以实现快…

利用Qt5.15.2编写Android程序时遇到的问题及解决方法

文章目录 背景1.文件读写 背景 目前我用的是Qt5.15.2来编写Qt程序&#xff0c;环境的配置看我这篇文章【Qt5.15.2配置Android开发环境】 项目中的一些配置的截图&#xff1a; 1.文件读写 假如直接用 QFileDialog::getExistingDirectory来获取路径的话&#xff0c;会得到类…

【学术会议-第五届机械设计与仿真国际学术会议(MDS 2025) 】前端开发:技术与艺术的完美融合

重要信息 大会官网&#xff1a;www.icmds.net 大会时间&#xff1a;2025年02月28日-03月02日 大会地点&#xff1a;中国-大连 会议简介 2025年第五届机械设计与仿真国际学术会议&#xff08;MDS 2025) 将于2025年02月28-3月02日在中国大连召开。MDS 2025将围绕“机械设计”…

leetcode刷题记录(一百)——121. 买卖股票的最佳时机

&#xff08;一&#xff09;问题描述 121. 买卖股票的最佳时机 - 力扣&#xff08;LeetCode&#xff09;121. 买卖股票的最佳时机 - 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。你只能选择 某一天 买入这只股票&#xff0c;并…

亲测有效!解决PyCharm下PyEMD安装报错 ModuleNotFoundError: No module named ‘PyEMD‘

解决PyCharm下PyEMD安装报错 PyEMD安装报错解决方案 PyEMD安装报错 PyCharm下通过右键自动安装PyEMD后运行报错ModuleNotFoundError: No module named ‘PyEMD’ 解决方案 通过PyCharm IDE python package搜索EMD-signal&#xff0c;选择版本后点击“install”执行安装

上海亚商投顾:沪指冲高回落 大金融板块全天强势 上海亚商投

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一&#xff0e;市场情绪 市场全天冲高回落&#xff0c;深成指、创业板指午后翻绿。大金融板块全天强势&#xff0c;天茂集团…

【unity游戏开发之InputSystem——02】InputAction的使用介绍(基于unity6开发介绍)

文章目录 前言一、InputAction简介1、InputAction是什么&#xff1f;2、示例 二、监听事件started 、performed 、canceled1、启用输入检测2、操作监听相关3、关键参数 CallbackContext4、结果 三、InputAction参数相关1、点击齿轮1.1 Actions 动作&#xff08;1&#xff09;动…

ubuntu22安装issac gym记录

整体参考&#xff1a;https://blog.csdn.net/Yakusha/article/details/144306858 安装完成后的整体版本信息 ubuntu&#xff1a;22.04内核&#xff1a;6.8.0-51-generic显卡&#xff1a;NVIDIA GeForce RTX 3050 OEM显卡驱动&#xff1a;535.216.03cuda&#xff1a;12.2cudnn&…

Linux下Ubuntun系统报错find_package(BLAS REQUIRED)找不到

Linux下Ubuntun系统报错find_package(BLAS REQUIRED)找不到 这次在windows的WSL2中遇到了一个非常奇怪的错误&#xff0c;就是 CMake Error at /usr/share/cmake-3.22/Modules/FindPackageHandleStandardArgs.cmake:230 (message):Could NOT find BLAS (missing: BLAS_LIBRAR…

15天基础内容-5

day13 【String类、StringBuilder类】 主要内容 String类常用方法【重点】 String类案例【重点】 StringBuilder类【重点】 StringBuilder类常用方法【重点&#xff1a; append】 StringBuilder类案例【理解】 第一章String类 1.1 String类的判断方法 String类实现判断功能…

CommonAPI学习笔记-1

CommonAPI学习笔记-1 一. 整体结构 CommonAPI分为两层&#xff1a;核心层和绑定层&#xff0c;使用了Franca来描述服务接口的定义和部署&#xff0c;而Franca是一个用于定义和转换接口的框架&#xff08;https://franca.github.io/franca/&#xff09;。 ​ 核心层和通信中间…

单片机基础模块学习——DS18B20温度传感器芯片

不知道该往哪走的时候&#xff0c;就往前走。 一、DS18B20芯片原理图 该芯片共有三个引脚&#xff0c;分别为 GND——接地引脚DQ——数据通信引脚VDD——正电源 数据通信用到的是1-Wier协议 优点&#xff1a;占用端口少&#xff0c;电路设计方便 同时该协议要求通过上拉电阻…

Golang Gin系列-9:Gin 集成Swagger生成文档

文档一直是一项乏味的工作&#xff08;以我个人的拙见&#xff09;&#xff0c;但也是编码过程中最重要的任务之一。在本文中&#xff0c;我们将学习如何将Swagger规范与Gin框架集成。我们将实现JWT认证&#xff0c;请求体作为表单数据和JSON。这里唯一的先决条件是Gin服务器。…

< OS 有关 > 阿里云:轻量应用服务器 的使用 :轻量化 阿里云 vpm 主机

原因&#xff1a; &#xff1c; OS 有关 &#xff1e; 阿里云&#xff1a;轻量应用服务器 的使用 &#xff1a;从新开始 配置 SSH 主机名 DNS Tailscale 更新OS安装包 最主要是 清除阿里云客户端这个性能杀手-CSDN博客 防止 I/O 祸害系统 操作&#xff1a; 查看进程&#x…

设计模式的艺术-代理模式

结构性模式的名称、定义、学习难度和使用频率如下表所示&#xff1a; 1.如何理解代理模式 代理模式&#xff08;Proxy Pattern&#xff09;&#xff1a;给某一个对象提供一个代理&#xff0c;并由代理对象控制对原对象的引用。代理模式是一种对象结构型模式。 代理模式类型较多…

K8S极简教程(4小时快速学会)

1. K8S 概览 1.1 K8S 是什么 K8S官网文档&#xff1a;https://kubernetes.io/zh/docs/home/ 1.2 K8S核心特性 服务发现与负载均衡&#xff1a;无需修改你的应用程序即可使用陌生的服务发现机制。存储编排&#xff1a;自动挂载所选存储系统&#xff0c;包括本地存储。Secret和…