Things to keep in mind concerning CSRF attacks

The first mile­stone re­leases of Vert.x 4.0.0 suf­fered from CVE-2020-35217. Thanks to Xhe­lal, we were able to ad­dress the se­cu­rity bugs and fix it on the first beta. This blog post is a ex­pla­na­tion why CSRF should be used in your web ap­pli­ca­tions.

Be aware of the danger: Cross-Site Request Forgery (CSRF)

A pop­u­lar web vul­ner­a­bil­ity that has at­tracted a lot of at­ten­tion in the re­search com­mu­nity is Cross-​Site Script­ing (XSS). This vul­ner­a­bil­ity al­lows the at­tacker to in­ject ar­bi­trary JavaScript (JS) code on a web­site that will run in the same ori­gin as the web­site. Ac­cord­ing to the Open Web Ap­pli­ca­tion Se­cu­rity Project (OWASP), XSS is the sec­ond most preva­lent issue in the 2017’s OWASP Top [1], and it is found in around two-​thirds of all web ap­pli­ca­tions. How­ever, while XSS gets all the at­ten­tion, few de­vel­op­ers pay at­ten­tion to an­other at­tack that can be equally de­struc­tive and far eas­ier to ex­ploit. This at­tack is called Cross-​Site Re­quest Forgery (CSRF). It was ranked by OWASP as the fifth most dan­ger­ous web vul­ner­a­bil­ity twice (2007, 2010) and eighth in 2013. For­tu­nately, the de­vel­op­ers’ aware­ness has in­creased in re­cent years and most web frame­works pro­vide at least one de­fen­sive mech­a­nism against CSRF. As a re­sult, CSRF was not listed in the 2017’s OWASP Top 10 list. Un­for­tu­nately, this at­tack is far from ex­tinct.

CSRF Origins

In 1988 Norm Hardy pub­lished a paper where he ex­plained a the­o­ret­i­cal se­cu­rity issue that he called “con­fused deputy” [2]. This se­cu­rity issue was first re­ported in 2000 in Bug­Traq (nowa­days Se­cu­ri­ty­Fo­cus [3]). The post[4] in Bug­Traq showed how ZOPE, a Python web frame­work, was vul­ner­a­ble to this web “con­fused deputy” that we today know as CSRF. This term (“CSRF”) was first used in June 2001 by Peter Watkins, fol­lowed by a de­tailed de­scrip­tion in 2004 by Thomas Schreiber [5]. The au­thor de­scribed a va­ri­ety of at­tack sce­nar­ios where CSRF could be ex­ploited, pro­vid­ing the most de­tailed de­scrip­tion of the prob­lem at the time. Since then CSRF has had many names such as XSRF, one-​click at­tack, Cross-​Site Ref­er­ence Forgery, ses­sion rid­ing, sea surf, hos­tile link­ing, “sleep­ing giant” etc. For the rest of this blog, we will refer to this vul­ner­a­bil­ity as CSRF.

How does CSRF exactly work?

There are many de­f­i­n­i­tions for it in the lit­er­a­ture, but the core idea re­mains the same; in a CSRF at­tack the vic­tim’s browser is tricked by an at­tacker into send­ing a state-​changing HTTP re­quest with au­then­ti­ca­tion cook­ies, which the vic­tim did not in­tend. This ex­ploits the fact that cook­ies are widely used on the in­ter­net and browsers au­to­mat­i­cally at­tach them to re­quests [6]. For in­stance, on­line shops, so­cial net­works, web­mail ap­pli­ca­tions, etc. use cook­ies to main­tain state and track/re-​identify users with­out need­ing to reau­then­ti­cate. The rea­son cook­ies are used is be­cause HTTP is a state­less pro­to­col. The server re­sponds to a re­ceived re­quest and then “for­gets” about the con­nec­tion. To pre­vent this state­less­ness of HTTP, the au­then­ti­ca­tion in­for­ma­tion is stored some­where in the server-​side (e.g. ses­sion store, data­base, etc.) and the browser re­ceives only an iden­ti­fier (ID) from the server for that ses­sion, often via a cookie. The browser stores this cookie and when a user sends a re­quest to the server, the browser will also au­to­mat­i­cally at­tach the cookie(s) for this web ap­pli­ca­tion. The server re­trieves the Ses­sion ID from the cookie and looks up in its ses­sion stor­age or data­base to re­trieve the user’s data, iden­ti­fied by the Ses­sion ID.

Many al­ter­na­tives exist when it comes to forg­ing a CSRF re­quest. If a state-​changing re­quest can be ex­e­cuted through HTTP GET, then an at­tacker can ex­ploit this in (mainly) two ways. One op­tion would be for the at­tacker to send an email that con­tains a HTML tag with the CSRF pay­load (e.g. <img src=”http://bank.com/trans­fer?amount=x&dest=y”/>). If the web­mail ap­pli­ca­tion loads HTML im­ages au­to­mat­i­cally, then the browser will send the HTTP GET re­quest and the CSRF at­tack suc­ceeds. The sec­ond op­tion is for the at­tacker to trick the user into vis­it­ing his ma­li­cious web­site, which con­tains the above HTML image tag. Note that the at­tacker is not lim­ited to only the <img> tag. The at­tack can be trig­gered by using dif­fer­ent HTML tags, which usu­ally pro­vide a src at­tribute. How­ever, in most cases, ap­pli­ca­tions per­form state-​changing re­quest through HTTP POST re­quests. In this case, the at­tacker has to cre­ate a hid­den JS form in his ma­li­cious web­site with the exact form fields that the server is ex­pect­ing. Then, the at­tacker can use JS’s events (e.g. on­load()) to au­to­mat­i­cally post the hid­den form when the vic­tim loads/vis­its the page.

CSRF can be con­sid­ered a type of the con­fused deputy at­tack where the web browser (con­fused deputy) is tricked into send­ing a forged re­quest (for a less priv­i­leged at­tacker) to a web ap­pli­ca­tion. A CSRF at­tack works be­cause, by de­sign, a web browser au­to­mat­i­cally at­taches all cook­ies that it has for the tar­get web ap­pli­ca­tion when a re­quest is sent. A server that does not pro­tect against CSRF would ac­cept and ex­e­cute the re­quest as com­ing from the vic­tim since the ses­sion cookie was part of the re­quest. What is worse, the vic­tim is not aware of the at­tack until when it is too late. The fig­ure below shows the steps of a com­mon CSRF at­tack. How­ever, some con­di­tions have to be ful­filled for the at­tack to work:

  • The at­tacker must find an un­pro­tected state-​changing op­er­a­tion in the tar­get web ap­pli­ca­tion.
  • The vic­tim must be al­ready au­then­ti­cated to the tar­get web ap­pli­ca­tion (i.e. a ses­sion cookie is al­ready stored in his/her browser).
  • The at­tacker must forge the state-​changing re­quest cor­rectly. This means that the at­tacker must in­clude all HTML form fields or re­quest pa­ra­me­ters that the server-​side ex­pects.
  • The at­tacker has to trick the au­then­ti­cated vic­tim into vis­it­ing the at­tacker’s web­site (where the CSRF at­tack will take place) or trick the vic­tim into click­ing a link.
  • The means for au­then­ti­ca­tion must be au­to­mat­i­cally at­tached to the re­quest by the browser (e.g. Basic Au­then­ti­ca­tion re­quest header [7] or cook­ies). Note that, dif­fer­ent from XSS, CSRF aims to reuse the ses­sion cookie, not steal it.

Impact of CSRF attacks

The im­pact of the at­tack de­pends on the spe­cific op­er­a­tion that is vul­ner­a­ble to CSRF, but also on the priv­i­leges that the vic­tim has. This can re­sult in a money trans­fer, change of pass­word, a pur­chase in a shop­ping web­site, ac­count com­pro­mise, cre­ated admin user, etc. Some­times CSRF can be even more dan­ger­ous than ses­sion hi­jack­ing. For in­stance, in a court case, the vic­tim can­not argue that he did not per­form a trans­ac­tion be­cause the IP of the re­quest (al­though un­in­tended) was that of the vic­tim. To makes things even worse, the vic­tim doesn’t even know which ma­li­cious web­site he vis­ited that trig­gered the CSRF at­tack. In the case of ses­sion hi­jack­ing, the ma­li­cious at­tacker logs in with stolen cre­den­tials (usu­ally) from an IP ad­dress dif­fer­ent from that of the vic­tim’s. There­fore, in this case, the vic­tim can argue that he was the vic­tim of an at­tack. There have also been other ex­am­ples of CSRF at­tacks that lead to re­mote code ex­e­cu­tion with root priv­i­leges [8] or com­pro­mise of a root cer­tifi­cate [9].

Some­times CSRF is mis­tak­enly con­fused with XSS, but they are two dif­fer­ent at­tacks. XSS aims to ex­e­cute ar­bi­trary JS code on a vul­ner­a­ble web­site. It abuses the trust that a client has in a cer­tain web ap­pli­ca­tion, thus click­ing the link. On the other hand, CSRF tricks the user’s browser to send un­in­tended HTTP re­quests to a vul­ner­a­ble web ap­pli­ca­tion. It ex­ploits the trust that a web ap­pli­ca­tion has in the user. The web ap­pli­ca­tion as­sumes that if a re­quest was re­ceived, then it orig­i­nated from the user (be­cause of the ses­sion cookie) and ex­e­cutes it. Ad­di­tion­ally, in a CSRF ex­ploit the at­tacker can trick the vic­tim’s browser to send an HTTP re­quest, but he can­not read the re­sponse of that re­quest while XSS can issue re­quests and also read the re­sponse. XSS at­tacks are based on JS, while CSRF at­tacks can also be car­ried out just by using a crafted HTML form. Fi­nally, if a web ap­pli­ca­tion is vul­ner­a­ble to XSS, then it is also vul­ner­a­ble to CSRF. How­ever, if a web ap­pli­ca­tion is safe from XSS, it might still be vul­ner­a­ble to CSRF.

Since its dis­cov­ery in 2001, there have been many re­ported CSRF at­tacks. Major web­sites such as Net­flix, Google, Yahoo, fi­nan­cial in­sti­tutes, Face­book, etc. have been vul­ner­a­ble to CSRF and in some cases even more than once. Some of the most fa­mous cases are:

  • The Net­flix web­site (2006): an at­tacker could add a DVD to the vic­tim’s shop­ping cart, change the ship­ping ad­dress of the vic­tim, or even com­pro­mise his/her ac­count.
  • New York Time’s web­site [10]: CSRF that leaks the email ad­dress of the user. It was used for spam­ming the vic­tims. The web­site kept users logged in for over a year.
  • ING Di­rect web ap­pli­ca­tion [10]: vul­ner­a­ble to a CSRF at­tack that al­lowed unau­tho­rized money trans­fers from vic­tim’s ac­count to the at­tacker’s ac­count.
  • YouTube [10]: The vul­ner­a­bil­ity al­lowed the at­tacker to per­form al­most all ac­tions that a user can nor­mally do.
  • Google, Yahoo, Pay­Pal (2008) [11] were vul­ner­a­ble to Login CSRF.
  • Face­book (2009) was vul­ner­a­ble to CSRF. The at­tacker could use an HTML <img> tag to steal the user’s ac­count in­for­ma­tion.
  • MetaFil­ter [10]: the vul­ner­a­bil­ity al­lowed an at­tacker to take con­trol of a user’s ac­count.
  • Twit­ter [12] was also vul­ner­a­ble to CSRF in 2010. When au­then­ti­cated users vis­ited the ma­li­cious web­site, they un­in­ten­tion­ally posted two tweets – one with a link lead­ing to this ma­li­cious web­site and an­other with a tweet about goats. Every user who clicked on the link pro­vided in the first tweet also posted those two tweets, hence the worm was spread.

Syn­chro­nizer Token Pat­tern (STP) [13] is one of the most pop­u­lar coun­ter­mea­sures. A se­cret, unguess­able, ran­dom value (known as CSRF token) is gen­er­ated on the server-​side using a cryptographically-​secure pseudo­ran­dom gen­er­a­tor (CSPRNG) with a ran­dom input/seed. The gen­er­ated token is stored in server-​side stor­age and must be tied to a spe­cific user (usu­ally linked to the Ses­sion ID). This stor­age can be a ses­sion data­s­tore (e.g. Redis), a data­base, a filesys­tem (e.g. in PHP), server’s mem­ory, etc. The CSRF token is sent as part of the server’s re­sponse and is usu­ally placed in a hid­den HTML form field. Once a re­quest ar­rives in server-​side, the server will use the Ses­sion ID from the ses­sion cookie (found in the in­com­ing re­quest) to ex­tract the CSRF token from the stor­age. It will then com­pare it against the CSRF token that came as part of the re­quest’s body (or in a cus­tom header).

Dou­ble Sub­mit Cookie [14] is an­other pop­u­lar coun­ter­mea­sure that makes use of cook­ies in­stead of ses­sion stor­age to store a CSRF token. The se­cu­rity of this coun­ter­mea­sure re­lies on the SOP. Only JS run­ning within the same ori­gin is al­lowed to read or mod­ify the cookie’s value. The server-​side gen­er­ates a CSRF token same as in the STP coun­ter­mea­sure. The server cre­ates a cookie with the CSRF token in it and sends both this cookie and the CSRF token (usu­ally in an HTML form) to the client-​side. When a re­quest is sent to the server-​side, this cookie that holds the CSRF token will be au­to­mat­i­cally sent by the browser in ad­di­tion to the CSRF token in the re­quest body/cus­tom header, hence the name “Dou­ble Sub­mit”. The server-​side will re­trieve the CSRF token from the cookie and com­pare against the CSRF token in the re­quest body/cus­tom HTTP re­quest header.

Great does not mean perfect!

Al­though anti-​CSRF de­fenses mit­i­gate CSRF at­tacks to a great ex­tent, they are not per­fect and may be sus­cep­ti­ble to dif­fer­ent at­tacks vec­tors:

Cryptography concerns

  • Use of un­safe func­tions for ran­dom­ness: the func­tion that is used to gen­er­ate CSRF to­kens/se­crets is cru­cial for se­cu­rity. Pseudo-​Random Num­ber Gen­er­a­tors (PRNG) are fast func­tions that out­put low-​quality ran­dom­ness and should not be used to gen­er­ate strings for crit­i­cal se­cu­rity op­er­a­tions. It is ad­vised to use cryptographically-​secure PRNG (CSPRNG) in­stead. They pro­vide enough ran­dom­ness/en­tropy in ex­change for longer gen­er­a­tion time. Most lan­guages pro­vide a CSPRNG [15] so make sure to check be­fore you end up using func­tions like Math.Ran­dom().
  • In­suf­fi­cient ran­dom­ness of the (CSRF) token: to­kens need to be ran­domly gen­er­ated (i.e. high en­tropy) so that it can­not be guessed or brute-​forced in a rea­son­able amount of time. In order to with­stand the com­pu­ta­tion power of today’s com­put­ers, to­kens needs to have an en­tropy of at least 128-bit to be con­sid­ered se­cure.
  • In­suf­fi­cient ran­dom­ness of the cryp­to­graphic key: in those cases when the CSRF token/cookie is signed and/or en­crypted (for ad­di­tional se­cu­rity or to pre­vent tam­per­ing), the se­cret key that is used for en­crypt­ing or sign­ing dur­ing token gen­er­a­tion might not be se­cure enough. The se­cret key should be ran­dom enough so that the at­tacker can­not eas­ily brute-​force it. De­vel­op­ers often copy and paste it from the doc­u­men­ta­tion code snip­pet or Stack Over­flow posts with­out re­al­iz­ing the risks.
  • Lack of key ro­ta­tion: se­cret keys should often be ro­tated. The life­time of the cryp­to­graphic key is im­por­tant and de­pends on many fac­tors as al­ready cov­ered in de­tail by OWASP [16].
  • Use of in­se­cure cryp­to­graphic al­go­rithms: a web frame­work might still be using an in­se­cure cryp­to­graphic al­go­rithm such as DES, MD-5, SHA-1, or use un­safe block ci­pher such as Elec­tronic Code Book (ECB). OWASP pro­vides de­tailed doc­u­men­ta­tion con­cern­ing cryp­to­graphic op­er­a­tions (as men­tioned above).
  • Use of dep­re­cated/un­patched cryp­to­graphic li­braries: the cryp­to­graphic al­go­rithms are often pro­vided by li­braries. An un­patched or dep­re­cated li­brary might be prob­lem­atic and de­vel­op­ers should al­ways be using the lat­est (patched) ver­sion.
  • In­se­cure stor­age of the ap­pli­ca­tion’s cryp­to­graphic key: aside from ran­dom­ness and key ro­ta­tion, its stor­age is also im­por­tant. Stor­ing a se­cret key hard­coded in the source code (or in some other in­se­cure lo­ca­tion) would com­pro­mise the key if the code is leaked or a (ma­li­cious) em­ployee has ac­cess to it.
  • Server-​side token stor­age: A pos­si­ble im­ple­men­ta­tion mis­take (for STP de­fense for ex­am­ple) would be the in­cor­rect map­ping user-​token be­tween the user and the CSRF se­cret that is stored on the server-​side. An in­cor­rect map­ping might lead to many users hav­ing the same token. If the at­tacker and vic­tim share the same token, the at­tacker can eas­ily forge a suc­cess­ful CSRF at­tack. Al­though this might sound as im­prob­a­ble, it has even hap­pened re­cently [17].

Token transmission from server-side to client-side

  • MITM at­tacks: Trans­mis­sion of the se­cret val­ues over HTTP is in­se­cure since a net­work at­tacker can per­form a tra­di­tional MITM at­tack by in­ter­cept­ing the re­quest and leak the CSRF token. Ad­di­tion­ally, SSL strip­ping at­tack or a more ad­vanced MITM [18] might be ex­ploited.
  • BREACH [19]: is an­other at­tack vec­tor that can leak the CSRF token using a compression-​based side-​channel if the HTTP re­sponse is com­pressed. This at­tack is pos­si­ble if the CSRF token is in the HTTP re­sponse body (which nor­mally is), along with some user-​specified input. The au­thors that dis­cov­ered BREACH showed how they leaked a CSRF token in 30 sec­onds in Mi­crosoft’s Out­look Web Ac­cess web­site.
  • Plac­ing the token in the URL: is a com­mon mis­take that might lead to CSRF token leak­age through log files, browser his­tory and Refer(r)er header. An­other trick is to re­trieve the CSRF token by using the so-​called “CSS His­tory Hack” [20].

HTTP(S) request with the CSRF token from client-side

  • Code in­jec­tion (XSS, Dan­gling Markup, CSS tricks): this cat­e­gory of at­tacks aims to leak the se­cret token by using JS (XSS), HTML (Dan­gling markup), or CSS. Any XSS vec­tor can be used to leak the CSRF token that is placed in the hid­den HTML form. One might think that CSRF is point­less when the at­tacker can al­ready per­form XSS, a larger threat than CSRF. How­ever, there are cases when the at­tacker can be de­tected, e.g. in server-​side XSS cases. Al­ter­na­tively, an XSS vec­tor in a sub­do­main might be ex­ploited to at­tack an XSS-​secure tar­get par­ent do­main. For in­stance, the at­tacker can use the XSS in the sub­do­main to set cook­ies for the par­ent do­main and per­form a cookie toss­ing at­tack (to be dis­cussed soon). Dan­gling Markup is an­other kind of at­tack that uses HTML to ex­tract the CSRF token when attacker-​controlled input is re­flected in the HTML. A de­tailed ex­am­ple of this at­tack can be found in this blog by Gareth Heyes\cite{dan­gling}.
  • Click­jack­ing [21]: is an­other at­tack that can leak CSRF token or ren­der the CSRF de­fense use­less. The de­fense can be by­passed by fram­ing the tar­get web ap­pli­ca­tion on the at­tacker’s web­site. The vic­tim is then tricked into sub­mit­ting an HTML form on the tar­get web ap­pli­ca­tion (same ori­gin) which is loaded in­side the at­tacker’s web­site with the CSRF token in it. Since the CSRF token is part of the re­quest, the de­fense be­comes point­less. How­ever, tra­di­tional Click­jack­ing is lim­ited to click­ing but­tons while in re­al­ity, an HTML form has to be filled in order to per­form a sen­si­tive op­er­a­tion. Stone [22] showed how Click­jack­ing could be used to achieve this. He sug­gests the use of drag-​and-drop API to leak the CSRF token and/or fill HTML forms.
  • Cookie toss­ing [23]: this at­tack vec­tor is the nat­ural enemy of Dou­ble Sub­mit coun­ter­mea­sure and ex­ploits the fact that an attacker-​controlled sub­do­main can set a cookie for the tar­get par­ent do­main. It also ex­ploits the com­plex na­ture of cook­ies. A cookie is stored as a unique com­bi­na­tion of name/do­main/path in the browser. Be­cause name/do­main/path de­ter­mine the unique­ness of a cookie, an at­tacker can cre­ate a cookie from a sub­do­main that he con­trols with the same name and do­main but with a dif­fer­ent path. This will cre­ate a whole new cookie and the browser will store it even if it has the same name. When the re­quest is sent, the browser will at­tach this header: “Cookie: Xname=good; Xname=bad” (and no other cookie at­trib­utes). As a re­sult, the server that hosts the tar­get par­ent do­main now sees two cook­ies with the same name but can­not dis­tin­guish which one be­longs to the par­ent do­main. The suc­cess of the at­tack re­lies on the fact that the at­tacker’s cookie (i.e. “Xname=bad” cookie) is the one that is con­sid­ered by the server. To in­crease the suc­cess chance, the at­tacker can also in­clude a spe­cific path in the forged cookie, e.g. path=trans­fer. This ex­ploits the fact that (most) browsers will con­sider a cookie with a path to be the “more specifically-​scoped” and will send it first. Some pro­gram­ming lan­guages (e.g. PHP) cre­ate an array from the Cookie header and only con­sider the first cookie of the array. Other lan­guages like Python con­sider the last cookie in the array. Egor Homakov [24] showed a de­tailed ex­am­ple of a real-​life ap­pli­ca­tion of cookie toss­ing on GitHub.
  • Cookie jar over­flow [25]: is an at­tack vec­tor that tar­gets the web browser’s cookie jar. When a web­site sets a cookie, the browser adds it to the cookie jar which can be thought of as a data­base in the browser that stores cook­ies. Just like a real jar, there is a limit to how many cook­ies it can store. Fire­fox al­lows up to 150 cook­ies while Chrome al­lows 180. If the limit is reached, the browser will start re­plac­ing old cook­ies with new ones. There­fore, an at­tacker can do a cookie jar over­flow to “kick out” every sin­gle cookie of the par­ent do­main and re­place them with attacker-​specified cook­ies (and CSRF token) just by run­ning a JS snip­pet code on a sub­do­main. Even if the at­tacker can­not mod­ify a cookie (e.g. HttpOnly or Same­Site), he can use this over­flow to con­trol what cook­ies the browser stores.

Server-side CSRF verification**

  • In­se­cure token com­par­i­son (tim­ing at­tacks) [26]: tim­ing at­tacks on token com­par­i­son can hap­pen if a token com­par­i­son is done using the ”==” op­er­a­tor or a func­tion that is based on this op­er­a­tor. The du­ra­tion of the com­par­i­son is longer for strings with many char­ac­ters in com­mon (e.g. “uni­ver­sity” and “uni­verse”) and shorter oth­er­wise (e.g., “uni­ver­sity” and “test”). This time dif­fer­ence in the com­par­i­son can be used as a side-​channel to guess the CSRF token.
  • Miss­ing checks for “safe” HTTP meth­ods: a com­mon mis­take is to per­form CSRF ver­i­fi­ca­tion only for un­safe HTTP meth­ods such as POST, PUT, DELETE, PATCH. In­deed, ac­cord­ing to RFC 2616 [27], “safe” meth­ods should be idem­po­tent. How­ever, de­vel­op­ers use GET-​based re­quests for state-​changing op­er­a­tions quite often in prac­tice (e.g. for log out). This al­lows for GET-​based CSRF at­tacks to hap­pen.
  • Miss­ing check for non-​POST un­safe HTTP meth­ods: is an even more dan­ger­ous prac­tice. There are few frame­work de­vel­op­ers that only per­form CSRF ver­i­fi­ca­tion only for POST re­quests and ig­nore other un­safe meth­ods such as DELETE or PUT. In some cases, the de­vel­oper doesn’t un­der­stand the risk of such be­hav­ior [28].
  • HTTP Method Over­ride is also a “fea­ture” that can by­pass the CSRF ver­i­fi­ca­tion that is per­formed only for spe­cific HTTP head­ers. The at­tacker can forge his re­quest as a GET re­quest and also add a cus­tom re­quest header (X-​HTTP-Method-Override) to over­ride the re­quest method to PUT, POST, or DELETE. Usu­ally, this is pro­vided as a mid­dle­ware. If this mid­dle­ware is spec­i­fied after the CSRF mid­dle­ware, then the CSRF ver­i­fi­ca­tion will be by­passed be­cause it con­sid­ers the re­quest as GET. Next, when method over­ride mid­dle­ware is ex­e­cuted, it will change the re­quest method to POST and will ex­e­cute the CSRF re­quest [29]. An­other at­tack vec­tor using HTTP Method Over­ride hap­pens when the at­tacker spec­i­fies an ar­bi­trary name as a mod­i­fied re­quest method and the coun­ter­mea­sure will trig­ger the CSRF ver­i­fi­ca­tion only for a list of spec­i­fied meth­ods (e.g. only for POST, DELETE, etc.). In this case, the ver­i­fi­ca­tion will not be called at all, lead­ing to CSRF.
  • Log­i­cal er­rors: are all er­rors that don’t throw an ex­cep­tion but have a flaw in the code’s logic or pro­gram­ming mis­takes (e.g. in­cor­rect “if-​else” clauses). As we will see dur­ing the field study, there are few frame­works that have ac­tu­ally fallen vic­tim to this prob­lem.
  • Re­play at­tack [30]: is one of the old­est tricks that is usu­ally ex­ploited in cryp­to­graphic pro­to­cols. The at­tacker in­ter­cepts a mes­sage that is sent from A to B, say a re­quest for money trans­fer, and then re­play this at­tack by send­ing the in­ter­cepted mes­sage to B mul­ti­ple times. B has no way of check­ing the fresh­ness of the mes­sage and will do the trans­ac­tion every time. This can hap­pen with CSRF to­kens as well. An at­tacker that leaks a sin­gle CSRF token can use it mul­ti­ple times until token ex­pi­ra­tion. This at­tack is also aided by the way ses­sions are usu­ally han­dled in prac­tice. Some ses­sions can last for days or months and if time is not spec­i­fied in the cookie, the end of the ses­sion is con­sid­ered when the browser is closed. How­ever, some browsers like Chrome have “Clear cook­ies and site data when you quit Chrome” fea­ture, which is by de­fault dis­abled. As a re­sult, the ses­sion does not re­ally end even when the browser is closed.

Cross-​Site Web­Socket Hi­jack­ing [31]: (WS) con­nec­tions are an­other pos­si­ble at­tack vec­tor. An at­tacker can write some code in his ma­li­cious web­site that ini­ti­ates a WS hand­shake with the tar­get server. Once the vic­tim vis­its the page, the browser will send an UP­GRADE re­quest header to­gether with the ses­sion cookie. In a nor­mal sce­nario, the server re­sponds with CORS re­sponse head­ers that would pre­vent the cross-​origin con­nec­tion. How­ever, the in­ter­est­ing fact is that WS does not re­spect SOP or CORS pol­icy and the con­nec­tion will ac­tu­ally be es­tab­lished. As a re­sult, the at­tacker can now leak the CSRF token and forge suc­cess­ful CSRF at­tacks.

In­cor­rect SOP re­lax­ation (e.g. faulty CORS): is also a pos­si­ble at­tack vec­tor that can lead to CSRF token leak­age. An over-​permissive CORS that sets the re­sponse head­ers Access-​Control-Allow-Origin: true and Access-​Control-Allow-Credentials:true would leak the CSRF token of the vic­tim. The at­tacker can sim­ply per­form a GET re­quest to re­trieve the CSRF-​protected HTML form, read the re­sponse and steal the CSRF token. Then, he can con­tinue per­form­ing a CSRF at­tack by pro­vid­ing the valid CSRF token.

Note: Same­Site cook­ies ap­pear to be the next at­tempt to pre­vent CSRF at­tacks. Al­though Same­Site raises the bar for at­tack­ers, it is not per­fect as well. For ex­am­ple, Same­Site: Lax does not com­pletely pre­vent CSRF. Three pos­si­ble at­tacks can be ex­ploited: 1) at­tacker can use top-​level nav­i­ga­tion (<a>) to trig­ger GET-​based CSRF. 2) “Client-​side” CSRF can cir­cum­vent this mech­a­nism and even send POST-​based CSRF re­quests with cook­ies at­tached. 3) <por­tal>, a new HTML tag that was in­tro­duced by Google in the end of 2019 for per­for­mant web­site fram­ing. Until now, it is still a draft and only avail­able on Google Ca­nary. How­ever, de­vel­op­ers should be aware of the se­cu­rity risks. If the tar­get web ap­pli­ca­tion is em­bed­ded into at­tacker’s site using <por­tal>, then the browser will send the Same­Site=Lax cookie even if it is a cross-​origin re­quest [32]. Re­cent at­tacks show that Same­Site can also be cir­cum­vented with other means [33].

I hope that de­vel­op­ers be­come aware of these at­tack vec­tors and read the doc­u­men­ta­tion of the frame­work they use care­fully. There is cur­rently no frame­work that pre­vents all these at­tack vec­tors and if se­cu­rity is your pri­or­ity, make sure to check that you are safe from the above-​mentioned at­tack vec­tors.

References

  1. https://owasp.org/www-​project-top-ten/2017/A7_2017-​Cross-Site_Script­ing_(XSS)
  2. https://doi.org/10.1145/54289.871709
  3. https://www.se­cu­ri­ty­fo­cus.com
  4. https://web.archive.org/web/20000622042229/http://www.zope.org/Mem­bers/jim/ZopeSe­cu­rity/ClientSide­Tro­jan
  5. https://crypto.stan­ford.edu/cs155old/cs155-​spring08/pa­pers/Ses­sion_Rid­ing.pdf
  6. https://homes.cs.wash­ing­ton.edu/~yoshi/pa­pers/czeskis-​arls.pdf
  7. https://tools.ietf.org/html/rfc7617
  8. https://www.kb.cert.org/vuls/id/584089/
  9. https://www.kb.cert.org/vuls/id/264385/
  10. https://peo­ple.eecs.berke­ley.edu/~daw/teach­ing/cs261-f11/read­ing/csrf.pdf
  11. https://dl.acm.org/doi/10.1145/1455770.1455782
  12. https://twit­ter.com/Twit­ter­Sup­port/sta­tus/25614603915
  13. https://cheat­sheet­series.owasp.org/cheat­sheets/Cross-​Site_Re­quest_Forgery_Pre­ven­tion_Cheat_Sheet.html#synchronizer-​token-pattern
  14. https://cheat­sheet­series.owasp.org/cheat­sheets/Cross-​Site_Re­quest_Forgery_Pre­ven­tion_Cheat_Sheet.html#double-​submit-cookie
  15. https://cheat­sheet­series.owasp.org/cheat­sheets/Cryp­to­graphic_Stor­age_Cheat_Sheet.html
  16. https://cheat­sheet­series.owasp.org/cheat­sheets/Key\_Man­age­ment\_Cheat\_Sheet.html\#key-​management-lifecycle-best-practices
  17. https://nvd.nist.gov/vuln/de­tail/CVE-2020-11825
  18. https://owasp.org/www-​chapter-london/as­sets/slides/David_Johansson-​Double_De­feat_of_Double-​Submit_Cookie.pdf
  19. http://www.breachat­tack.com/re­sources/BREACH%20-%20SSL,%20gone%20in%2030%20sec­onds.pdf
  20. https://blog.je­re­mi­ah­gross­man.com/2006/08/i-​know-where-youve-been.html
  21. https://en.wikipedia.org/wiki/Click­jack­ing
  22. https://www.con­tex­tis.com/media/down­loads/Next_Gen­er­a­tion_Click­jack­ing.pdf
  23. https://media.black­hat.com/bh-​ad-11/Lun­deen/bh-​ad-11-​Lundeen-New_Ways_Hack_WebApp-​WP.pdf
  24. http://homakov.blogspot.com/2013/03/hacking-​github-with-webkit.html
  25. https://www.sjo­erd­langkem­per.nl/2020/05/27/overwriting-​httponly-cookies-from-javascript-using-cookie-jar-overflow/
  26. https://cwe.mitre.org/data/de­f­i­n­i­tions/208.html
  27. https://www.ietf.org/rfc/rfc2616.txt
  28. https://github.com/hapijs/crumb/is­sues/4
  29. http://blog.nib­blesec.org/2014/05/nodejs-​connect-csrf-bypass-abusing.html
  30. https://en.wikipedia.org/wiki/Re­play_at­tack
  31. https://christian-​schneider.net/Cross­SiteWeb­Sock­etHi­jack­ing.html
  32. https://re­search.se­cu­ri­tum.com/security-​analysis-of-portal-element/
  33. https://www.face­book.com/notes/facebook-​bug-bounty/client-​side-csrf/2056804174333798/?fref=men­tions
Next post

Eclipse Vert.x 4.0.2 released!

Eclipse Vert.x version 4.0.2 has just been released. It fixes quite a few bugs that have been reported by the community.

Read more
Previous post

Eclipse Vert.x 3.9.5 released!

Eclipse Vert.x version 3.9.5 has just been released. It fixes quite a few bugs that have been reported by the community.

Read more
Related posts

Some Rest with Vert.x

This post is part of the Introduction to Vert.x series. Let’s go a bit further this time and develop a CRUD-ish application

Read more

Unit and Integration Tests

Let’s refresh our mind about what we developed so far in the introduction to vert.x series. We forgot an important task. We didn’t test the API.

Read more

Real-time bidding with Websockets and Vert.x

The expectations of users for interactivity with web applications have changed over the past few years. Users during bidding in auction no longer want to press the refresh button.

Read more