Why is my Android keyboard sending unencrypted data? And where?


I recently switched phones from a LG G4 to a Sony Xperia X Performance (isn't that a mouthful!), so I had a spare Android phone lying around. What better use for than to sniff some traffic!


First up is ai.type Free Emoji Keyboard, a free keyboard that has built in text-swiping features (Google Play), emoji, a calculator and much more. Android keyboards have the ability to read what you type, mostly just to improve text correction and prediction. This is an understandable permission but has the opportunity for misuse.

I loaded up Burp Suite, added the proxy setting to the phone and off I went. First request right off:

Holy leaking information batman! The app sent my email addresses, latitude, longitude, IP address and device info to their server over HTTP.

Now you may be thinking "well ads display in apps too, they must send juicy tracking information back too", so let's take a look.

Here's a request after opening up Don't Tap The White Tile:

GET /v2/config.json?u-id-key=82549130&u-key-ver=1&h-user-agent=Mozilla%2F5.0+%28Linux%3B+Android+6.0%3B+LG-H812+Build%2FMRA58K%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F53.0.2785.124+Mobile+Safari%2F537.36&tz=-25200000&u-appbid=com.umonistudio.tile&mk-version=pr-SAND-ETFTH-20151009&u-appver= HTTP/1.1
User-Agent: Mozilla/5.0 (Linux; Android 6.0; LG-H812 Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.124 Mobile Safari/537.36
If-Modified-Since: Thu, 29 Sep 2016 17:31:14 GMT
Host: config-ltvp.inmobi.com
Connection: close
Accept-Encoding: gzip

And the response is nothing spectacular:

HTTP/1.1 200 OK
Content-Type: application/json
Last-Modified: Mon, 03 Oct 2016 05:32:46 GMT
Vary: Accept-Encoding
Content-Length: 1867
Connection: keep-alive

    "common": {
        "ids": {
            "O1": true,
            "SO1": true,
            "IX": true,
            "SID": true,
            "LID": true,
            "UDID": true,
            "UM5": true,
            "IDA": true,
            "IDV": true,
            "FBA": true,
            "GID": true,
            "LTVID": true,
            "si": 60,
            "srt": 3,
            "shs": 50,
            "e": true,
            "sced": true,
            "scoe": true,
            "scvw": false,
            "ep": "https://sdkm.w.inmobi.com/user/e.asm",
            "mr": 3,
            "ri": 3,
            "wfd": 0,
            "cof": 0,
            "ao": false,
            "aoep": "https://sdkm.w.inmobi.com/user/e.asm",
            "aoi": 86400,
            "as": true,
            "assi": 180,
        "metric": {
            "url": "https://sdkm.w.inmobi.com/metrics/e.asm",
            "nri": 5,
            "max": 1000,
            "sf": 50,
            "dt": 10
        "endpoints": {
            "house": "http://a.ai.inmobi.com/v2/ad.html",
            "rules": "https://rules-ltvp.inmobi.com/v2/rules.json",
            "events": "https://e-ltvp.inmobi.com/storm/v1/event"
        "mdb": 1000,
        "elim": 100,
        "pint": 30,
        "mkey": 20,
        "mval": 50,
        "plim": 100,
        "mec": 5,
        "aidl": 100,
        "mr": 5,
        "at": {
            "session": false,
            "purchase": false,
        "ltvid": 0
    "IOS": {
    "AND": {


At least it's over HTTPS and just has non-personal identifiable information.

Here's another example call from Vertigo Racing via Flurry analytics:

Again, over SSL and just sending back phone data information.


Back to our target, I found that  the keyboard would instantly generate a HTTP request after I'm done typing. This sounds safe!

It sends a GET request to http://textreport.aitype.net with information that identifies what app was in use, date, and some weird long string, see below for the request.

GET /aggregationserver/agreggate?d_ins_id=dzi389isCLU&fl=en_KZ&cal_dow=2&cal_doy=277&cal_y=2016&cal_dom=3&l=en&t=rVjlC57xipA0sUVkCk49twiILhTcPv42C2DNGgrZ0cxilyN1QTONhIW2%2BHkiimGXcDkiH2f6Klzt%0AGlBi3gqmTOIZhRD%2B%2Fyi8TCmCnVB%2FPak%3D%0A&c=CA&p=com.lge.qmemoplus&cal_hod=0&d=c65c7885266ec9e3&cal_moh=30&cal_woy=41&aid=8775b9ea-80ed-42a8-ba29-597bd896c452& HTTP/1.1
User-Agent: Dalvik/2.1.0 (Linux; U; Android 6.0; LG-H812 Build/MRA58K)
Host: textreport.aitype.net
Connection: close
Accept-Encoding: gzip

I haven't been able to decode the string yet, so I haven't been able to come down to what it is sending but one can only imagine. The data it is sending is base64 encoded, possibly padded with some other device information. I'll update the post if I get any further. It is possible that the information it sends back is encrypted and "helps improve" the text prediction service. Even so, why must it send that information back? Why can the app not improve a user's predictive text on the device itself? I tested a few other keyboards ( Minuum, Google Keyboard, KitKat Keyboard, Chrooma Keyboard) and nothing was sent. 

But wait there's more! The keyboard will periodically want to send some large binary data to http://foxserver.aitype.net/server/kcctc

93 kilobytes of data? Not suspicious at all. I've uploaded the above data if anyone else would like to poke around in it, see the attachments at the bottom of this post.

It is quite scary when an app sends this type of information over plain text, considering how much one trusts their mobile device.


Attachment Size
post_request.data_.txt (91.02 KB) 91.02 KB