文档章节

[译]搭建账户系统

niithub
 niithub
发布于 2017/09/08 18:40
字数 5433
阅读 19
收藏 1
点赞 0
评论 0

搭建账户系统

 

 

Troy Hunt 近期发表了一篇题为『新时代的认证指南』的博文。文章对于「你的网站应该使用什么样的密码规则」给予了很多实用的建议,而通过参考权威机构的建议总是有助于说服同事或老板。

我在 Google 工作期间从事过的一个项目就是他们的统一账户系统(特别是反劫持)。大多数网站都会有一个登录系统,阅读 Troy 的文章极大地启发了我去建立这样的一个系统,从而将那些建议应用其中。

1. 最好不要有

不管是什么业务,进行用户认证并不是你的主职,现代登录系统需要考虑的有很多,密码只是一个开始。如果你成功建立了账户,最终还得考虑:

  • 找回密码
  • 电子邮箱的认证
  • 账户登出,常常比你想象的要困难(见下文)
  • 密码的强力保护
  • 基于短信、手机应用和硬件密钥的双因子验证
  • 对账户劫持的保护(当攻击者已经知道了正确密码而用户还没有双因子验证时)
  • 用户的地区、语言、姓名、个人头像等的偏好
  • 对桌面和移动端的登录支持
  • 异常行为的通知
  • 只允许特定手机的登录

随着大公司对用户验证意识的提高和攻击者的攻击能力的提升,一成不变的验证技术已经不符合时代的变化。幸运的是,你现在可以将你的身份验证环节外包给那些支持 OAuth 协议的公司。

Web 开发者常常会在建立完自己的账户系统之后,才觉得添加『使用 Facebook 登录』『使用 Google 登录』是个不错的方案。如果你是为了建立一个全新的网站而阅读这篇文章,我建议『使用第三方登录』应该成为你的网站的唯一选项。如今,建立自己的账户系统就像是建立自己的数据中心,而不是使用 AWS。

人们有时候会担心,如果只提供『第三方登录』按钮用来登录,那么那些大型的 ID 提供商可能会试图窃取他们的客户。通常情况下,人们担心的情况是,使用 ID 提供商登录,但是却被要求设置密码。其实不用担心这一点,这种情况不太可能发生,就算真的发生了,你也随时可以通过电子邮件给他们发送一个链接将你的客户群迁移到你自己的系统上。

2. 使用邮箱或电话号码来识别用户

不要强制用户设置用户名,即使你的业务体验是基于用户名的,比如聊天论坛之类的。用户通常是通过邮箱或者是电话抑或是两者同时验证的,如果你想让每个用户都拥有一个独一无二的用户名(用来展示的),那应该单独选择,为什么呢?

  • 无论如何你都是要用户提供邮箱地址的
  • 如果用户名成为你的系统的个人识别符,你要考虑用户是会随时更改它的
  • 用户经常会忘记用户名,可一般不会忘记邮箱或电话号码
  • 挑选用户名的过程常常是让人沮丧,一旦用户使用了一个用户名,却因为该用户名已经存在而不能通过时,有些人就会放弃了,从而你就流失了一位用户
  • 将用户名和用来展示的名字分开可以大大减少对用户设置的限制,例如禁止空格

3. 完全放弃密码

 

 

如果你还没准备好将账户系统完全依赖于第三方 ID 提供商,那么千万不要设置密码,这样对每个人都有好处。

这个主意并不像它听起来那么愚蠢。你已经向用户询问他们的电子邮箱了,你所应该在你的登录系统上添加的第一个功能就是用户忘记密码后该如何恢复,你可以通过电子邮件给用户发送一个可点击的链接。这样,只要用户能够使用该邮箱就能够登录你的系统,而你的网站密码也用不着增加额外的安全性。

我们跳过这一步,直接进入下一步,取而代之的——你的登录系统可以变得更简单,只需通过邮件向用户发送一封包含了登录cookie的链接,用户只需点击链接便能登录。Medium.com 便是如此

通过这种方法,只要用户的设备装有电子邮件客户端,就能够登录。对于台式机、笔记本电脑、手机和平板来说也是如此。对于游戏机和电视来说可能行不通,不过你的目标用户可能不是这些人群。其中的匹配过程最好用蓝牙的方式,因为这些设备没有方便使用的键盘。

过去常常有这样的说法:缺少密码输入框会使用户感到不自在。而现代的谷歌登录体验正是如此,他们仅仅要求用户输入他们的电子邮箱地址,所以用户并不会感到有什么不自在,而且这么做还大有好处。

而这种方法还有个好处:有些人只有电话号码而没有电子邮箱。在发展中国家尤其如此,所以如果这些国家的用户是你的网站的潜在目标市场的话,最终你可能要支持仅能通过手机接受验证码的方式登录。这样的账户根本就不需要密码,如果你所有的用户都有密码,那么你需要返回并为安全敏感的代码路径添加许多特殊的情况(这很容易导致致命的错误)。

4. 不要使用密保问题

如果你就是想使用密码——大概你懒得向你的老板解释为什么你这么特立独行,那么请至少不要让用户通过密保问题来找回他们的密码。

  • 密保问题常常被猜测。用户很难想出那些只有他们知道而其他人答不出来的问题。
  • 预设的问题使得猜测的现象更加严重
  • 预设问题往往带有文化差异,从而使得它们对于许多用户并不友好(例如:『你们高中学校的吉祥物是什么?』)。
  • 一些『精明』的用户意识到他们不能想出一个难以猜测的答案,所以仅仅在这个位置填入密码,导致了他们在忘记密码时无法恢复。
  • 还有一堆的高端黑客,会在密码恢复流程上做点文章,你可不希望这事发生在你身上吧。

Google 曾经在密保问题上遇到过严重的问题。这是我的几位老同事发表的研究,值得一看(视频在下面,来自 youtube,需要翻墙)。

 

 

一场在谷歌进行的关于密保问题和答案的谈话

这是一些问答的例子:

  • 问:你最喜欢的食物是?答:披萨。答案常常是披萨。仅仅通过猜出这个问题的答案,你就能破解大约 20% 的说英语的用户。再添加十个猜测选项,你就能破解三分之一的设置了这个问题的用户。而对于韩国用户,你可以用 10 个以内的选项破解 43% 的用户。
  • 问:你是在星期几结的婚?答:星期四 是用户自定义的问题,但却有个致命的缺陷 —— 一般攻击者只需要尝试 5 次,就能破解正确答案。而这还不至于被检测为暴力破解。
  • 问:我是在哪个城市出生的?答:首尔在一些国家里,大多数人会聚居在少数的几个大城市里。观察 ID 验证用户界面所使用的语言,可大大缩小可能的城市列表。通过这个问题,你能够破解 40% 的用户。
  • 问:我的第一位老师叫什么名字?答:Mr Smith, Smith, John, John S. Smith,JOHN SMITH, Jon Smth。 这些都是正确答案,但是却不能正确通过。我为这些问题提供了模糊匹配的模式,因为用户的答案总是差那么一点儿。匹配逻辑通常需要了解一些问题背景(『编辑距离』算法本身不足以满足诸如街道地址等的情况)。你还得让你的产品支持多语言,祝你好运吧。

专业的账户系统是不会单独使用密保问题来允许用户恢复密码的。它仅仅只是一种参考。我只给予你小于 2% 的机会去通过一个足够复杂的机制来获得这个权利。这就是为什么 Google 逐步淘汰密保问题而采用短信的方式来恢复密码。当然短信恢复自身也存在一些问题,但相比于密保问题还是好很多的。

5. 避免使用验证码

验证码是许多登录表单的常见功能。我在 Google 期间也做了一些相关的工作。但是,在如今验证码几乎没有什么价值,而且执行率非常之低。

 

 

这些验证码都无济于事。

首先要正确理解验证码的作用,它们仅仅对自动化攻击施加非常简单的限制。他们并不会保护你的账户系统免于批量注册的风险。除了账户安全,我还花了几年时间研究 Google 的注册滥用。我们亲眼看到垃圾邮件发送者轻松地解决了数千万个那些我们认为很难的验证码。有那些专业处理验证码的公司,如 DeathByCaptcha,他们使用的是光学字符识别和人工识别。普通的验证码让盲人用户无法进行注册,这确实是个问题。而基于语音的验证识别对于机器很容易,对人来说却很困难。

使用验证码阻止暴力破解密码是很有帮助的。暴力破解一个账户的密码,可能需要成百上千次的尝试,一个简单的方法来阻止这种现象是在他们经过了几次失败的尝试之后就开始加入验证码。在机械的循环中,即使是使用一个简单的验证码来延缓进程也足够了。

对于阻止批量账户注册,验证码却不太管用。建立一个系统去检测和阻止这类现象是另一桩工作,在这方面我也花了好几年的时间。你可以大致了解一下这有多困难,登录 buyaccs.com 并对比一下黑市账户销售商收取的巨大差价。防御系统较好的网站的账户通常会收取更高的价格。除非你是 Big 5 之一,不然在注册安全方面,你所做的不可能超过我们,这也是我建议你将登录系统外包给那几家主要的公司的另一个原因。

如果你仍然想要使用验证码,请使用 reCAPTCHA 并确保你的验证码放置在了适当的位置,以免重放攻击。不要尝试使用你自己制作的或是你在 GitHub 上找到的工具包,这样的验证码很容易被现代的光学字符识别所解决,除了降低客户注册的成功率之外并没有什么用处。

6. 外包双因子验证

 

 

如今双因子验证是一个很常见的功能。然而,把它做好却是很困难的,而且花费不菲,你不会想自己动手去实现它的。

  • 短信是不稳定的,特别是在有些国家,恢复码常常不能显示。你最终可能会选择语音合成的电话,因为电话更加稳定一些,而现在你又需要考虑多语种的语音合成引擎了。
  • 大量的短信或电话将会是一笔大的开销,即使你能通过大批量获得优惠。
  • 人们可能常常会更换电话号码。如果你的密码恢复流程是基于电子邮件地址的,那么这个过程将会变得很容易。但是一旦你的系统引入了稳定的双因子认证,密码恢复将变成你系统中的一个漏洞。如果你不去修复它,攻击者将会很轻松地进行破解。而如果你尝试阻止它也并不会起作用。
  • 双因子验证会被攻击者滥用,他们将它添加到钓鱼或者黑入的账户里。这是为了在执行恶意活动期间,防止真正的用户取回该账号。
  • 电话号码很容易受到移植攻击,所以如今的趋势是要求用户设置移动应用或安全密钥。为了实现这项措施意味着更多的工作,当然,这两项可能都不管用,所以你最终还是需要一些客户支持流程来帮助他们恢复。
  • 如你所见,双因子验证增加了大量客户的手动操作,因为你不再使用密保问题或电子邮件的方式恢复用户的密码了。而这个开销很大。

其中一些问题是很根本的,但是大多数已经有人帮你解决了,他们将免费为你支付电话费和客户支持人员

不过,如果你仍然不想使用他们提供的服务,那么还有一些创业公司可以为你解决小部分的双因子验证难题。

7. 不要强制用户更改密码

Troy 已经把这一点解释的很好了,我这里就不再赘述,但还要再强调一遍,这很重要。不要仅仅是因为用户的密码已经使用一段时间了,就让用户更改密码。

  • 一些用户可能无法通过这个流程,从而导致你流失一部分用户。
  • 用户可比你聪明,他们会更改密码(一次、两次、三次),然后立即将其更改为旧密码,这意味着你得存储最近密码的历史记录以防止此类行为。但我敢打赌,你不会这样做的。
  • 这样并不会增加安全性。

8. 不要为会话设置有效期

是的,这又是个不好的『最佳实践』。人们常常会为会话 cookie 设置有效期,觉得这样做增加了安全性,出于同样的原因,人们会认为为密码设置有效期也会增加安全性。

  • 攻击者往往会立即进行恶意活动,所以设置有效期并没有多大用处。
  • 会话有效期这一设置使得用户习惯于意料之外的密码提示,这使得他们非常容易被欺骗。
  • 存储有效期的随机性会产生大量的 bug,导致了你的开发人员将大量的时间花在了修复 bug 上。你的网站的大部分代码应该不能处理这种,在一个操作中途,使用的会话过期了的情况,所以你必须返回去修复它,前提是你能够发现的话。而由于用户报告的随机性,这使得追踪错误变得更加困难了。

9. 记得登出

在不成熟的账户系统中,登出错误是非常常见的。这听起来很简单,但是实现这一功能的公认方法,是有缺陷的。

  • 简单地删除会话的 cookie 对用户来说是方便的,但是这意味着你在遭受『跨站脚本攻击』后无法恢复。一旦发现『跨站脚本攻击』,你会希望,让可能被盗取的会话 cookie 无效,但是如果登出只是『要求浏览器删除 cookie』,那么这样做是不行的。
  • 将时间戳添加到会话 cookie,然后设置『最后登出时间』,每个操作都需要检查帐户数据库,以了解用户的会话是否过旧。这可能会导致操作响应变慢,意味着开发人员将要对此进行优化(毕竟这似乎也没什么)。但是如果他们移除了对攻击者感兴趣的一个端口的检查,那么你在第一步中遇到问题将会再次出现。另外,这意味着退出一个浏览器或设备,就会将所有用户登出,这不是预期的行为。

正确的方法是使用内存中缓存来保存过期会话 cookie 的列表。但是,对于大多数公司来说,有个成本更低而且足够好的替代方案:让用户的退出链接仅仅当作是清除会话 cookie 的一种方式,紧接着可以让会话 cookie 过期,并且每隔5分钟自动更新。替换过期会话 cookie 的行为可以通过查询数据库,以查看管理员是否强制注销了该账户。如果用户显示的是过期的 cookie,则需要重新登录。这就意味着 cookie 清理之后就不太可能被盗用了。

10. 从营销邮件中分离帐号电子邮件

 

 

一般我们会用公司的主要电子邮箱服务器来给用户发送恢复密码链接、登录验证等信息。然而,贵公司的一些人却会通过给用户发送那些他们不想收到的商业邮件与用户建立『联系』。

即使用户同意在帐号注册期间收到这类信息,但其中大部分用户却不想再收到这样的信息,有些人甚至会将其举报为垃圾邮件。那些精明的用户知道,这是一个极其方便的解决方案,仅仅简单地点击『举报垃圾邮件』,就能让这些令人讨厌的电子邮件消失,而不必把精力花费在寻找用微小字体写着的『取消订阅』链接,或是劳神费力地写电子邮件过滤器。

而不幸的是,这类行为将会降低你的电子邮件域名的信誉。从你的帐户系统发送的邮件最终很可能会进入用户的垃圾邮件文件夹。我们在注册或进行密码恢复的流程中,都能看到这类让我们检查垃圾邮件文件夹的提示 —— 就是这个原因。

解决这个问题的一种方法是,购买单独的顶级域名来发送邮件,并确保符合电子邮件验证标准。但是,一些用户可能会注意到域名不匹配,从而将你的电子邮件举报为网络钓鱼。最佳方案是使用不同电子邮件验证标准的域名发送你的营销邮件,但你的产品人员可能不认可。所以,还是那句话,你选择自己干的那一刻,也同时承担了痛苦。

11. 保护好你的密码数据库

一旦你拥有了密码,你的数据库就成了攻击者的目标(而且他们常常能得手)。他们对你的公司并不感兴趣,他们只是想要密码,以方便他们尝试那些更高价值目标。所以,数据泄露是个严重的问题,也许对客户的直接影响没那么大,但有可能导致严重的后果。而使用 OAuth 协议的数据库对于攻击者来说却没什么价值, 因此不太可能受到攻击。

结论

关于帐户系统我还能写好多东西。保护你的网站,使其免受恶意帐户入侵或注册,这方面内容可以单独写成一本书了。这书我写不了,不过如果你有兴趣的话,可以看看这个视频,这是我在 2012 年的一次访谈

老实说,这看似是一个浩大的工程,实则并非如此。所以我一直建议你要硬着头皮坚持做下去,并且把你的账户管理外包给那些大公司。因为,你的主要业务并不是去操心怎样摆弄验证码、不是怎样写『登出』的设计文档、不是诊断为什么你会流失那些忘记密码的用户、也不是去考虑为什么发送信息到秘鲁会不稳定。你在这些事情上花费的每一分钱,对于那些提供了『使用第三方登录』的竞争对手来说,他们将这些钱都花在了他们的核心业务上。

所以,不要回头看了,放弃你的密码数据库吧。

© 著作权归作者所有

共有 人打赏支持
niithub
粉丝 4
博文 41
码字总数 54335
作品 0
南京
程序员
[译]Windows 服务用户帐户

在 Windows 操作系统中,每个服务都运行在一个用户帐户安全上下文中。其用户名和密码在服务安装时由 CreateService 函数指定,并可以通过 ChangeServiceConfig 函数进行更改,通过 QuerySer...

日久不生情
2017/11/30
0
0
CentOS 6.4(32位) + PPTP + RADIUS + MySQL

大家好,非常感谢大家百忙中查看我的帖子! 环境: CentOS 6.4(32位) + PPTP + RADIUS + MySQL 实现的功能: 在CentOS系统上使用PPTP协议搭建VPN服务,VPN账户认证使用RADIUS读取MySQL账户密...

奔跑吧甘兄
2015/06/19
190
0
windows打开 centos版的samba 输入密码提示,用户或密码错误

今天搭建好了centos 的Samba发现centos系统可以直接访问,但是wind访问出现账户和密码错误。(这里已经排除了搭建问题和账户等问题) 找了很多资料后才发现 网络安全:LAN管理器身份验证级别...

lk442634939
07/11
0
0
模块部署(译)

模块部署 概述 在 Tachyon 源代码树中, 目录包含一些工具可以协助你在 AWS EC2 或 virtualbox 搭建 Tachyon集群。 In Tachyon source tree, directory contains utilities to help you set...

Ryan-瑞恩
2015/10/21
46
0
关于搭建linux sftp文件服务器的疑问

我按照网上的步骤搭建了sftp的文件服务器,用ssh工具可以链接,也能上传文件,但是用jsch类库上传文件时,能够成功链接sftp账户,但是上传文件时会报一个no such file的错误,但是用root账户...

最明亮的少年
2016/07/20
320
1
风中影/multi.shop.cms

multi B2C商城 联系方式 QQ:304846928 Email: 微信:anlaser 其他:提供 系统简介 multi cms是一个开源电子商城系统,以B2C模式运营的在线商城。 系统分为前台和后台,前台主要功能包括用户...

风中影
2016/12/12
0
0
Samba服务器搭建

Samba服务器搭建了下的步骤如下: 它是实现Linux和Windows之间的文件共享;smbd负责服务器共享文件,客户端权限认证 1.服务安装 yum –y install samba 2.主配置文件是/etc/samba/sam.conf(...

大唐十三郎
2017/11/19
0
0
Samba服务器搭建

Samba服务器搭建了下的步骤如下: 它是实现Linux和Windows之间的文件共享;smbd负责服务器共享文件,客户端权限认证 1.服务安装 yum –y install samba 2.主配置文件是/etc/samba/sam.conf(...

大唐十三郎
2017/11/19
0
0
Android 手机开机密码破解锁定

Android 手机使用Pattern图案加密后,如果忘记密码或多次解锁失败后,会被google自动锁定,无法再次进入开机首页。 本文就是针对这种情况,研究探索了一种破解锁定的方法,具体锁定环境和操作...

长平狐
2013/01/06
265
0
安全加固第一部分

学习来自:http://www.mottoin.com/97568.html 安全加固 补丁的修复 cmd systeminfo 找到补丁程序,记录了系统安装的补丁数目,我这里是2个,显然补丁没打全,存在系统漏洞 使用nessus 下载安...

Alyoyojie
2017/03/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

about git flow

  昨天元芳做了git分支管理规范的分享,为了拓展大家关于git分支的认知,这里我特意再分享这两个关于git flow的链接,大家可以看一下。 Git 工作流程 Git分支管理策略   git flow本质上是...

qwfys
今天
1
0
Linux系统日志文件

/var/log/messages linux系统总日志 /etc/logrotate.conf 日志切割配置文件 参考https://my.oschina.net/u/2000675/blog/908189 dmesg命令 dmesg’命令显示linux内核的环形缓冲区信息,我们可...

chencheng-linux
今天
1
0
MacOS下给树莓派安装Raspbian系统

下载镜像 前往 树莓派官网 下载镜像。 点击 最新版Raspbian 下载最新版镜像。 下载后请,通过 访达 双击解压,或通过 unzip 命令解压。 检查下载的文件 ls -lh -rw-r--r-- 1 dingdayu s...

dingdayu
今天
0
0
spring boot使用通用mapper(tk.mapper) ,id自增和回显等问题

最近项目使用到tk.mapper设置id自增,数据库是mysql。在使用通用mapper主键生成过程中有一些问题,在总结一下。 1、UUID生成方式-字符串主键 在主键上增加注解 @Id @GeneratedValue...

北岩
今天
2
0
告警系统邮件引擎、运行告警系统

告警系统邮件引擎 cd mail vim mail.py #!/usr/bin/env python#-*- coding: UTF-8 -*-import os,sysreload(sys)sys.setdefaultencoding('utf8')import getoptimport smtplibfr......

Zhouliang6
今天
0
0
Java工具类—随机数

Java中常用的生成随机数有Math.random()方法及java.util.Random类.但他们生成的随机数都是伪随机的. Math.radom()方法 在jdk1.8的Math类中可以看到,Math.random()方法实际上就是调用Random类...

PrivateO2
今天
2
0
关于java内存模型、并发编程的好文

Java并发编程:volatile关键字解析    volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在...

DannyCoder
昨天
0
0
dubbo @Reference retries 重试次数 一个坑

在代码一中设置 成retries=0,也就是调用超时不用重试,结果DEBUG的时候总是重试,不是0吗,0就不用重试啊。为什么还是调用了多次呢? 结果在网上看到 这篇文章才明白 https://www.cnblogs....

奋斗的小牛
昨天
2
0
数据结构与算法3

要抓紧喽~~~~~~~放羊的孩纸回来喽 LowArray类和LowArrayApp类 程序将一个普通的Java数组封装在LowArray类中。类中的数组隐藏了起来,它是私有的,所以只有类自己的方法才能访问他。 LowArray...

沉迷于编程的小菜菜
昨天
0
0
spring boot应用测试框架介绍

一、spring boot应用测试存在的问题 官方提供的测试框架spring-boot-test-starter,虽然提供了很多功能(junit、spring test、assertj、hamcrest、mockito、jsonassert、jsonpath),但是在数...

yangjianzhou
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部