当前位置: 首页 > 科技观察

8年的开发,登录界面写的这么烂,,

时间:2023-03-14 23:26:21 科技观察

但是我在面试或者和很多工作经验很短的同学交流的时候发现,虽然很多同学的简历上都写着:负责登录/注册项目的功能模块的开发设计工作,但他们只是简单的实现了功能逻辑,并没有在安全方面考虑太多。本文主要是和大家聊聊。在设计一个登录界面的时候,不仅仅是功能的实现,在安全性方面我们也需要考虑。安全隐患暴力破解!只要网站暴露在公网上,就很有可能被人盯上。试试这种简单有效的爆破方式:通过各种方式获取网站用户名后,编写程序遍历所有可能的密码,直到找到正确的密码!伪代码如下:#密码字典password_dict=[]#登录界面login_url=''defattack(username):forpasswordinpassword_dict:data={'username':username,'password':password}content=requests.post(login_url,data).content.decode('utf-8')if'loginsuccess'incontent:print('gotit!passwordis:%s'%password)那么在这种情况下,我们该如何预防呢?①验证码中聪明的同学想到了。我可以在密码错误达到一定次数时增加验证码验证!比如我们设置当用户密码错误达到3次时,用户需要输入图片验证码才能继续登录操作。伪代码如下:fail_count=get_from_redis(fail_username)iffail_count>=3:ifcaptchaisNone:returnerror('需要验证码')check_captcha(captcha)success=do_login(username,password)ifnotsuccess:set_redis(fail_username,fail_count+1)PS:伪代码不考虑并发,实际开发可以考虑加锁。这样确实可以过滤掉一些非法的攻击,但是以目前的OCR技术,普通的图片验证码确实很难有效的防止机器人(我们为此吃了不少苦头)。当然,我们也可以花钱购买第三方公司提供的滑动验证等验证方案,但都不是100%安全,是可以被破解的(惨痛的教训)。②登录限制这时候另一个同学说我可以直接限制异常用户的登录操作。当密码错误达到一定次数后,将直接拒绝用户登录,一段时间后恢复用户。比如我们设置一个账号登录错误10次,那么该账号的所有登录操作都会在5分钟内被拒绝。伪代码如下:fail_count=get_from_redis(fail_username)locked=get_from_redis(lock_username)iflocked:returnerror('loginrefused')iffail_count>=3:ifcaptchaisNone:returnerror('需要验证码')check_captcha(captcha)success=do_login(username,password)ifnotsuccess:set_redis(fail_username,fail_count+1)iffail_count+1>=10:#Failedmorethan10times,setthelockflagset_redis(lock_username,true,300s)这样确实可以解决用户密码被盗的问题爆炸了。但是这样会带来另外一个风险:虽然攻击者无法获取网站的用户信息,但是可以阻止我们网站的所有用户登录!攻击者只需要无限循环遍历所有用户名(即使没有,也是随机的)登录,那么这些用户就会被永远锁定,导致正常用户无法登录网站!③IP限制由于无法直接针对用户名,我们可以对IP进行处理,直接封杀攻击者的IP。一切都会好起来的。我们可以设置当某个IP下调用登录接口错误次数达到一定次数后,禁止该IP进行登录操作。伪代码如下:ip=request['IP']fail_count=get_from_redis(fail_ip)iffail_count>10:returnerror('loginrefused')#otherlogic#dosomething()success=do_login(username,password)ifnotsuccess:set_redis(fail_ip,true,300s)也能在一定程度上解决问题。其实很多限流操作都是针对IP进行的。比如Nginx的限流模块,可以限制一个IP在单位时间内的访问次数。但是这里也存在问题:比如现在很多学校和公司都使用同一个出口IP。如果直接通过IP限制,可能会误杀其他正常用户。现在虚拟专用网非常多,攻击者可以在封IP后切换虚拟专用网进行攻击。④有没有更好的方法防止手机验证?当然有。我们可以看到,近几年几乎所有的应用都要求用户绑定手机。一是国家实名制要求,二是手机基本上和身份证一样,基本可以代表一个人的身份。因此,很多安全操作都是基于手机验证,登录也是可以的:当用户输入密码超过3次时,要求用户输入验证码(最好使用滑动验证)。当用户输入密码超过10次时,会弹出手机验证,要求用户使用手机验证码和密码双重验证才能登录。手机验证码的防刷是另一个问题,这将这里就不展开了,以后有时间再说说我们在防刷验证码方面做了什么。伪代码如下:fail_count=get_from_redis(fail_username)iffail_count>3:ifcaptchaisNone:returnerror('需要验证码')check_captcha(captcha)iffail_count>10:#超过10次,使用验证码和密码登录inifdynamic_codeisNone:returnerror('请输入手机验证码')ifnotvalidate_dynamic_code(username,dynamic_code):delete_dynamic_code(username)returnerror('手机验证码错误')success=do_login(username,password,dynamic_code)ifnotsuccess:set_redis(fail_username,fail_count+1)我们结合上面的同时,加入手机验证码的验证方式,基本上可以防止相当数量的恶意攻击者。但是没有一个系统是绝对安全的,我们只能尽可能地增加攻击者的攻击成本。您可以根据自己网站的实际情况选择合适的策略。中间人攻击?什么是中间人攻击?中间人攻击(简称MITM),简单的说就是在A和B的通信过程中,攻击者获取或修改A和B的通信内容。例如:小白寄快递到小黄,途中经过A快递点,小黑躲在A快递点,或者干脆开一个B快递点冒充A快递点。然后偷偷打开小白的快递给小黄看看里面是什么.甚至可以留着小白的快递,然后装个一毛钱一样的盒子,寄给小黄。在登录过程中,如果攻击者嗅探客户端向服务器发送的登录请求,就可以轻松获取用户的用户名和密码。①HTTPS是防止中间人攻击最简单有效的操作。替换HTTPS,修改网站所有HTTP请求,强制使用HTTPS。为什么HTTPS可以防止中间人攻击?HTTPS实际上是在HTTP和TCP协议之间加入了SSL/TLS协议来保证数据传输的安全。与HTTP相比,HTTPS主要有以下特点:内容加密数据完整性认证HTTPS的具体原理这里就不展开了,大家可以自行google。②加密传输除了HTTPS,我们还可以手动加密传输敏感数据:用户名可以在客户端采用非对称加密方式进行加密,在服务器端进行解密。可以在客户端进行MD5后传输密码,防止密码明文泄露。除了上面我们讲到的,其实还有很多其他的工作可以考虑,比如:操作日志,用户的每一次登录和敏感操作都需要记录下来(包括IP,设备等)。对于异常操作或者登录提醒,有了上面的操作日志,我们就可以根据日志进行风险提示。例如,当用户登录异常、修改密码、登录异常时,可以向用户发送短信提醒。拒绝弱密码。注册或修改密码时,不允许用户设置弱密码。为了防止用户名被遍历,有些网站在注册时输入用户名后会提示用户名是否存在。这样会存在网站所有用户名被泄露的风险(遍历接口即可),需要在交互或逻辑上进行限制。...后记现在国家不断出台各种法律,越来越重视用户数据。作为开发者,我们还需要做更多的工作来保护用户数据和用户隐私。后面也会跟大家聊一聊我们在数据安全方面都做了哪些工作,希望能给大家一点帮助。作者:哒哒哒哒代码编辑:陶家龙来源:juejin.im/post/6859214952704999438