Indeed Job Search

Retest Observations

We retested this app on 20.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

From the Google Play Store page:

Find jobs using Indeed, the most comprehensive search engine for jobs.
In a single search, Indeed offers free access to millions of jobs from thousands of company websites and job boards.

From search to apply, Indeed's Job Search app helps you through the entire process of finding a new job.

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 HTTP GET request is made to graph.facebook.com

GET https://graph.facebook.com/v3.0/115882278440564?fields=supports_implicit_sdk_logging%2Cgdpv4_nux_content%2Cgdpv4_nux_enabled%2Cgdpv4_chrome_custom_tabs_enabled%2Candroid_dialog_configs%2Candroid_sdk_error_categories%2Capp_events_session_timeout%2Capp_events_feature_bitmask%2Cseamless_login%2Csmart_login_bookmark_icon_url%2Csmart_login_menu_icon_url&format=json&sdk=android HTTP/1.1

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

 {
  "supports_implicit_sdk_logging":true,"gdpv4_nux_enabled":false,"gdpv4_chrome_custom_tabs_enabled":true,"android_sdk_error_categories":[ {
    "name":"login_recoverable","items":[ {
      "code":102
    }
    , {
      "code":190
    }
    ],"recovery_message":"Please log in to this app again to reconnect your Facebook account."
  }
  ],"app_events_session_timeout":60,"app_events_feature_bitmask":5,"seamless_login":1,"smart_login_bookmark_icon_url":"https:\/\/static.xx.fbcdn.net\/rsrc.php\/v3\/yh\/r\/HyQ4Fq_iGUX.png","smart_login_menu_icon_url":"https:\/\/static.xx.fbcdn.net\/rsrc.php\/v3\/yR\/r\/xi3BPJ134MF.png","id":"115882278440564"
}

 

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

format:                       json
sdk:                          android
event:                        MOBILE_APP_INSTALL
advertiser_id:                474364c6-e9cf-4971-8dd2-b1dc3c605450
advertiser_tracking_enabled:  true
installer_package:            com.android.vending
anon_id:                      XZa41da6f3-5c60-4bc4-8def-e45bc166af70
application_tracking_enabled: true
extinfo:                      ["a2","com.indeed.android.jobsearch",1304,"4.9","8.1.0","Nexus 5","en_GB","GMT","",1080,1776,"3.00",4,13,8,"Europe\/London"]
application_package_name:     com.indeed.android.jobsearch

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

 {
  "success":true
}

 

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":"fb_sdk_initialize","_eventName_md5":"d470d22f237aee69843355edba5a8178","_logTime":1543678097,"_ui":"unknown","_implicitlyLogged":"1","core_lib_included":"1","login_lib_included":"1","places_lib_included":"1","all_lib_included":"1","share_lib_included":"1","messenger_lib_included":"1","applinks_lib_included":"1"},{"_eventName":"fb_mobile_activate_app","_eventName_md5":"cb7f3b6cd294afce05ece615d43ea7b9","_logTime":1543678097,"_ui":"MainActivity","_session_id":"e1fba388-564e-4274-86d6-7c756dd6b011","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:                      XZa41da6f3-5c60-4bc4-8def-e45bc166af70
application_tracking_enabled: true
extinfo:                      ["a2","com.indeed.android.jobsearch",1304,"4.9","8.1.0","Nexus 5","en_GB","GMT","",1080,1776,"3.00",4,13,8,"Europe\/London"]
application_package_name:     com.indeed.android.jobsearch

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

 {
  "success":true
}

Action from app:  The user is asked to sign in, or continue without an account. By choosing to continue it is implied that the user agrees to the Term and Conditions and Privacy Policy

Screenshot of Dialog shown to user:

 


Test user action 2:  The user chooses to continue without an account

 

 

Test user action 3: The user conducts a job search
Action from app: A Facebook 1x1 pixel is used to track the users requests. Although this isn't through graph.facebook.com it is still of interest for the scope of this project.

Data around the download of the Facebook pixel, request to https://connect.facebook.com

/**
* Copyright (c) 2017-present, Facebook, Inc. All rights reserved.
*
* You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
* copy, modify, and distribute this software in source code or binary form for use
* in connection with the web services and APIs provided by Facebook.
*
* As with any software that integrates with the Facebook platform, your use of
* this software is subject to the Facebook Platform Policy
* [http://developers.facebook.com/policy/]. This copyright notice shall be
* included in all copies or substantial portions of the software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
fbq.version="2.8.34";
fbq._releaseSegment = "stable";
fbq.pendingConfigs=["global_config"];
(function(a,b,c,d) {
  var e= {
    exports: {
      
    }
    
  };
  e.exports;
  (function() {
    var f=a.fbq;
    f.execStart=a.performance&&a.performance.now&&a.performance.now();
    if(!function() {
      var b=a.postMessage||function(){};
      if(!f) {
        b( {
          action:"FB_LOG",logType:"Facebook Pixel Error",logMessage:"Pixel code is not installed correctly on this page"
        }
        ,"*");
        "error"in console&&console.error("Facebook Pixel Error: Pixel code is not installed correctly on this page");
        return!1
      }
      return!0
    }
    ())return;
    var g=function() {
      function a(a,b) {
        for(var c=0;c<b.length;c++) {
          var d=b[c];
          d.enumerable=d.enumerable||!1;
          d.configurable=!0;
          "value"in d&&(d.writable=!0);
          Object.defineProperty(a,d.key,d)
        }
        
      }
      return function(b,c,d) {
        c&&a(b.prototype,c);
        d&&a(b,d);
        return b
      }
      
    }
    (),h=typeof Symbol==="function"&&typeof (typeof Symbol==="function"?Symbol.iterator:"@@iterator")==="symbol"?function(a) {
      return typeof a
    }
    :function(a) {
      return a&&typeof Symbol==="function"&&a.constructor===Symbol&&a!==(typeof Symbol==="function"?Symbol.prototype:"@@prototype")?"symbol":typeof a
    };
    function i(a,b) {
      if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")
    }
    f.__fbeventsModules||(f.__fbeventsModules= {
      
    }
    ,f.__fbeventsResolvedModules= {
      
    }

The app receives the following response

https://www.indeed.co.uk/m/?ctype=wifi&app=4.9%2CAndroid
/**
* Copyright (c) 2017-present, Facebook, Inc. All rights reserved.
*
* You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
* copy, modify, and distribute this software in source code or binary form for use
* in connection with the web services and APIs provided by Facebook.
*
* As with any software that integrates with the Facebook platform, your use of
* this software is subject to the Facebook Platform Policy
* [http://developers.facebook.com/policy/]. This copyright notice shall be
* included in all copies or substantial portions of the software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
(function(a,b,c,d) {
  var e= {
    exports: {
      
    }
    
  };
  e.exports;
  (function() {
    var f=a.fbq;
    f.execStart=a.performance&&a.performance.now&&a.performance.now();
    if(!function() {
      var b=a.postMessage||function(){};
      if(!f) {
        b( {
          action:"FB_LOG",logType:"Facebook Pixel Error",logMessage:"Pixel code is not installed correctly on this page"
        }
        ,"*");
        "error"in console&&console.error("Facebook Pixel Error: Pixel code is not installed correctly on this page");
        return!1
      }
      return!0
    }
    ())return;
    var g=typeof Symbol==="function"&&typeof (typeof Symbol==="function"?Symbol.iterator:"@@iterator")==="symbol"?function(a) {
      return typeof a
    }
    :function(a) {
      return a&&typeof Symbol==="function"&&a.constructor===Symbol&&a!==(typeof Symbol==="function"?Symbol.prototype:"@@prototype")?"symbol":typeof a
    }
    ,h=function() {
      function a(a,b) {
        var c=[],d=!0,e=!1,f=void 0;
        try {
          for(var a=a[typeof Symbol==="function"?Symbol.iterator:"@@iterator"](),g;
          !(d=(g=a.next()).done);
          d=!0) {
            c.push(g.value);
            if(b&&c.length===b)break
          }
          
        }
        catch(a) {
          e=!0,f=a
        }
        finally {
          try {
            !d&&a["return"]&&a["return"]()
          }
          finally {
            if(e)throw f
          }
          
        }

The app sends the following HTTP GET requests to facebook.com

GET https://www.facebook.com/tr/?id=579216298929618&ev=PageView&dl=https%3A%2F%2Fwww.indeed.co.uk%2Fm%2F%3Fctype%3Dwifi%26app%3D4.9%252CAndroid&rl=&if=false&ts=1543678291603&sw=360&sh=640&v=2.8.34&r=stable&ec=0&o=30&fbp=fb.2.1543678115273.895057293&it=1543678291319&coo=false HTTP/2.0
GET https://www.facebook.com/tr/?id=579216298929618&ev=Microdata&dl=https%3A%2F%2Fwww.indeed.co.uk%2Fm%2F%3Fctype%3Dwifi%26app%3D4.9%252CAndroid&rl=&if=false&ts=1543678293134&cd[Schema.org]=%5B%5D&cd[OpenGraph]=%7B%7D&cd[Meta]=%7B%22title%22%3A%22Job%20Search%20%7C%20Indeed%22%7D&cd[DataLayer]=%5B%5D&cd[JSON-LD]=%5B%5D&sw=360&sh=640&v=2.8.34&r=stable&ec=1&o=30&fbp=fb.2.1543678115273.895057293&it=1543678291319&coo=false&es=automatic HTTP/2.0
GET https://www.facebook.com/tr/?id=579216298929618&ev=PageView&dl=https%3A%2F%2Fwww.indeed.co.uk%2Fm%2Fjobs%3Fq%3DIt%2Bsupport%26l%3DGravesend%26from%3Dhome%26ctype%3Dwifi&rl=http%3A%2F%2Fwww.indeed.co.uk%2Fm%2F%3Fctype%3Dwifi%26app%3D4.9%252CAndroid&if=false&ts=1543678309638&sw=360&sh=640&v=2.8.34&r=stable&ec=0&o=30&fbp=fb.2.1543678115273.895057293&it=1543678309374&coo=false HTTP/2.0
GET https://www.facebook.com/tr/?id=579216298929618&ev=Microdata&dl=https%3A%2F%2Fwww.indeed.co.uk%2Fm%2Fjobs%3Fq%3DIt%2Bsupport%26l%3DGravesend%26from%3Dhome%26ctype%3Dwifi&rl=http%3A%2F%2Fwww.indeed.co.uk%2Fm%2F%3Fctype%3Dwifi%26app%3D4.9%252CAndroid&if=false&ts=1543678311157&cd[Schema.org]=%5B%5D&cd[OpenGraph]=%7B%7D&cd[Meta]=%7B%22title%22%3A%22IT%20Support%20Jobs%20in%20Gravesend%20-%20December%202018%20%7C%20Indeed.co.uk%22%2C%22meta%3Adescription%22%3A%22Apply%20to%20IT%20Support%20jobs%20now%20hiring%20in%20Gravesend%20on%20Indeed.co.uk%2C%20the%20world%27s%20largest%20job%20site.%22%7D&cd[DataLayer]=%5B%5D&cd[JSON-LD]=%5B%5D&sw=360&sh=640&v=2.8.34&r=stable&ec=1&o=30&fbp=fb.2.1543678115273.895057293&it=1543678309374&coo=false&es=automatic HTTP/2.0

Test user action 4: The user closes the application
Response from app: No futher data is sent or received by the app from graph.facebook.com

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
Note 3: The tracking pixel sent by Facebook is seperate to the SDK, but still sends application data to Facebook

Company Response

Indeed, 21 December, 2018 (via E-Mail to Privacy International)

"We take the privacy of our users very seriously, and have devoted significant resources to protect their rights and the relationship of trust we have with those users. We always endeavour to be as transparent as possible with our users. Section 2.2 of our Privacy Policy details the data shared between Indeed and third party sites, including facebook, when our users log in through such third party sites (see below). This applies to facebook account holders who have agreed to facebooks terms of service and who logged into Indeed from facebook. This allow users to create accounts and log in with their facebook accounts if they so choose, and any data sharing is limited and initiated by the user.

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