Duolingo: Learn Languages Free

Retest Observations

We retested this app on 19.02.2019. The app still exhibits the behaviour documented below.

Disclaimer: Additionally the tested app may still share data with other third parties. This is outside the scope of this work.

Read more

DuoLingo is an app to assist in learning a foreign language

From the Google Play Store page:

"Learn Spanish, French, German, Italian, Russian, Portuguese, Turkish, Dutch, Irish, Danish, Swedish, Ukrainian, Esperanto, Polish, Greek, Hungarian, Norwegian, Hebrew, Welsh and English."

Observed Behaviour

This documentation demonstrates actions taken by the test user and the apps subsequent responses.

Test user action 1: The user taps on the application icon, which opens the application
Response from app: The application is initialised and the following data is sent and received by the app:

Immediately after the app is opened, the following data is sent to graph.facebook.com (Graph)

Form data:
format:                       json
sdk:                          android
custom_events_file:           [{"_eventName":"fb_mobile_activate_app","_eventName_md5":"cb7f3b6cd294afce05ece615d43ea7b9","_logTime":1543670798,"_ui":"HomeActivity","_session_id":"e5730336-375e-4795-8010-aa7e95d738fa","fb_mobile_launch_source":"Unclassified"}]
event:                        CUSTOM_APP_EVENTS
advertiser_id:                474364c6-e9cf-4971-8dd2-b1dc3c605450
advertiser_tracking_enabled:  true
installer_package:            com.android.vending
anon_id:                      XZ0470fe20-65c7-4f8c-ad33-551e3dc056a2
application_tracking_enabled: true
extinfo:                      ["a2","com.duolingo",669,"3.107.7","8.1.0","Nexus 5","en_","GMT","",1080,1776,"3.00",4,13,8,"Europe\/London"]
application_package_name:     com.duolingo

With the response:

 {
  "success":true
}

Response from app: A splash screen is show
Test user action 2:  The user clicks "Get Started"

Without any further user action, the app sends the following request to graph.facebook.com

Form data:
format:                       json
sdk:                          android
custom_events_file:           [{"_eventName":"splash_load","_eventName_md5":"3867cf40e31d90b1eb35663b4009ff44","_logTime":1543669877,"_ui":"LaunchActivity","_session_id":"40105443-bd6a-4699-94a9-048bacf3cfd7"}]
event:                        CUSTOM_APP_EVENTS
advertiser_id:                474364c6-e9cf-4971-8dd2-b1dc3c605450
advertiser_tracking_enabled:  true
installer_package:            com.android.vending
anon_id:                      XZ0470fe20-65c7-4f8c-ad33-551e3dc056a2
application_tracking_enabled: true
extinfo:                      ["a2","com.duolingo",669,"3.107.7","8.1.0","Nexus 5","en_","GMT","",1080,1776,"3.00",4,13,8,"Europe\/London"]
application_package_name:     com.duolingo

The app receives the following response from graph.facebook.com:

 {
  "success":true
}

Test user action 3: The user goes through the preference process, setting themselves to Learn German, regular learning speed, selects not to take the placement test, chooses other preferences. Finally the user chooses start
Response from app: After clicking start, the following response takes place

Form data:
format:                       json
sdk:                          android
custom_events_file:           [{"_eventName":"welcome","_eventName_md5":"40be4e59b9a2a2b5dffb918c0e86b3d7","_logTime":1543669935,"_ui":"unknown","_session_id":"40105443-bd6a-4699-94a9-048bacf3cfd7"}]
event:                        CUSTOM_APP_EVENTS
advertiser_id:                474364c6-e9cf-4971-8dd2-b1dc3c605450
advertiser_tracking_enabled:  true
installer_package:            com.android.vending
anon_id:                      XZ0470fe20-65c7-4f8c-ad33-551e3dc056a2
application_tracking_enabled: true
extinfo:                      ["a2","com.duolingo",669,"3.107.7","8.1.0","Nexus 5","en_","GMT","",1080,1776,"3.00",4,13,8,"Europe\/London"]
application_package_name:     com.duolingo

The app receives the following response from graph.facebook.com:

 {
  "success":true
}

Test user action 4: While the user is completing their course, Facebooks advertising network is contacted through graph.facebook.com
Response from app: Some example responses are shown below

COPPA:                 false
APPBUILD:              669
KG_RESTRICTED:         false
VALPARAMS:             {"is_emu":"false"}
UNITY:                 false
ACCESSIBILITY_ENABLED: false
APPNAME:               Duolingo
ADAPTERS:              AN
AFP:                   6ae92ab2d0ebb68768f8e4963d919588
NUM_ADS_REQUESTED:     1
SESSION_TIME:          1543670041.532
PLACEMENT_ID:          506953166177069_523478221191230
MAKE:                  LGE
REQUEST_TIME:          1543670042.958
CARRIER:               
SDK_CAPABILITY:        [3,4,5,7,11,16,17]
TEMPLATE_ID:           200
CLIENT_REQUEST_ID:     9e31ec6a-6b85-40be-8330-5203af4c8487
DENSITY:               3.0
M_BANNER_KEY:          Y29tLmR1b2xpbmdvIGNvbS5hbmRyb2lkLnZlbmRpbmc=
SCREEN_HEIGHT:         592
SDK_VERSION:           4.99.1
SCREEN_WIDTH:          360
ID_SOURCE:             SHARED_PREFS
REQUEST_TYPE:          0
SDK:                   android
OSVERS:                8.1.0
CLIENT_EVENTS:         
APP_MIN_SDK_VERSION:   21
OS:                    Android
ANALOG:                {"total_memory":"1944141824","accelerometer_y":"0.18333435","accelerometer_x":"-0.06915283","accelerometer_z":"9.841278","charging":"1","available_memory":"1086988288","battery":"100.0","free_space":"8784875520"}
PLACEMENT_TYPE:        native
ROOTED:                2
MODEL:                 Nexus 5
BUNDLE:                com.duolingo
ASHAS:                 6c155e2720ec59b013c73e29f27ba599f4bf9ebc;
LOCALE:                en
NETWORK_TYPE:          1
IDFA:                  474364c6-e9cf-4971-8dd2-b1dc3c605450
ATTRIBUTION_ID:        
APPVERS:               3.107.7
INSTALLER:             com.android.vending
IDFA_FLAG:             1
SESSION_ID:            760b0ea6-84da-4edc-9687-be5535333fab
COPPA:                 false
APPBUILD:              669
KG_RESTRICTED:         false
VALPARAMS:             {"is_emu":"false"}
UNITY:                 false
ACCESSIBILITY_ENABLED: false
APPNAME:               Duolingo
ADAPTERS:              AN
AFP:                   6ae92ab2d0ebb68768f8e4963d919588
NUM_ADS_REQUESTED:     1
SESSION_TIME:          1543670041.532
PLACEMENT_ID:          506953166177069_523478221191230
MAKE:                  LGE
REQUEST_TIME:          1543670042.960
CARRIER:               
SDK_CAPABILITY:        [3,4,5,7,11,16,17]
TEMPLATE_ID:           200
CLIENT_REQUEST_ID:     ab5959fb-6277-48c5-a146-2982fe224b15
DENSITY:               3.0
M_BANNER_KEY:          Y29tLmR1b2xpbmdvIGNvbS5hbmRyb2lkLnZlbmRpbmc=
SCREEN_HEIGHT:         592
SDK_VERSION:           4.99.1
SCREEN_WIDTH:          360
ID_SOURCE:             
REQUEST_TYPE:          0
SDK:                   android
OSVERS:                8.1.0
CLIENT_EVENTS:         [{"name":"error","data":{"ex":"IllegalStateException","ex_msg":"Cannot get advertising info on main thread."},"time":1543670042,"request_id":"Error retrieving advertising id from Google Play Services"}]
APP_MIN_SDK_VERSION:   21
OS:                    Android
ANALOG:                {"charging":"1","available_memory":"1087234048","total_memory":"1944141824","battery":"100.0","free_space":"8784887808"}
PLACEMENT_TYPE:        native
ROOTED:                2
MODEL:                 Nexus 5
BUNDLE:                com.duolingo
ASHAS:                 6c155e2720ec59b013c73e29f27ba599f4bf9ebc;
LOCALE:                en
NETWORK_TYPE:          1
IDFA:                  474364c6-e9cf-4971-8dd2-b1dc3c605450
ATTRIBUTION_ID:        
APPVERS:               3.107.7
INSTALLER:             com.android.vending
IDFA_FLAG:             1
SESSION_ID:            760b0ea6-84da-4edc-9687-be5535333fab

Test user action 5: The user completes the course
Action from app:The user is taken to course results screen

The app sends the following to graph.facebook.com

format:                       json
sdk:                          android
custom_events_file:           [{"_eventName":"show_home","_eventName_md5":"710bb5dd2b61c02175f49bc39b77748a","_logTime":1543670373,"_ui":"HomeActivity","_session_id":"40105443-bd6a-4699-94a9-048bacf3cfd7"}]
event:                        CUSTOM_APP_EVENTS
advertiser_id:                474364c6-e9cf-4971-8dd2-b1dc3c605450
advertiser_tracking_enabled:  true
installer_package:            com.android.vending
anon_id:                      XZ0470fe20-65c7-4f8c-ad33-551e3dc056a2
application_tracking_enabled: true
extinfo:                      ["a2","com.duolingo",669,"3.107.7","8.1.0","Nexus 5","en_","GMT","",1080,1776,"3.00",4,13,8,"Europe\/London"]
application_package_name:     com.duolingo

The app receives the following response from graph.facebook.com:

 {
  "success":true
}

Test user action 6: The user gracefully closes the app
Action from app:The app closes

The app sends the following to graph.facebook.com

format:                       json
sdk:                          android
custom_events_file:           [{"_eventName":"fb_mobile_deactivate_app","_eventName_md5":"92255b491a4e25b5d809edcf3665affe","_logTime":"1543670438","_ui":"HomeActivity","_session_id":"40105443-bd6a-4699-94a9-048bacf3cfd7","_valueToSum":563,"fb_mobile_time_between_sessions":"session_quanta_0","fb_mobile_launch_source":"Unclassified","fb_mobile_app_interruptions":"1"}]
event:                        CUSTOM_APP_EVENTS
advertiser_id:                474364c6-e9cf-4971-8dd2-b1dc3c605450
advertiser_tracking_enabled:  true
installer_package:            com.android.vending
anon_id:                      XZ0470fe20-65c7-4f8c-ad33-551e3dc056a2
application_tracking_enabled: true
extinfo:                      ["a2","com.duolingo",669,"3.107.7","8.1.0","Nexus 5","en_","GMT","",1080,1776,"3.00",4,13,8,"Europe\/London"]
application_package_name:     com.duolingo

The app receives the following response from graph.facebook.com:

 {
  "success":true
}
Notes and Commentary

Note 1: In the videos below, the clocks between the VirtualBox Virtual Machine and the Phone handset are not synchronised.
Note 2: The phone videos are split into multiple parts due to a 180 second limitation in Android Developer Bridge screenrecord command

Company Response

 

Duolingo, 5 March 2019 (via Email to Privacy International)

“Duolingo thanks Privacy International for their important work raising awareness of this issue. As part of our ongoing commitment to privacy, we are removing the Facebook SDK App Events component from both the Android and iOS apps in the next version releases.” 

Date Tested
01/12/2018
App Version
3.107.7
Number of App Installs (according to Google Play Store at time of analysis)
100,000,000+
Facebook SDK Version
4.26.0
Opt out of Ads Personalisation (Google Settings)
Not Enabled (Default Setting)