参考:https://blog.csdn.net/2303_78006750/article/details/138022514
**说明:**本章节所介绍的 JavaScript 并不深入,因为在 Web 安全领域不需要对 JavaScript 掌握非常深入,我们只需要能够利用本章节提及到的一些语句对网站进行测试就足够了。
1)JavaScript 简介
01-JS简介.pdf
1.1)JavaScript 背景
Web 前端有三层:
- HTML:从语义的角度,描述页面结构。
- CSS:从审美的角度,描述样式( 美化页面 )
- JavaScript:从交互的角度,描述行为( 实现业务逻辑和页面控制 )
JavaScript 在红队攻防中具有重要的作用,了解 JS 在攻击和防御中的运用对于提高安全防护能力具有重要意义。
JavaScript 发展历史
JavaScript 诞生于 1995 年。网景公司的员工布兰登 • 艾奇(Brendan Eich,1961年~)在1995年开发出了 JavaScript 语言。
JavaScript 是由网景公司(Netscape)发明,最初命名为 LiveScript;1995 年 12 月与 SUN 公司合作,因市场宣传需要,改名为 JavaScript。
JavaScript 是 Sun 注册并授权给 Netscape 使用的商标。后来 Sun 公司被 Oracle 收购,JavaScript 版权归 Oracle 所有。
备注:由于 Sun 公司当时的 Java 语言特别火,所以为了傍大牌,就借势改名为 JavaScript
同时期还有其他的网页语言,比如 VBScript、JScript 等等,但是后来都被 JavaScript 打败了,所以现在的浏览器中,只运行一种脚本语言就是 JavaScript。
1996 年,微软为了抢占市场,推出了 JScript 在 IE3.0 中使用。
1996 年 11 月网景公司将 JS 提交给 ECMA (国际标准化组织) 成为国际标准,用于对抗微软。
JavaScript 是世界上用的最多的 脚本语言。
JavaScript 的发展
2003 年之前,JavaScript 被认为** “牛皮癣”**,用来制作页面上的广告,弹窗、漂浮的广告。什么东西让人烦,什么东西就是 JavaScript 开发的。所以很多浏览器就推出了屏蔽广告功能。
2004 年,JavaScript 命运开始改变。那一年,谷歌公司开始带头使用 Ajax 技术,Ajax 技术 就是 JavaScript 的一个应用。并且,那时候人们逐渐开始提升用户体验了。Ajax 有一些应用场景。比如,当我们在百度搜索框搜文字时,输入框下方的智能提示,可以通过 Ajax 实现。比如,当我们注册网易邮箱时,能够及时发现用户名是否被占用,而不用调到另外一个页面。从 2005 年开始,几乎整个 B/S 开发界都在热情地追捧 Ajax。
2007 年乔布斯发布了第一款 iPhone,这一年开始,用户就多了上网的途径,就是用移动设备上网。JavaScript 在移动页面中,也是不可或缺的。并且这一年,互联网开始标准化,按照 W3C 规则三层分离,JavaScript 越来越被重视。
2010 年,人们更加了解 HTML5 技术,HTML5 推出了一个东西叫做 Canvas(画布),工程师可以在 Canvas 上进行游戏制作,利用的就是 JavaScript。
2011 年,Node.js 诞生,使 JavaScript 能够开发服务器程序了。
如今,WebApp 已经非常流行,就是用 网页技术开发手机应用。
手机系统有 iOS、安卓。比如公司要开发一个“携程网”App,就需要招聘三队人马,比如 iOS 工程师 10 人,安卓工程师 12 人,前端工程师 8 人。共30人,开发成本大;而且如果要做需求迭代,就要改 3 个版本。现在,假设公司都用 Web 技术,用 HTML+CSS+JavaScript 这一套技术就可以开发多种终端的页面。也易于迭代(网页一改变,所有的终端都生效了)。
虽然目前 WebApp(Web应用)在功能和性能上的体验远不如 Native App(原生应用),但是“在原生 App 中内嵌一部分 H5 页面”已经是一种趋势。
1.2)JavaScript 介绍
JavaScript 入门易学性
- JavaScript 对初学者比较友好、简单易用。可以使用任何文本编辑工具编写,只需要浏览器就可以执行程序。
- JavaScript 是有界面效果的(相比之下,C 语言只有白底黑字)。
- JavaScript 是 **弱变量类型 **的语言,变量只需要用 var/let/const 来声明。而 Java 中变量的声明,要根据变量的类型来定义。
**举例:**比如 Java 中需要定义如下变量:
int a; // 整型
float a; // 单精度浮点类型
double a; // 双精度浮点类型
String a; // 字符串类型
boolean a; // 布尔型
而 JavaScript 中,只需要用一种方式来定义:
// ES5 写法
var a;// ES6 写法
const a; // 常量
let a; // 变量
JavaScript 是脚本语言
JavaScript 运行在用户的终端网页上,而不是服务器上,此时我们称之为** “前端语言”**。就是服务于页面的交互和视觉,不能直接操作数据库。
**“后端语言” **是运行在服务器上的,比如 PHP、ASP、JSP 等等,这些语言都能够操作数据库,能够对数据库进行 “增删改查” 操作。
**备注:**Node.js 是用 JavaScript 开发的,我们也可以用 Node.js 技术进行服务器端编程。
虽然,前端语言 JavaScript 无法直接操作后端数据库。不过我们 Web 安全工程师可以利用前端的漏洞操作以执行未授权的后端操作,包括访问、篡改或删除敏感数据。因此,对前端代码的审查和安全性加固同样重要,以确保整个 Web 应用程序的安全性。
JavaScript 的组成
JavaScript 基础分为三个部分:
- ECMAScript:JavaScript 的 语法标准。包括 变量、表达式、运算符、函数、if 语句、for 语句 等。
- DOM:Document Object Model(文档对象模型),操作页面上的元素的 API。比如 让盒子移动、变色、改变大小、轮播图 等等。
- BOM:Browser Object Model(浏览器对象模型),操作浏览器部分功能的 API。通过 BOM 可以 操作浏览器窗口,比如弹框、控制浏览器跳转、获取浏览器分辨率 等等。
**通俗理解就是:**ECMAScript 是 JS 的语法;DOM 和 BOM 浏览器运行环境为 JS 提供的 API。
1.3)JavaScript 的特点
特点 1:解释型语言
JavaScript 是解释型语言,不需要事先被翻译为机器码;而是边翻译边执行(翻译一行,执行一行)。
特点 2:单线程
参考:https://www.yuque.com/blogking/cookie/el4ro2krublv9t3r
JavaScript 是单线程的,同一时刻只能执行特定的任务。
特点 3:ECMAScript 标准
- ECMAScript 是一种由 ECMA 国际( 前身为欧洲计算机制造商协会,英文名称是 European ComputerManufacturers Association)制定和发布的脚本语言规范。
- JavaScript 是由公司开发而成的,问题是不便于其他的公司拓展和使用。所以欧洲的这个 ECMA 的组织,牵头制定 JavaScript 的标准,取名为 ECMAScript。
- 简单来说,ECMAScript 不是一门语言,而是一个标准。ECMAScript 规定了 JS 的编程语法和基础核心知识,是所有浏览器厂商共同遵守的一套 JS 语法工业标准。
- ECMAScript 在 2015 年 6 月,发布了 ECMAScript 6 版本(ES6),语言的能力更强(也包含了很多新特性)。
- ECMA 赋予了 JavaScript 新的能力和活力。
1.4)编程语言的分类
翻译器
计算机不能直接理解任何除机器语言以外的语言,所以必须要把程序员所编写的语言翻译成机器语言,计算机才能执行程序。程序语言翻译成机器语言的工具,被称为翻译器。
由此可见,所谓的 “翻译”,指的是翻译成计算机能够执行的指令。
翻译器翻译的方式有两种:一种是编译,另一种是解释。两种方式之间的区别在于翻译的时机不同。
- **编译器:**在代码执行之前,事前把所有的代码一次性翻译好,生成中间代码文件,然后整体执行。
- **解释器:**边翻译,边执行(在代码执行时进行及时翻译,并立即执行)。当编译器以解释的方式运行时,也称之为解释器。
对应的语言,称之为 “编译型语言”、“解释型语言”。
编译型语言
- **定义:**事先把所有的代码一次性翻译好,然后整体执行。
- **优点:**运行更快。
- **不足:**移植性不好,无法跨平台。
- 编译型语言举例:C、C++、Go
比如说,C 语言的代码文件是 .c 后缀,翻译之后文件是 .obj 后缀,系统执行的是 obj 文件;再比如,Java 语言的代码文件是 .java 后缀,翻译之后的文件是 .class 后缀。( 注意,Java 语言不是严格的编译型语言,这个一会儿会讲)
解释型语言
- 定义:边翻译边执行(翻译一行,执行一行),不需要事先一次性翻译。
- **优点:**移植性好,跨平台。
- **缺点:**运行更慢。( 慢是相对来说,安全的需求还没达到机器极限性能 )
- 解释型语言举例:JavaScript、PHP、Python。
Java 语言
**Java 语言:**既不是编译型语言,也不是解释型语言。翻译过程:
(1)编译: .java 代码文件先通过 javac 命令编译成 .class 文件。
(2)执行: .class 文件再通过 jvm 虚拟机,解释执行。有了 jvm 的存在,让 java 跨平台了。
既有编译过程,也有解释执行的过程。
1.5)JavaScript 入门
安装 JavaScript
首先需要安装 nodejs
下载地址:https://nodejs.org/en/download/prebuilt-installer
然后 VSCode 安装 Code Runner 插件
开始写第一行 JavaScript 代码
JavaScript 代码的书写位置在哪里呢?
这个问题,也可以理解成:引入 JS 代码,有哪几种方式。
**方式一:**行内式
代码举例:
<input type=="button" value="点我点我" οnclick="alert('网络安全')" />
完整的可执行代码如下:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><input type=="button" value="点我点我" οnclick="alert('网络安全')" /></body>
</html>
分析:
- 可以 将单行或少量 JS 代码写在 HTML 标签的事件属性 中(以 on 开头的属性),比如放在上面的 onclick 点击事件中。
- 这种书写方式,不推荐使用,原因是:可读性差,尤其是需要编写大量 JS 代码时,容易出错;引号多层嵌套时,也容易出错。
- 关于代码中的「引号」,在 HTML 标签中推荐使用双引号,JS 中推荐使用单引号。
**方式二:**内嵌式
我们可以在 html 页面的 标签里放入 标签对,并在
<script type="text/javascript">//在这里书写 JS 代码alert('网络安全');console.log('树立网安意识,莫念无名之利.');</script>
分析:
- text 表示纯文本,因为 JavaScript 也是一个纯文本的语言。
- 可以将多行 JS 代码 写到
扩展知识:https://cloud.tencent.com/developer/article/1612474
XSS 漏洞:利用 XSS 漏洞,黑客可以在网站中输入恶意代码,最终被渲染到 HTML 网页,攻击浏览网页的用户。
跨网站脚本(Cross-site scripting,XSS) 又称为 跨站脚本攻击,是一种经常出现在 Web 应用程序的安全漏洞攻击,也是代码注入的一种。XSS 是由于 Web 应用程序对用户的输入过滤不足而产生的,攻击者利用网站漏洞把恶意的脚本代码注入到网页之中,当其他用户浏览这些网页时,就会执行其中的恶意代码,对受害者用户可能采取 Cookie 窃取、会话劫持、钓鱼欺骗等各种攻击。这类攻击通常包含了 HTML 以及用户端脚本语言。
XSS 攻击 通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是 JavaScript,但实际上也可以包括 Java、VBScript、ActiveX、 Flash或者甚至是普通的 HTML。攻击成功后,攻击者可能得到更高的权限(如执行一些操作)、私密网页内容、会话和 cookie 等各种内容。
**总结:**当一个网页的信息输入框没有正确地过滤和转义用户输入时,就可能会被攻击者利用来注入跨站脚本(XSS)。
参考:https://blog.csdn.net/weixin_46709219/article/details/109698457
:::info
验证一个站点是否可以被 XSS 注入
- 站点输入框是否可以填写 JS 代码
- 填写的 JS 代码是否可以实现对应效果
满足上述条件其一,则该站点存在 XSS 注入漏洞风险
:::
// 这段代码是一个简单的 JavaScript 脚本
// 它会在网页加载时弹出一个警告框, 显示当前页面的 cookie 信息.
// 这种操作可能会被用于恶意目的, 例如盗取用户的登录凭据或其他敏感信息.
// 因此, 在编写和执行类似脚本时需要格外小心, 确保安全性和合法性.
<script> alert(document.cookie); </script>
<script> alert('Hack'); </script>
<script> print('Hack'); </script>
什么是 XSS 攻击?
XSS(跨站脚本)攻击是一种常见的安全漏洞。它发生在恶意用户将代码(通常是 JavaScript 脚本)注入到网页中。当其他用户浏览该网页时,这段恶意代码会在他们的浏览器中运行,可能会窃取数据、劫持用户会话或执行其他恶意操作。
HTML 实体编码 是怎么防护 XSS 攻击的?
当你在网页中显示用户输入的内容时,直接显示这些内容可能会带来安全风险。
例如,如果一个用户在评论中输入了:
<script>alert('XSS');</script>
如果没有保护措施,这段代码会直接在网页上执行,显示一个弹窗。这就是一个 XSS 攻击。
HTML 实体编码通过 将特殊字符转换为不会被浏览器解释为代码的形式,来防止这种情况发生。
如何工作?
- 特殊字符转义:HTML实体编码会将像
< 、>
这些特殊字符转换成<、>
这样一来,即使用户输入了恶意代码,浏览器也不会执行它,而是显示这些字符。 - 示例:
- 用户输入:
<script>alert('XSS');</script>
- 经过 HTML 实体编码后:
<script>alert('XSS');</script>
- 用户输入:
浏览器会将编码后的内容显示为普通文本:
<script>alert('XSS');</script>
而不会执行它。
通俗类比
想象一下,你在写一个公告板,每个人都可以贴便条。如果有人贴了一张上面写着“爆炸”的便条,别人看到可能会惊慌失措。但如果你在展示这些便条前,先把“爆炸”这个词改成“[危险词汇]”,那么别人看到就知道这是一个不能直接展示的词,而不会被吓到。
同样的道理,HTML 实体编码就是在把“危险”的字符换成“安全”的字符,让浏览器知道这些只是普通文字,而不是需要执行的代码。
总结
HTML 实体编码通过将用户输入的特殊字符转化为不会被浏览器执行的形式,有效地防止了 XSS 攻击。这样,用户输入的任何恶意代码都会被当作普通文本显示,而不会对其他用户造成威胁。
**方式三:**引入外部的 JS 文件
这种引入外部 JS 文件的方式,更难以让运维人员发现其漏洞。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><!-- 这里引入外部的 JS 文件 --><script src="tool.js"></script><!-- <script src="https://www.hacker.com/tool.js"></script> -->
</body>
</html>
tool.js 文件内容( 所有 JS 内容都写入在该 JS 文件中 )
alert('网络安全');
上面这段代码,依然是放到 body 标签里,可以和内嵌的 JS 代码并列。
另外,引用外部 JS 文件的 script 标签中间不可以再写代码。
总结:
我们在实战开发中,基本都是采用方式三,因为这种方式,可以确保 HTML 文件和 JS 文件是分开的,有利于代码的结构化和复用。很少会有人把一大堆 JS 代码塞到 HTML 文件里。但是在学习 Web 安全时,我们都是通过方式一或方式二去进行漏洞发现或利用的。
JS 的一些简单语法规则
- JavaScript 对换行、缩进、空格不敏感,每一条语句以分号结尾。
<script type="text/javascript">alert('床前明月光');alert('疑是地上霜');
</script>
等价于:
<script type="text/javascript">alert('床前明月光');alert('疑是地上霜');
</script>
**备注:**每一条语句末尾要加上分号,虽然分号不是必须加的,如果不写分号,浏览器会自动添加,但是会消耗一些系统资源。
-
所有的符号,都是英语的,比如括号、引号、分号。
-
严格区分大小写
注释
我们不要把 HTML、CSS、JavaScript 三者的注释格式搞混淆了。
- HTML 的注释
<!-- 我是注释 -->
- CSS 的注释
<style type="text/css">/*
我是注释
*/p{font-weight: bold;font-style: italic;color: red;
}</style>
注意:CSS 只有
/* */
这种注释,没有 // 这种注释。
而且注释要写在
- JavaScript 的注释
单行注释:
// 我是注释
多行注释:
/*多行注释多行注释
*/
**补充:**VS Code 中,单行注释的快捷键是「Ctrl + /」,多行注释的默认快捷键是 Alt + Shift + A。
当然,如果你觉得多行注释的默认快捷键不方便,我们还可以修改默认快捷键。操作如下:首选项 --> 键盘快捷方式 --> 查找“注释”这两个字 --> 将原来的快捷键修改为「Ctrl + Shift + /」
JavaScript 输入输出语句
参考:https://juejin.cn/post/7000740929636139038
- 弹出警告框:alert 语句
我们要学习的第一个语句,就是 alert 语句。
alert(英文翻译为 “警报”)的用途:弹出 “警告框”。
<script>alert('马哥教育');</script>
总结:
alert() 方法是 显示一条弹出提示消息和确认按钮的警告框。
需要注意的是 :alert() 是一个阻塞的函数,如果我们不点确认按钮,后面的内容就不会加载出来。( 并且我们也可以在 alert 中填写命令,比如 document.cookie 等。则会执行该命令返回其执行结果 )
- **控制台输出:
- console.log(“”) 表示在控制台中输出。console 表示“控制台”,log 表示“输出”。
- 在浏览器中,按 F12 即可打开控制台,选择「console」栏,即可看到打印的内容。
<script>console.log("恭喜你成功引起了我的注意");
</script>
**控制台:**是工程师、程序员调试程序的地方。程序员经常使用这条语句输出一些东西,来测试程序是否正确。
普通人是不会在意控制台的,但是有些网站另藏玄机。有个很有意思的地方是,百度首页的控制台,悄悄地放了一段招聘信息:
毕竟做前端的人是经常使用控制台的。
**总结:**alert() 主要用来显示消息给用户,console.log() 用来给程序员自己调试用的。
- 弹出输入框:prompt 语句
prompt() 就是专门用来弹出能够让用户输入的对话框。用得少,测试的时候偶尔会用。
<script>var a = prompt("请输入你的看法");console.log(a);
</script>
上方代码中,用户输入的内容,将被传递到变量 a 里面,并在控制台打印出来。
prompt() 语句中,用户不管输入什么内容,都是字符串。
alert() 和 prompt() 的区别:
- alert() 可以直接使用。
- prompt() 会返回用户输入的内容。我们可以用一个变量,来接收用户输入的内容。
示例: