BLOG POSTS
CSN Follow-Up: Another CAPTCHA Problem Hidden In Plain Sight
By Laban Sköllermark (@LabanSkoller)
This is a follow-up on the previous post Brute-Forcing Borrowers’ PINs at the Swedish Board of Student Finance (CSN) where I describe some vulnerabilities discovered in August 2020 and the response from CSN. It seems I missed another problem with the CAPTCHA though. And it was right in front of my eyes…
If you read my previous post you might have spotted it yourself. If not, you get one more chance now before I tell you. Please study this screenshot carefully (or skip to the vulnerability if you prefer):
Can you spot something that might be a problem? No, it’s not that the correct numbers are pre-filled in the input field. I entered them before taking the screenshot. :)
Timeline
Date | Event |
---|---|
2020-NOV-20 | Problem spotted while finalizing the previous blog post |
2020-NOV-26 | Vulnerability report sent to CSN and CERT-SE for the vulnerability presented in this post plus four other potential problems under a 90-day disclosure deadline |
2020-NOV-26 | Reception of report confirmed by CERT-SE who said they will not take any action since I reported directly to CSN as well, unless I need help in case they don't respond |
2020-NOV-27 | Reception of report confirmed by the information security responsible person at CSN. They also promised to tell me when the problems are fixed. |
2020-DEC-02 | My other (anonymous) contact person at CSN responds that they currently don't know if the broken CAPTCHA solution is used elsewhere on their site and they don't know when they will know... :) (CC to the responsible person) |
2020-DEC-03 | Earliest publication date for this blog post as communicated to CSN and CERT-SE |
2020-DEC-09 | Publication of this post at 00:30 CET |
The Vulnerability
The important part in the above screenshot is:
Can’t see the picture? When you click on the link, the numbers will appear in a new window. It takes about 30 seconds until you see the numbers.
I did read that section several times back in August but didn’t think much of what it meant and I never clicked the link. But when I did…
The link Can’t see the picture? goes to the page
captcha?visaSiffror=true
. visaSiffror is Swedish for showNumbers. The
HTTP request made when clicking the link will return the correct number for the
CAPTCHA in text format but after 30 seconds. So the CAPTCHA is not a problem at
all for robots – it’s just a delay. This is probably thought of as a feature
rather than a bug to facilitate for people with disabilities but the security
consequences are rather huge.
A new number is randomized every time the page captcha
is requested. The page
captcha?visaSiffror=true
will return the number from the last CAPTCHA
generated. When this blog post was published the CAPTCHA solution was still
online even though the page for ordering new PIN codes was disabled due to my
previous findings. CSN don’t know (!) if the CAPTCHA solution is used
elsewhere on their site. This means you can probably still play along in this
proof of concept. Links will open in a new tab/window.
- Open this blog post in a new private/incognito window to get rid of old cookies etcetera. Follow the rest of the instructions in that window.
- Visit
/bas/does-not-exist
to get aJSESSIONID
cookie - Visit
captcha?visaSiffror=true
- Wait 30 seconds for the request to finish
- Observe the text
null
which means no CAPTCHA number to show exists - Visit
captcha
- Observe an image with a five-digit number. Example:
- Reload the page
- Observe an image with a new five-digit number. Example:
- Remember the number (or leave that tab/window open)
- Once again visit
captcha?visaSiffror=true
- Wait 30 seconds for the request to finish
- Observe the number now written as text. Example:
45345
In the previous post I concluded that a brute force attack on an account’s PIN succeeds in average after 6930 guesses. Using the above method in a sequential script means an attack would take less than twelve hours on average.
The CAPTCHA number is not tied to the person requesting a new PIN code however,
but to the browser session represented by the JSESSIONID
cookie, so multiple
CAPTCHAs can be valid for an account at any given time. My idea is that the
waiting for 30 seconds can be parallelized so that several threads fetch
separate CAPTCHAs, wait 30 seconds, and then order new PINs.
The idea is to prepare multiple sessions with known CAPTCHA numbers and then use them when needed when ordering new PINs. Every time a new PIN is ordered, five new PIN code guesses are allowed.
So this is a method of allowing an automated brute force attack against a victim’s (frequently changing) PIN even if the CAPTCHA bypass vulnerability described in the previous post is solved.
Reporting The Vulnerability
Since the only functionality that I know of where the broken CAPTCHA was being used was turned off, I decided to report the vulnerability to CSN with just a seven-day disclosure deadline to give them some time to inform me if the CAPTCHA is being used elsewhere. If it was, I would give them 90 days instead. They responded that they don’t know (!) whether the CAPTCHA is being used elsewhere and have no estimate on when they will, so I decided to publish this post as soon as it was finished.
My recommendation to CSN is to solve the described vulnerability before opening up the functionality for ordering new PINs again.
In the report sent to CSN (and CERT-SE) I also included four other possible attack scenarios. Those four are probably possible to perform right now and I don’t know of any mitigations, so I will apply a 90-day disclosure deadline to those and publish them on the 24th of February 2021 at the earliest.
security.txt Partly Implemented
But CSN did do something right. Almost at least…
In August I recommended CSN to publish a vulnerability disclosure policy (VDP)
and a security.txt file with a communication
channel for vulnerability reports. Friday the 4th of December 2020 I saw that
they have actually published
one. It doesn’t follow the
specification
since the content type is text/html
instead of text/plain
and the page is
full of HTML tags so it cannot be parsed by a machine but it gets the message
through to a human eye so it’s definitely better than not having one. The
Contact
field is missing the mailto
URI scheme but that’s true for
Defensify‘s security.txt
file as well (where I work).
That file is by the way presented as a download instead of as a page due to
Squarespace’s missing support for plain text files. The
tjanster.csn.se domain where
the vulnerabilities I’ve found reside doesn’t have a security.txt file however.
Comments?
Do you have questions, comments or corrections? Please interact with the tweet or LinkedIn post or make a pull request.
Credit
- Meme created with imgflip’s meme generator
- Update 2020-DEC-09: Thanks to Joakim Tufvegren for pointing out that the 14th of December 2020 has not happened yet. I saw the security.txt file on csn.se Friday the 4th of December. Page updated.
Update 2021-JAN-15: Hugo upgraded on the web server from 0.59.1 to 0.66.0 (used locally while writing) to render the ordered list correctly. I didn’t notice that it didn’t become a list after publishing and nobody complained.