参考文献:
拒绝服务攻击(DoS攻击)
基本介绍
拒绝服务攻击(denial-of-service attack, DoS)是一种网络攻击手法,其目的在于使目标电脑的网络或系统资源耗尽,使服务暂时中断或停止,导致其正常用户无法访问。
当黑客使用网络上两个或以上被攻陷的电脑向特定的目标发动攻击时,称为分布式拒绝服务攻击(distributed denial-of-service attack,简称DDoS攻击)。
攻击方法
可以具体分成三种形式: 带宽消耗型、资源消耗型、漏洞触发型。
- 带宽消耗型: 攻击者通过向目标发送大量的数据流量,消耗目标系统的带宽资源,导致网络拥塞。例如: UDP洪泛攻击、ICMP洪泛攻击。
- 资源消耗型: 攻击者试图消耗目标系统的连接资源,通过发送大量的连接请求,使系统无法处理合法用户的连接。例如: SYN洪泛攻击、应用程序级洪泛攻击。
- 漏洞触发型: 透过尝试触发缓存溢出等漏洞,使操作系统发生核心错误或蓝屏死机,达到拒绝服务攻击。例如: 死亡之Ping。
防御手段
对应的防御方式通常为入侵检测、流量过滤和多重验证,旨在堵塞网络带宽的流量将被过滤,而正常的流量可正常通过。
- 流量过滤: 使用防火墙、入侵检测系统(IDS)或入侵防御系统(IPS)等网络设备,过滤掉来自已知攻击源的恶意流量,并将合法流量传递给目标系统。
- 流量清洗: 当获取到流量时,将正常流量和恶意流量区分开,正常的流量则回注回客户网站,反之则屏蔽。这样一来可站点能够保持正常的运作,仅仅处理真实用户访问网站带来的合法流量。
- 黑洞引导: 将所有受攻击计算机的通信全部发送至一个"黑洞"(空接口或不存在的计算机地址)或者有足够能力处理洪流的网络设备商,以避免网络受到较大影响。
- 负载均衡(Load balancing): 将流量分散到多台服务器上,以分担单个服务器的压力,并确保即使有部分服务器受到攻击,其他服务器仍然能够提供服务。
- 内容分发网络(Content Delivery Network, CDN): 使用CDN服务来分发和缓存网站内容,将流量分散到全球各地的服务器上,提高系统的容量和弹性。
- 限制连接数和请求频率: 通过配置网络设备或服务器,限制单个IP地址或用户的连接数和请求频率,以防止恶意用户过度消耗资源。
SQL注入(SQL Injection)
基本介绍
SQL注入(SQL Injection)是一种广泛存在于Web应用程序中的安全漏洞,攻击者通过在用户输入的数据中注入恶意的SQL代码,从而欺骗应用程序执行非预期的数据库操作。其原理是利用应用程序对用户输入数据的处理不当。当应用程序接收用户输入并将其直接拼接到SQL查询语句中,而没有进行充分的验证、过滤或转义时,攻击者可以在输入中插入恶意的SQL代码,改变原始查询的逻辑。
攻击方法
举一个登录网站的例子,该网站使用SELECT * FROM users WHERE username = '<user_input>' AND password = '<user_input>';
来验证登录信息,如果攻击者输入的用户名为' OR '1'='1
,那么该网站就会执行SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '<user_input>';
,一旦攻击者输入的密码也是真实存在的,该网站的身份验证就会被成功绕过。
一般来说,SQL注入攻击能带来以下的危害:
- 数据泄露: 攻击者可以通过注入恶意代码来获取数据库中的敏感信息,如用户凭据、个人信息等。
- 数据篡改: 攻击者可以修改数据库中的数据,包括添加、删除或修改记录。
- 绕过认证: 通过注入恶意代码,攻击者可以绕过应用程序的认证和授权机制,获得未授权的访问权限。
防御手段
为了防止SQL注入攻击,可采取以下安全措施:
- 使用参数化查询或预编译语句: 通过使用参数化查询(绑定参数)或预编译语句,可以将用户输入数据与查询逻辑分离,从而防止注入攻击。例如:
# 参数化查询 cursor.execute("SELECT * FROM users WHERE username = %s AND password = %s", [username, password]) # 预编译语句 cursor.prepare("SELECT * FROM users WHERE username = ? AND password = ?") cursor.execute(username, password)
- 输入验证和过滤: 对用户输入进行严格的验证和过滤,只接受预期的数据格式,并拒绝包含恶意代码的输入。例如:
# 表单验证 from django import forms from django.core.validators import RegexValidator class LoginForm(forms.Form): username = forms.CharField(max_length=30) password = forms.CharField(widget=forms.PasswordInput) # 替换特殊字符 username = re.sub(r'[^\w]+', '', username) # 白名单字符过滤 if not re.match(r'^[a-zA-Z0-9]+$', username): pass
- 使用ORM(对象关系映射)查询: Django之类的ORM提供了一个高级的数据库访问层,可以自动处理SQL查询和参数化,并确保输入值被正确地转义和引用,而不是直接将用户输入拼接到查询字符串中。例如:
User.objects.filter(username=username, password=password)
跨站脚本攻击(XSS)
基本介绍
跨站脚本攻击(Cross-Site Scripting, XSS)是一种常见的Web应用程序安全漏洞,攻击者通过注入恶意脚本代码到受信任的网页中,从而在用户的浏览器中执行恶意代码。这种攻击也是利用了Web应用程序对用户输入的不充分过滤和验证。
与SQL注入的区别在于:
- 目标不同: SQL注入针对的是数据库,而XSS针对的是网页代码
- 攻击方式: SQL注入使用SQL语句片段,而XSS一般是用JavaScript的完整脚本
攻击方法
假设有一个简单的留言板应用程序,用户可以在上面发表留言。该应用程序在提交留言时没有对用户输入进行充分的过滤和转义处理。攻击者可以利用这个漏洞,通过在留言中注入如下恶意脚本代码来攻击其他用户:
<script>
// 恶意代码
alert('恶意攻击已成功!');
// 攻击者可以执行其他恶意操作,如窃取用户的敏感信息
</script>
当其他用户浏览包含恶意留言的页面时,他们的浏览器会执行注入的恶意脚本代码,弹出一个对话框显示恶意攻击成功的消息。攻击者也可以执行其他恶意操作,如窃取用户的Cookie,发送用户的敏感信息到攻击者的服务器等。
防御手段
解决跨站脚本攻击的方法包括以下几个方面:
- 输入验证和过滤: 对用户的输入进行严格的验证和过滤,确保只接受预期的数据格式。可以使用白名单来验证输入,只允许特定的字符和格式。
- 转义输出: 在将用户输入插入到HTML页面中之前,对其进行适当的转义处理。这样可以确保任何恶意脚本代码都会被当作普通文本而不被执行。Web应用程序框架通常提供了转义函数或模板引擎来简化这个过程。
// 原生的encodeURIComponent() let userInput = "<script>alert('XSS');</script>"; let encodedInput = encodeURIComponent(userInput); console.log(encodedInput); // 输出结果:%3Cscript%3Ealert%28%27XSS%27%29%3B%3C%2Fscript%3E
- 使用HTTP头部的Content Security Policy(CSP):CSP是一种通过HTTP头部向浏览器传递安全策略的机制。通过设置适当的CSP策略,可以限制页面中允许加载的资源和执行的脚本,从而减少跨站脚本攻击的风险。
- 使用HttpOnly标记: 将敏感的Cookie标记为HttpOnly,这样浏览器将禁止通过JavaScript访问这些Cookie,减少被窃取的风险。
跨站请求伪造(CSRF)
基本介绍
跨站请求伪造(Cross-Site Request Forgery, CSRF)是一种Web应用程序安全漏洞,也被称为"One-Click Attack"或"Session Riding"。它利用了Web应用程序对用户发出的请求未进行充分验证的问题,从而允许攻击者在受害者不知情的情况下执行恶意操作。
同源策略
同源策略是一个比较笼统的概念,它是为了限制一个源的文档或者它加载的脚本如何能与另一个源的资源进行交互。就是说,它限制baidu.com的脚本不能访问到taobao.com的资源。
现代浏览器同时采用了三种同源策略:
- DOM同源策略: 禁止对不同源页面DOM进行操作。这里主要场景是iframe跨域的情况,不同域名的iframe是限制互相访问的
- XMLHttpRequest同源策略: 禁止使用XHR对象向不同源的服务器地址发起HTTP请求
- Cookie、localStorage等同源策略
不过,浏览器并不限制<img>
, <tag>
, <form>
等标签等进行跨域访问。
攻击方法
一般的攻击过程如下:
- 受害者登录受信任的网站A,并在会话中建立了有效的身份验证凭据(如Cookie)
- 攻击者构造了一个恶意网站B,并在B的页面中插入一个指向A的请求,通常是使用img或script标签隐藏的图片或脚本
- 受害者在浏览器中访问恶意网站B,而不知道其中包含对A的请求
- 由于浏览器会自动发送A网站的Cookie,恶意请求会被发送到A,并由A以受信任用户的身份进行处理
- 攻击者成功利用了受害者的身份执行了恶意操作,例如更改密码、发表评论、进行资金转移等
防御手段
要防御CSRF攻击,可以采取以下措施:
- 随机化请求令牌(CSRF Token): 在每个用户请求中包含一个随机生成的令牌,并将其与用户会话相关联。在提交操作时,验证请求令牌是否与会话中的令牌匹配,从而确保请求的合法性
- 同源检测(Same-Origin Policy): 浏览器实施了同源策略,它限制了来自不同源的网站之间的交互。确保关键操作仅限于同一域名下的页面,以阻止跨域请求
- 缺点: 妨碍第三方集成、跨域API调用
- 避免使用敏感操作的GET请求: GET请求会被一些浏览器预加载、预渲染和缓存,可能导致CSRF攻击。对于敏感操作,应使用POST请求,并在请求中包含CSRF令牌
- 添加验证码: 要求用户在关键操作之前进行验证码验证,以提供额外的身份验证层级
Session认证 + CSRF Token
当涉及到CSRF Token的使用时,有两种常见的情况: 前后端不分离和前后端分离。在前后端不分离的情况下,可以通过后端生成CSRF Token并将其嵌入到响应的表单中,这样CSRF Token将随表单的提交被发送到后端进行验证。
而在前后端分离的情况下,为了使用CSRF Token,需要进行两次请求。首先,前端应用程序向后端发送一个请求以获取CSRF Token。一旦获得了CSRF Token,前端可以将其添加到请求头的'X-CSRFToken'
字段中用于验证。以axios为例:
import Cookies from 'js-cookie';
onMounted(async()=> {
await axios.get('csrf-token/')
axios.defaults.headers.common['X-CSRFToken'] = Cookies.get('csrftoken');
})
const response = await axios.post(endpoint, {
"imageDataURL": imageDataURL.value,
"modelName": selectedModelName.value
})