RCE in DuoLingo’s TinyCards App for Android [CVE-2017-16905]


The TinyCards Android application provided by DuoLingo can be injected with malicious content by an MITM attacker. Because this application is a web-app framed in an Android WebView, this can lead directly to remote code execution (RCE) within the app. The root cause is lack of SSL being used on app startup when the initial web content is loaded into the WebView.

The vendor has fixed this issue in v1.0 (version code 10) that was released via Google Play Store on November 20th, 2017 and users should install the latest version. MITRE has assigned # CVE-2017-16905 to track this issue.

Vulnerability Details

TinyCards is a flashcard application for preparing for tests and memorizing vocabulary. It is made by DuoLingo, which provides a platform for learning new languages. While monitoring network traffic of a test device running Android, we observed that during application startup an initial HTTP call is made to a non-HTTPS site, which then redirects to an HTTPS version. Further research into the application revealed that the application is essentially a thin browser wrapper using Android’s WebView around a web application loaded remotely.

Because the initial call is done without HTTPS, it is possible for an MITM attacker to intercept this traffic and inject their own content.  Since this is a web app, this can result in remote code execution within the application since all the content is web based.

Screenshots of the captured traffic and relevant source code:


Steps To Replicate (on Ubuntu 17.10)

1. Install the application on the Android device but do not start it.

2. Install dnsmasq and NGINX on the Linux host:

sudo apt-get install dnsmasq nginx

3. Modify the /etc/hosts file to add the following entry to map the domain name to the Linux host:

192.168.1.x tinycards.duolingo.com

4. Configure /etc/dnsmasq.conf file to listen on the IP and restart DNSMASQ

sudo /etc/init.d/dnsmasq restart

5. Add a file with malicious content (you may need to use sudo):

cd /var/www/html
echo powned >index.html

6. Modify the settings on the Android test phone to static, set DNS to point to “192.168.1.x”. AT THIS POINT – Android will resolve DNS against the Linux computer and serve the large servers file

7. Open the app on the Android device and observe injected content.

All testing was done on v1.0 (version code 9)  of the Android application using a Linux host running Ubuntu v17.10 and Android test device running Android v7.

Vendor Response and Mitigation

To fix this issue, the vendor has changed the initial URL for web content being loaded within the app to use SSL. The vendor has fixed this issue in v1.0 (version code 10) that was released via Google Play Store on November 20th, 2017 and users should install the latest version.

Bounty Information

DuoLingo doesn’t currently offer bounties, however, this bug has fulfilled the requirements of Google Play Security Reward Program and a bounty has been paid from that program.


CVE-ID: CVE-2017-16905
HackerOne Reports: 281605 (DuoLingo) and 293444 (Google Play Rewards)


We would like to thank the vendor for the quick turnaround and fix for this  vulnerability. Text of the advisory written by Yakov Shafranovich.


2017-10-21: Report opened with the vendor via HackerOne to clarify scope
2017-11-06: Technical details of vulnerability provided to the vendor via HackerOne
2017-11-07: Report triaged and being reviewed by the vendor
2017-11-20: Vendor patched the issue and asked for testing of the fix
2017-11-20: Fix confirmed, communication regarding disclosure
2017-11-28: Report submitted to Google’s Play Rewards program via HackerOne
2017-11-29: Rejection received due to scope, follow-up communication with Google regarding scope
2017-12-04: Follow-up conversation about disclosure with Google and the vendor
2017-12-05: Disclosure requested from DuoLingo via HackerOne
2018-01-04: Public disclosure on HackerOne, and publication of this advisory