在nodejs中如何防止ssrf攻击

在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.mzph.cn/news/90884.shtml

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

相关文章

word 多级目录的问题

一、多级标题自动编号 --> 制表符 -> 空格 网址: 【Word技巧】2 标题自动编号——将多级列表链接到样式 - YouTube 二、多级列表 --> 正规形式编号 网址:Word 教学 - 定框架:文档格式与多级标题! - YouTube 三、目…

【项目】基于C++11实现的数据库连接池

文章目录 前置知识关键技术点项目背景连接池功能点介绍MySQL Server参数介绍功能设计连接池功能点介绍开发平台选型 关于MySQL数据库编程MySQL接口介绍 测试表设计Connection设计数据库配置文件mysql.conf日志文件log.hppConnectionPool设计压力测试源码链接: 前置知…

南京大学【软件分析】13 Static Analysis for Security

文章目录 1. Information Flow Security2. Confidentiality and Integrity3. Explicit Flows and Covert/Hidden Channels4. Taint Analysis污点分析案例 1. Information Flow Security 引起安全问题最主要的两大原因是:injection errors(2013-2019排名…

【深度学习实验】卷积神经网络(六):卷积神经网络模型(VGG)训练、评价

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入必要的工具包 1. 构建数据集(CIFAR10Dataset) a. read_csv_labels() b. CIFAR10Dataset 2. 构建模型(FeedForward&…

【网络协议】TCP

TCP协议全称为传输控制协议(Transmission Control Protocol).要理解TCP就要从他的特性开始说,这些特性各自之间或多或少各有联结,需要以宏观视角来看待。 目录: 1.TCP报文格式 因为报文解释过于繁琐,具体内容请看这篇文章TCP报文…

问题 - 谷歌浏览器 network 看不到接口请求解决方案

谷歌浏览器 -> 设置 -> 重置设置 -> 将设置还原为其默认值 查看接口情况,选择 All 或 Fetch/XHR,勾选 Has blocked cookies 即可 如果万一还不行,卸载浏览器重装。 参考:https://www.cnblogs.com/tully/p/16479528.html

微信小程序开发基础(二)基本组件

本帖开始介绍小程序中的一些基本组件~ 微信小程序是一种轻量、快速、跨平台的应用程序,是微信公众号的重要组成部分。随着微信小程序的普及,越来越多的开发者和企业开始使用微信小程序来搭建自己的应用,但是对于初次接触微信小程序的开发者…

CSS 基础 3

目录 🚀 导读 -- target 盒子模型 看透网页布局的本质 盒子模型组成 边框(border) border-style ​编辑border-color border-width 边框写法 简写 分开写 表格细线边框 边框会影响盒子实际大小 内边距 内容 内边距-padding padding属性简写 pad…

《PPT 自我介绍》:一本让你的职场表现更加出色的秘籍?

这里提供一个2000字左右的PPT自我介绍模板制作指南: 自我介绍是面试或工作中常见的情况,利用PPT可以给人留下更深刻的印象。但如何快速且专业地制作一个自我介绍PPT呢?这里给大家介绍几点技巧: 1. 选择一个简洁大方的PPT模板 首先要选择一…

STM32F4X UCOSIII任务信号量

STM32F4X UCOSIII任务信号量 任务信号量与内核信号量对比内核信号量任务信号量 UCOSIII任务信号量API任务信号量发送函数任务信号量接收函数 UCOSIII任务信号量例程 之前的章节中讲解过信号量这个机制,UCOSIII除了有内核信号量之外,还有任务信号量。在UC…

前端项目练习(练习-002-NodeJS项目初始化)

首先,创建一个web-002项目,内容和web-001一样。 下一步,规范一下项目结构,将html,js,css三个文件放到 src/view目录下面: 由于html引入css和js时,使用的是相对路径,所以…

详解C语言—文件操作

目录 1. 为什么使用文件 2. 什么是文件 3. 文件的使用 文件指针 文件的打开和关闭 三个标准的输入/输出流: 4. 文件的顺序读写 对字符操作: fputc: fgetc: 练习复制整个文件: 对字符串操作:…

WebGL雾化

目录 前言 如何实现雾化 线性雾化公式 雾化因子关系图 根据雾化因子计算片元颜色公式 示例程序(Fog.js) 代码详解​编辑 详解如何计算雾化因子(clamp()) 详解如何计算最终片元颜色(根据雾化因子计算片元颜色…

搭建自己的搜索引擎之四

一、前言 搭建自己的搜索引擎之三 介绍了通过HTTP RESTful 对ES进行增删改查,这一般手工运维ES时使用,程序代码中最好还是使用Java API去操作ES会更容易维护,但ES API竟然贼多,本篇介绍一下 四种 API及其简单使用。 注&#xff…

第1篇 目标检测概述 —(2)目标检测算法介绍

前言:Hello大家好,我是小哥谈。目标检测算法是一种计算机视觉算法,用于在图像或视频中识别和定位特定的目标物体。常见的目标检测算法包括传统的基于特征的方法(如Haar特征和HOG特征)以及基于深度学习的方法&#xff0…

Docker(三)、Dockerfile探究

Dockerfile探究 一、镜像层概念1、通过执行命令显化docker的机制 二、Dockerfile基础命令1、FROM 基于基准镜像【即构建镜像的时候,依托原有镜像做拓展】2、LABEL & MAINTAINER -说明信息3、WORKDIR 设置工作目录4、ADD & COPY 复制文件5、ENV 设置环境常量…

crypto:Alice与Bob

题目 根据题目描述,将98554799767分解成两个素数 得到两个素数101999和966233。根据题目提示把它们拼接起来进行md5的32位小写哈希

提升您的Mac文件拖拽体验——Dropzone 4 for mac

大家都知道,在Mac上进行文件拖拽是一件非常方便的事情。然而,随着我们在工作和生活中越来越多地使用电脑,我们对于这个简单操作的需求也越来越高。为了让您的文件拖拽体验更加高效和便捷,今天我们向大家介绍一款强大的工具——Dro…

[plugin:vite:css] [sass] Undefined mixin.

前言: vite vue3 TypeScript环境 scss报错: [plugin:vite:css] [sass] Undefined mixin. 解决方案: 在vite.config.ts文件添加配置 css: {preprocessorOptions: {// 导入scss预编译程序scss: {additionalData: use "/resources/_ha…

8章:scrapy框架

文章目录 scrapy框架如何学习框架?什么是scarpy?scrapy的使用步骤1.先转到想创建工程的目录下:cd ...2.创建一个工程3.创建之后要转到工程目录下4.在spiders子目录中创建一个爬虫文件5.执行工程setting文件中的参数 scrapy数据解析scrapy持久…