Day30:安全开发-JS应用NodeJS指南原型链污染Express框架功能实现审计

news2024/11/15 11:21:21

目录

环境搭建-NodeJS-解析安装&库安装

功能实现-NodeJS-数据库&文件&执行

安全问题-NodeJS-注入&RCE&原型链

案例分析-NodeJS-CTF题目&源码审计

开发指南-NodeJS-安全SecGuide项目

思维导图


JS知识点:

功能:登录验证,文件操作,SQL操作,云应用接入,框架开发,打包器使用等

技术:原生开发,DOM,常见库使用,框架开发(VueNodeJS),打包器(Webpack)

安全:原生开发安全,NodeJS安全,Vue安全,打包器Webpack安全,三方库安全问题等

环境搭建-NodeJS-解析安装&库安装

0 、文档参考:

https://www.w3cschool.cn/nodejs/

1、Nodejs安装

https://nodejs.org/en

2、三方库安装

express

Express是一个简洁而灵活的node.js Web应用框架

body-parser

node.js中间件,用于处理 JSON, Raw, Text和URL编码的数据。

cookie-parser

这就是一个解析Cookie的工具。通过req.cookies可以取到传过来的cookie,并把它们转成对象。

multer

node.js中间件,用于处理 enctype="multipart/form-data"(设置表单的MIME编码)的表单数据。

mysql

Node.js来连接MySQL专用库,并对数据库进行操作。

安装命令:

npm i express

npm i body-parser

npm i cookie-parser

npm i multer

npm i mysql

node.js开发的Web应用使用的是JS但是属于是后端代码,浏览器是看不到的,类似php

创建sql.js文件并粘贴实例代码

  • 发现代码不能运行,需要安装需要的库
  • 注意如果网速太慢,可以设置国内的镜像
  • 换上 阿里巴巴开源镜像站-OPSX镜像站里的淘宝 NPM 镜像
  • 发现展示出Hello World。

sql.js

// express_demo.js 文件

// 引入 Express 框架,用于快速构建基于 Node.js 的 Web 应用程序。
var express = require('express');
// 创建 Express 应用程序实例
var app = express();

// 处理根路径的 GET 请求,返回 'Hello World'
app.get('/', function (req, res) {
   res.send('Hello World');
});

// 启动服务器,监听端口 3000
var server = app.listen(3000, function () {
  // 获取服务器地址和端口
  var host = server.address().address;
  var port = server.address().port;

  // 输出服务器访问地址信息到控制台
  console.log("应用实例,访问地址为 http://%s:%s", host, port);
});

查看需要下载源,修改下载源

//查看是否更换
npm config get registry

npm config set registry [https://registry.npmmirror.com](https://link.zhihu.com/?target=https%3A//registry.npmmirror.com)

安装需要用到的库,在终端输入命令:node .\sql.js

设置不同的页面渲染

// 引入 Express 框架
const express = require('express');
// 创建 Express 应用程序实例
const app = express();

// 处理 '/login' 路径的 GET 请求,返回简单的登录页面
app.get('/login', function(req, res) {
  res.send('<hr>登录页面</hr>');
});

// 处理根路径的 GET 请求,发送名为 'sql.html' 的文件
// __dirname 是一个 Node.js 全局变量,表示当前脚本所在的目录。
app.get('/', function(req, res) {
  res.sendFile(__dirname + '/' + 'sql.html');
});

// 启动服务器,监听端口 3001
const server = app.listen(3001, function() {
  console.log('Web 服务器已经启动,监听端口 3001!');
});

功能实现-NodeJS-数据库&文件&执行

1 、Express开发 

2、实现用户登录 

3、加入数据库操作

-文件操作

1、Express开发

2、实现目录读取

3、加入传参接受

-命令执行(RCE

1、eval

2、exec & spawnSync

实现用户登录

  • req.query 用于处理 URL 查询字符串参数GET请求,而 req.body 用于处理 POST 请求中的表单数据。
  • 还需要下载const bodyParser = require('body-parser'); 相关库 npm i body-parser
  • 并且post请求还需要创建一个解析URL编码的bodyParser中间件实例
// 引入 Express 框架
const express = require('express');
const bodyParser = require('body-parser');

// 创建 Express 应用程序实例
const app = express();
// 创建一个用于解析 URL 编码的 bodyParser 中间件实例
const urlencodedParser = bodyParser.urlencoded({ extended: false });

// 处理 '/login' 路径的 GET 请求,返回简单的登录页面
app.get('/login', function(req, res) {
  // 从请求中获取用户名和密码
  const u = req.query.username;
  const p = req.query.password;

  console.log(u);
  console.log(p);

  // 检查用户名和密码是否为 admin 和 123456
  if (u === 'admin' && p === '123456') {
    res.send('欢迎进入后台管理页面');
  } else {
    res.send('登录用户或密码错误');
  }
});

// 处理 '/login' 路径的 POST 请求,使用 bodyParser 解析表单数据
app.post('/login', urlencodedParser, function(req, res) {
  // 从请求中获取表单提交的用户名和密码
  const u = req.body.username;
  const p = req.body.password;

  console.log(u);
  console.log(p);

  // 检查用户名和密码是否为 admin 和 123456
  if (u === 'admin' && p === '123456') {
    res.send('欢迎进入后台管理页面');
  } else {
    res.send('登录用户或密码错误');
  }
});

// 处理根路径的 GET 请求,发送名为 'sql.html' 的文件
// __dirname 是一个 Node.js 全局变量,表示当前脚本所在的目录。
app.get('/', function(req, res) {
  res.sendFile(__dirname + '/' + 'sql.html');
});

// 启动服务器,监听端口 3001
const server = app.listen(3001, function() {
  console.log('Web 服务器已经启动,监听端口 3001!');
});

sql.html Post提交

登录成功

加入数据库操作

导入mysql ,npm i mysql下载相关依赖

const mysql = require('mysql');

导入 mysql 模块

var connection = mysql.createConnection({
host     : 'localhost',
user     : 'root',
password : 'root',
database : 'dome01'
});

建立与 MySQL 数据库的连接并执行查询语句,查询数据库中的内容

const mysql = require('mysql');

var connection = mysql.createConnection({
host     : 'localhost',
user     : 'root',
password : 'root',
database : 'dome01'
});

// 建立与 MySQL 数据库的连接
connection.connect();

// 定义从 'admin' 表中选择所有列的 SQL 查询
const sql ='select * from admin';

// 执行 SQL 查询
connection.query(sql, function(error, data){
  // 检查查询执行中是否存在错误
  if(error){
    console.log('数据库连接失败!');
  }

  // 记录从查询中检索到的全部数据
  console.log(data);

  // 记录结果集中第一行的用户名
  console.log(data[0]['username']);

  // 记录结果集中第一行的密码
  console.log(data[0]['password']);
});

将mysql的内容添加至登录验证中

// 处理 '/login' 路径的 POST 请求,使用 bodyParser 解析表单数据
app.post('/login', urlencodedParser, function(req, res) {
  // 从请求中获取表单提交的用户名和密码
  const u = req.body.username;
  const p = req.body.password;

  // 输出获取到的用户名和密码,用于调试
  console.log(u);
  console.log(p);

  // 创建与 MySQL 数据库的连接
  var connection = mysql.createConnection({
    host     : 'localhost',
    user     : 'root',
    password : 'root',
    database : 'dome01'
  });

  // 建立数据库连接
  connection.connect();

  // 构建 SQL 查询,检查数据库中是否存在匹配的用户名和密码
  const sql = 'select * from admin where username="'+u+'" and password="'+p+'"';
  console.log(sql);

  // 执行 SQL 查询
  connection.query(sql, function(error, data){
    // 检查查询执行中是否存在错误
    if(error){
        console.log('数据库连接失败!');
    }

    try {
        // 检查用户名和密码是否匹配数据库中的数据
        if(u == data[0]['username'] && p == data[0]['password']){
            // 如果匹配,发送欢迎消息到前端
            res.send('欢迎进入后台管理页面');
        }
    } catch {
        // 捕获异常,如果没有匹配的数据或其他错误,发送错误消息到前端
        res.send('错误');
    };**
  });
})

文件操作

导入fs ,npm i fs下载相关依赖npm i fs

const fs = require('fs');

调用文件管理函数,传递目录参数
http://127.0.0.1:3000/file?dir=./
http://127.0.0.1:3000/file?dir=…/

// 引入文件系统和 Express 框架
const fs = require('fs');
const express = require('express');
const app = express();

// 处理 '/file' 路径的 GET 请求
app.get('/file', function (req, res) {
    // 从请求中获取目录参数
    const dir = req.query.dir;
    console.log(dir);

    **// 调用文件管理函数,传递目录参数
    filemanage(dir);**
});

// 启动 Express 应用监听在3000端口
var server = app.listen(3000, function () {
    console.log('Web应用已启动在3000端口!');
});

// 文件管理函数,接收一个目录参数
function filemanage(dir) {
    **// 使用 fs.readdir 读取目录下的文件
    fs.readdir(dir, function (error, files) {
        // 打印目录中的文件列表
        console.log(files);**
    });
}

命令执行(RCE)

导入child_process ,npm i child_process下载相关依赖

const rce=require('child_process');

exec & spawnSync调用系统命令
eval调用代码命令执行
,将字符串当做代码解析

安全问题-NodeJS-注入&RCE&原型链

1 SQL 注入 & 文件操作

2RCE执行&原型链污染

2、NodeJS黑盒无代码分析

实战测试NodeJS安全:

判断:参考前期的信息收集

黑盒:通过对各种功能和参数进行payload测试

白盒:通过对代码中写法安全进行审计分析

-原型链污染

如果攻击者控制并修改了一个对象的原型,(__proto__)

那么将可以影响所有和这个对象来自同一个类、父祖类的对象。

SQL注入

这个语句,后面整体为真,实际上是查询了真个表

当使用拼接方式带入数据库查询时,这里就已经产生了 sql 注入漏洞

sql 注入防护手段:预编译

RCE执行&原型链污染

在很多 Web 应用中,开发人员会使用一些函数,这些函数以一些字符串作为输入,功能是将输入的字符串当作代码或者命令来进行执行。当用户可以控制这些函数的输入时,就产生了 RCE 漏洞。
RCE 漏洞是非常严重的安全漏洞,一旦出现,就意味着攻击者可以获取服务器的命令执行权限,从而对服务器安全造成极大的影响。
nodejs 中主要就是下面这:eval(代码执行),exec & spawnSync(命令执行)

文件操作

这里的 server 是访问以下 url,dir 是传递的参数,这里就可以目录遍历,通过修改 dir 参数即可。127.0.0.1:3000/file?dir=./

这里文件管理权限设置不当,同样也会造成目录遍历漏洞

原型链污染

如果攻击者控制并修改了一个对象的原型,(__proto__)
那么将可以影响所有和这个对象来自同一个类、父祖类的对象。

测试代码:

// foo是一个简单的JavaScript对象
let foo = {bar: 1} //1=1 0 __proto__= x
// 原型链污染
// foo.bar 此时为1
console.log(foo.bar)//输出为1

// 修改foo的原型(即Object)
foo.__proto__.bar = '2'

// // 由于查找顺序的原因,foo.bar仍然是1
console.log(foo.bar)//输出为1

// // 此时再用Object创建一个空的zoo对象
let zoo = {}

// 查看zoo.bar,此时bar为2
console.log(zoo.bar)//输出为2

执行结果:

利用原型链污染,调用系统计算器

// 创建一个包含属性 bar 的对象 foo,并将 bar 设置为 1
let foo = {bar: 1};

// 输出 foo 对象的 bar 属性,预期输出为 1
console.log(foo.bar); // 输出: 1

// 修改 foo 对象的原型链上的 bar 属性,将其设置为执行命令 'require(\'child_process\').execSync(\'calc\');'
//调用计算机
foo.__proto__.bar = 'require(\'child_process\').execSync(\'calc\');';

// 输出 foo 对象的 bar 属性,预期输出仍为 1,因为直接属性优先于原型链上的属性
console.log(foo.bar); // 输出: 1

// 创建一个空对象 zoo
let zoo = {};

// 使用 eval 执行 zoo 对象的 bar 属性,由于 zoo 对象没有 bar 属性,会导致 ReferenceError
//调用计算机
console.log(eval(zoo.bar));

安全问题:

  • 额,迪总说了打 ctf 有用,实战中基本没用,要求太多了,听了就当没听过就行。
  • 在 y2-rce.js 演示了一下原型链污染结合 rce 导致的漏洞,通过污染原型链,使其新创建的对象拥有 bar,
    且由于后续还使用了不安全函数 eval 执行了其中的代码

案例分析-NodeJS-CTF题目&源码审计

1 CTFSHOW 几个题目

https://ctf.show/ Web334-344

https://f1veseven.github.io/2022/04/03/ctf-nodejs-zhi-yi-xie-xiao-zhi-shi/

2、YApi管理平台漏洞

https://blog.csdn.net/weixin_42353842/article/details/127960229

CTFSHOW 几个题目

CTFSHOW 这个需要 vip,而且不便宜,感兴趣的可以自己冲,没 vip 貌似不能打,
迪总演示的是 web 入门的 334 关,直接 ctrl+f 在 web 入门页面搜 334 就能找到这关

  • ctfshow:
    https://ctf.show
  • ctf-nodejs 之一些小知识:
    https://f1veseven.github.io/2022/04/03/ctf-nodejs-zhi-yi-xie-xiao-zhi-shi/

2、YApi 管理平台漏洞(这个没讲,迪总只是给看了下)
https://blog.csdn.net/weixin_42353842/article/details/127960229

开发指南-NodeJS-安全SecGuide项目

https :// github . com / Tencent / secguide

思维导图

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

EI期刊复现:面向配电网韧性提升的移动储能预布局与动态调度策略程序代码!

适用平台&#xff1a;MatlabYalmipCplex/Gurobi/Mosek 程序提出一种多源协同的两阶段配电网韧性提升策略。在灾前考虑光伏出力不确定性与网络重构&#xff0c;以移动储能配置成本与负荷削减风险成本最小为目标对储能的配置数量与位置进行预布局&#xff1b;在灾后通过多源协同…

保护IP地址安全:维护网络安全

在今天的数字化时代&#xff0c;IP地址是互联网通信的基础&#xff0c;也是网络安全的重要组成部分。保护IP地址安全至关重要&#xff0c;因为恶意攻击者可能利用IP地址进行网络入侵、数据泄露、服务拒绝等攻击。因此&#xff0c;制定有效的保护措施&#xff0c;维护IP地址的安…

深入理解指针——C语言

目录 1. 内存和地址 2. 指针变量和地址 3. 指针变量类型的意义 4. const修饰指针 5. 指针运算 6. 野指针 7. assert断言 8. 指针的使用和传址调用 9. 数组名的理解 10. 使用指针访问数组 11. 一维数组传参的本质 12. 冒泡排序 13. 二级指针 14. 指针数组 15. 指…

英语同传翻译,北京本地同声传译收费价格多少

同声传译是一项高度专业化的服务&#xff0c;广泛应用于国际会议、商务洽谈、法庭审判等场合。由于其对译员的语言能力、专业知识以及应变能力的极高要求&#xff0c;使得同声传译的收费价格也相对较高。那么&#xff0c;英语同传翻译北京本地同声传译的收费价格到底是多少呢&a…

深入探索C与C++的混合编程

实现混合编程的技术细节 混合使用C和C可能由多种原因驱动。一方面&#xff0c;现有的大量优秀C语言库为特定任务提供了高效的解决方案&#xff0c;将这些库直接应用于C项目中可以节省大量的开发时间和成本。另一方面&#xff0c;C的高级特性如类、模板和异常处理等&#xff0c;…

Aigtek功率信号源的特点有哪些

功率信号源是一种用于产生高功率信号的电子设备&#xff0c;主要应用于无线通讯、雷达测量、广播电视等领域中。功率信号源具有输出功率大、稳定可靠、频率范围宽等特点&#xff0c;使其成为现代电子技术中不可或缺的重要组成部分。 以下是功率信号源的主要特点&#xff1a; 高…

科研三维模型高精度三维扫描服务3d逆向测绘建模工业产品抄数设计

三维抄数技术在科研三维模型的应用已经日益广泛&#xff0c;其高精度、高效率的特点使得科研工作者能够更快速、更准确地获取和分析数据。这一技术的核心在于通过专业的三维扫描仪对实物进行高精度测量&#xff0c;再将这些数据转化为三维数字模型&#xff0c;为后续的研究提供…

react 综合题-旧版

一、组件基础 1. React 事件机制 javascript 复制代码<div onClick{this.handleClick.bind(this)}>点我</div> React并不是将click事件绑定到了div的真实DOM上&#xff0c;而是在document处监听了所有的事件&#xff0c;当事件发生并且冒泡到document处的时候&a…

springboot268码头船只货柜管理系统

码头船只出行和货柜管理系统的设计与实现 摘要 针对于码头船只货柜信息管理方面的不规范&#xff0c;容错率低&#xff0c;管理人员处理数据费工费时&#xff0c;采用新开发的码头船只货柜管理系统可以从根源上规范整个数据处理流程。 码头船只货柜管理系统能够实现货柜管理…

运行springboot项目提示:java: 错误: 不支持发行版本 18、java: 错误: 无效的源发行版:18

java: 错误: 不支持发行版本 18 解决方法&#xff1a;修改字节码版本&#xff0c;可以多试几次。 java: 错误: 无效的源发行版&#xff1a;18 解决方法&#xff1a; 出现这些错误原因&#xff1a; spring版本与jdk版本不对应 我的spring boot版本是3.2.2&#xff0c;对应的j…

AI-线性回归模型

线性回归应用场景 房价预测&#xff0c;通过分析房地产市场的历史数据&#xff0c;如房屋大小、位置、建造年份等因素&#xff0c;线性回归可以帮助预测未来房价的走势。 销售额预测&#xff0c;企业可以利用线性回归模型来预测产品的销售额&#xff0c;这通常涉及到产品价格、…

如何选择合适的IP代理,如何为网络爬虫设置代理

目录 前言 1. 代理类型的选择 2. 代理速度 3. 代理稳定性 4. 代理的匿名性 5. 代理的地理位置 总结 前言 在进行网络爬虫任务时&#xff0c;为了避免被目标网站封禁IP或限制访问频率&#xff0c;我们通常会使用代理来隐藏真实的IP地址。选择合适的IP代理对于爬虫的成功…

降维算法之主成分分析 (Principal Component Analysis, PCA)

注意&#xff1a;本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站 &#xff08;[www.aideeplearning.cn]&#xff09; 主成分分析&#xff08;PCA&#xff09;是一种统计方法&#xff0c;用于减少数据的维度&#xff0c;同时尽量保留原始数据中的方差。PCA在机器学…

【Flask开发实战】项目介绍-防火墙规则查询系统

一、前言 硬件防火墙为常备主用网络安全设备&#xff0c;主要通过网络访问控制方式实现安全防护。 不同厂家防火墙的网络访问控制功能均采用同样的模式操作&#xff1a;防火墙配置若干条防火墙规则&#xff0c;当IP包到来&#xff0c;防火墙根据包的五元组属性&#xff08;协…

线上会议大厅应该具备哪些功能,线上会议大厅搭建要注意什么

引言&#xff1a; 随着互联网和信息技术的不断发展&#xff0c;线上会议大厅逐渐成为各行各业进行会议和交流的重要工具。但是&#xff0c;真正的线上会议大厅必须具备一定的功能和特性&#xff0c;才能满足用户的需求&#xff0c;提升会议体验。 一&#xff0e;线上会议大厅应…

13.7 Map 接口(血干JAVA系列)

这里写目录标题 13.7.1 Map接口简介13.7.2 Map.Entry接口简介13.7.3 Map接口的常用子类1.新的子类&#xff1a;HashMap2.相关操作实例(1)实例操作1——向集合中增加和取出内容【例13.26】增加和取得内容 (2)实例操作2------------ 判断指定的key或value是否存在【例13.27】判断…

代码随想录day19(2)二叉树:二叉树的最大深度(leetcode104)

题目要求&#xff1a;求出二叉树的最大深度 思路&#xff1a;首先要区分二叉树的高度与深度。二叉树的高度是任一结点到叶子结点的距离&#xff0c;而二叉树的深度指的是任一节点到根节点的距离&#xff08;从1开始&#xff09;。所以求高度使用后序遍历&#xff08;从下往上&…

金蝶云星空对接打通阿里宜搭逐个单据查询接口与新增表单实例接口

金蝶云星空对接打通阿里宜搭逐个单据查询接口与新增表单实例接口 数据源平台:金蝶云星空 金蝶K/3Cloud结合当今先进管理理论和数十万家国内客户最佳应用实践&#xff0c;面向事业部制、多地点、多工厂等运营协同与管控型企业及集团公司&#xff0c;提供一个通用的ERP服务平台。…

392.判断子序列

题目&#xff1a;给定字符串s和t&#xff0c;判断s是否为t 的子序列。 字符串的一个子序列是原始字符串删除一些字符而不改变剩余字符相对位置形成的新字符串。 解题思路&#xff1a;s是否是 t 的子序列&#xff0c;因此只要能找到任意一种 s 在 t 中出现的方式&#xff0c;即…

义乌购关键字搜索API接口技术详解与代码示例

义乌购关键字搜索API接口技术详解与代码示例 在电子商务蓬勃发展的今天&#xff0c;义乌购作为国内知名的批发市场平台&#xff0c;为广大商家和消费者提供了丰富的商品资源。为了方便开发者快速接入义乌购平台&#xff0c;实现商品信息的搜索与获取&#xff0c;义乌购开放了关…