Work record > > solution to prevent swipe of login SMS verification code

Time:2019-11-8

I. write in the front


In the history of Internet development, security is always a hot topic. You have security shield and I have broken shield spear. The so-called “one foot high” and “one foot high”, but internet security is also developing slowly in this kind of attack and defense.

But today’s writing is not as tall as the above, just a small anti brush solution.

This is often encountered in the work, and only one record is made here for review.

If there is any lack of preciseness or perfection, please correct it. Thank you

II. Scene introduction and problem highlighting


Scenario: in the blockchain shared travel platform we made for XX, the login of the blockchain browser system is based on the user’s mobile number + verification code.

Because it’s used by internal users and there is no special security processing in logging in, our test brother blew it up during the test (like the test brother here).

By this point, we must have received a bug, business expectation.

1: the same IP is limited to 5 times in a minute

2: if it is more than 5 times, it will be locked for 1 hour. During the locking period, it is necessary to add picture verification code to obtain SMS

After receiving this requirement, we made a simple current limiting and brush preventing function with redis.

III. solutions


First, analyze the requirements,

1: restrict the same IP

2: limit the number of times per unit time

Using redis to realize ideas

1: when a request for SMS verification code comes, we first determine whether the IP address has been locked (the number of accesses per unit time exceeds the limit)

2: if it is not locked, judge whether the IP is accessed for the first time. If it is, add a life cycle to the IP and record the number of accesses.

3: if it is not the first visit, judge whether it meets the limit requirements in unit time.

To complete these three, we do not need to define three keys in redis

msg_lock_key_{ip}Record times IP locked

msg_time_key_{ip}Record IP per unit time

msg_counter_key_{ip}Record IP access times per unit time

Let’s go straight to the last piece of code,

public boolean checkMsgFrequency(String remotIp) {
        String romteIpString = remotIp.replace(".", "");

        //1: judge whether this IP has been restricted
        String msgLockKey = Constants.API_MSG_LOCK_KEY + romteIpString;
        if (jedis.exists(msgLockKey)) {
            //This IP has been locked
            Logger.info ("this IP [{}] exceeds the specified access frequency key: {}", remotip, msglockkey);
            return false;
        }

        //2: judge whether this IP has been accessed within the specified time
        String msgTimeKey = Constants.API_MSG_TIME_KEY + romteIpString;
        String msgCounterKey = Constants.API_MSG_COUNTER_KEY + romteIpString;
        //Key does not exist
        if (!jedis.exists(msgTimeKey)) {
            //Join cache
            jedis.setEx(msgTimeKey, "0", imageCode.getLimitTime());
            jedis.setEx(msgCounterKey, "1", imageCode.getLimitTime());
        }

        if (jedis.exists(msgTimeKey) && (jedis.incrBy(msgCounterKey, 1) > imageCode.getLimitCounter())) {
            Logger.info ("this IP [{}] exceeds the specified access frequency, and locks the key: {}", remotip, msgtimekey);
            jedis.setEx(msgLockKey, "0", imageCode.getLimitlockTime());
            return false;
        }
        return true;
    }

This is a simple code implementation. Logic is this logic. There are many ways to implement it.

You can use spring AOP + custom annotation to repackage the logic.

You can also use the redis + Lua script to subpackage the above three-step logic.

This depends on the individual, the important understanding of the realization of ideas, the realization of ten million ways there is always a suitable for you.

Four, summary


For the current limiting and anti brushing of rare resources, the access frequency or times per unit time is generally limited.

We are mainly to understand its solution to the problem, rather than remember the implementation code.

Main ideas:

1: check whether the current request resource is locked for the secondary request (IP or uid).

2: if it is not locked, add a life cycle (i.e. a time limit unit) to the request, and record the number of accesses.

3: then judge whether the request meets the locking condition

The general idea is these three steps.

This record is to deepen your memory, at the same time, so as to warm up, if it can help you, very happy.

If there is something wrong, please leave a message and correct it. Thank you!

If you have better ideas, welcome to exchange