百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

JavaScript DOM 内容操作常用方法和 XSS 注入攻击

myzbx 2025-07-02 23:15 4 浏览

当项目的安全团队找上门告诉您,您开发的项目存在 XSS 安全漏洞,作为一个开发人员,就问您慌不慌??

HTML 内容写入的时候,如果稍不注意就会触发隐藏 BOSS 漏洞 XSS。

XSS 漏洞原理就是利用了网站上内容输入的地方,比如说常见的评论提交,老六 通过输入评论的地方,提交一些 包含 JS 代码的内容 到服务器,服务器没做任何操作直接写入到数据库,最后在评论查询的时候直接将数据库的内容原样返给前端,而前端拿到此内容的时候,也不做任何处理,直接将内容以 HTML 的形式渲染的页面中,这时候 老六 输入的非法内容就会被当做 JS 代码执行,这就是典型的 XSS 注入攻击。

要避免 XSS 漏洞,就需要对不可信的内容进行过滤;或者不要把这部分内容当做 HTML 处理,直接当做文本渲染也可以避免 XSS 注入。

DOM 属性操作

在了解 DOM 内容操作之前,先学习几个常用的 DOM 属性操作方法,毕竟 JS 与 CSS 联动一般都是通过 DOM 属性进行关联。

比如 JS 控制 class 属性的变化,再在 CSS 中编写不同的 class 样式,就可以让 HTML 元素渲染成不同的样子。

// 获取 DOM 属性值
element.getAttribute(name)
// 设置 DOM 属性值,已存在的属性值会被修改
element.setAttribute(name, value)
// 删除 DOM 属性
element.removeAttribute(name)

// 操作 class 方法
element.classList.add(c1, c2, c3, ...) // 添加
element.classList.remove(c1, c2, c3, ...) // 删除
// force 使用布尔值将强制只允许删除或者只允许修改
element.classList.toggle(className, force) // 如果存在则删除,不存在则添加
element.classList.contains(className) // 判断是否存在

// 其他常用属性
element.id // 设置 id
element.className // 设置 class
element.style // 直接设置样式

// 特定标签属性
img.src // 设置图片地址

通过 className 可直接设置元素的 class 属性,这儿有一个问题,为什么不是直接使用 class 设置呢?

原因是:class 是 JS 中的关键字,为避免引起一些语法问题,所以就换了一个名字 className

通过 className 控制类名的增删改虽然也不是不能做,但是始终有那么一点点麻烦,所以后来就引入了 classList 用来专门控制 class 属性。

Attribute 相关的几个方法,则是可以用来控制元素的所有属性,包括自定义属性和一些默认的属性 id、style、className 等。所以记住 Attribute 几个方法就已经可以打穿 DOM 属性操作了。

示例:

<style>
  .red {
    color: red; 
  }
  .blue {
    color: blue;
  }
  [data-type="bold"] {
    font-weight: bold;
  }
  [data-type="italic"] {
    font-style: italic;
  }
</style>

<div id="test">哈哈哈哈哈</div>
<img id="img">

<script>
  const test = document.getElementById('test');
  const img = document.getElementById('img');
  
  // 设置属性
  test.setAttribute('data-type', 'bold')

  // 获取属性值
  const type = test.getAttribute('data-type')
  console.log(' ~ type:', type);

  // 移除属性
  test.removeAttribute('data-type')

  // 添加新的属性
  test.setAttribute('data-type', 'italic')

  // 判断是否存在Class
  const hasRed = test.classList.contains('red')
  console.log(' ~ hasRed:', hasRed);

  // 添加Class
  test.classList.add('red')

  // 移除Class
  test.classList.remove('red')

  // 如果不存在则添加 blue,存在 blue 则移除
  test.classList.toggle('blue')

  
  // 给图片设置地址
  img.src = 'https://developer.mozilla.org/static/media/firefox.1eabb4da07c095ca04fa.svg'
  // 获取图片地址
  console.log(' ~ img.src:', img.src);
  
  // 换个 ID 属性
  img.id = 'img-1'
  // 获取 ID 属性
  console.log(' ~ img.id:', img.id);

  // 设置图片的 class
  img.className = 'img-1'
  // 获取图片的 class
  console.log(' ~ img.className:', img.className);

  // 设置图片边框
  img.style.border = '1px solid red'
  img.style.borderWidth = '4px'
  img.style['border-color'] = 'blue'
  // 设置图片宽度
  img.style.width = '100px'
  // 获取图片的样式
  console.log(' ~ img.style:', img.style['border-width']);
</script>

在使用 style 属性设置样式的时候,如果使用的是 . 语法赋值,那么必须要改为 小驼峰命名,原因是 JS 中的 . 语法不支持短横线,比如 borderWidth,不能使用 border-width

在使用数组取值语法的时候,可以直接使用 css 的属性赋值,比如 img.style['border-color'] = 'blue'

DOM 内容操作

DOM 属性操作一般不会触发安全问题, XSS 注入都是发生在 DOM 内容操作的时候,所以在使用 JS 进行 DOM 内容操作时需特别小心。

常用的两个个方法:

// 设置 DOM HTML 内容
element.innerHTML = htmlString;
// 设置 DOM 文本内容
element.textContent = textString;

实例:

<div id="test1">哈哈哈哈哈</div>
<div id="test2">哈哈哈哈哈</div>

<script>
const test1 = document.getElementById('test1');
const test2 = document.getElementById('test2');
// 写入 HTML 内容
test1.innerHTML = '<strong>警告</strong>:用户输入内容'; 

// 写入文本内容
test2.textContent = '<strong>安全文本</strong>'; // 直接显示文本,不解析 HTML

// 区别对比
console.log(test2.innerHTML); // 输出: <strong>安全文本</strong>
console.log(test2.textContent); // 输出: <strong>安全文本</strong>
</script>

运行结果:

XSS 注入

在使用 innerHTML 设置 HTML 内容时,如果用户输入的内容中包含 JS 脚本,那么就会导致 XSS 注入。

比如这样:

<div id="test1">哈哈哈哈哈</div>
<div id="test2">哈哈哈哈哈</div>

<script>
  const test1 = document.getElementById('test1');
  const h1 = `<script>alert("XSS");<\/script>`;
  // 直接插入 script 标签被浏览器拦截了,不会引发 XSS 注入
  test1.innerHTML = h1;

  const test2 = document.getElementById('test2');
  // 但可以换一种变体,使用 img 标签也可以做到 XSS 注入
  const h2 = `<img src=x onerror="alert('XSS')">`;
  test2.innerHTML = h2;
</script>

HTML5 规范规定:通过 innerHTML 动态插入的 <script> 标签不会执行其中的 JavaScript 代码。
这是浏览器的一种安全机制,目的是防止开发者无意或恶意插入可执行脚本。

XSS 注入可能导致的问题:非法用户直接在网站中运行 JS 代码,可以获取用户信息,从而伪造一些请求,达到非法目的。

相关推荐

C语言速成之数组:C语言数据处理的核心武器,你真的玩透了吗?

程序员Feri一名12年+的程序员,做过开发带过团队创过业,擅长Java、鸿蒙、嵌入式、人工智能等开发,专注于程序员成长的那点儿事,希望在成长的路上有你相伴!君志所向,一往无前!数组:C语言数据处理...

ES6史上最全数JS数组方法合集-02-数组操作

数组生成array.ofletres=Array.of(1,2,3)console.log(res)//[1,2,3]下标定位indexOf用于查找数组中是否存在某个值,如果存...

前端性能拉胯?这 8 个 JavaScript 技巧让你的代码飞起来!

在前端开发的江湖里,JavaScript就是我们手中的“绝世宝剑”。但为啥别人用剑就能轻松斩敌,你的代码却总拖后腿,页面加载慢、交互卡顿?别着急!今天带来8个超实用的JavaScript实...

12种JavaScript中最常用的数组操作整理汇总

数组是最常见的数据结构之一,我们需要绝对自信地使用它。在这里,我将列出JavaScript中最重要的几个数组常用操作片段,包括数组长度、替换元素、去重以及许多其他内容。1、数组长度大多数人都知道可...

手把手教你在Webpack写一个Loader

前言有的时候,你可能在从零搭建Webpack项目很熟悉,配置过各种loader,面试官在Webpack方面问你,是否自己实现过一个loader?如果没有去了解过如果去实现,确实有点尴尬,其...

const关键字到底该什么用?(可以用const关键字定义变量吗)

文|守望先生经授权转载自公众号编程珠玑(id:shouwangxiansheng)前言我们都知道使用const关键字限定一个变量为只读,但它是真正意义上的只读吗?实际中又该如何使用const关键字...

“JavaScript变量声明三兄弟,你真的会用吗?

在JavaScript中,var、let和const是声明变量的关键字,它们在作用域、变量提升、重复声明和重新赋值等方面有显著区别。以下是它们的相同点和不同点,并通过代码示例详细说明。一、相同点声明变...

ES6(二)let 和 const(es6 var let const区别)

let命令let和var差不多,只是限制了有效范围。先定义后使用不管是什么编程语言,不管语法是否允许,都要秉承先定义,然后再使用的习惯,这样不会出幺蛾子。以前JavaScript比较随意,...

js 里面 let 和 const的区别(js中的let)

在JavaScript(包括Vue、Node.js、前端脚本等)中,const和let是用于声明变量的两种方式,它们的主要区别如下:constvslet的区别特性constlet是否...

JDK21新特性:Sequenced Collections

SequencedCollectionsJDK21在JEP431提出了有序集合(SequencedCollections)。引入新的接口来表示有序集合。这样的集合都有一个明确的第一个元素、第二个...

动态编程基础——第 2 部分(动态编程是什么)

有两种方法可以使用动态规划来解决问题。在这篇文章中,我们将了解制表法。请参阅我的动态编程基础——第1部分了解记忆方法。记忆制表什么是动态规划?它是一种简单递归的优化技术。它大大减少了解决给定...

Lambda 函数,你真的的了解吗(lambda函数用法)

什么是lambda函数lambda函数是一个匿名函数,这意味着与其他函数不同,它们没有名称。这是一个函数,它添加两个数字,写成一个命名函数,可以按其名称调用它们:defadd(x,y):...

JavaScript 数组操作方法大全(js数组操作的常用方法有哪些)

数组操作是JavaScript中非常重要也非常常用的技巧。本文整理了常用的数组操作方法(包括ES6的map、forEach、every、some、filter、find、from、of等)...

系列专栏(六):解构赋值(解构赋值默认值)

ES6作为新一代JavaScript标准,已正式与广大前端开发者见面。为了让大家对ES6的诸多新特性有更深入的了解,MozillaWeb开发者博客推出了《ES6InDepth》系列文章。CSDN...

js列表遍历方法解读(js遍历链表)

JavaScript提供了多种遍历数组(或列表)的方法。以下是一些常用的方法及其解读:for循环:vararray=[1,2,3,4,5];for(vari=0;...