As a regular user of apps like Lyft, Uber, Flywheel and anything that makes commuting more convenient, curiosity and free time lead me to open burp and start lurking around. I saw many interesting things but in this post I will focus only on the things related to the issue I found.
Lyft offers the option to enter coupons to get credit for rides. This way they attract new customers and retain current ones. The request to validate such coupons looks like this:
PUT /users/MY_USER_ID_HERE HTTP/1.1
Authorization: fbAccessToken XXXXXXXXXXXXX
Accept-Encoding: gzip, deflate
Easy right? Only one parameter. Let’s get the fuzzer out to play!
After trying the classic “AAAAAAA….” x 10000 I did not find anything interesting. So I started with special characters to see if those are properly escaped, SQLi, etc. but nothing there. Almost by coincidence I combined both. Special characters and tons of ‘A’ and I noticed something. The response took longer than usual. Mmmm. After playing with several payload I found one that ilustrates perfectly what was going on. My payload was ‘<%?:TESTAAAAAA
If we look at the time it takes to process every request, we see that our payload x3000 takes 260 milliseconds. But when we send the payload x24000 the time increases to 13 seconds! Anything after that simply times out. Also interesting is the fact that a payload of 50k of just alphanumerics values just takes 300 milliseconds. The issues come when you append <% to it. So AAAAA…AAAA x 50k takes 300miliseconds but <%AAAA…..AAAAA x50k times out.
I can imagine a DOS attack from a botnet being devastating if it takes advantage of this issue. My suggestion would be to discard any input that is over certain length. Coupon codes need to be “typable” by users so I assume that they don’t want it longer than say, 10 characters. Also, I would suggest to discard anything not entirely alphanumeric.
During my tests I tried to avoid hammering the server too much but I did a significant amount of requests in a short period of time. Given that my request was validating coupon codes, this could allow an attacker to brute force coupons to obtain credit. If we take into account that, from what I have seeing the format of coupons are:
– I would say case INsensitive
– Beween 6 to 10 chars long
it would be possible in a distributed attack to successfully brute force them. Now, I don’t know how it internally works and maybe what I am saying does not apply, but its worth mentioning. Given that the only way to apply coupons is typing them in the app, 3 requests within a second is a red flag at least!
I reported my findings to Lyft at 2AM and at 9AM I had already an email from one of their engineers thanking me and following up. It is awesome to work with companies that really care and appreciate your time. They fixed the problem that same day and where totally transparent with me on how they did it. On top of that, they invited me to visit their office and meet the team to talk about security best practices, and I think that is awesome!
They seem to have fix a “hungry regex” in their platform and indeed, if I run the same attack things look much better now.
Every request took less than a second. Good job guys!