当前位置: 首页 > news >正文

DOM 被劫持

文档对象模型(DOM)充当着 HTML 和 JavaScript 之间的接口,搭建起静态内容与动态交互之间的桥梁,对现代 Web 开发而言,DOM 的作用不可或缺。

然而,DOM 也有一个致命的陷阱 —— DOM 劫持。DOM 劫持是指当 HTML 元素与全局 JavaScript 变量或函数产生冲突时,可能会导致 Web 应用程序出现不可预期的行为,甚至产生潜在的安全漏洞。

今天就可大家一起来聊聊 DOM 劫持的问题。

DOM 劫持是怎么发生的?

每个 HTML 元素都可以有一个唯一的 id 或 name 属性,方便在 JavaScript 中引用特定的元素。例如,下面的 HTML 按钮具有一个值为 "myButton" 的 id 属性:

<button id="myButton">Click Me!</button>

我们可以在 JavaScript 代码中使用此 ID 来操作按钮,例如,当点击时改变其文本:

document.getElementById('myButton').onclick = function() {this.textContent = 'Clicked!';
};

如果 HTML 元素的 id 或 name 属性与全局 JavaScript 变量或函数冲突会发生什么呢?

当浏览器加载 HTML 页面时,它会自动为 HTML DOM 中的每个 id 和 name 属性创建全局 JavaScript 变量。如果我们有一个名为 “myButton” 的 HTML 元素,浏览器会创建一个全局 JavaScript 变量 myButton,引用该 HTML 元素。

现在,让我们考虑一个场景,其中我们声明了一个名为 myButton 的 JavaScript 函数:

function myButton() {// some code
}

但我们还有一个 id 或 name 为 “myButton” 的 HTML 元素。当页面加载时,浏览器的自动进程会引用 HTML 元素并覆盖 JavaScript 函数 myButton

<button id="myButton">Click Me!</button>console.log(myButton); // This will log the HTML button element, not the function

这个过程叫做 DOM 劫持,它可能会引发不可预测的行为和安全漏洞。如果攻击者能控制这些属性,他们可能有能力向网页注入恶意代码,从而引发包括跨站脚本(XSS)在内的安全问题。

为了说明这一点,让我们考虑以下情景:

Enter your name: <input id="username" type="text">
<button onclick="greet()">Greet</button>function greet() {var username = document.getElementById('username').value;alert(`Hello ${username}`);
}

攻击者可以输入类似 <img id='alert' src=x onerror='alert(1)'> 的内容,创建一个 'id' 为 'alert' 的新 HTML 组件。该组件会破坏 JavaScript 中的正常 alert 功能。下次网站尝试使用此功能时,它将无法正常工作,甚至可能运行恶意代码。

我们想象现在有一个带有用户反馈功能的基本 Web 应用程序。用户输入自己的姓名和反馈消息,然后提交。页面显示反馈:

html:

<h2>Feedback Form</h2>
<form><label for="name">Name:</label><br><input type="text" id="name" name="name"><br><label for="feedback">Feedback:</label><br><textarea id="feedback" name="feedback"></textarea><br><input type="submit" value="Submit">
</form><div id="feedbackDisplay"></div>

JavaScript:

document.querySelector('form').onsubmit = function(event) {event.preventDefault();let name = document.getElementById('name').value;let feedback = document.getElementById('feedback').value;let feedbackElement = document.getElementById('feedbackDisplay');feedbackElement.innerHTML = `<p><b>${name}</b>: ${feedback}</p>`;
};

这段代码会获取用户的姓名和反馈,并将其显示在 FeedbackDisplay div 内的段落元素中。

攻击者可以通过在反馈表单中提交一段 HTML 来利用此代码。例如,如果他们在名称字段中输入以下代码并提交表单,则反馈显示区域就会被 Script 替换:

<script id="feedbackDisplay">window.location.href='http://conardli.top';</script>

当表单尝试显示下一条反馈时,就会执行脚本,将用户重定向到恶意网站。这是 DOM 劫持造成严重后果的一个例子 —— 攻击者可以控制用户的浏览器,从而窃取敏感数据或安装恶意软件。

缓解 DOM 劫持的安全编码实践

通过更深入地了解这些漏洞,我们可以继续采取一些最佳实践来减轻 DOM 劫持的风险。

正确定义变量和函数的作用域

DOM 劫持的最常见原因之一是滥用 JavaScript 中的全局作用域。

通过在特定的作用域范围内定义变量和函数,我们可以限制对该范围或任何嵌套范围的覆盖,并最大限度地减少潜在的冲突。

我们来用 JavaScript 的作用域规则并重构前面的示例来展示如何做到这一点:

(function() {// All variables and functions are now in this function's scopeconst form = document.querySelector('form');const feedbackElement = document.getElementById('feedbackDisplay');form.onsubmit = function(event) {event.preventDefault();const name = document.getElementById('name').value;const feedback = document.getElementById('feedback').value;// Sanitize user inputname = DOMPurify.sanitize(name);feedback = DOMPurify.sanitize(feedback);const newFeedback = document.createElement('p');newFeedback.textContent = `${name}: ${feedback}`;feedbackElement.appendChild(newFeedback);};
})();

首先我们使用了 DOMPurify 来对上述代码块中的用户输入进行清理。

在此版本的代码中,我们将所有内容都包含在立即调用函数表达式 (IIFE) 中,这会创建一个新作用域。form 和 FeedbackElement 变量以及分配给 onsubmit 事件处理程序的函数不在全局作用域内,因此它们不能被劫持。

使用唯一标识符

确保网页上的每个元素都有唯一的 id 可以降低无意中覆盖重要函数或变量的风险。另外,避免使用通用名称或可能与全局 JavaScript 对象或函数冲突的名称。

避免全局命名空间污染

保持全局命名空间干净是编写安全 JavaScript 的一个重要方面。全局作用域中的变量和函数越多,DOM劫持的风险就越大。使用 JavaScript 的函数作用域或 ES6 的块作用域来保留变量和函数。这是使用后者的示例:

    let form = document.querySelector('form');let feedbackElement = document.getElementById('feedbackDisplay');form.onsubmit = function(event) {event.preventDefault();let name = document.getElementById('name').value;let feedback = document.getElementById('feedback').value;// Sanitize user inputname = DOMPurify.sanitize(name);feedback = DOMPurify.sanitize(feedback);let newFeedback = document.createElement('p');newFeedback.textContent = `${name}: ${feedback}`;feedbackElement.appendChild(newFeedback);};

在这段代码中,我们使用块(由 {} 定义)来创建新作用域。所有变量和函数现在都限制在该块中,并且不在全局作用域内。

正确使用 JavaScript 特性

现代 JavaScript 提供了一些有助于最大限度地缓解 DOM 劫持的风险。特别是 ES6 中引入的 let 和 const 关键字提供了对声明变量的更多控制。

在以前,我们使用 var 关键字声明 JavaScript 变量。var 有一些怪癖,其中之一是就它没有块作用域,只有函数作用域和全局作用域。这意味着用 var 声明的变量可以在声明它的块之外访问和覆盖。

另一方面,let 和 const 都具有块作用域,这意味着它们只能在声明它们的块内访问。这一特性通常使它们成为变量声明的更好选择,因为它限制了覆盖变量的可能性。

我们还可以使用 const 来声明常量 — 分配它们后我们无法更改的值。它们可以防止重要的变量被意外覆盖。

    const form = document.querySelector('form');const feedbackElement = document.getElementById('feedbackDisplay');form.onsubmit = function(event) {event.preventDefault();const name = document.getElementById('name').value;const feedback = document.getElementById('feedback').value;// Sanitize user inputname = DOMPurify.sanitize(name);feedback = DOMPurify.sanitize(feedback);const newFeedback = document.createElement('p');newFeedback.textContent = `${name}: ${feedback}`;feedbackElement.appendChild(newFeedback);};

在此代码中,我们将所有 var 的使用替换为 const。我们将所有变量限制在声明它们的块中,并且常量不能被覆盖。

但是 ,使用 let 和 const 并不能完全消除 DOM 劫持的风险,但这种做法仍然是安全编码的一个关键方面。

使用 Devtools 发现潜在的 DOM 劫持风险

例如 Chrome 或 Firefox 中的浏览器开发者工具,也是探测 DOM 劫持漏洞的强大助手。

最简单的方法,我们直接打开 Devtools

然后在控制台输入 window ,这里面包含了网站全局作用域下所有的全局变量和函数。

然后我们检查下是否有任何看起来不合适的变量,尤其是那些与 HTML 元素 id 或 name 同名的变量。

通过 Elements 选项卡,编辑页面的 HTML 来操控 DOM 并测试潜在的漏洞。例如,添加一个 id 与全局变量或函数相匹配的元素,看看是否会被覆写。

相关文章:

DOM 被劫持

文档对象模型&#xff08;DOM&#xff09;充当着 HTML 和 JavaScript 之间的接口&#xff0c;搭建起静态内容与动态交互之间的桥梁&#xff0c;对现代 Web 开发而言&#xff0c;DOM 的作用不可或缺。 然而&#xff0c;DOM 也有一个致命的陷阱 —— DOM 劫持。DOM 劫持是指当 H…...

PIG框架学习2——资源服务器的配置详解

一、前言 1、pig资源服务器的配置 Spring Security oauth2相关的依赖是在pigx-common-security模块中引入的&#xff0c;其他模块需要进行token鉴权的&#xff0c;需要在微服务中引入pigx-common-security模块的依赖&#xff0c;从而间接引入相关的Spring security oauth2依赖…...

vue+element ui实现图片上传并拖拽进行图片排序

用到的技术栈&#xff1a; vue2element Uivue-dragging 如何使用&#xff1a; 第一步: 安装 npm install awe-dnd --save第二步: 引入 main.js 文件 // 引入组件 import VueDND from awe-dnd // 添加至全局 Vue.use(VueDND)具体项目代码 <el-form-item label"封面…...

国产服务器 BIOS下组建RADI不同RAID卡-超详细

国产服务器 长城 组建Raid的方法 说明 大多数国产服务器通用型服务器进入BIOS的都是按DEL键。 9361RAID卡组建方法 在服务器启动过程中&#xff0c;按下DEL键进入BIOS界面。 进入设备管理器&#xff0c;选择AVAGO MegaRAID页签。 3. 进入RAID卡设备&#xff0c;选择Main Me…...

UE4 4.21-4.27使用编辑器蓝图EditorBlueprint方法

在UE4 4.21中&#xff0c;编辑器蓝图&#xff08;Editor Blueprint&#xff09;是一个强大的工具&#xff0c;允许开发者扩展和自定义Unreal编辑器的功能。通过编辑器蓝图&#xff0c;我们可以创建自定义的工具和功能&#xff0c;以优化开发流程。 本教程将指导您如何在UE4 4.…...

105、Zero-1-to-3: Zero-shot One Image to 3D Object

简介 官网  使用合成数据集来学习相对摄像机视点的控制&#xff0c;这允许在指定的摄像机变换下生成相同对象的新图像&#xff0c;用于从单个图像进行三维重建的任务。 实现流程 输入图像 x ∈ R H W 3 x \in \R^{H \times W \times 3} x∈RHW3&#xff0c;所需视点的相…...

scala 安装和创建项目

Scala&#xff0c;一种可随您扩展的编程语言&#xff1a;从小型脚本到大型多平台应用程序。Scala不是Java的扩展&#xff0c;但它完全可以与Java互操作。在编译时&#xff0c;Scala文件将转换为Java字节码并在JVM&#xff08;Java虚拟机&#xff09;上运行。Scala被设计成面向对…...

Python办公自动化 – 自动化文本翻译和Oracle数据库操作

Python办公自动化 – 自动化文本翻译和Oracle数据库操作 以下是往期的文章目录&#xff0c;需要可以查看哦。 Python办公自动化 – Excel和Word的操作运用 Python办公自动化 – Python发送电子邮件和Outlook的集成 Python办公自动化 – 对PDF文档和PPT文档的处理 Python办公自…...

如何在Win10电脑接收苹果手机日程提醒呢?

有很多小伙伴手机使用的是iPhone苹果手机&#xff0c;但办公电脑使用的win10系统的电脑&#xff0c;这时候如果想要在win10电脑上同步接收苹果手机上设置的日程提醒&#xff0c;该怎么操作呢&#xff1f;如何在win10电脑接收苹果手机日程提醒呢&#xff1f; 如果你设置的日程提…...

227.【2023年华为OD机试真题(C卷)】小明找位置(二分查找-JavaPythonC++JS实现)

🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-小明找位置二.解题思路三.题解代码Python题解代…...

【现代密码学】笔记3.4-3.7--构造安全加密方案、CPA安全、CCA安全 《introduction to modern cryphtography》

【现代密码学】笔记3.4-3.7--构造安全加密方案、CPA安全、CCA安全 《introduction to modern cryphtography》 写在最前面私钥加密与伪随机性 第二部分流加密与CPA多重加密 CPA安全加密方案CPA安全实验、预言机访问&#xff08;oracle access&#xff09; 操作模式伪随机函数PR…...

服务器带宽有什么用? 带宽不足怎么办?

服务器带宽是指服务器能够接收和传输数据的速率&#xff0c;通常以每秒传输的数据量来衡量。它是支持特定应用服务器网络和因特网&#xff08;Internet&#xff09;访问的单一网络线路&#xff0c;对网络速度、响应时间、应用程序处理速度等方面都有影响。 服务器带宽有什么作…...

Alphafold2蛋白质结构预测AI工作站配置推荐

AlphaFold2计算特点 蛋白质三维结构预测是一项计算量非常巨大的任务&#xff0c;科学家多年的探索研究&#xff0c;形成了X射线晶体学法、核磁共振法、冷冻电镜等。 2021年底&#xff0c;谷歌的DeepMind团队的采用人工智能方法的AlphaFold2算法在生物界引起了极大的轰动…...

如何让ArcGIS Pro启动显示空白页面

刚接触ArcGIS Pro的你是否会觉得在操作上有那么一些不习惯&#xff0c;从一开始软件启动就发现和ArcGIS差距很大&#xff1a;丰富的欢迎页面&#xff0c;加上默认加载的地图让你眼花缭乱&#xff0c;这里教你如何去掉这些繁杂的内容&#xff0c;还你一个干净的启动页面。 跳过…...

超市账单管理系统产品数据新增Servlet实现

超市账单管理系统产品数据新增Servlet实现 package com.test.controller; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import ja…...

计算机组成原理之计算机硬件发展和计算机系统的组成

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…...

《JVM由浅入深学习【七】 2024-01-11》JVM由简入深学习提升分享

亲爱的读者们&#xff0c;欢迎来到本篇博客&#xff0c;这是JVM第七次分享&#xff0c;下面是七个JVM常用常面的分享&#xff0c;请笑纳 目录 1. 几个与JVM 内存相关的核心参数2.如何计算一个对象的大小3.堆为什么要分为新生代和老年代4.JVM堆的年轻代为什么要有两个 Survivor…...

Golang leetcode142 环形链表 暴力map 快慢指针法

文章目录 环形链表 leetcode142暴力遍历 map哈希记录快慢指针法 环形链表 leetcode142 该题目要求找到入环的第一个节点 我们可以通过map进行记录&#xff0c;没到新的节点查询是否经过原有节点 入环节点&#xff0c;上两个节点的next相同 若有入环节点&#xff0c;则一定能检…...

基于java,springboot的论旅游管理系统设计与实现

环境以及简介 基于java,springboot的论旅游管理系统设计与实现&#xff0c;Java项目&#xff0c;SpringBoot项目&#xff0c;含开发文档&#xff0c;源码&#xff0c;数据库以及ppt 源码下载 环境配置&#xff1a; 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服…...

掌握视频节奏,玩转剪辑艺术!,轻松调整视频播放速度与秒数的技巧大揭秘

你是否经常觉得视频播放得太快或太慢&#xff0c;无法满足你的观看需求&#xff1f;或者想要控制视频的长度&#xff0c;却不知道该如何下手&#xff1f;今天&#xff0c;我们将为你揭秘几种简单又实用的方法&#xff0c;让你轻松调整视频的播放速度和秒数&#xff01; 首先&a…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...