2021-09-04

                                        CSRF详细剖析

CSRF (Cross Site Request Forgery)是跨站域请求伪造。

这个Cross Site跨站类似XSS,但是两者有区分,XSS的Cross Site是指本网站运行了来自其它网站的脚本;而CSRF的Cross Site指的是我在其它的网站对本网站产生了影响。

原理:我以www.a.com和www.b.com两个网站为例子,用户用的是www.a.com,用户正常使用,登陆网站,输入用户名和密码点击登陆,这时候会到a网站后台请求,后台验证用户名和密码正确,登陆成功,后台会会发送一个cookie给到用户的浏览器。

www.b.com是攻击者网站,攻击者通过b网站对a网站发起请求,这个时候他利用用户的cookie,(为什么会有cookie,因为攻击者发送链接比如是一个发表评论功能的poc(poc可以通过burpsuite生成,将提交的表单通过burpsuite抓包右键有个生成CSRF poc)链接给用户)用户去点击用该浏览器打开,刚好该浏览器有用户的cookie,所以就以用户的身份对网站发表评论的操作了。

小结:攻击者利用b.com发起请求到a.com的后端完成相关功能操作,而没有访问前端(后端需要前端登陆才能进入后台,因为用户之前登陆过,浏览器存在cookie了,点开链接的时候就默认不再进入登陆页面,直接操作)

危害:利用用户登录态    用户不知情     完成业务请求  冒充用户发帖   冒充用户发帖背锅

防御:1.禁止第三方网站带Cookies

cookie有个sameSite属性,sameSite=strict这个设置不允许第三方链接带有cookie发送请求,也就是说攻击者链接发过来,用户点击不会带有自身cookie请求。所以用户身份不会被利用,但是sameSite这个设置只适用Chrome和Opera两个浏览器,这两个浏览器共有一个内核,但是还有其他浏览器不适用,所以这个方法目前不太适用。(浏览器未能普及,不适用)

2.验证码:就是每个功能都使用验证码输入验证,比如每次发表评论,需要填写验证码才可以。这样的话攻击者给用户的链接都会失败,因为没有输入验证码,所以做不了任何功能,但是这个方法显然让用户体验性很差,因为任何一个功能都需要输验证码,评论、删除、退出等等,显然体验性不好,所以这个方法目前也不太适用。(用户体验差,不适用)

3.referer:referer是请求里面的一个请求头。禁止来自第三方的链接请求,也就是说,在referer头里面,设置当前a网站的请求访问,来自其它网站都拦截。当然这种方法规则要写严谨,否则也是存在绕过机制,因为有的referer是个摆设,没有做验证。相对来说,这种方法目前很适用。(流行,适用)

4.token:后端生成随机字符串,放到两个地方,一个是页面表单中,第二个是放到cookies中。

实际使用中,input会使用hidden属性隐藏token,第一步下发,就是用户到了发表页面,后端随机给用户这个页面一个token,然后用户发表评论,会带着这个token去后端验证那个token是否一样,如果一样就能成功发表。而攻击者发送链接给用户,用户点击这时候链接给不了token值,所以做不了任何操作。这种方法目前很流行适用,

核心思想:页面中有一个token,而攻击者不会访问前端页面,两个token他都拿不到。

如果两者token缺一呢?只有cookies 的token没有表单中的token提交的时候会把这个token带过去,没办法防御;如果有表单中的token没有cookies中的token,那攻击者随意捏造一个,也可以绕过。所以两者缺一不可。

当然这个token设置一定要随机,而不是一个摆设,像万能验证码那种,随便一串数字就能验证

。而是要真实的去做验证。(很流行,很适用)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
使用python中的pymsql完成如下:表结构与数据创建 1. 建立 `users` 表和 `orders` 表。 `users` 表有用户ID、用户名、年龄字段,(id,name,age) `orders` 表有订单ID、订单日期、订单金额,用户id字段。(id,order_date,amount,user_id) 2 两表的id作为主键,`orders` 表用户id为users的外键 3 插入数据 `users` (1, '张三', 18), (2, '李四', 20), (3, '王五', 22), (4, '赵六', 25), (5, '钱七', 28); `orders` (1, '2021-09-01', 500, 1), (2, '2021-09-02', 1000, 2), (3, '2021-09-03', 600, 3), (4, '2021-09-04', 800, 4), (5, '2021-09-05', 1500, 5), (6, '2021-09-06', 1200, 3), (7, '2021-09-07', 2000, 1), (8, '2021-09-08', 300, 2), (9, '2021-09-09', 700, 5), (10, '2021-09-10', 900, 4); 查询语句 1. 查询订单总金额 2. 查询所有用户的平均年龄,并将结果四舍五入保留两位小数。 3. 查询订单总数最多的用户的姓名和订单总数。 4. 查询所有不重复的年龄。 5. 查询订单日期在2021年9月1日至9月4日之间的订单总金额。 6. 查询年龄不大于25岁的用户的订单数量,并按照降序排序。 7. 查询订单总金额排名前3的用户的姓名和订单总金额。 8. 查询订单总金额最大的用户的姓名和订单总金额。 9. 查询订单总金额最小的用户的姓名和订单总金额。 10. 查询所有名字中含有“李”的用户,按照名字升序排序。 11. 查询所有年龄大于20岁的用户,按照年龄降序排序,并只显示前5条记录。 12. 查询每个用户的订单数量和订单总金额,并按照总金额降序排序。
06-03
这里是使用 Python 的 PyMySQL 完成上述任务的代码: ```python import pymysql # 连接数据库 conn = pymysql.connect(host='localhost', port=3306, user='root', password='123456', database='test') # 创建游标 cur = conn.cursor() # 创建 users 表 cur.execute(''' CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(20), age INT ) ''') # 创建 orders 表 cur.execute(''' CREATE TABLE orders ( id INT PRIMARY KEY, order_date DATE, amount INT, user_id INT, FOREIGN KEY (user_id) REFERENCES users(id) ) ''') # 插入数据 users_data = [ (1, '张三', 18), (2, '李四', 20), (3, '王五', 22), (4, '赵六', 25), (5, '钱七', 28) ] orders_data = [ (1, '2021-09-01', 500, 1), (2, '2021-09-02', 1000, 2), (3, '2021-09-03', 600, 3), (4, '2021-09-04', 800, 4), (5, '2021-09-05', 1500, 5), (6, '2021-09-06', 1200, 3), (7, '2021-09-07', 2000, 1), (8, '2021-09-08', 300, 2), (9, '2021-09-09', 700, 5), (10, '2021-09-10', 900, 4) ] for user in users_data: cur.execute('INSERT INTO users VALUES (%s, %s, %s)', user) for order in orders_data: cur.execute('INSERT INTO orders VALUES (%s, %s, %s, %s)', order) # 提交事务 conn.commit() # 查询语句 # 1. 查询订单总金额 cur.execute('SELECT SUM(amount) FROM orders') print(cur.fetchone()[0]) # 2. 查询所有用户的平均年龄,并将结果四舍五入保留两位小数。 cur.execute('SELECT ROUND(AVG(age), 2) FROM users') print(cur.fetchone()[0]) # 3. 查询订单总数最多的用户的姓名和订单总数。 cur.execute(''' SELECT users.name, COUNT(*) AS total_orders FROM users JOIN orders ON users.id = orders.user_id GROUP BY users.id ORDER BY total_orders DESC LIMIT 1 ''') print(cur.fetchone()) # 4. 查询所有不重复的年龄。 cur.execute('SELECT DISTINCT age FROM users') print([row[0] for row in cur.fetchall()]) # 5. 查询订单日期在2021年9月1日至9月4日之间的订单总金额。 cur.execute('SELECT SUM(amount) FROM orders WHERE order_date BETWEEN "2021-09-01" AND "2021-09-04"') print(cur.fetchone()[0]) # 6. 查询年龄不大于25岁的用户的订单数量,并按照降序排序。 cur.execute(''' SELECT users.name, COUNT(*) AS total_orders FROM users JOIN orders ON users.id = orders.user_id WHERE age <= 25 GROUP BY users.id ORDER BY total_orders DESC ''') print(cur.fetchall()) # 7. 查询订单总金额排名前3的用户的姓名和订单总金额。 cur.execute(''' SELECT users.name, SUM(amount) AS total_amount FROM users JOIN orders ON users.id = orders.user_id GROUP BY users.id ORDER BY total_amount DESC LIMIT 3 ''') print(cur.fetchall()) # 8. 查询订单总金额最大的用户的姓名和订单总金额。 cur.execute(''' SELECT users.name, SUM(amount) AS total_amount FROM users JOIN orders ON users.id = orders.user_id GROUP BY users.id ORDER BY total_amount DESC LIMIT 1 ''') print(cur.fetchone()) # 9. 查询订单总金额最小的用户的姓名和订单总金额。 cur.execute(''' SELECT users.name, SUM(amount) AS total_amount FROM users JOIN orders ON users.id = orders.user_id GROUP BY users.id ORDER BY total_amount ASC LIMIT 1 ''') print(cur.fetchone()) # 10. 查询所有名字中含有“李”的用户,按照名字升序排序。 cur.execute('SELECT * FROM users WHERE name LIKE "%李%" ORDER BY name ASC') print(cur.fetchall()) # 11. 查询所有年龄大于20岁的用户,按照年龄降序排序,并只显示前5条记录。 cur.execute('SELECT * FROM users WHERE age > 20 ORDER BY age DESC LIMIT 5') print(cur.fetchall()) # 12. 查询每个用户的订单数量和订单总金额,并按照总金额降序排序。 cur.execute(''' SELECT users.name, COUNT(*) AS total_orders, SUM(amount) AS total_amount FROM users JOIN orders ON users.id = orders.user_id GROUP BY users.id ORDER BY total_amount DESC ''') print(cur.fetchall()) # 关闭游标和连接 cur.close() conn.close() ``` 注意:在运行代码之前,需要先安装 PyMySQL 模块,可以使用以下命令进行安装: ``` pip install pymysql ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

掠你容颜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值