I'm currently working on a library that enables QA or Developers debug network traffic in their app, we currently use OKHttp and I know how to create an interceptor and dispatch all request data to the lib. such that Developers or QA can view such data (Payload/URL/Size/Response Codes/Duration...etc), however I want to create a more generic solution that listens to HTTP traffic or even TCP traffic then take it from there, however I couldn't find a starting point, I know that this is possible since Firebase Performance is doing it, but still I couldn't find an API or anyway to listen to such traffic.
I hope that someone from Google's Firebase Performance Team shares some info about how they do it if it's not a trade-secret :)
I came across this solution: https://github.com/cyruliu/Sensitive_API_Monitor/blob/master/app/src/main/java/com/android/reverse/apimonitor/NetWorkHook.java
However it looks kinda bad with reflection, I hope to find a better way.
The short answer: It's not possible without proxying the whole device.
For OkHttp3 specifically I wrote a lib here: https://github.com/shehabic/sherlock that implements an interceptor that creates a new session every time your open your app and captures network requests, you can also have multiple session, it adds a floating icon that helps you access sessions and requests' history as well as some export capabilities, additionally it adds a secondary launcher icon that you can use to access the captures requests without interrupting the app's process.
Regarding Firebase Performance, all the magic is actually in the Firebase-Perf Gradle plugin; to simplify it, it scans through the project's code and replaces direct calls to OkHttpClient to be be proxied through their own FirebaseOkHttpClient and from there they get all the details even for https request as they become the http client.
I hope that this saves someone some time in the future.
Related
I've read nearly all posts on Stack Overflow regarding the topic session handling within Cordova apps, but none of them seems to touch the whole process from a best practices view.
To sum up what I've learned so far:
1.) Cordova apps usually deliver their web content from the mobile devices filesystem (which means the local /www directory of the Cordova project), not the hosted instance of a web application.
2.) If the application needs to deal with session cookie(s) set by the server backend, an (additional) preceding AJAX request is required to get that session cookie information transfered to the Cordova app implicitely and without having to deal with document.cookie and/or localStorage peristency on client side.
3.) In order to get this AJAX request working AND transmit the session data successfully, CORS neeeds to be enabled on server side and the transmission of session data enabled:
res.setHeader('Access-Control-Allow-Origin', '*'); // possible security issue
res.setHeader('Access-Control-Allow-Credentials', true); // even more evil possible security issue
4.) If the application targets Lollipop (= API level 21) or above for the Android platform, it must be secured that the following has been included in YourApplication.java (= file containing the MainActivity class) in the Function "onCreate":
CookieManager.setAcceptFileSchemeCookies(true);
If I'm getting things right, this seems to open a lot of (hopefully) unnecessary security holes to the backend. So I am asking myself: is this really a common used pattern, or are there any better best practices around to cover the described scenario?
Perhaps I should add, that in my case a normal web client gets a session cookie back by already doing the initial page load of the application. This is required, as the application assigns an auto-incrementing (e.g.) guest_72385 nickname to the user on his first connect, as he must be able to join parts of the application without having to login but nonetheless needs to use a unique username.
I just can't get my head straight about this one. I'm currently building a rather large-scale application on Android. I've run in to a couple of problems regarding security and authentication though...
The Scenario:
I have an application that's making calls through HTTP (will implement SSL later) to a server running PHP and MySQL. Of course i want to use the existing user-database, so migration to another DB is not a solution..
I've managed to create the "register users via Android to the server"-functionality.
I've also made a working login, BUT this is where the problems start.
As users in the Android application I'am working on adds, edits, deletes and sync stuff on the server via/to the application, things get rather complicated. A little too complicated for me it seems :)
Problems:
As I get the result from my server-side login and pass it from the
server to Android via JSON, the connection dies and server-side I
'aint logged-on (sessions dies) whereas on the phone I'am. How can I
make the log-on persistent both on the server and in Android without
the need to log-on again? So that subsequent calls from Android to
the server is made with the same user, still authenticated. I.e. I
want sort of a one-time login ('till I logout) like in the
Spotify-app (and many others).
If I've understood things right, implementing SSL correct makes it
possible to send passwords in clear text to the server without the need to hash them first. Is this correct?
I just can't stop thinking about the fact that a MIM-attack would compromise any unique id I send from Android to the server. My first thought was to have the UID on the Android device as a "key" to the server after a successful log-on. But if that key gets in the wrong hands, the user associated with that UID will be compromised. I've looked at the AccountManager on Android but it seems rather over-kill in my case.
If someone could supply examples or at least guidelines, I'd be much grateful!
Thanks in advace!
ADDED SOLUTION DIAGRAM AFTER EDIT
Notice that this diagram shows the first start of the application. Later startups will NOT show the Login / Register form, but use the DUT instead.
// Alexander
Issue some form of a short-lived authentication token to Android apps. They would need to pass it in every request, and you will check it your Web app. Breaking the connection doesn't end the session, if it does, you have bug in your Web app: fix it. In Android, as long as you are using the same HttpClient instance, it will continue to use the same session, nothing special is needed.
Whatever you do, do not put off implementing SSL, do it now.
I have profiles in my mobile app and in web project. We are currently thinking about how can we synchronize them. The point is, if person add something to mobile profile - we can just send a bundle of ids to webserver and server will add them as well. The same with removing items. But what is if person will removes in mobile profile without constant connection, then removes something inside his profile in webserver`s profile? And after that we have to synchronize it somehow.
I understand that solution of such issue has to be already found, but unfortunately I didn`t find anything helpful yet.
I'd recommend watching Virgil Dobjanschi's Google I/0 2010 talk on designing RESTful client applications: here. It's about an hour long, but very informative and helpful.
Some key points to note are:
Use a SQLite database to act as a cache between your application and the webserver, so changes can be saved even there is no connection, then sent/received once you gain connection again.
Use a Service to handle REST calls, as it won't be restricted by a single Activity's lifecycle. This way your server requests can still be executed and properly handled if a user or the Android OS kills your Activity, a phone call pushes your application off the screen, etc. I'm using an Intent Service, as it handles threading for you.
You also need to determine which syncing relationship is most suitable for your application. What I mean by that is "Which database should overwrite the other: The SQLite or the webserver?". So when there are differences between the two, which data should be deemed "correct"? This is commonly referred to as master-slave.
I have an Android App which uses http communication for nearly every operation. I want to be able to demo without connection to the internet by somehow replaying the http exchange. How can this be done? So I want to somehow almost like mock objects but really mock http session so I can always demo the app on or offline. This is really a very cool thing to be able to do. Since you can demo the app easily and reliably. Does anyone know how I could do this. Replicating the whole server side is just not an options its got too much stuff. Its important not to just show screencast but the real data exchange. I just want to be able to run thru the app and replay. Maybe debug as well. Thanks
Here's a hybrid solution using similar ideas from other answers:
You could write a dead simple HTTP server that listens on "localhost:80" (or whatever the port is on the server you're targeting) and point your application to this host instead by factoring out the host name from requests. Your local server has a reference to the actual remote server and does the following:
If ONLINE, forwards the request as-is to the real server, gets the response, saves it locally either in an in-memory cache keyed by the request URL or a file named with the URL as its identifier (munged appropriately)
If OFFLINE, looks up a request in its (in-memory or file system) cache and returns the contents from the cache instead
This is kind of like the record/playback mode that #nicholas.hauschild says.
Now you can just run your app once when ONLINE, causing your localhost server to save away requests that it issues against the real server. Then when you run your app OFFLINE, it just returns these cached contents instead whenever the same URLs are issued.
Hope this helps.
If you're device is rooted, you can use tcpdump as explained in this post: http://www.vbsteven.be/blog/android-debugging-inspectin-network-traffic-with-tcpdump/
or use AndroShark (get if from xda-developers here: http://forum.xda-developers.com/showthread.php?t=725692)
or this one (wifi only): http://www.9bitlabs.com/default.aspx
I would create a "Record Mode", and a "Playback Mode" for my app.
While in Record Mode, I would write out a file each time an http request was made. The file would be named by the endpoint the request is made. The contents of the file would a collection of serialized http requests/responses broken up by line. You could then deserialize lines from this file until you find the proper request, and play back the deserialized response.
This approach would also allow you to create Record/Playback profiles, where you could record multiple different sessions (by placing the files into a different directory) and then playback from whichever profile you choose.
This whole approach could be done with a small wrapper class around the HttpClient object you are using.
One way would be to use an HTTP proxy. Redirect all web traffic to the proxy, which can be running locally on the phone. This could be done with little or no source code change.
find a way using fiddler on pc,and android app take fiddler as proxy.So the http traffic is record.
http://blog.csdn.net/grhunter/article/details/5830199
Simples solution lies in faking it when there is no connection. If there is a error in connection, make sure ur app throws some preset data rather than an error in connection thing.
I am looking for reading resources or sample applications that can help me hammer out the following application workflow:
The client application establishes a connection to our server
The client application scans for updates on a regular interval
If an administrator has posted a new message, the new message is displayed in a widget.
I currently have 2 concerns:
I want to ensure that the monitoring service is not a major battery drain.
What is the most secure and simple method to establish the connection to retrieve data?
....There are a lot of suggestions out there... I need to know what method I should be researching over all others. Currently, all options are on the table because I have yet configure our server.
There are a lot of questions here, I'll try to give a succinct answer.
For the infrastructure I would go with HTTP REST calls to retrieve JSON data reprsenting your messages. Here is a decent link about writing an HTTP REST client for android, there are many others online.
For security, I would definitely start with SSL, but if you need to authenticate the requests I would also look at OAuth to secure you remote API.
As far as A, Have you considered using C2DM (aka "push") to trigger the updates? Then there's no client bandwidth beyond what is being used anyways for the Market/GMail/Talk connection. If you need to support Android versions below 2.2 it's not really an option at the moment, though.
Otherwise there's a few good examples of being a good citizen when polling from a widget; Jeff Sharkey's android-sky is probably the oldest, best, and most authoritative.
For B, unless I'm misunderstanding your need it's pretty hard to beat HTTPS; rolling your own "secure" transport over vanilla HTTP or anything lower-level is just asking for a disaster.