在nodejs中如何防止ssrf攻击

news2024/11/25 13:16:49

在nodejs中如何防止ssrf攻击

什么是ssrf攻击

ssrfserver-side request forgery)是服务器端请求伪造,指攻击者能够从易受攻击的Web应用程序发送精心设计的请求的对其他网站进行攻击。(利用一个可发起网络请求的服务当作跳板来攻击其他服务)。

我们用一个例子来解释一下这个概念 。想象一下,我们有一个应用程序,用户需要上传图片及图片名称。那么这个时候是使用img标签显示图片的时候就会先下载图片(向服务器提出请求)。既然攻击者知道我们是在发出这些GET请求,他就会把http://localhost/admin这样的网址作为图片名称传递给服务端。如果我们的系统没有考虑到此攻击,那么将向服务器发送一个请求,当有人能够访问我们的内部系统或服务时这是非常危险的。现在。如果我们显示的是图像是下载请求的结果,它可以使攻击者更容易地探索内部服务和做一些事情。

不同类型的ssrf攻击

  • 服务器攻击:在上面说到的通过图片传递url的例子可知,如果我们传递了类似于localhost127.0.0.1 或者服务器本身的IP,那么我们本身就是在攻击这个服务器。
  • 内部后端系统:在这种情况下,攻击者试图与其他后端系统进行通信。为此他使用了包含内部IP的地址例如 http://192.168.0.68/admin 或者直接使用域名例如https://payment/something
  • 外部系统:这可能是一个只有我们的服务器或内部服务能够交互的外部系统。这可能是一个银行API或任何限制其服务到我们的IP`地址的其他形式的身份验证和授权。

在这里插入图片描述

基本ssrf和盲ssrf是什么

在从URL下载图片的例子中,如果我们直接将响应返回给用户。那么攻击者就能够看到响应并更快地探索我们的内部服务。

如果我们没有显示来自请求的任何响应,那么攻击类型就会变成盲ssrf,这使得攻击者在没有看到响应的情况下更难探索我们的系统。

ssrf攻击的一个例子

下面是一段简历生成网站代码,当我们为个人网站填写一个字段时。它会检查该字段是否是一个有效的网站。如果它不能访问该网址,会给一个反馈。这个应用程序有一个基本部分,路由。必须对自己进行身份验证才能访问这些路由。我们有一个内部服务被称为付款。只有主要的应用程序可以访问它,而且它不是公开的。(这完全是简单化的,目的是了解可能发生的情况)。

让我们看看代码的核心。它包括:

  • 个人网站:查看网址,它会给我们一条信息,告诉我们是否能访问成功,并返回来自个人网站的回应,同时对整个网址提供预览。
  • 我的:用于检查当前用户的余额。它向我们的支付服务发送请求。
  • 钱包:向我们内部的支付服务发送请求。
const express = require('express');
const app = express();
const axios = require('axios');
app.use(express.json());
const paymentServiceAddress = 'localhost:3011'
app.post('/personal-website', async (req, res) => {
    const url = req.body?.url;
    try {
        const websiteHomePageTest = await axios.get(url);
        await saveAddressInProfile(url);
        res.json({ message: 'success', url, data: websiteHomePageTest.data });
    }
    catch (error) {
        if (axios.isAxiosError(error)) {
            return res.json({ message: 'failed', error: error.message }).status(500);
        } else {
            console.error(error);
            res.json({ message: 'failed' }).status(500);
        }
    }
});

app.post('/me/balance', someAuthenticationMiddleware, async (req, res) => {
    const response = await axios.post(`http://${paymentServiceAddress}/1/balance`);
    const balance = response.data.balance;
    res.json({ balance });
})

app.post('/me/balance/payin', someAuthenticationMiddleware, async (req, res) => {
    const payIn = await payIn()
    const response = await axios.post(`http://${paymentServiceAddress}/1/balance/increase`);
    const balance = response.data.balance;
    res.json({ balance });
})

app.listen(3010, () => console.log(`Example app listening at http://localhost:3010`));
async function saveAddressInProfile(image) { console.log('保存图片'); }
function someAuthenticationMiddleware(req, res, next) { next(); }
async function payIn() { }

如果我们在个人网站上使用一个有效的网址,我们会得到这个结果:

在这里插入图片描述

现在,如果我们尝试其他的URL,可以检查是否具备其他额外的服务。

在这里插入图片描述
这个响应给了我们一个内部服务的IPport。现在攻击者应该开始使用这个URL来寻找其他服务。

如果我们尝试一个地址http://localhost:3011。我们看到结果是success,这意味着在这个网址后面有一个服务。让我们看看支付服务的实施情况。我们不能直接向这个服务提出请求,因为它是在一个私人网络中,但是我们可以从主应用程序中提出请求。

const express = require('express');
const app = express();
app.use(express.static('static'));
app.use(express.json());

app.get('/', (req, res) => {
    res.send('pong');
});

app.get('/:userId/balance', async (req, res) => {
    const balance = getUserBalance(req.params.userId);
    res.json({ balance });
});

const users = [
    { id: 1, name: 'leo', balance: 100 },
    { id: 2, name: 'alex', balance: 200 },
    { id: 3, name: 'Jack', balance: 300 }
]
function getUserBalance(userId) {
    return users.find(user => user.id == userId)?.balance;
}

app.listen(3011, () => {
    console.log(`Example app listening at http://localhost:3011`);
});

在尝试了一点点之后攻击者会发现有一个路径可以获取用户信息。(当URL不正确时,付款服务返回404,我们在响应中看到结果)。

通过使用balance路由,我们可以访问所有用户,使用他们的用户名。一般情况下在主程序上使用这个路径/me/balance,我们可以看到自己的信息,但现在我们也可以未经授权访问其他用户的平衡。

在这里插入图片描述

如何防止ssrf攻击

校验

黑名单

可以使用正则表达式来验证URL,或者列出一个黑名单。列出一些禁止的短语,比如127.0.0.1localhost。我们可以直接使用正则表达式,也可以Zodhapivalidatorjs这些库。

IP地址

直接限制可访问的ip

域名

直接限制可访问的域名。

使用适当的认证和授权

在我们的示例中,看到主应用程序可以访问任何类型的对支付服务的请求。一个更好的方法是传递用户身份验证信息(可能是JWT或会话或任何东西),然后支付从JWT有效载荷中获得用户标识,然后我们确定该用户可以访问这些数据。即使是后端服务也应该在彼此之间有有限的访问权限。如果他们依靠用户访问,那么获得未经授权的访问可能会更困难。

不暴露对未知请求的回应

这个例子中的另一个错误是,它在成功和失败时都公开了一个HTTP请求响应。任何额外信息都可能是攻击者的线索。因此,当个人网站不可用或提供内部服务器时,我们不应该暴露任何相关服务的响应。

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

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

相关文章

mac docker部署hadoop集群

1. 安装docker 确保电脑已经安装docker docker安装过程可自行查找资料,mac下docker可以使用brew命令安装 安装之后,查看docker版本,确认安装成功 docker -v2. 下载jdk 最好下载jdk-8,jdk的版本过高可能hadoop2.x不支持jdk-8的下…

掌握 JavaScript 数组方法:了解如何操作和优化数组

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…

Android Logcat 命令行工具

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。 目录 一、导读二、概览三、日常用法3.1 面板介绍3.2 日志过滤…

零代码编程:用ChatGPT批量将多个文件夹中的视频转为音频

有多个文件夹中的 视频,都要批量转换成音频格式。 转换完成后要删除视频。虽然现在已经有很多格式转换软件可以实现这个功能,但是需要一个个文件夹的操作,还要手动去删除视频。用ChatGPT来写一个批量自动操作程序吧: 输入提示词如…

获取el-select选中的下标

accountZbList:[ ]:下拉列表已通过接口获取数据 <el-row><el-col :span"12"><el-form-item label"账簙" prop"accountTook" class"itemzb"><el-select v-model"tableForm.accountTook" placeholder&…

软件测试基础学习

注意&#xff1a; 各位同学们&#xff0c;今年本人求职目前遇到的情况大体是这样了&#xff0c;开发太卷&#xff0c;学历高的话优势非常的大&#xff0c;公司会根据实际情况考虑是否值得培养&#xff08;哪怕技术差一点&#xff09;&#xff1b;学历稍微低一些但是技术熟练的…

改进的最大内切圆算法求裂缝轮廓宽度

前段时间我将网上最大内切圆算法进行了代码的整理&#xff0c;原先博主上传的代码稍微有点乱&#xff0c;可能也是它自己使用&#xff0c;大家可以看这篇整理好的&#xff1a;最大内切圆算法计算裂缝宽度。 最大内切圆算法详解 一个圆与给定的多边形或曲线的每一条边或曲线都…

13.(开发工具篇github)如何在GitHub上上传本地项目

一:创建GitHub账户并安装Git 二:创建一个新的仓库(repository) 三、拉取代码 git clone https://github.com/ainier-max/myboot.git git clone git@github.com:ainier-max/myboot.git四、拷贝代码到拉取后的工程 五、上传代码 (1)添加所有文件到暂存

PyTorch 模型性能分析和优化 — 第 1 部分

一、说明 这篇文章的重点将是GPU上的PyTorch培训。更具体地说&#xff0c;我们将专注于 PyTorch 的内置性能分析器 PyTorch Profiler&#xff0c;以及查看其结果的方法之一&#xff0c;即 PyTorch Profiler TensorBoard 插件。 二、深度框架 训练深度学习模型&#xff0c;尤其是…

江西广电会展集团总经理李悦一行莅临拓世科技集团调研参观,科技璀璨AIGC掀新潮

在江西这片充满活力的土地上&#xff0c;数字经济如潮水般涌动&#xff0c;会展文化与科技的完美结合&#xff0c;正如新时代的璀璨繁星照亮夜空&#xff0c;更预示着一场AIGC创新的壮丽篇章即将展开。作为拓世科技集团的老朋友&#xff0c;江西广电多位领导多次莅临拓世科技集…

【MATLAB源码-第40期】基于matlab的D*(Dstar)算法栅格路径规划仿真。

1、算法描述 D*算法路径规划 D*算法&#xff08;Dynamic A*&#xff09;是A*算法的一种变种&#xff0c;主要用于在地图中的障碍物信息发生变化时重新计算路径&#xff0c;而不需要从头开始。该算法适用于那些只有部分信息已知的环境中。 工作原理&#xff1a; 1. D*算法首先…

嵌入式Linux应用开发-第七章-RK3288和 RK3399的 LED驱动程序

嵌入式Linux应用开发-第七章-RK3288和 RK3399的 LED驱动程序 RK3288和 RK3399的 LED驱动程序7.3 RK3288和 RK3399的 LED驱动程序7.3.1 原理图7.3.1.1 fireflye RK3288的 LED原理图7.3.1.2 firefly RK3399的 LED原理图 7.3.2 所涉及的寄存器操作7.3.2.1 RK3288的 GPIO8_A1引脚7.…

探索ClickHouse——使用MaterializedView存储kafka传递的数据

在《探索ClickHouse——连接Kafka和Clickhouse》中&#xff0c;我们讲解了如何使用kafka engin连接kafka&#xff0c;并读取topic中的数据。但是遇到了一个问题&#xff0c;就是数据只能读取一次&#xff0c;即使后面还有新数据发送到该topic&#xff0c;该表也读不出来。 为了…

Ae 效果:CC Smear

扭曲/CC Smear Distort/CC Smear CC Smear &#xff08;CC 漩涡条纹&#xff09;可以将两点之间的源图像内容进行拉伸扭曲变形&#xff0c;形成一种类似油墨被涂抹或者柔体被拉扯之后的漩涡条纹效果。 ◆ ◆ ◆ 效果属性说明 From 从 漩涡条纹效果的起点。 默认为合成的中心。…

麒麟v10获取wwn

for i in cat /proc/partitions | awk {print $4} | grep sd do echo "Device: $i WWID: /usr/lib/udev/scsi_id --page0x83 --whitelisted --device/dev/$i" done | sort -k4

用于时间触发的嵌入式软件的IDE

TTE Systems的RapidiTTy IDE为希望创建“时间触发”微控制器软件以提高整体系统可靠性的开发人员提供了一个独立的环境。RapidiTTy&#xff08;下面的图1&#xff09;旨在解决深度嵌入的应用&#xff0c;包括医疗&#xff0c;国防&#xff0c;汽车和工业部门以及白色和棕色商品…

【Linux】Linux远程访问Windows下的MySQL数据库

1.建立Windows防火墙规则 首先需要开放windows防火墙&#xff0c;针对3306端口单独创建一条规则&#xff0c;允许访问。 打开windows安全中心防火墙与保护&#xff0c;点击高级设置 进入之后&#xff0c;点击入站规则&#xff0c;新建一条规则 新建端口入站规则 端口填写330…

【计算机网络】 基于TCP的简单通讯(客户端)

文章目录 流程伪代码代码实现加载库创建套接字连接服务端收发数据关闭套接字、卸载库 测试 流程伪代码 //1、加载库//2、创建套接字//3、连接服务端while(true){//4、发送数据//5、接收数据} //6、关闭套接字、卸载库代码实现 加载库 int err 0;WORD version MAKEWORD(2, 2…

表单控件拖拽平台都有哪些特点?

什么样的表单控件拖拽平台可以提升办公协作效率&#xff1f;在竞争激烈的当今社会&#xff0c;利用低代码技术平台的优势和特点&#xff0c;可以将企业内部的数据资源真正利用起来&#xff0c;帮助更多领域的客户朋友做出更有竞争优势的经营决策&#xff0c;实现数字化转型和流…

【Verilog 教程】6.3Verilog状态机

关键词&#xff1a;状态机&#xff0c;售卖机 有限状态机&#xff08;Finite-State Machine&#xff0c;FSM&#xff09;&#xff0c;简称状态机&#xff0c;是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。状态机不仅是一种电路的描述工具&#xff0c;而且…