身份认证漏洞¶
从概念上讲,认证漏洞很容易理解。不过,这些漏洞往往非常关键,因为认证与安全之间存在着密切的联系。
身份验证漏洞使得攻击者能够获取敏感数据和功能。这些漏洞还会暴露出更多的攻击途径,为攻击者提供更多的攻击机会。因此,了解如何识别和利用这些身份验证漏洞,以及如何绕过常见的防护措施,是非常重要的。
什么是身份认证¶
身份验证是验证用户或客户端身份的过程。网站可能会面临来自互联网上任何人的潜在威胁。因此,强大的身份验证机制对于确保网站的安全至关重要。
身份验证主要有三种类型:
- 一些众所周知的信息,比如密码或安全问题的答案。这些有时被称为“知识因素”。
- 你所拥有的东西,都是一些具体的物理对象,比如手机或安全令牌。这些东西有时被称为“占有因素”。
- 你所具有的特质或行为方式。例如,你的生物特征或行为模式。这些有时被称为“内在因素”。
认证机制依赖于一系列技术来验证其中一个或多个因素。
认证和授权有什么区别¶
认证是指验证用户是否真实身份的过程。授权则涉及确认用户是否被允许执行某些操作。
例如,身份验证用于确定试图以用户名 Carlos123 访问网站的人是否真的是创建该账户的人。
一旦 Carlos123 通过身份验证,他们的权限将决定他们可以执行哪些操作。例如,他们可能被授权访问其他用户的个人信息,或者删除其他用户的账户。
Note
身份认证问的问题是:"你是谁?",授权访问问的问题是:"你能干什么?"
认证漏洞如何产生¶
在认证机制中,大多数漏洞的出现方式有两种:
- 这些认证机制存在缺陷,因为它们无法有效抵御暴力攻击。
- 在实现过程中,由于逻辑缺陷或编码错误,攻击者完全有可能绕过认证机制。这种情况有时被称为“认证失效”。
在网页开发的许多领域,逻辑缺陷会导致网站出现异常行为,这或许是一个安全问题,也可能不是。然而,由于身份验证对安全性至关重要,因此存在逻辑缺陷的身份验证机制很可能会让网站面临安全威胁。
身份认证漏洞示例¶
基于密码的认证方式¶
对于那些采用基于密码登录机制的网站来说,用户需要自行注册一个账户,或者由管理员分配一个账户给用户。这个账户会关联一个唯一的用户名和秘密密码,用户需要在登录表单中输入这些密码来进行身份验证。
在这种情况下,知道密码这一事实就足以作为用户身份的证明。这意味着,如果攻击者能够获取或猜出其他用户的登录凭据,那么该网站的安全性就会受到威胁。
这可以通过多种方式来实现。以下章节将介绍攻击者如何采用暴力攻击手段,以及暴力攻击方式中存在的一些漏洞。
暴力破解攻击¶
暴力攻击是指攻击者通过反复尝试不同的用户名和密码组合来猜测有效的登录凭据。这类攻击通常借助包含用户名和密码列表的自动化工具进行实施。通过自动化处理这一过程,尤其是使用专门的工具,攻击者就能够快速进行大量的登录尝试。
暴力破解并不总是意味着随意猜测用户名和密码。通过使用基本逻辑或公开可用的信息,攻击者可以更精确地调整暴力破解攻击的实施方式,从而做出更合理的猜测。这样一来,这种攻击方式的效率大大提高。那些仅使用基于密码登录方式的身份验证系统的网站,如果缺乏有效的暴力破解防护机制,就会面临极大的安全威胁。
爆破用户名¶
如果用户名具有某种明显的规律或模式,那么猜测其密码就变得非常容易了。例如,很多商业账户的登录用户名都采用 firstname.lastname@somecompany.com 这样的格式。不过,即使没有明显的规律,有时仍然会看到一些高权限账户使用一些可预测的用户名,比如 admin 或 administrator 。
在审计过程中,需要检查网站是否公开了用户名称。例如,是否可以在不登录的情况下访问用户资料。即使资料中的内容被隐藏,但资料中的用户名有时仍然与登录用户名相同。此外,还需要检查 HTTP 响应,看看是否有电子邮件地址被公开。偶尔,响应中会出现高级用户的电子邮件地址,比如管理员或 IT 支持人员的地址。
爆破密码¶
密码同样可以被暴力破解,不过破解的难度会随着密码的复杂程度而变化。许多网站都采用了某种形式的密码策略,要求用户创建具有高熵值的密码,理论上来说,这样的密码仅凭暴力破解就难以被破解。这通常涉及对密码进行以下约束:
- 至少需要一定数量的字符(通常不少于8位)
- 由小写字母和大写字母组成的混合体
- 至少包含一个特殊字符
不过,虽然高熵密码很难被计算机破解,但我们可以利用对人类行为的基本了解,利用用户无意中引入的漏洞来攻击这个系统。与其使用由随机字符组合而成的强密码,用户往往更喜欢使用他们能够记住的密码,然后试图让这些密码符合密码策略的要求。例如,如果禁止使用 mypassword 作为密码,那么用户可能会尝试使用 Mypassword1! 或 Myp4$$w0rd 之类的密码。
在那些政策规定用户需要定期更改密码的情况下,用户通常会对喜欢的密码进行一些微小的、可预测的修改。例如, Mypassword1! 可能会被修改为 Mypassword1? 或 Mypassword2!. 。
对可能的凭证类型和可预测的模式的了解意味着,暴力攻击往往可以更加复杂且有效,而无需简单地尝试每一种可能的字符组合。
用户枚举¶
用户名枚举是指攻击者能够观察到网站行为的变化,从而判断某个用户名是否有效。
用户名枚举通常发生在登录页面上,例如,当用户输入一个有效的用户名但密码错误时;或者发生在注册表单上,当用户输入一个已被占用的用户名时。这大大减少了暴力破解登录所需的时间和努力,因为攻击者可以快速生成一份有效的用户名列表。
-
状态代码:在暴力攻击的情况下,由于大多数猜测都是错误的,因此返回的 HTTP 状态代码很可能都是相同的。如果某个猜测返回了不同的状态代码,那么这强烈表明用户名是正确的。对于网站来说,无论结果如何,始终返回相同的状态代码是一种良好的做法,但实际上并非所有网站都遵循这一规范。
-
错误信息:有时,返回的错误信息会有所不同,这取决于是用户名或密码都错误,还是只有密码错误。不过,最好的做法是在这两种情况下使用相同的、通用的错误信息。不过,偶尔会出现一些微小的输入错误。即使某个字符的位置不正确,也会导致不同的错误信息出现,即使这个字符在渲染后的页面上并不明显。
- 响应时间:如果大多数请求的响应时间都相当一致,那么那些有偏差的响应时间则表明背后可能发生了一些不同的情况。这再次表明,猜测的用户名可能是正确的。例如,一个网站可能会在验证用户名有效之后才会检查密码是否正确。这个额外的步骤可能会导致响应时间略有增加。虽然这种差异很微妙,但攻击者可以通过输入过长且复杂的密码来使这种延迟更加明显,从而让网站花费更长时间来处理该请求。
Note
通常而言,主要通过错误响应和时间来进行用户枚举,比如登录错误时,网站会提示用户名错误,此时可以密码喷洒/用户名枚举攻击,注册时同理,若系统提示该用户已存在,同样存在攻击可能。而通过响应时间判断属于侧信道攻击的一种,由于错误的用户名密码和正确的用户名密码在代码执行逻辑层面肯定有区别,所以会有微弱的时间差异
存在缺陷的暴力破解防御机制¶
通常而言,在攻击者成功入侵一个账户之前,会经历多次失败的尝试。从逻辑上讲,暴力攻击防御的核心在于尽可能使自动化攻击变得复杂,从而减缓攻击者尝试登录的速度。防止暴力攻击的两种最常见方法就是:
- 如果远程用户尝试登录的次数过多,系统会锁定该账户,以防止其继续尝试登录。
- 如果同一IP地址的连续登录尝试次数过多,就阻止该用户的登录。
这两种方法都能提供不同程度的保护,但都无法完全避免被攻击,尤其是当它们采用有缺陷的逻辑进行实施时。
例如,有时你会发现,如果多次无法登录,你的 IP 地址可能会被封锁。在某些实现中,当该IP地址成功登录时,对应的失败登录次数的计数器会重置。这意味着攻击者只需在每次尝试失败后继续登录自己的账户,就能避免达到这个限制。
在这种情况下,只需定期在字典中添加自己的登录信息,就能使这种防御措施几乎失去效力。
账号锁定¶
网站为了防止暴力攻击,通常会采取一种措施:当满足某些可疑条件时,锁定账户——通常是指多次登录失败。就像普通的登录失败一样,服务器返回的“账户被锁定”信息也可以帮助攻击者获取用户名列表。
Note
例如系统在登录失败时,返回了**差异化**的提示信息。
- 输入**不存在的用户名**:系统提示“用户名或密码错误”。
- 输入**存在的用户名但密码错误**:系统提示“密码错误,账号已被锁定,还剩 2 次尝试机会”。
此时攻击者可以使用字典批量提交用户名和任意密码。只要系统返回了包含“锁定”、“剩余次数”或“已锁定请X分钟后重试”的提示,攻击者就 100% 确认该用户名在系统中是真实存在的。
锁定账户可以一定程度上防止针对特定账户的暴力攻击。然而,这种方法并不能完全阻止那种攻击者试图访问任何随机账户的暴力攻击行为。
例如,可以使用以下方法来绕过这种防护措施:
- 列出一些可能的有效用户名。这可以通过用户名枚举来实现,或者基于一些常见的用户名列表来进行筛选。
- 请选出一小部分密码,你认为至少有一个用户可能会使用这些密码。重要的是,所选的密码数量不得超过允许的登录尝试次数。例如,如果你确定允许的尝试次数为 3 次,那么最多只能尝试 3 个密码。
- 使用诸如 Burp Intruder 这样的工具,尝试用每一个选定的密码来攻击每一个候选的用户名。这样,你就可以在不触发账户锁定的情况下,尝试破解每一个账户。只需要一个用户使用其中三种密码中的任何一种,就能成功入侵一个账户。
账户锁定也无法有效防止密码喷洒攻击。这种攻击方式会使用一个庞大的密码字典,其中包含从数据泄露中窃取到的真实登录凭证。凭证填充攻击的原理在于:许多人会在多个网站上重复使用相同的用户名和密码。因此,字典中一些被破解的凭证也有可能在目标网站上生效。然而,账户锁定并不能有效防范密码喷洒攻击,因为每个用户名只会被尝试一次而已。密码喷洒攻击非常危险,因为攻击者有时只需一次自动化攻击就能突破多个账户的防护。
Note
事实上,账号锁定机制可能会造成系统被恶意DOS攻击,此时攻击者不关心密码是什么,其目的是**让合法用户无法登录**。
在攻击者获取了目标系统的有效用户名列表(例如通过前面的枚举,或泄露的员工邮箱列表)的前提下,可以编写脚本,针对这些真实账号,故意连续输入错误密码,迅速触发系统的锁定阈值,从而让正常的业务账号都无法使用系统
用户速率限制¶
网站另一种防止暴力攻击的方法是通过用户速率限制来实现。在这种情况下,如果在短时间内发出过多的登录请求,就会导致你的 IP 地址被封锁。通常,只有以下几种方式才能解除对 IP 的封锁:
- 在经过一定的时间间隔后自动解封
- 由管理员手动解封
- 在成功通过验证码挑战后,由用户手动完成操作。
通常,比起锁定账户,采用用户速率限制更为合适,因为这种方式较少受到用户名枚举攻击和服务拒绝攻击的影响。不过,这种方法仍然不够安全。正如我们在之前的实验中看到的例子所示,攻击者可以通过多种方式来操纵自己的 IP 地址,从而绕过限制
由于该限制是基于从IP地址发送的 HTTP 请求频率来设定的,因此有时候也可以通过一次请求尝试猜测多个密码的方式来绕过这一防护措施。
HTTP中的基本认证¶
虽然这种认证方式已经存在了相当长的时间,但由于其相对简单且易于实现,因此有时仍然会被使用。在 HTTP 基本认证中,客户端从服务器接收到一个认证令牌,该令牌是由用户名和密码拼接而成,然后以 Base64 编码的形式生成的。这个令牌由浏览器进行存储和管理,浏览器会在每个后续请求的头部中添加这个令牌,格式如下:
由于多种原因,这种方法通常并不被视为一种安全的认证方式。首先,每次发送请求时都需要重复发送用户的登录信息。除非网站启用了 HSTS 机制,否则用户的登录信息仍有可能被中间人攻击所获取。
此外,大多数 HTTP 基本身份验证的实现并不支持暴力攻击防护机制。由于令牌仅由静态数据组成,因此很容易受到暴力攻击的威胁。
HTTP 基本身份验证也极易受到与会话相关的攻击,尤其是 CSRF 攻击。仅依靠基本身份验证本身是无法有效防御这类攻击的。
在某些情况下,利用易受攻击的 HTTP 基本认证机制,攻击者可能仅能访问那些看似无用的页面。然而,除了为攻击者提供额外的攻击途径外,以这种方式暴露的凭据还可能被用于其他更为敏感的场景中。
多因子认证中的漏洞¶
许多网站仅依赖单因素认证,即通过密码来验证用户的身份。不过,有些网站要求用户使用多种认证因素来证明自己的身份。
对于大多数网站来说,验证生物特征信息是不切实际的。不过,现在越来越常见的是结合“必选认证”和“可选认证”的双重认证机制,这种认证基于用户已知的信息和实际拥有的设备。通常,用户需要同时输入传统的密码以及来自外部物理设备的临时验证代码。
虽然有时攻击者能够获取单个基于知识的因素,比如密码,但同时从非带内来源获取另一个因素的情况则较为罕见。因此,双因素认证显然比单因素认证更安全。不过,就像任何安全措施一样,其安全性取决于具体的实施方式。如果双因素认证的实施不当,那么其安全性同样可以被突破,就像单因素认证一样可能被绕过。
同样值得注意的是,只有验证多个不同的因素,才能充分发挥多因素认证的优势。如果仅通过一种方式来验证同一个因素,那就不能称之为真正的双因素认证。基于电子邮件的 2FA 就是这样一个例子。虽然用户需要输入密码和验证码,但访问账户时只需要知道自己的邮箱登录凭据即可。因此,这里的“知识认证因素”实际上被重复验证了一遍。
双因子认证令牌¶
验证代码通常由用户通过某种物理设备来读取。许多高安全性的网站现在都会提供专门的设备供用户使用,比如 RSA 令牌或键盘式设备,用户可以通过这些设备访问在线银行或笔记本电脑。除了为安全性设计之外,这些专用设备还有一个优点,那就是能够直接生成验证代码。同样地,许多网站也会使用专门的移动应用来进行验证,比如 Google Authenticator。
另一方面,一些网站会将验证代码作为短信发送到用户的手机上。虽然从技术上讲,这种方式仍然是在验证“你拥有某物”这一因素,但这种做法存在被滥用的风险。首先,代码是通过短信传输的,而不是由设备本身生成的,这就使得代码可能被截获。此外,还存在 SIM 卡交换的风险,即攻击者可以非法获取带有受害者电话号码的 SIM 卡。这样一来,攻击者就能接收到所有发送给受害者的短信,包括包含验证代码的短信。
绕过双因素认证¶
有时,双因素认证的实施存在缺陷,以至于用户完全有可能绕过这一认证机制。
如果用户在首先被要求输入密码之后,又需要在另一个页面上输入验证码,那么实际上在输入验证码之前,用户就已经处于“已登录”状态了。在这种情况下,值得测试一下是否可以在完成第一次身份验证后直接进入“仅限已登录用户”的页面。偶尔,你会发现有些网站在加载页面之前并不检查你是否完成了第二次身份验证。
存在缺陷的双因素验证逻辑¶
有时,双因素认证中的逻辑缺陷会导致这样一种情况:当用户完成初始登录步骤后,网站无法充分验证同一用户是否真的正在执行第二步的操作。
例如,用户首先使用其正常的登录凭据进行登录,具体步骤如下:
POST /login-steps/first HTTP/1.1
Host: vulnerable-website.com
...
username=carlos&password=qwerty
然后,他们会获得一个与他们的账户相关的 cookie 值,之后会被带到登录过程的第二步:
HTTP/1.1 200 OK
Set-Cookie: account=carlos
GET /login-steps/second HTTP/1.1
Cookie: account=carlos
在提交验证码时,系统会使用这个 Cookie 来确定用户试图访问的是哪个账户。
POST /login-steps/second HTTP/1.1
Host: vulnerable-website.com
Cookie: account=carlos
...
verification-code=123456
在这种情况下,攻击者可以使用自己的凭据登录,然后在提交验证码时将 account cookie 的值改为任意的用户名。
POST /login-steps/second HTTP/1.1
Host: vulnerable-website.com
Cookie: account=victim-user
...
verification-code=123456
如果攻击者能够暴力破解验证码,那将极其危险。因为这样一来,他们就可以仅凭用户名就登录到任何用户的账户了。他们甚至根本不需要知道用户的密码。
Note
该攻击的前提在于返回的Cookie或其他身份标识可以被篡改伪造,否则无法成功
爆破2FA的验证码¶
与密码类似,网站也需要采取相应措施来防止有人通过暴力攻击的方式破解双因素验证代码。这一点尤为重要,因为这类代码通常只是简单的 4 位或 6 位数字。如果没有有效的防御措施,破解这样的代码简直易如反掌。
一些网站试图通过这种方法来防止这种情况的发生:当用户输入一定数量的错误验证码时,系统会自动将用户注销。但实际上这种方法并不有效,因为高级攻击者可以通过为 Burp Intruder 创建自动化脚本来实现多步验证过程。此外,还可以使用 Turbo Intruder 扩展来实现这一目的。
Note
具体攻击手法可参考:burpsuite官方靶场之验证篇 - FreeBuf网络安全行业门户
其他认证机制中的漏洞¶
除了基本的登录功能之外,大多数网站还提供了一些附加功能,使用户能够管理自己的账户。例如,用户可以在忘记密码时更改密码或重置密码。然而,这些机制也可能存在漏洞,可能会被攻击者利用。
大多数网站都会努力避免登录页面出现已知的漏洞。不过,人们往往忽略了同样需要采取措施来确保相关功能也同样具有安全性这一点。在攻击者能够创建自己的账户并因此轻松访问这些额外页面的情况下,这一点尤为重要。
保持登录状态¶
一个常见的功能是允许用户在关闭浏览器会话后仍然保持登录状态。这通常是一个简单的复选框,上面写着类似“记住我”或“保持登录状态”这样的文字。
通常,这种功能是通过生成某种“记住我”的令牌来实现的,然后将该令牌存储在持久性cookie中。由于拥有这个cookie可以让你绕过整个登录过程,因此最好让这个cookie难以被猜测到。不过,有些网站会根据一些固定的组合来生成这个cookie,比如用户名和时间戳。有些网站甚至会将密码作为cookie的一部分。如果攻击者能够创建自己的账户,他们就可以研究自己的cookie,从而推断出cookie的生成方式。一旦他们掌握了这个公式,他们就可以尝试暴力破解其他用户的cookie,以获取他们的账户信息。这种方法非常危险。
一些网站认为,只要cookie以某种方式进行了加密处理,那么即使它使用了静态值,也无法被猜测到。虽然如果操作得当的话,这种想法可能是正确的,但简单地使用像Base64这样的双向编码方式来“加密”cookie实际上没有任何保护作用。即使使用单向哈希函数进行加密,也无法完全防止攻击。如果攻击者能够轻易识别出哈希算法,并且没有使用盐值,他们就可以通过不断尝试哈希来破解cookie。这种方法可以用来突破登录尝试的限制,因为如果对cookie的猜测没有设置限制的话。
即使攻击者无法创建自己的账户,他们仍然有可能利用这一漏洞。通过使用常见的攻击手段,比如 XSS 攻击,攻击者可以窃取其他用户的“记住我” cookie,并推断出 cookie 的构造方式。如果网站使用的是开源框架,那么 cookie 的构造细节甚至可能被公开记录下来。
在极少数情况下,即使密码已经被哈希处理,仍然有可能从 cookie 中提取出用户的明文密码。网上有各种已知的密码列表,如果用户的密码出现在这些列表中,那么解密哈希值通常就像将哈希值直接粘贴到搜索引擎中进行搜索一样简单。这充分说明了在有效的加密方案中,添加盐值的重要性。
密码重置¶
在实践中,有些用户可能会忘记自己的密码,因此通常会提供一种重置密码的功能。由于在这种情况下显然无法使用传统的基于密码的身份验证方式,网站不得不采用其他方法来确保用户确实是本人自己在重置密码。因此,密码重置功能本身就具有危险性,必须采取严格的安全措施来保障其安全性。
这一功能通常有几种不同的实现方式,这些方式存在的利用方式也有所不同。
通过电子邮件发送密码¶
显然,如果网站能够妥善管理用户密码,那么就不应该再向用户发送他们的当前密码。相反,一些网站会生成一个新的密码,并通过电子邮件将该密码发送给用户。
Note
值得一提的是,如果一个网站能帮用户找回原密码,那么可以肯定该网站要么是明文存储用户密码,要么就是使用可解密的算法存储用户密码,管理员可以随意获取用户密码,这是极度不安全和侵犯隐私的
一般来说,应避免通过不安全的渠道传输持久性的密码。在这种情况下,安全性依赖于两种机制:一种是生成的密码在较短时间内到期,另一种是用户能够立即更改自己的密码。否则,这种方案很容易受到中间人攻击的威胁。
电子邮件通常也不被认为是一种安全的信息存储方式,因为用户的收件箱是持续存在的,而且并没有被设计用于安全存储机密信息。许多用户在多个设备之间会通过不安全的渠道来同步他们的收件箱。
通过URL重置密码¶
一种更可靠的密码重置方法是向用户发送一个唯一的 URL,该 URL 会引导用户进入密码重置页面。不过,一些不太安全的实现方式会使用一个容易猜到的参数来标识要重置的账户,例如:
在这个示例中,攻击者可以将 user 参数替换为他们所知道的任何用户名。这样,用户就会被直接带到一个页面上,在那里他们可以为该任意用户设置新的密码。
这个流程的更好实现方式是生成一种高熵、难以猜测的令牌,然后基于该令牌来创建重置 URL。在最佳情况下,这个 URL 应该不会给出任何关于哪个用户的密码正在被重置的线索。
http://vulnerable-website.com/reset-password?token=a0ba0d1cb3b63d13822572fcff1a241895d893f659164d4cc550b421ebdd48a8
当用户访问该 URL 时,系统应检查该令牌是否在后端存在,如果存在,则确定该令牌对应的是哪个用户的密码需要重置。这个令牌会在一段时间后失效,在密码被重置后会被立即销毁。
然而,有些网站在提交重置表单后并不重新验证令牌的有效性。在这种情况下,攻击者可以自行访问重置表单,删除令牌,然后利用这个页面来重置任意用户的密码。
如果重置邮件中的 URL 是动态生成的,那么这种重置方式也可能面临密码泄露的风险。在这种情况下,攻击者可以窃取其他用户的令牌,然后使用该令牌来更改该用户的密码。
登录中的用户修改密码¶
通常,更改密码需要用户先输入当前的密码,然后再输入新的密码两次。这些页面在验证用户名和当前密码是否匹配方面,本质上与普通的登录页面采用相同的流程。因此,这些页面同样可能受到类似攻击的威胁。
如果密码更改功能允许攻击者无需以受害者的身份登录即可直接访问密码信息,那么这一功能就可能会带来严重的风险。例如,如果用户名被存储在某个隐藏字段中,攻击者就有可能在请求中修改该值,从而针对任意用户进行攻击。这种情况可能会被利用来枚举用户名和暴力破解密码。
Note
事实上,很多网站仅对登录实现了防暴力破解机制,未对密码修改进行限制,在这种情况下,如果攻击者可以通过某种方式获取到用户修改密码的请求,那么可以变相的进行暴力破解攻击,特别是该请求中含有用户名等可控字段时
如何防御身份认证漏洞¶
身份验证是一个复杂的话题。正如我们所看到的,很容易出现各种漏洞和缺陷。要列出所有可以用来保护自己网站的措施显然是不可能的。不过,还是有一些基本原则需要始终遵循。
小心处理用户凭据¶
即使是最强大的认证机制,如果在不知情的情况下将有效的登录凭据泄露给攻击者,这些机制也毫无用处。显然,永远不应该通过未加密的连接传输任何登录数据。虽然你可能已经为登录请求实现了 HTTPS 加密,但请确保通过将所有尝试进行 HTTP 连接的请求重定向到 HTTPS 连接来加强这一安全措施。
您还应该对网站进行审计,确保没有任何用户名或电子邮件地址通过公开可访问的配置文件被泄露,或者出现在 HTTP 响应中。
不要依赖用户来保证安全性¶
严格的身份验证措施通常需要用户付出一些额外的努力。由于人的天性,几乎总会有用户找到办法来避免这些麻烦。因此,在可能的情况下,你应该鼓励用户采取安全的行为方式。
最明显的例子就是实施有效的密码策略。一些传统的策略并不奏效,因为人们会自行创建一些容易预测的密码并将其纳入策略中。相反,采用某种简单的密码检查工具会更有效,这种工具可以让用户尝试不同的密码,并实时反馈密码的安全性。一个著名的例子是 Dropbox 开发的 JavaScript 库 zxcvbn 。通过只允许那些被密码检查工具评为安全的密码,可以比使用传统策略更有效地强制用户使用安全的密码。
Note
比如用户设置Password@123,该密码确实满足大部分密码复杂度策略,但它属于有规律、可被猜测出的弱密码,这也是为什么弱密码仍然广泛存在的理由
防止用户名枚举¶
如果泄露了系统中存在某个用户的信息,那么攻击者就更容易破解你的认证机制了。在某些情况下,由于网站的性质原因,知道某个人的账户存在本身就已经属于敏感信息了。
无论尝试使用的用户名是否有效,都重要的是要使用完全相同的通用错误信息,并且确保这些信息的确是完全相同的。每次登录请求时,都应该返回相同的 HTTP 状态代码。最后,在不同情况下,尽量使响应时间尽可能难以区分。
实现强大的暴力破解防护机制¶
鉴于暴力攻击的构造其实非常简单,因此必须采取措施来防止或至少破坏任何试图进行暴力登录的尝试。
一种较为有效的方法是实施严格的基于IP的用户速率限制。这需要通过一些措施来防止攻击者篡改用户的真实IP地址。理想情况下,当达到一定的限制后,每次登录尝试都要求用户完成一项验证码测试。
请记住,这种方法并不能完全消除暴力破解的威胁。不过,如果让这个过程变得尽可能繁琐和需要手动操作,那么任何潜在的攻击者都可能会放弃攻击,转而寻找更容易攻击的目标。
仔细核查认证逻辑是否正确¶
简单的逻辑缺陷很容易潜入代码中。在身份验证方面,这些缺陷有可能完全破坏你的网站和用户的安全。因此,彻底审查所有的验证逻辑以消除缺陷,是确保身份验证功能稳健的关键。如果有一个可以被绕过的安全检查机制,那实际上还不如没有检查机制好。
不要只关注登录验证¶
务必不要只关注登录页面,而忽略了与身份验证相关的其他功能。这一点在攻击者可以自由注册自己的账户并尝试使用这些功能的情况下尤为重要。请记住,密码重置或更改操作同样属于潜在的攻击途径,因此必须采取同样严格的防护措施来保障登录流程的安全性。
适当的多因素认证机制¶
虽然多因素认证可能并不适用于所有网站,但一旦操作得当,它确实比单纯的基于密码的登录方式要安全得多。需要注意的是,验证同一因素的不同实例并不属于真正的多因素认证。通过电子邮件发送验证代码实际上只是一种更为繁琐的单因素认证形式而已。
基于短信的 2FA 技术实际上是通过验证两种因素来确认用户身份——一种是你已知的信息,另一种是你拥有的物品。不过,由于存在通过更换 SIM 卡等方式来欺骗系统的风险,因此这种系统可能存在不可靠的情况。
理想情况下,应该使用专门的设备或应用程序来实施两步验证,这样就能直接生成验证代码。因为这些工具是专门为提供安全性而设计的,所以通常来说它们更加安全。
最后,确保双因素认证的逻辑部分也是可靠的,这样就不会容易被绕过。