《白帽子讲 Web 安全》之服务端请求伪造(SSRF)深度剖析:从攻击到防御

news2025/3/31 22:46:59

引言

在当今复杂的网络环境中,Web 应用安全犹如一座时刻需要精心守护的堡垒。随着技术的不断演进,各类安全威胁层出不穷,其中服务端请求伪造(SSRF)正逐渐成为令开发者与安全从业者头疼的一大难题。吴翰清在《白帽子讲 Web 安全》中对 SSRF 进行了深入探讨,接下来让我们详细梳理这一安全隐患的相关知识。

SSRF 攻击简介

定义

服务端请求伪造(Server Side Request Forgery,SSRF)本质上是一种严重的 Web 应用漏洞。攻击者通过精心构造特定的参数值,诱使 Web 应用将外部输入参数当作 URL 来处理,进而驱使服务端去访问那些服务器程序原本预期之外的 URL。这些输入参数形式多样,既可以是不完整的 URL,也能是单纯的域名、IP 地址或者端口值等。

示例

以提供翻译服务的网站为例,正常情况下用户提交网页 URL 供网站进行翻译操作。但倘若该网站存在 SSRF 漏洞,攻击者便有机可乘。他们提交恶意 URL,网站服务器在毫无察觉的情况下,按照指令访问该恶意 URL,甚至可能因此访问到内网资源,导致敏感信息泄露等严重后果。比如攻击者提交 “http://192.168.1.100/internal_secret_file”,若服务器未做有效防范,就会尝试访问内网 IP 对应的敏感文件。

SSRF 漏洞成因

1.用户输入处理不当

许多 Web 应用在处理用户输入时过于草率。当使用用户输入来构造 HTTP 请求的 URL 时,却没有进行全面且严格的验证与过滤。像是未仔细检查 URL 所采用的协议是否合法,是常见的 HTTP/HTTPS,还是潜藏风险的 file、gopher 等协议;对域名的合法性以及端口值是否处于合理范围也未加以核实。以 Python 的 Flask 框架为例,如果代码编写如下:

from flask import Flask, request

app = Flask(__name__)

@app.route('/fetch')
def fetch():
    url = request.args.get('url')
    # 这里没有对url进行任何验证就直接使用
    response = requests.get(url)
    return response.text

如此一来,用户输入的任何 URL 都可能被服务器访问,极大地增加了 SSRF 风险。

2.使用未经验证的第三方库或框架

在开发过程中,不少开发者依赖各种第三方库或框架来加快开发进度。然而,部分未经充分安全验证的库或框架,在处理 URL 请求环节存在安全漏洞,极易被攻击者利用。例如某些老旧版本的 HTTP 请求库,在处理 URL 重定向等操作时,没有对目标 URL 进行严格检查,攻击者可借此构造恶意请求,突破应用的安全防线。

3.缺乏安全配置

服务器自身的配置若存在缺陷,同样会为 SSRF 攻击敞开大门。比如服务器未对可访问的 URL 范围做出明确限制,或者未严格检查请求来源,使得攻击者能够轻易绕过安全限制。以 Nginx 服务器为例,如果配置文件中没有设置合理的访问控制规则,像以下错误配置:

server {
    listen 80;
    server_name example.com;
    location / {
        proxy_pass $request_uri;
        # 这里没有对proxy_pass的目标进行任何限制
    }
}

攻击者就可以通过精心构造请求,让服务器访问任意他们指定的 URL。

SSRF 攻击进阶

1.攻击内网应用

攻击者一旦发现 Web 应用存在 SSRF 漏洞,便会将目标对准内网应用或服务。通过构造特殊的 URL,诱使服务器去访问内网的 Redis、MySQL 等数据库服务。

例如利用 file 协议,攻击者可以构造类似 “file:///etc/passwd” 的 URL,若服务器权限配置不当,就会读取服务器本地的敏感文件。

利用 gopher 协议攻击 Redis 服务时,攻击者构造的 URL 可以向 Redis 服务器发送恶意指令,如修改数据库内容、获取敏感数据等。假设 Redis 服务在内网 IP 为 192.168.1.101,端口为 6379,攻击者构造的 gopher URL 可能如下:

gopher://192.168.1.101:6379/_*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$4%0d%0amalic%0d%0a

这条 URL 会尝试在 Redis 中设置恶意数据。

2.端口扫描

端口扫描也是攻击者利用 SSRF 漏洞的常见手段。通过向不同的端口发送请求,并根据响应判断端口是否开放,攻击者能够探测内网的服务和端口信息。攻击者可以编写脚本,利用 SSRF 漏洞构造一系列请求来扫描内网端口。例如使用 Python 编写一个简单的端口扫描脚本,结合 SSRF 漏洞向不同端口发送请求:

import requests

def scan_port(url, port):
    target_url = f"{url}:{port}"
    try:
        response = requests.get(target_url)
        if response.status_code == 200:
            print(f"端口 {port} 开放")
    except requests.RequestException:
        pass

base_url = "http://vulnerable_server/ssrf_endpoint?url="
for port in range(1, 1025):
    scan_port(base_url, port)

通过这种方式,攻击者可以为后续更深入的攻击做准备。

3.攻击非 Web 应用

SSRF 的攻击范围并不局限于 Web 应用,基于网络协议的其他服务,如 FTP、SMTP 等同样可能成为受害者。攻击者可以构造符合相应协议的 URL,借助 SSRF 漏洞与这些服务进行交互并执行恶意操作。例如构造一个针对 FTP 服务的 URL“ftp://attacker_server:21”,如果服务器对该 URL 请求未做限制,攻击者可能通过 FTP 服务上传恶意文件、获取敏感信息等。

SSRF 绕过技巧

1.绕过限制访问内网

为突破服务器对 URL 的限制从而访问内网资源,攻击者想出了多种特殊方法。DNS 重绑定技术是其中之一,攻击者通过控制 DNS 服务器,使域名在不同时间解析为不同 IP 地址。先让域名解析为外网可访问的 IP 地址,绕过服务器对访问内网 IP 的限制;在获取服务器连接后,再将域名解析为内网 IP 地址,从而实现对内网资源的访问。另外,攻击者还会使用特殊的 URL 编码和变形方式绕过过滤。例如将 “.” 编码为 “%2e”,将 “/” 编码为 “%2f” 等,以此绕过服务器对 URL 格式的简单过滤规则。

2.利用协议特性

不同的网络协议具有各自独特的特性,攻击者善于利用这些特性来绕过安全检测。以 HTTP 协议中的 30x 重定向为例,攻击者可以构造一个包含重定向指令的 URL,将服务器的请求重定向到内网地址。假设攻击者控制了一个恶意网站 “evil.com”,他们构造的 URL 可能是 “http://vulnerable_server/ssrf_endpoint?url=http://evil.com/redirect?target=http://192.168.1.100”,当服务器访问evil.com时,evil.com返回 302 重定向指令,将服务器请求重定向到内网 IP 地址 192.168.1.100,从而绕过服务器原本对直接访问内网地址的限制。

SSRF 防御方案

1.使用 URL 黑名单或白名单

黑名单

采用黑名单机制,即限制访问特定的 URL。然而,这种方式存在较大局限性,因为难以穷举所有危险的 URL,而且攻击者总能通过各种手段绕过黑名单限制,所以实际安全性较低。例如攻击者可以通过对危险 URL 进行变形、编码等方式,使其不在黑名单范围内。

白名单

相较而言,白名单机制更为可靠。它只允许访问特定的、经过严格验证的 URL。在实际应用中,明确指定允许访问的域名或 IP 地址范围是关键。例如在 Java 的 Spring 框架中,可以通过配置文件设置允许访问的 URL 白名单:

security.ssrf.whitelist=example.com,192.168.1.0/24

这样服务器只会访问白名单内的 URL,大大降低了 SSRF 攻击风险。

2.验证输入的 URL

对用户输入的 URL 进行严格验证是防御 SSRF 的重要一环。需要检查 URL 所采用的协议,只允许安全的协议,如 HTTP 或 HTTPS 协议,禁止 file、gopher 等可能被用于恶意攻击的协议。同时,对域名和 IP 地址的合法性也要进行核实。例如使用 Python 的urllib.parse库验证 URL:

from urllib.parse import urlparse

def validate_url(url):
    result = urlparse(url)
    if result.scheme not in ['http', 'https']:
        return False
    try:
        # 验证域名或IP地址的合法性
        socket.gethostbyname(result.netloc.split(':')[0])
        return True
    except socket.gaierror:
        return False

3.限制请求的端口和协议

明确限制服务器可以访问的端口和协议,是减少攻击面的有效手段。禁止服务器访问不必要的端口,如一些常见的敏感端口,像 Redis 的 6379 端口MySQL 的 3306 端口等。同时,只允许使用必要的协议,避免启用可能被攻击者利用的协议。例如在服务器配置文件中设置只允许 HTTP 和 HTTPS 协议访问特定端口:

server {
    listen 80;
    server_name example.com;
    location / {
        proxy_pass http://backend_server;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        # 限制只允许HTTP和HTTPS协议
        if ($scheme!~ ^(http|https)$) {
            return 403;
        }
        # 限制只允许访问特定端口,如80和443
        if ($server_port!~ ^(80|443)$) {
            return 403;
        }
    }
}

4.使用 DNS 解析控制

对 URL 中的域名进行 DNS 解析,并检查解析后的 IP 地址是否合法,能够有效防止通过 DNS 重绑定等技术绕过限制。在服务器端获取 URL 中的域名后,先进行 DNS 解析,然后对比解析得到的 IP 地址是否在允许范围内。例如在 Node.js 中可以使用dns模块进行 DNS 解析验证:

const dns = require('dns');
const url = require('url');

function validateUrlWithDns(urlStr) {
    const parsedUrl = url.parse(urlStr);
    return new Promise((resolve, reject) => {
        dns.lookup(parsedUrl.hostname, (err, address) => {
            if (err) {
                reject(err);
            } else {
                // 假设允许的IP范围是192.168.1.0/24
                const allowedRange = '192.168.1.0/24';
                if (isInRange(address, allowedRange)) {
                    resolve(true);
                } else {
                    reject(new Error('IP地址不在允许范围内'));
                }
            }
        });
    });
}

function isInRange(ip, range) {
    const [start, end] = range.split('/')[1] === '32'? [ip, ip] : getRange(range);
    return ip >= start && ip <= end;
}

function getRange(cidr) {
    const parts = cidr.split('/');
    const ip = parts[0].split('.').reduce((acc, part) => acc * 256 + parseInt(part, 10), 0);
    const bits = parseInt(parts[1], 10);
    const mask = (0xffffffff << (32 - bits)) >>> 0;
    const start = ip & mask;
    const end = start | ~mask;
    return [start, end];
}

5.记录和监控

记录所有的请求和响应,对防御 SSRF 至关重要。通过详细记录,便于及时发现异常请求。同时,对服务器的网络访问进行实时监控,一旦察觉到可疑的 SSRF 攻击行为,能够迅速采取措施。例如使用日志管理工具,如 ELK(Elasticsearch、Logstash、Kibana)组合,将服务器的请求和响应日志收集到 Elasticsearch 中,通过 Logstash 进行日志处理和过滤,再利用 Kibana 进行可视化展示和分析。一旦发现大量指向内网 IP 的请求或者异常的 URL 请求,安全人员可以及时介入调查并采取相应防御措施。

小结

服务端请求伪造(SSRF)作为近年来日益猖獗的 Web 安全风险,给 Web 应用的安全带来了巨大挑战。攻击者凭借这一漏洞,能够肆意访问内网资源、进行端口扫描等恶意操作,严重威胁数据安全与系统稳定。为有效防御 SSRF,我们需综合运用多种策略。

输入验证层面,严格把关用户输入的 URL,确保其合法性;采用白名单机制,精准限定服务器可访问的 URL 范围;

在网络层面,限制请求的协议和端口,减少攻击面;借助 DNS 解析控制,防范 DNS 重绑定等绕过手段;同时,强化监控与日志记录,以便及时察觉并处置潜在攻击。只有全方位、多层次地构建防御体系,持续关注安全动态,不断优化防御策略,才能在这场与 SSRF 的对抗中,守护好 Web 应用的安全,为用户营造可靠的网络环境。喜欢就点点赞和关注评论一起进步呗

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

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

相关文章

豪越消防一体化安全管控平台:消防管理智能化

在社会快速发展、城市建设日益复杂的今天&#xff0c;消防安全始终是保障人民生命财产安全、维护社会稳定的重要基石。传统消防管理模式在应对当下复杂多变的消防安全需求时&#xff0c;逐渐暴露出诸多局限性&#xff0c;而豪越消防一体化平台的出现&#xff0c;为消防管理领域…

瑞芯微RK356X主板复用接口配置方法,触觉智能嵌入式方案商

本文介绍瑞芯微RK356X系列复用接口配置的方法&#xff0c;基于触觉智能RK3562开发板演示&#xff0c;搭载4核A53处理器&#xff0c;主频高达2.0GHz&#xff1b;内置独立1Tops算力NPU&#xff0c;可应用于物联网网关、平板电脑、智能家居、教育电子、工业显示与控制等行业。 复…

NX二次开发刻字功能——预览功能

这个预览功能其实在NX软件中很常见,有利于建模者确定刻字的位置,这个功能早在唐康林老师的超级长方体教程中出现过。我只是学以致用。把该功能集成刻字中。 在勾选预览的同时,如果点击放大镜也就是显示预览结果,要刻字的对象透明度数值为70,同时预览结果文字会变成撤销,如…

容器主机CPU使用率突增问题一则

关键词 LINUX、文件系统crontab 、mlocate根目录使用率 There are many things that can not be broken&#xff01; 如果觉得本文对你有帮助&#xff0c;欢迎点赞、收藏、评论&#xff01; 一、问题现象 业务一台容器服务器&#xff0c;近期经常收到cpu不定期抖动告警&#x…

华为hcia——Datacom实验指南——配置IPv4静态路由,默认路由和浮动静态路由

什么是IPv4 IPv4静态路由&#xff0c;是手动配置的&#xff0c;不会随着网络拓扑的变化而变化&#xff0c;所配置的路由信息也不会在网络中传播&#xff0c;所以它主要运用在小型网络或者作为动态路由的补充。 IPv4的配置 配置的命令很简单 IP route-static &#xff08;目…

【Apache Hive】

一、Hive简介 官网&#xff1a;https://hive.apache.org 1、Hive是什么&#xff1f; Apache Hive 是一款建立在Hadoop之上的开源数据仓库系统&#xff0c;可以将存储在Hadoop文件中的结构化、半结构化数据文件映射为一张数据库表&#xff0c;基于表提供了一种类似SQL的查询模型…

SQL Server安装进度卡在 57%:Windows Update 服务异常

问题现象&#xff1a; 安装 SQL Server 2022 时进度停滞在 57%&#xff0c;日志报错 Error code 0x80070422&#xff0c;提示 “Windows Update 服务未运行”。 快速诊断 检查服务状态&#xff1a; # 查看 Windows Update 服务状态 Get-Service -Name wuauserv | Select-Object…

YOLO历代发展 图像增强方式 架构

YOLO1 YOLOV5 数据增强 mosaic 仿射变换(Affine)、透视变换(Perspective) 网络搭建

DexGrasp Anything:具有物理-觉察的普遍机器人灵巧抓取

25年3月来自上海科技大学的论文“DexGrasp Anything: Towards Universal Robotic Dexterous Grasping with Physics Awareness”。 能够抓取任何物体的灵巧手&#xff0c;对于通用具身智能机器人的开发至关重要。然而&#xff0c;由于灵巧手的自由度高&#xff0c;物体种类繁多…

对称加密算法和非对称加密算法

在这个互联网普及的时代&#xff0c;在不同终端对敏感甚至机密数据进行传输是非常常见的场景&#xff0c;但是如何保证数据传输过程的安全性和高效性是一个值得深入探讨的问题。 为此&#xff0c;伟大的人类研究出了多种加密算法&#xff0c;我们可以大致将其分为两类&#xf…

【计算机网络】OSI七层模型完全指南:从比特流到应用交互的逐层拆解

OSI模型 导读一、概念二、模型层次结构2.1 物理层&#xff08;Physical Layer&#xff09;2.2 数据链路层&#xff08;Data Link Layer&#xff09;​2.3 ​网络层&#xff08;Network Layer&#xff09;​2.4 ​传输层&#xff08;Transport Layer&#xff09;​2.5 ​会话层&…

数据不互通、审批慢?如何实现多系统智能协同

在企业信息化建设的过程中&#xff0c;数据孤岛和复杂的审批流程常常成为实现高效协同的巨大障碍。对于许多组织来说&#xff0c;面对越来越复杂的业务需求&#xff0c;如何实现多系统智能协同不仅关乎效率&#xff0c;更直接影响企业的竞争力。 数据不互通和审批流程慢的痛点…

如何用 Postman 正确传递 Date 类型参数,避免服务器解析错误?

如何在 Postman 中传递 Date 类型参数。调试工具如何模拟发送用户端的当前时间呢&#xff1f; Postman 传递 Date 类型参数教程

JUC 03

今天是2025/03/28 20:46 day 14 总路线请移步主页Java大纲相关文章 今天进行JUC 6,7,8 个模块的归纳 首先是JUC的相关内容概括的思维导图 由于内容比较多且重要&#xff0c; 个人还整理了一份详细JUC的思维导图&#xff0c;需要的请评论。是 xmind文件 6. 锁机制 深入解析…

CentOS 7 部署RuoYi 项目

换源 备份现有的 YUM 源配置文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 默认的 CentOS 官方镜像源替换为阿里云的镜像源&#xff0c;以提高下载速度和稳定性。 curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.co…

【JavaScript】八、对象

文章目录 1、对象的声明2、对象的使用3、对象中的方法4、遍历对象5、内置对象Math 1、对象的声明 一种数据类型&#xff0c;使用typeof查看类型&#xff0c;结果是object可以详细的描述描述某个事物 声明语法&#xff1a; // 多用花括号形式声明 // 比如声明一个person对象 …

Processor System Reset IP 核 v5.0(vivado)

这个IP的作用&#xff0c;我的理解是&#xff0c;比普通按键复位更加高效灵活&#xff0c;可以配置多个复位输出&#xff0c;可以配置复位周期。 1、输入信号&#xff1a; 重要的信号有时钟clk信号&#xff0c;一般连接到系统时钟&#xff1b;输入复位信号&#xff0c;一般是外…

linux0.11内核源码修仙传第十一章——硬盘初始化

&#x1f680; 前言 本文是初始化最后一部分了&#xff0c;对硬盘的初始化&#xff0c;对应于书中的第20回。希望各位给个三连&#xff0c;拜托啦&#xff0c;这对我真的很重要&#xff01;&#xff01;&#xff01; 目录 &#x1f680; 前言&#x1f3c6;块设备管理&#x1f3…

包络解调在故障诊断中的应用-广义检波解调案例

前言 前面我们曾介绍过广义检波解调的原理&#xff0c;那么今天就将学过的知识点真正用在故障诊断上&#xff0c;由于工厂数据集不能轻易获取&#xff0c;因此通过实验室仿真数据集来介绍整个诊断流程。 数据集 加拿大渥太华是故障诊断领域蛮出名的一个数据集&#xff0c;其…

喜报|迪捷软件入选工信部“2024年信息技术应用创新解决方案”

为进一步深化行业信息技术应用创新&#xff0c;健全信息技术应用创新产业生态&#xff0c;加快新技术新产品应用推广&#xff0c;强化应用牵引和需求导向&#xff0c;加强区域联动和资源整合&#xff0c;工业和信息化部网络安全产业发展中心&#xff08;工业和信息化部信息中心…