Reinventing authentication

Arseni Mourzenko
Founder and lead developer
December 28, 2017
Tags: security 8 user-experience 10

I'm de­light­ed by the sim­plic­i­ty of OAuth 2.0 (as far as its in­te­gra­tion into Flask and ex­press takes takes less than five min­utes) and the fact that it makes pass­word man­age­ment some­one else's prob­lem.¹ Re­al­ly, I'm so de­light­ed that I now use it in every brows­er-based ap­pli­ca­tion I main­tain, in­clud­ing this blog.

How­ev­er—and there should al­ways be a how­ev­er, oth­er­wise, there would be no blog post—I feel that I reached its lim­its in terms of how I imag­ine the au­then­ti­ca­tion work­flow. There are, for me, three ma­jor lim­i­ta­tions:

SSL client cer­tifi­cates

It doesn't make friends with oth­er au­then­ti­ca­tion mech­a­nisms. This is a heavy lim­i­ta­tion, since makes it im­pos­si­ble to use in a con­text of SSL client cer­tifi­cates I'm push­ing to use on every REST ser­vice I main­tain.

User ex­pe­ri­ence

It pro­vides a ter­ri­ble user ex­pe­ri­ence with way too many redi­rects. With poor la­ten­cy, such as in a sub­way or a ho­tel Wi-Fi, this quick­ly be­comes an­noy­ing.

OAuth's flaw, in this way, is to rely on client com­mu­ni­ca­tion only. This makes the ex­change un­nec­es­sar­i­ly com­plex. If one could af­ford com­mu­ni­ca­tion be­tween the ap­pli­ca­tion and the au­then­ti­ca­tion ser­vice, things be­come much, much sim­pler, and have two ma­jor ben­e­fits: they tremen­dous­ly (I hope I have se­ri­ous proof for such a strong word) re­duce the band­width us­age and the num­ber of redi­rects.

The pur­pose of the ap­pli­ca­tion is to know whether the user au­then­ti­cat­ed us­ing a third-par­ty ser­vice, and if yes, who is this user. This means that the work­flow can be as sim­ple as that:

What hap­pens here is that when the user reach­es the home page of the ap­pli­ca­tion, he may click on the lo­gin but­ton which di­rect­ly di­rects the user to the au­then­ti­ca­tion ser­vice. As soon as he au­then­ti­cates, the ser­vice gets the user back to the ap­pli­ca­tion. At this point, the ap­pli­ca­tion doesn't know yet if the user was au­then­ti­cat­ed or not, and does a serv­er-side re­quest to the au­then­ti­ca­tion ser­vice. If the user ac­tu­al­ly au­then­ti­cat­ed, the ser­vice re­sponds with a JSON con­tain­ing the in­for­ma­tion about the user, such as the first and last name or the pro­file pic­ture. If the user only pre­tend­ed to au­then­ti­cate, the app will know that through the same re­quest.

Se­cu­ri­ty lev­els

It doesn't have a sim­ple, straight­for­ward way to mix high-se­cu­ri­ty au­then­ti­ca­tion with low-se­cu­ri­ty one. OK, that wasn't par­tic­u­lar­ly clear, so let me ex­plain.

In an ap­pli­ca­tion, there could be ac­tions which re­quire to be ab­solute­ly sure that the user who per­forms them is the ac­tu­al user, and there could be oth­er ac­tions which are so mi­nor, that if a hack­er would gain ac­cess to them, it wouldn't be a big deal. While the ones which are sen­si­tive may re­quire strong pass­words, two-fac­tor au­then­ti­ca­tion, or even some­thing more se­cure, the oth­er ones may, some­times, be per­fect­ly fine with a sim­ple four-dig­its pin code.

By chance, in many cas­es, the ac­tions one needs to per­form on a move (in a sub­way, or when us­ing some­one else's PC) are those non se­cu­ri­ty-crit­i­cal ones. This means that in those cir­cum­stances, one can fall­back to a less se­cure but more con­ve­nient way to au­then­ti­cate. In some cas­es, it could even in­crease the se­cu­ri­ty; for in­stance, I'm not par­tic­u­lar­ly hap­py en­ter­ing my Google pass­word on a PC I don't trust, and would pre­fer en­ter­ing a one-time key.

Every­thing is an au­then­ti­ca­tion means

A com­mon mis­take is to con­sid­er that a pass­word re­set pro­ce­dure has some­thing spe­cial, which makes it dif­fer­ent from... an or­di­nary au­then­ti­ca­tion.

From users' per­spec­tive, it may make sense only be­cause “it was al­ways done this way,” which is not a valid rea­son. In re­al­i­ty, it's just a mean to get ac­cess to the ac­count—prob­a­bly a la­bo­ri­ous mean, but still, noth­ing more than that.

From de­vel­op­ers' per­spec­tive, it doesn't make sense what­so­ev­er, makes the busi­ness log­ic much more dif­fi­cult, and of­ten re­duces se­cu­ri­ty. In gen­er­al, de­vel­op­ers fo­cus on the pri­ma­ry au­then­ti­ca­tion mech­a­nism, try­ing to make it se­cure (al­though many are still at the stage at which hash­ing the pass­word with MD5 would im­prove se­cu­ri­ty), but com­plete­ly lose the se­cu­ri­ty per­spec­tive when de­sign­ing the pass­word re­set pro­ce­dure. This leads to tech­niques such as: “Call us and tell us your birth­day date, and we'll re­set your pass­word” or “Hey, we emailed you the new pass­word” which in­evitably leads to pub­lic dis­as­ter. You can get what­ev­er se­cu­ri­ty you want, 2-fac­tor au­then­ti­ca­tion in­clud­ed, if you give the ac­cess away for any ac­count as soon as a guy calls the sup­port, it takes no ef­fort to have what­ev­er ac­cess one wants to an ac­count.

Com­bined with what I said in the pre­vi­ous sec­tion, a dif­fer­ent way of imag­in­ing the sys­tem is to con­sid­er that the per­son has one or sev­er­al strong au­then­ti­ca­tion means, and one or sev­er­al... less strong ones. As the or­di­nary ones are used to gain ac­cess to all but the most se­cu­ri­ty-crit­i­cal fea­tures of the ap­pli­ca­tion, the strong ones al­low to man­age the au­then­ti­ca­tion means them­selves. In prac­tice, it gives a very in­tu­itive way of han­dling ac­count se­cu­ri­ty for the user. Imag­ine a user has three au­then­ti­ca­tion means:

An ac­cess with a sim­ple PIN doesn't get much ac­cess. An ac­cess with a smart card, be­ing much more se­cure, gives ac­cess to the max­i­mum num­ber of fea­tures. One of the fea­tures is to be able to add oth­er au­then­ti­ca­tion means.

Cur­rent­ly, the prob­lem is that if the user los­es his smart card or for­gets the PIN code, there is noth­ing he can do to ac­cess the ac­count. This is un­for­tu­nate. To be safe, the user can add an­oth­er lev­el four au­then­ti­ca­tion means:

Here, the user added Face­book OpenID with 2-fac­tor au­then­ti­ca­tion, be­cause it is sim­ple and straight­for­ward, but it doesn't give too much ac­cess. To have a re­cov­er ca­pa­bil­i­ty, the user also added a lev­el four pro­ce­dure which makes it pos­si­ble to re­set the pass­word by se­cu­ri­ty staff af­ter show­ing an ID.

This leads to a clear, easy to un­der­stand sys­tem which can in­te­grate with­out much dif­fi­cul­ty more orig­i­nal ways to au­then­ti­cate, such as SSL client cer­tifi­cates. More­over, be­ing in­tu­itive, it in­creas­es se­cu­ri­ty by as­sign­ing se­cu­ri­ty lev­els to au­then­ti­ca­tion ways and us­ing those lev­els to al­low or deny spe­cif­ic ac­tions with­in the sys­tem, as well as as­sum­ing that every­thing which re­sults into get­ting an ac­cess to the ac­count is au­then­ti­ca­tion.

1 Come on, I know the dif­fer­ence be­tween au­then­ti­ca­tion and au­tho­riza­tion. The fact is, while be­ing de­signed for one thing, OAuth 2.0 found it­self to be used for both things. I'm fine with that.