I will start with a very very short introduction on OS certificate pinning for Android. Starting with version 4.2 of Android system/OS level SSL/TLS certificate pinning was introduced (see also this URL for more info.). The list of pinned certificates using this mechanism is located at: "/data/misc/keychain/pins" and contains by default around 40 entries for Google services like mail.google.com, youtube.com, etc. I would very much like to have my own certificate pinned by having it added to this list. However, modifying this list requires an Android permission (android.permission.WRITE_SECURE_SETTINGS) that's only available to system apps.
Doe anyone know if there might by some kind procedure in place at Google to submit a request to be added to this list (i.e. /data/misc/keychain/pins)?
WebViews are tricky, not least because there is no perfect way to implement pinning in them except with Android N using Network Security Configuration.
The best you can do is override shouldInterceptRequest and implement the network calls yourself using one of the methods described in Android Security: SSL Pinning, however this only intercepts GET requests so if your WebViews use POST requests then you are out of luck. Android-SSL-Pinning-WebViews shows an example of doing this.
Related
I know this question is very similar to this one: Using Charles proxy to decrypt googleapis.com,
but it is very old and I think google changed some stuff about their APIs.
I'm using Charles to inspect HTTP requests from an android app (which is not mine).
This app uses SSL pinning, so I bypassed it with this tutorial:
https://lucy-janewalsh.com/blog/2019/10/29/unpinning-an-app
This works perfectly for every domain, except firestore.googleapis.com.
Charles gives me this error:
No request was made. Possibly the SSL certificate was rejected.
Do you know if this is possible to inspect requests made to this address?
Thanks
That tutorial only disables SSLPinning by the conscrypt library and only if the app that uses this library has not been obfuscated. If the app is obfuscated the class can not be found and the pinning will remain active. Also keep in mind that conscrypt is based on my experience not very often used by Android apps. Other libraries that provide SSLPinning like OKHttp are way more often used (e.g. covered by this Frida snippet.
In your case everything depends on the app you try to intercept the traffic of. Decompile it e.g. using Jadx or your favorite app decompiler and try to identify the used library/method for SSL pinning. If the app is obfuscated (class names changed) then most likly you have to write your own frida code to disable pinning (or at least adapt the class names form an existing frida code snippet that performs unpinning for the SSL-library used in your app).
I have a mobile app written in Flutter. I am calling Google API's for Places and for Geocoding. Since the calls to these services are made by including the key in the url it is very important that this keys be restricted so that anyone can't just intercept and use them to make many calls and rack up a big account for us with Google.
Examples of API calls are:
https://maps.googleapis.com/maps/api/place/autocomplete/json?input=$input&types=address&language=$lang&components=country:za&key=$apiKey
and
https://maps.googleapis.com/maps/api/geocode/json?latlng=$lat,$lon&key=$apiKey
(where $apiKey=our Google Maps API Credentials Key $input, $lang, $lat and $lon represent other variables)
Google currently allows the following Application Restrictions on API Credentials:
None
HTTP Referrers
IP Addresses
Android Apps
iOS Apps
When I don't have any restrictions on my key (option "None") then my mobile application works perfectly fine. However, if I choose to restrict it to iOS Apps (and specify the Bundle Identifier for my app) I get the error "This IP, site or mobile application is not authorized to use this API key". The same happens when I restrict the key to Android Apps and specify my Package Id and SHA1 signature for the Android app.
What am I missing? According to https://developers.google.com/maps/api-key-best-practices#restrict_apikey I should be fine to restrict the key to my specific mobile application. It seems like Google Maps is not picking up that I'm indeed making the call from the correct mobile app. The error occurs regardless of whether I run this in the Simulator or on an actual device in either debug or release mode. (I have tested the iOS version of the app from Test Flight too. When I remove the restrictions, my api calls work; when I restrict it only to my iOS app's Bundle Identifier it stops working.) Is there anything else I need to configure? Is the problem perhaps that the app is written in Flutter?
I found some links (like this) that suggest that mobile applications should never use the key directly in the url but should rather use our own server as a proxy to Google and then we should restrict access to our server's IP. This seems like an unnecessary overhead since the very existence of the option to restrict the key to specific app id's and platforms suggests that this should be possible (as does the Google documentation I refer to).
I ended up creating a proxy server. (More on that below).
Thinking about it critically I realised there would not really be any way for the API to discern whether incoming requests are being made from the specific mobile app or not so I don't think the restriction to specific iOS or Android apps is really possible for https requests.
I also investigated some of the flutter plugins provided but most of them seem to use google_maps_webservice in the background. And google_maps_webservice requires either a key in the app code or a proxy to be specified. Most of the plugins derived from google_maps_webservice don't even offer the proxy option and requires a key to be specified. So even if these plugins are used, one ends up "giving away" your key in the app code which makes it possible to reverse-engineer and obtain your code. (It ends up in the AppDelegate.m file on iOS and AndroidManifest.xml in Android). Google recommends against giving out your api key in this way.
So I ended up creating a proxy server. Requests are made to my proxy without the key and then the proxy passes on the request to Google after adding the secret key. The proxy then returns the response to the app. The app and traffic between app and server never contains a key.
Luckily my app was already using AWS and users were signing in with Cognito. So I could create the Proxy easily in API Gateway and I let the app authenticate to my proxy server using Cognito. This ensures that only users validly logged in on my app in Cognito will be able to call the proxy and keys are always kept secret.
If you want to take advantage of Google Map Service API configuration for a specific Android/iOS app you'll need to be using the native Android & native iOS SDKs which depend upon the SHA fingerprint & package name, or bundle id.
As the Google Places API seems popular a number of third-party attempts exist: https://pub.dev/packages?q=google+places
a similar situation exists for geocoding: https://pub.dev/packages?q=google+geocoding
You can see if any fit your app or you'll need to create your own platform channel for support: https://flutter.dev/docs/development/platform-integration/platform-channels
I am creating a small demo app to implement ssl certificate pinning in android webview. I have generated the certificates of the host.
Can anyone suggest me how to pin the certificates in the application code.
I have searched many links but I am still stuck.
WebViews are tricky, not least because there is no perfect way to implement pinning in them except with Android N using Network Security Configuration.
The best you can do is override shouldInterceptRequest and implement the network calls yourself using one of the methods described in Android Security: SSL Pinning, however this only intercepts GET requests so if your WebViews use POST requests then you are out of luck. Android-SSL-Pinning-WebViews shows an example of doing this.
I use a device group without a server as documented here. I want to know if it's possible to design a chrome extension in order to use GCM notifications in these conditions. I know I can add/remove a device using HTTP request and an API key (so emulating the server) but this approach has several problems from security point of view because I need to put my API key in the extension. What I'd like to do, instead, is to use the approach used on Android but I didn't find a way.
There is a Google+ mobile application for Android. To receive all the information it must be using some API.
How I can retrieve this information from my phone and see from where this app is getting data? I'd love to access it myself and see how it works.
You are talking about "reverse engineering" a network protocol.
Full sniffing
Get a market enabled emulator: How to install Android Market App on the emulator?
Get a network sniffer: tcpdump, wireshark, ...
Start to sniff what's going over the wire
http://www.thoughtcrime.org/software/sslstrip/ - an ssl stripping proxy
Inject your ca: http://www.mcbsys.com/techblog/2010/12/android-certificates/
This should, in theory, enable you to sniff any https or plain text connection.
Already available APIs
I would not try to hijack the connection. There is already a contacts API, it's called xmpp. You should be able to use the talk integration to pull your friend list.
Future APIs
You may also want to sign up for the upcoming API.
UPDATE
It appears that the Android client uses (at least partially) XMPP. The regular client requires an open XMPP connection and you can see a "RealTimeChat" in your logcat. It looks like the connection is encrypted because you get a "TLS required" message (the client seems to go through the XMPP connection states). I'm not sure if that's used for client based posts or just for server push. You can see the open connections with the help of "netstat". The connection goes away when google plus terminates.
I'd thus expect the API to be really open once released (or rev.eng).
UPDATE 2 (06. Jul. 2011)
Hangout is build on XMPP/MUC+JINGLE (muc == multiuser chat, jingle is roughly a SIP alternative on top of XMPP). And yes, they'll release the the details of it :-)
UPDATE 3 (06. Jul. 2011)
Multiple XMPP components for gtalk/gplus have been revealed by reading the JS code. It also emphasizes that they have build a great deal of features on XMPP.
They haven't launched the API yet. If there is something you want to build on Google+, they encourage you to signup here: https://services.google.com/fb/forms/plusdevelopers/
The API hasn't been released yet. Heck, the product hasn't even been released yet. Thats like developing a video game for playstation 5.
Yes it is. Its coming "soon" read :: http://www.webpronews.com/api-coming-soon-for-google-plus-2011-07