Yesterday I saw a post on Zhihu, the Chinese Quora, asking why some popular websites adopted QR code as the default login method and also the security concerns behind it. I didn’t see an answer that truly answers the question, so I decided to speak out my thoughts.

If the following reasoning doesn’t interest you, you might also jump to the “Conclusion” section.

How does login work?

Let me briefly introduce the process that a user logs on a website.

  1. When you visit the website for the first time, the website will start a session.
    • The session is stored on the website server. The server internally keeps the information and gives a unique session_id to the browser.
    • After that, every time you visit the website, your browser will send the session_id to the server.
    • The server knows which session it is by session_id. Although this session_id might be seen by someone else, remember that only the server knows the information of the corresponding session because the server is the only one that has it.
  2. When you have not logged in yet, the session corresponding to the session_id contains the information that says “this user has not logged in yet.” Therefore, the server shows you contents for guests.
  3. You visit the login page. Fill in username and password. Click the login button.
  4. Your browser sends your username and password to the server.
  5. The server checks its database and confirms your identity. So, it updates the session corresponding to the session_id, keeping something like “This user has logged in, with username xxx.”
  6. You revisit the website. Your browser sends the same session_id again to the server. The server checks the corresponding session, finds that you have already logged in, and knows which user you are. Therefore, the server can send you the page that only you can see.

By the way, session_id is usually stored in cookies. But it can also be stored and passed to the server using some other methods.

How does login with QR code work?

Look at the above process again. We can find that the browser has not much interesting to do other than sending the same session_id to the server again and again, and rendering what the server returns. It is the server that decides what users see.

So, we need to focus on how to let the server update the session from guest to logged in. You must show something to prove yourselves to the server. Otherwise, you can login anyone else’s bank account. In the previous example, the username and password combination is the identification. Login with QR code gives another way to prove your identity to the server.

Here is the process of logging in with QR code.

  1. When you visit the login page, your browser will send the session_id as before. The server assigns a login_token to the session.
    • There is a link qr_verify_url that will be used to confirm your login.
    • login_token will be needed by qr_verify_url.
    • The website shows qr_verify_url together with login_token as a QR code.
  2. You scan the QR code with the website’s smartphone App which you have already logged in. Now your App knows the qr_verify_url and the login_token.
    • Notice that you must do it with the website’s App, not any other QR code scanner.
    • Notice that you must have logged into the App before, which means that there is a secret app_token binding to your account that only your App and the server know.
  3. The App shows you a confirmation, saying that it is a login request. If you confirm that it is you, click the login button.
  4. After your confirmation, the App sends login_token and app_token to the qr_verify_url.
  5. The server verifies app_token and login_token, and find both valid. It then finds the session_id corresponding to the login_token. The rest process is the same as the password login. The server updates the session information corresponding to session_id.
  6. Meanwhile, the browser keeps asking the server: “Has the session corresponding to session_id logged in yet?” Once the browser finds the login successful, it will redirect to some logged in page. Everything is done.
  7. Since the server knows the session corresponding to session_id has logged in, it will show you logged-in version every time you visit the website.

For Example

Let me take Taobao as an example. You can see a big QR code on the login page.


We can examine it using some online QR code reader


It’s a short URL. Let’s see what’s in the link.


The url variable keeps qr_verify_url together with login_token. And where is the session_id? Look at your browser. It should be visiting the server again and again. The session_id can be some values of the cookies. It can also be that the server knows the session_id from the login_token.


Let’s scan the QR code with our Taobao App. Confirm the login. And we are done.


Security Concerns

Now that we know the login process let’s stand at attackers’ point, to see what attacks can be performed. I want to convince you that even if logging in with QR code doesn’t make it more secure, at least it is not worse compared to traditional password login.

Replace the QR Code (Man-in-the-Middle Attack)

  1. The attacker visits the login page and gets a QR code.
  2. The attacker hijacks the user’s traffic somehow. When the user visits the login page, the QR code will be replaced with the attacker’s.
  3. The user doesn’t know something goes wrong, scans the code and click the confirm button.
  4. The attacker logs in successfully.

This was a feasible attack plan. It no longer is nowadays, especially for popular websites. Popular websites use HTTPS protocol to ensure the transmission security. Compared to HTTP protocol, HTTPS encrypt the message so that only the server can decrypt it. It’s still almost impossible to crack the encryption, even for supercomputers.

That is to say, the attacker does not even know you are visiting the login page, not to mention tempering with it.

Replace the QR Code (Malicious Browser Plugins or Virus)

  1. The user accidentally installed some malicious browser plugins or virus.
  2. The QR code on the login page is replaced with the attacker’s by the malicious plugin or the virus.
  3. The attacker logs in successfully.

It is feasible, even for today. But this is not a problem introduced by QR code login. Users suffer from malicious software for quite a long time. Malicious software can do everything they want. They can replace the login page with some phishing website. They can also record users’ keyboard if they use traditional password login. So, this is not a new problem.

Scan QR code at the wrong time

  1. The attacker put up a QR code on his/her Twitter/Facebook.
  2. The user scans the QR code.
  3. The App seriously asks the user to confirm it is the user himself/herself trying to log in now.
  4. Although the user is not trying to log on the website now, the user just somehow feels the mission to click on the confirm button.
  5. The attacker logs in successfully.

It’s feasible theoretically but still not a new problem. With traditional password login, the attacker could make up some fancy words to induce users to hand out their username and password.

There is more obstacle for this attack to succeed. The QR code might change frequently. In the previous Taobao example, the QR code changes every one minute. If the attacker posts the QR code on the Facebook, then he/she must have thousands of super fans so that someone will scan the QR code within one minute.

The attacker scanned the QR code showed on my monitor

This is entirely a joke because now you successfully logged in the attacker’s account. No attacker does this.

Missing Smartphone

  1. The attacker stole the user’s smartphone somehow.
  2. The attacker breaks the PIN/TouchID/FaceID somehow (which is an amazing work by the way).
  3. The attacker visits the login page and scans the QR code with the App.
  4. The attacker logs in successfully.

This is another joke and an old problem. Since the attacker can use the App on the user’s smartphone, why bother logging in on a computer?

Besides, missing smartphone introduces lots of security problems. It’s a well-known issue. Not something new with QR code login.

QR Code to Phishing Websites

What if the attacker made a QR Code pointing to a phishing website? In fact, it doesn’t work.

Remember there is an app_token. The App won’t send it to websites other than its own. Without app_token, the attacker cannot log in.

QR Code to Malicious Smartphone Software

It’s still an old problem. Users click on malicious links and get malicious software installed. They suffer it for a long time. It’s not news.

Crack the Smartphone App

  1. The attacker hacks into your smartphone.
  2. The attacker cracks the App and finds the app_token.
  3. The attacker sends app_token together with login_token to qrcode_verify_url and confirm the login.

It might work, but it’s very hard.

  1. It’s very hard to hack into a smartphone and get root access, especially remotely.
  2. The app_token might be encrypted. It’s also hard to decrypt.
  3. The server might also check other information other than app_token and login_token. It takes time to figure it out.

Better App and website design can make this attack almost impossible.

Some Potential Benefits that QR Code Login Brings

Avoid Leaking Password

Typing the password might be seen by the attacker or recorded by a camera. The password might leak when the user types it. QR Code login, on the other hand, requires the App to send secret messages in the background which is not visible to human eyes or cameras. If the network traffic is encrypted (it should), the attacker cannot eavesdrop either.

Replace a General Token with a Specific Token

The password is a general token. You use it all over the network. The app_token on the other hand, is a specific token. It is used only by the smartphone App.

If the password is leaked somehow, the attacker knows how to log on the website. The attacker might also succeed to log on other websites because most users use the same password for all sites. Even if app_token is leaked somehow, the attacker could at most log on the website, not any other.

Replace a Long-term Token with a Short-term Token

The password is usually a long-term token. Most users don’t change their passwords frequently. On the other hand, login_token could expire in minutes. app_token could also expire if the user doesn’t use the App for some time. Users can also invalidate the app_token on the website by clicking “remove this device” as soon as the user loses the smartphone.


Some users have to try different passwords every time they are logging in. Some users type very slow. Some users have complicated passwords. It might be painful for some users to type passwords to log in. On the other hand, open the App and scan the QR code may be more comfortable.

Harsh Reality

It seems that QR code beats password. Well, not quite. There are some premises for QR code login to be secure. If some of them are false, it might be vulnerable.


Websites rely on HTTPS to avoid the content being tampered. Inappropriate configuration might also cause problems. For example,

  • The server doesn’t force HTTPS connection. The attacker could force the user to visit the website with HTTP.
  • CDN isn’t configured correctly. HTTPS might degrade to HTTP.
  • The website allows HTTP content (such as javascript scripts) inside an HTTPS page. The attacker can insert malicious code into javascript scripts in order to replace the QR code.

Program Bugs

For example,

  • The App sends app_token to any websites.
  • The App doesn’t force HTTPS connection.
  • The expiration time of the QR code is too long.

User Education

If users don’t have some basic security awareness, they expose themselves to all kinds of attacks. For example,

  • Install malicious software on computers or smartphones
  • Jump to the attacker’s bait
  • Don’t treat the confirmation text seriously.


In my opinion, login with QR code at least does not introduce new security issues, if it doesn’t improve security a little bit. But for this statement to fulfill, websites and users should work together. Websites should avoid bugs and bad design on security. Users should have more security awareness.