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

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

Untitled

#知识点:

1、NodeJS-开发环境&功能实现
2、NodeJS-安全漏洞&案例分析
3、NodeJS-开发指南&特有漏洞

演示案例:

➢环境搭建-NodeJS-解析安装&库安装
➢功能实现-NodeJS-数据库&文件&执行
➢安全问题-NodeJS-注入&RCE&原型链
➢案例分析-NodeJS-CTF题目&源码审计
➢开发指南-NodeJS-安全SecGuide项目

#环境搭建-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

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

    • 发现代码不能运行,需要安装需要的库
    • 注意如果网速太慢,可以设置国内的镜像
    • 换上 阿里巴巴开源镜像站-OPSX镜像站里的淘宝 NPM 镜像
    • 发现展示出Hello World。
    **npm config set registry [https://registry.npmmirror.com](https://link.zhihu.com/?target=https%3A//registry.npmmirror.com)
    查看是否更换
    npm config get registry**
    

    Untitled

// express_demo.js 文件// 引入 Express 框架
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);
});

Untitled

  • 设置不同的页面渲染
// 引入 Express 框架
const express = require('express');
// 创建 Express 应用程序实例
const app = express();// 处理 '/login' 路径的 GET 请求,返回简单的登录页面
app.get('/login', function(req, res) {res.send('<hr>登录页面</hr>');
});// 处理根路径的 GET 请求,发送名为 'sql.html' 的文件
app.get('/', function(req, res) {res.sendFile(__dirname + '/' + 'sql.html');
});// 启动服务器,监听端口 3001
const server = app.listen(3001, function() {console.log('Web 服务器已经启动,监听端口 3001!');
});

Untitled

Untitled

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

1、实现用户登录

  • 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 和 123456if (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 和 123456if (u === 'admin' && p === '123456') {res.send('欢迎进入后台管理页面');} else {res.send('登录用户或密码错误');}
});// 处理根路径的 GET 请求,发送名为 'sql.html' 的文件
app.get('/', function(req, res) {res.sendFile(__dirname + '/' + 'sql.html');
});// 启动服务器,监听端口 3001
const server = app.listen(3001, function() {console.log('Web 服务器已经启动,监听端口 3001!');
});

Untitled

Untitled

Untitled

Untitled

2、加入数据库操作

  • 导入mysql ,npm i mysql下载相关依赖
const mysql = require('mysql');
  • 导入 mysql 模块
var connection = mysql.createConnection({
host     : 'localhost',
user     : 'root',
password : 'root',
database : 'dome01'
});
  • 建立与 MySQL 数据库的连接并执行查询语句,查询数据库中的内容

Untitled

// 建立与 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('错误');};**});
})

Untitled

Untitled

3、文件操作

  • 导入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);**});
}

Untitled

1、Express开发
2、实现目录读取
3、加入传参接受

4、命令执行(RCE)

  • 导入child_process ,npm i child_process下载相关依赖
const rce=require('child_process');
  • exec & spawnSync调用系统命令
  • eval调用代码命令执行,将字符串当做代码解析
// 引入child_process模块
const rce = require('child_process');// 使用exec方法调用系统命令'notepad',打开记事本
rce.exec('notepad');// 使用spawnSync方法调用系统命令'calc',打开计算器
rce.spawnSync('calc');// 使用eval调用代码命令执行,将字符串当做代码解析
// 请注意:避免在生产环境中使用eval,可能存在安全风险
eval('require("child_process").exec("calc");');

Untitled

Untitled

Untitled

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

1、SQL注入&文件操作

Untitled

Untitled

2、RCE执行&原型链污染
2、NodeJS黑盒无代码分析

黑盒测试和白盒测试区别,以及Payload 定义:

  1. 黑盒测试(Black Box Testing):
    • 黑盒测试是基于功能需求和规格说明的外部测试方法。
    • 测试人员在执行黑盒测试时,对系统内部的实现细节一无所知,只关注系统的输入和输出,以及系统的功能行为。
    • 测试人员将系统视为一个黑盒子,只关注输入数据、预期输出和系统行为,而不考虑内部的代码逻辑和结构。
    • 黑盒测试主要关注系统的功能、界面、性能、安全性等方面,以验证系统是否符合规格说明和用户需求。
    • 测试方法包括等价类划分、边界值分析、场景测试、错误推测等。
  2. 白盒测试(White Box Testing):
    • 白盒测试是基于系统的内部实现、代码结构和逻辑的测试方法。
    • 测试人员在执行白盒测试时,了解系统的内部结构和代码,可以直接检查、分析和测试系统的内部组成部分。
    • 白盒测试主要关注系统的代码覆盖率、逻辑路径、错误处理、性能优化等方面,以验证代码的正确性和质量。
    • 测试方法包括语句覆盖、分支覆盖、路径覆盖、条件覆盖、代码审查等。
  3. Payload 是指在攻击中传递的恶意代码、数据或命令。在进行 Payload 测试时,安全专家会设计和使用各种 Payload 来验证目标系统的安全性,并确定系统是否容易受到攻击或是否存在潜在的漏洞。

实战测试NodeJS安全:

判断:参考前期的信息收集
黑盒:通过对各种功能和参数进行payload测试
白盒:通过对代码中写法安全进行审计分析

  1. 信息收集(Reconnaissance):
    • 收集应用程序的基本信息,如版本号、依赖项版本等。
    • 查看应用程序的公开文档,了解其工作原理和功能。
    • 分析配置文件,查看是否有敏感信息泄漏的风险。
  2. 黑盒测试(Black Box Testing):
    • 通过输入字段,**尝试注入攻击,例如 SQL 注入、XSS(跨站脚本攻击)**等。
    • 测试文件上传功能,确保上传的文件受到适当的限制和验证。
    • 构造恶意请求,测试是否存在拒绝服务(DoS)漏洞。
    • 尝试绕过身份验证和授权,确保访问控制的有效性。
  3. 白盒测试(White Box Testing):
    • 对代码进行审计,查找潜在的安全问题。
    • 检查是否存在明文密码、硬编码的敏感信息等。
    • 确保应用程序对用户输入进行适当的验证和转义,以防止注入攻击。
    • 避免使用不安全的函数和方法,如 evalexec 等。
    • 确保文件上传和下载等操作受到适当的安全限制。
    • 检查是否启用了适当的安全头,如 CSP(内容安全策略)、X-Frame-Options、X-Content-Type-Options 等。
  4. 依赖项安全:
    • 定期审查依赖项的更新和安全漏洞。
    • 使用安全审计工具,如 npm audit,来检查依赖项的安全性。
    • 使用仅允许信任的依赖项,并确保避免使用已弃用或存在漏洞的依赖项。

原型链污染

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

Untitled

// 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));**

Untitled

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

1、CTFSHOW几个题目

Untitled

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

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

https://github.com/Tencent/secguide

Untitled

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

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

相关文章

MySQL知识点总结(三)——事务

MySQL知识点总结&#xff08;三&#xff09;——事务 事务事务的四大特性ACID原子性一致性隔离性持久性 脏读、幻读、不可重复读脏读不可重复读幻读 隔离级别读未提交读已提交可重复读串行化 事务的原理InnoDB如何实现事务的ACID事务的两阶段提交redo log与binlog的区别事务两阶…

【DevOps】产品需求文档(PRD)与常见原型软件

文章目录 1、PRD介绍1.1、概述1.2、前提条件1.3、主要目的1.4、关键内容1.5、表述方式1.6、需求评审人员1.7、一般内容结构 2、需求流程3、常见原型软件3.1、Word3.2、Axure3.2.1、详细介绍3.2.2、应用分类3.2.3、优缺点 3.3、摹客RP3.4、蓝湖3.5、GUI Design Studio 1、PRD介绍…

业务流程自动化平台在制造业应用案例,助力业务自动化、智能化

捷昌驱动成立于2000年&#xff0c;并于2018年9月在上海证券交易所上市&#xff0c;是一家专注于线性驱动产品研发、生产及销售的科技集团。 公司整合全球资源&#xff0c;为智慧办公、医疗康护、智能家居、工业自动化等关联产业提供驱动及智能控制解决方案&#xff0c;以科技驱…

荣耀手机如何录屏?在线分享3个录屏方法

荣耀手机如何录屏&#xff1f;荣耀手机录屏是一项非常实用的功能&#xff0c;它可以帮助我们轻松记录手机屏幕上的内容&#xff0c;无论是游戏攻略、教育学习还是工作演示&#xff0c;都能够方便地进行录制。通过录屏&#xff0c;我们可以随时随地记录和分享自己的操作和见解。…

探究Steam爆款游戏”幻兽帕鲁“:玩家评价揭秘

探究Steam爆款游戏”幻兽帕鲁“&#xff1a;玩家评价揭秘 文章目录 探究Steam爆款游戏”幻兽帕鲁“&#xff1a;玩家评价揭秘1 背景描述2 数据说明3 数据来源4 问题描述5 数据探索与预处理5.1 数据加载5.2 数据清洗 6 数据分析6.1 评论分布分析6.2 评论内容情感分析6.3 地理分布…

力扣热门100题刷题笔记 - 2.两数相加

力扣热门100题 - 2.两数相加 题目链接&#xff1a;2.两数相加 题目描述&#xff1a; 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。请你将两个数相加&#xff0c;并以相同形式返…

图书|基于Springboot的图书管理系统设计与实现(源码+数据库+文档)

图书管理系统目录 目录 基于Springboot的图书管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、个人中心 2、管理员管理 3、用户管理 4、图书出版社管理 5、公告类型管理 6、所在书架管理 7、图书类型管理 8、论坛管理 9、公告信息管理 10、图书信…

【数据结构】(分治策略)中位数的查询和最接近点对问题

中位数查询&#xff1a; 寻找一组字符串中第k小的数&#xff0c;返回其值和下标。 不可以有重复值&#xff08;在缩小规模的时候&#xff0c;会导致程序死循环&#xff09; 相对位置的转换体现了分治策略的思想。> 划分函数 int partition(int *nums,int left, int rig…

Jmeter 自动化性能测试常见问题汇总

一、request 请求超时设置 timeout 超时时间是可以手动设置的&#xff0c;新建一个 http 请求&#xff0c;在“高级”设置中找到“超时”设置&#xff0c;设置连接、响应时间为2000ms。 1. 请求连接超时&#xff0c;连不上服务器。 现象&#xff1a; Jmeter表现形式为&…

SQL sever2008中创建用户并赋权

一、创建数据库dream CREATE DATABASE dream; 二、创建登录用户XZS 法一&#xff1a;使用SSMS创建 通过查询 sys.syslogins 系统视图来确定当前登录是否具有系统管理员权限。执行以下查询语句&#xff1a; SELECT name, isntname FROM sys.syslogins WHERE sysadmin 1;选…

初始mach-o文件及在项目中应用

本文字数&#xff1a;2250字 预计阅读时间&#xff1a;15分钟 01 认识mach-o的必要性 了解mach-o的结构可以帮助认识系统加载二进制文件的动态链接和静态链接。应用层面&#xff0c;使用initialize的c函数计算启动时间耗时也需要以mach-o的结构知识为铺垫。还可以用在使用clang…

2、排列重要性 Permutation Importance

您认为模型哪些特性是重要的? 文章目录 1、简介2、工作原理3、代码示例4、解释排列重要性1、简介 对于模型来说,我们可能会问的最基本的一个问题是:哪些特征对预测影响最大? 这个概念被称为特征重要性。 有多种方法可以衡量特征重要性。一些方法回答了上面提到的问题的微…

怎么把几百M大小的视频做成二维码?扫码播放视频在线教程

怎么把几百M大小的视频做成一个二维码展示呢&#xff1f;通过二维码来作为视频的载体是现在很常用的一种手段&#xff0c;通过这种方式不仅成本比较低&#xff0c;而且传播速度也比较快&#xff0c;通过访问云端数据就可以播放视频。 视频二维码生成的方法一般会通过二维码生成…

C++模版初阶

前言 在本文我们将学习模版的基础知识点&#xff0c;了解泛型编程。 一、泛型编程 1、引入 我们如何实现一个通用的交换函数呢&#xff1f; 我们先看一段代码&#xff0c;如下&#xff1a; void Swap(int& left, int& right) {int temp left;left right;right te…

机器学习 | 如何利用集成学习提高机器学习的性能?

目录 初识集成学习 Bagging与随机森林 Otto Group Product(实操) Boosting集成原理 初识集成学习 集成学习&#xff08;Ensemble Learning&#xff09;是一种通过组合多个基本模型来提高预测准确性和泛化能力的机器学习方法。它通过将多个模型的预测结果进行整合或投票来做…

【Java程序设计】【C00243】基于Springboot的社区医院管理系统(有论文)

基于Springboot的社区医院管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的社区医院管理服务系统 本系统分为系统功能模块、管理员功能模块、用户功能模块以及医生功能模块。 系统功能模块&#xff1a;社…

ElementUI Form:Checkbox 多选框

ElementUI安装与使用指南 Checkbox 多选框 点击下载learnelementuispringboot项目源码 效果图 el-checkbox.vue &#xff08;Checkbox 多选框&#xff09;页面效果图 项目里el-checkbox.vue代码 <script> const cityOptions [上海, 北京, 广州, 深圳] export def…

JProfiler for Mac:提升性能和诊断问题的终极工具

在当今的高性能计算和多线程应用中&#xff0c;性能优化和问题诊断是至关重要的。JProfiler for Mac 是一个强大的性能分析工具&#xff0c;旨在帮助开发者更好地理解其应用程序的运行情况&#xff0c;提升性能并快速诊断问题。 JProfiler for Mac 的主要特点包括&#xff1a;…

2024/2/3

一&#xff0e;选择题 1、适宜采用inline定义函数情况是&#xff08;C&#xff09; A. 函数体含有循环语句 B. 函数体含有递归语句‘、考科一 ’ C. 函数代码少、频繁调用 D. 函数代码多、不常调用 2、假定一个函数为A(int i4, int j0) {;}, 则执行“A (1);”语句后&#xff0c…

机器学习复习(2)——线性回归SGD优化算法

目录 线性回归代码 线性回归理论 SGD算法 手撕线性回归算法 模型初始化 定义模型主体部分 定义线性回归模型训练过程 数据demo准备 模型训练与权重参数 定义线性回归预测函数 定义R2系数计算 可视化展示 预测结果 训练过程 sklearn进行机器学习 线性回归代码…