Prezi is a popular presentation service used by procrastinating teens and adults alike who haven’t learned how to use powerpoint. It breaks away from the boring slide to slide style and gives some flair to a presentation. While I have never used this service I noticed they had a bug bounty program and decided to look into it.
I found this exploit a couple months ago when I began penetration testing, so my only hope at the time was spamming the url with some characters and seeing what the program gave me. I began with control characters like %0A and %0D and got some peculiar results; with a string like “helloWorld%0A” the new line would be successfuly parsed in the DOM:
After a few more tries I was unable to gain anything from this, since Prezi successfully encodes quotation marks and other XSS characters. After one more refresh though, to the delight of my skiddie knowledge, I was presented with the Almighty of debug pages.
This was the result of the “Debug=True” flag accidentally being set on a development server exposed to production. After this section there was a dump of 718 environmental server variables.
These variables included a lot, but most that were highly sensitive were censored due to Django’s built-in debug code:
HIDDEN_SETTINGS = re.compile(‘API|TOKEN|KEY|SECRET|PASS|SIGNATURE’, flags=re.IGNORECASE)
CLEANSED_SUBSTITUTE = ‘********************’
The security then was the responsibility of the server admin to name all sensitive variables with one of those in the “HIDDEN_SETTINGS” variable (only as a last resort, turning debug off in servers exposed to prod is the first line of defense). After triggering this error once, I was not able to trigger it again with the same string. I later found out this was because only one of their servers had the debug flag on, making it hard to reproduce.
He is risen
At this point I was ready to report the issue but I decided to try the other control character ‘%0D’ and see what happend. This time I found the Almighty debug page’s Son
The control character doesn’t show up in the request URL for some unknown reason. Since this was in another part of the site a different error was triggered and different info presented. This then dumped 313 url regex routes for their Django app. Most were properly configured to not allow unauthenticated viewing, but a more sophisticated actor could likely have made something of these.
He is risen, indeed
At this point I reported the vulnerability to Prezi through email and continued looking into the information that was given in these variable dumps. An interesting variable combination that was not masked by Django was GOOGLE_ANALYTICS_USER_EMAIL and GOOGLE_ANALYTICS_USER_PASS (which should have been masked). I reported this to Prezi and they verified this could have resulted in take over of that gmail account and the associated analytics account, but it was not in use anymore so they retired the account.
Prezi quickly discovered that they had just one server with a debug flag on and it was a development server accidentally exposed to prod, which is why this was not easily reproducible. They reconfigured that server and resolved the issue.
- 12:03 AM CDT: Issue reported to Prezi over email
- 6:45 AM CDT: Confirmation by Prezi of email receipt
- 8:42 AM CDT: Issue confirmed fixed and $1000 bounty awarded
At the time this was my first experience reporting to a bug bounty program and it was very enjoyable, I would like to thank Prezi for their professionalism and speedy responses. If you are interested make sure to check out https://bugbounty.prezi.com/