Is your login interface really secure?

Author: da da da da beat Code

https://juejin.im/post/6859214952704999438

Preface

When everyone learns to write programs, the first line of code is all hello world. But when you start to learn WEB background technology, the first function of many people is to write login (softly: I don't know others, I am anyway).
But when I interviewed or communicated with many classmates with short work experience, I found that many classmates wrote on their resumes:, 负责项目的登录/注册功能模块的开发和设计工作but they simply implemented the functional logic and did not consider too much in terms of safety. This article is mainly to chat with you. When designing a login interface, it is not only a functional realization, but also what we need to consider in terms of security.

Security Risk

Brute force!

As long as the website is exposed on the public network, there is a high probability that it will be targeted. Try to blast this simple and effective way:
After obtaining the user name of the website in various ways, write a program to traverse all possible Password until the correct password is found

The pseudo code is as follows:

# 密码字典
password\_dict = \[\]
# 登录接口
login\_url = ''
def attack(username):
 for password in password\_dict:
     data = {'username': username, 'password': password}
       content = requests.post(login\_url, data).content.decode('utf-8')
       if 'login success' in content:
           print('got it! password is : %s' % password)

So how do we prevent this situation?

Verification code

A smart classmate just thought of it, I can add verification code verification when its password is incorrect for a certain number of times! For example, we set that when the user's password is incorrect for 3 times, the user is required to enter the image verification code to continue the login operation:

The pseudo code is as follows:

fail\_count = get\_from\_redis(fail\_username)
if fail\_count >= 3:
 if captcha is None:
  return error('需要验证码')
    check\_captcha(captcha)
success = do\_login(username, password)
if not success:
 set\_redis(fail\_username, fail\_count + 1)

The pseudo code does not consider concurrency, and the actual development can consider locking.

This can indeed filter out some illegal attacks, but with the current OCR technology, ordinary image verification codes are really difficult to effectively prevent robots (we have suffered a lot from this). Search for the public ordinate: rHub , [   ] to get the introduction tutorial for the front and back ends! Of course, we can also spend money to buy a verification scheme similar to the sliding verification provided by the third party company, but it is not 100% safe and can be cracked (a painful lesson).

Login restrictions

At this time, some students said that I can directly restrict the login operation of abnormal users. When the password error reaches a certain number of times, the user's login will be directly rejected, and the user will be restored after a period of time. For example, when we set an account to log in with 10 errors, all login operations of the account will be rejected within 5 minutes.

The pseudo code is as follows:

fail\_count = get\_from\_redis(fail\_username)
locked = get\_from\_redis(lock\_username)

if locked:
 return error('拒绝登录')
if fail\_count >= 3:
 if captcha is None:
  return error('需要验证码')
    check\_captcha(captcha) 
success = do\_login(username, password)
if not success:
 set\_redis(fail\_username, fail\_count + 1)
    if fail\_count + 1 >= 10:
     # 失败超过10次,设置锁定标记
     set\_redis(lock\_username, true, 300s)

Umm, this can indeed solve the problem of user password being blasted. However, this will bring another risk: Although the attacker cannot obtain the user information of the website, it can prevent all users of our website from logging in!
The attacker only needs to loop through all the usernames (even if none, random) to log in, then these users will always be locked, causing normal users to be unable to log in to the website!

IP restrictions

Since it is not possible to directly target the user name, we can deal with the IP address. If the attacker's IP is blocked directly, everything will be fine. We can set that when the number of errors in calling the login interface under a certain IP reaches a certain amount, the IP is prohibited from logging in.

The pseudo code is as follows:

ip = request\['IP'\]
fail\_count = get\_from\_redis(fail\_ip)
if fail\_count > 10:
 return error('拒绝登录')
# 其它逻辑
# do something()
success = do\_login(username, password)
if not success:
 set\_redis(fail\_ip, true, 300s)

This can also solve the problem to a certain extent. In fact, many current limiting operations are performed on IP. For example, the current limiting module of nginx can limit the number of accesses of an IP within a unit time.
But there are still problems here:

  • For example, many schools and companies now use the same export IP. If you directly restrict the IP, you may accidentally kill other normal users.

  • With so many VPNs now, attackers can switch VPNs to attack after the IP is blocked

Phone verification

Isn't there a better way to prevent it? Of course there is. We can see that in recent years, almost all applications have allowed users to bind their mobile phones. One is the country’s real-name policy requirements, and the second is that mobile phones are basically the same as ID cards and can basically represent a person’s identity. So many security operations are based on mobile phone verification, and login is also possible.

  1. When the user enters the password more than 3 times, the user is required to enter the verification code (slide verification is best)

  2. When the user enters the password more than 10 times, the mobile phone verification pops up, requiring the user to log in with the mobile phone verification code and password dual authentication

Mobile phone verification code anti-swipe is another issue. I will not start here. I will talk about what we have done in the future when we have time.

The pseudo code is as follows:

fail\_count = get\_from\_redis(fail\_username)

if fail\_count > 3:
 if captcha is None:
  return error('需要验证码')
    check\_captcha(captcha) 
    
if fail\_count > 10:
 # 大于10次,使用验证码和密码登录
 if dynamic\_code is None:
     return error('请输入手机验证码')
    if not validate\_dynamic\_code(username, dynamic\_code):
     delete\_dynamic\_code(username)
     return error('手机验证码错误')

 success = do\_login(username, password, dynamic\_code)
    
 if not success:
     set\_redis(fail\_username, fail\_count + 1)

We have combined the methods mentioned above and added the verification mode of the mobile phone verification code, which can basically prevent a considerable number of malicious attackers. But no system is absolutely secure, we can only increase the attacker's cost as much as possible. You can choose the appropriate strategy according to the actual situation of your website. Search for the public vertical number: b , follow the reply [  vue  ] to get the introductory tutorial for the front and back ends!

Man in the middle attack?

What is a man in the middle attack

***Man-in-the-middle attack (abbreviated to MITM)***. Simply put, during the communication between A and B, the attacker obtains or modifies A through sniffing, interception, etc. The content of communication with B.

Take a chestnut: To  小白send 小黄a courier, you have to pass through courier point A on the way, 小黑and hide at courier point A, or simply open a courier point B to pretend to be courier point A. Then secretly demolished 小白to 小黄express, to see what's inside stuff. You can even leave 小白the courier behind, pack a dime box and send it to you 小黄.

During the login process, if the attacker sniffs the login request sent from the client to the server, he can easily obtain the user's username and password.

HTTPS

The simplest and most effective operation to prevent man-in-the-middle attacks is to replace HTTPS and modify all HTTP requests in the website to force the use of HTTPS.

*** Why can HTTPS prevent man-in-the-middle attacks? ***
HTTPS actually adds the SSL/TLS protocol between the HTTP and TCP protocols to ensure the safe transmission of data. Compared with HTTP, HTTPS has the following characteristics:

  • Content encryption

  • Data integrity

  • Authentication

The specific HTTPS principle is no longer extended here, you can Google

Encrypted transmission

In addition to HTTPS, we can also manually encrypt and transmit sensitive data:

  • Username can use asymmetric encryption on the client and decrypt on the server

  • The password can be transmitted after MD5 on the client to prevent the plaintext of the password from being exposed

other

In addition to the above we talked about, there are actually many other tasks to consider, such as:

  • Operation log , each user's login and sensitive operations need to record logs (including IP, equipment, etc.)

  • Abnormal operation or login reminder . With the above operation log, we can make risk reminders based on the log. For example, when the user is logging in, changing the password, or logging in abnormally, the user can be notified by SMS

  • When rejecting weak password  registration or changing passwords, users are not allowed to set weak passwords

  • Prevent user name from being traversed  . When registering some websites, after entering the user name, it will prompt whether the user name exists. In this way, there is a risk that all user names of the website will be leaked (just traverse the interface), which requires interactive or logical restrictions

  • ...

postscript

Now the country is constantly promulgating various laws, and more and more attention is paid to user data. As developers, we also need to do more to protect user data and user privacy. I will also talk to you later, what we have done in terms of data security, I hope I can give you a little help.

There is no way, but the technique can be achieved; if there is no way, it ends with the technique

Welcome everyone to follow the Java Way public account

Good article, I am reading ❤️

Guess you like

Origin blog.csdn.net/hollis_chuang/article/details/108480423
Recommended