Is there better ways to intercept & modify network response in android? - android

When testing a app(without source code), I need to mock some response from 3party apis that I don't has access to yet.
My current way to do this is LSPosed + ssl unpinning module + fiddler's autoresponder.
But I can't make it work without a computer, which making test the app outside the office very inconvenient.
I'm about to make a module to hook some apis to do so, maybe a frida script?
But before I do this...
ANY suggestions ? or is there a easier way to forgery responses for some certain links?

Related

Automate app local notification by manipulating the request and response

I am looking for ways to basically manipulate data that is shown in my app by intercepting the API calls it makes and then basically manipulate the data ( positive and negative scenarios) and then observe how my App behaves. I have been manually intercepting these calls and doing it in Charles Proxy tool but I want to get rid of it and looking for a way to do this through Automation. Set up my test data intercept the API calls through a proxy and then run my functional tests on the App. I am looking to do this for both Android and IPhone Apps.
Note: I have been using Appium for Automation.
Appium is a black-box test automation tool, it has no API to manipulate with application on server side. On Android, it allows you to start Activity/Fragment with pre-defined state, but it is not equal to what you are doing.
I think the right way here is to mock your server, there are multiple libraries, one example.
Then you can make a build for Android/iOS apps to use your mocked server instead of real server. In this case you will pre-define response instead of overriding it with proxy.
You can ask your developer to log the things you want to intercept or if they are already being intercepted in logs.You just need to collect the logs from ADB and use that in your appium code.
You can get the adb logs using :
List<LogEntry> logEntries = driver.manage().logs().get("logcat").getAll();
for(LogEntry entries:logEntries){
if(entries.getMessage().contains("*Things you need from logs*")){
entry= entries.getMessage();
}
}
return entry;

Android : what kind of server?

I'm developing an android app where I would like to fetch some data (mostly text) from the internet but not necesseraly from a website! I would like to have a server that allows clients to fetch some text data. What kind of server fits my goals the best? Http or maybe simply tcp? I don't know much about http so I don't know if it matches my goals and/or if it handles well a kind of text "database".
Edit:
A use case could be: people could write comments and send them to the server. Then clients could refresh their app by fetching new comments from the server. Therefore I'M asking what kind of server could best handle services and kind offre database if needed.
I like using NodeJS in combination with ExpressJS for such purposes. This combination allows you to easily work with HTTP/HTTTPS which is allowed by practically every firewall or proxy server. As of the latter reason I recommend you to use HTTP instead of an own protocol. Furhtermore, Java offers the HTTPURLConnection client which is very easy to use. Moreover, securing traffic with TLS (SSL) is very simple. In addition, NodeJS is resource efficient, runs on Windows, Linux and even on OS X.
For getting the text you can use HTTP GET request handled by the get() method of the Express instance.
This compact tutorial helped me to get familiar with Express on NodeJS.
Without knowing what your use-case is it's difficult to make a good recommendation.
With that said you may find something like https://parse.com/ suitable.
They provide an Android sdk and the 'getting started' tutorials will have you up and running in no time at all.

Is it necessary to use HTTP based client/server communication for an app development?

I want to make an app on Android using MySQL.
I'm new here, so I first see many other's app design. I find one thing is that if they have to use database, they often use RESTful design, defining some API for HTTP protocol for client/server side communication. And then, there're lots of things to do, like: mapping resources into url, sending/recieving doGet, doPost,.. requests.
But I don't understand. This is an app develop, not a web develop. Why do they have to make an app so much like a web? If I don't want to use phoneGap, HTML5, .. that kind of HTML-based develop, I want to write a native app. And I still want to seperate client and server end in my code, my server side could communicate with MySQL, and my client side display it to user, and they're all written in java. Since they're all java, so I got a native idea:
"why don't I call my server side code directly from my client end?"
Since it's all run on an app, there's no necessarity to map it into a url for user to access. But as I observed, most of people don't do this. So I want to know why they donnot make their app the way I think? Is it for security concerning? Or to reduce debug difficulty? Or for later expansion to other platform like iOS?
I want to know why they choose HTTP based client/server communication.
It's not just about security, because in either way you'd be setting an external Socket to the destination, but also because there's no native way to communicate between you app and MySQL. The most common approach in this way is using a web-service, where you'd implement a HTTP server with some code in your favourite language (PHP, Python...) that would process your requests made by your clients and process them accordingly. This third-party script would communicate with the database.
If you finally choose this approach and you're concerned about security, I'd choose some asymmetric encryption algorithm as TLS, where you could encrypt your messages with the public key and decrypt them in the server side with the private key.
You can share the public key with no concerns, you can simply embed in your code, but you could also put it in your web-server and make your clients download it each time they connect. This way, if some day you change it (because of a Heartbleed situation, for instance), they'll always have the current public key; otherwise, you'd need to update your app if you hardcode the public key in your code.
Some useful links:
Android Encryption with the Android Cryptography API
Create SSL-Socket over SSL-Socket with Client Authentication
How dangerous might be publishing a public key?

How to capture network traffic data of specific third-party App? Is it possibile?

Now I have a demand to capture the network traffic data of some specific third-party Apps, get the content and type of the data for future use, does Android provide API for this? Thanks for any advice.
If you are looking for something like tcpdump. It is not possible with in android app from another app or service. Unless you have root previliges, if I'm not wrong.
You have two options, If you need to make it in a-synchronize mode, you can use AsyncHttpClient else you can use HttpClient. Read about them.

Faking HTTP request responses for testing in Android

I'm writing an Android app which sometimes needs to request data through HTTP from a REST API. I'm using the Apache DefaultHttpClient for performing requests. Is there a way to write tests for this app and "replace" DefaultHttpClient's response when running the tests so that test results are always consistent?
As an example of the things I'd like to test, one of the web services I'm accessing takes a string and performs a text search, returning a paged list of objects. I need to test the cases where the list is empty, the list fits in the first page, or the list is larger than a page and the app needs to make several requests to get the complete list.
I'm not the developer of this web API nor can modify its responses, so I can't change what it returns. For the above example, if I want to test the case where the list returned is empty, I could just search for a string which I'm sure won't return any results, but the other two cases are harder because what the service can return is always changing.
I think ideally I would have a way to get a modified DefaultHttpClient when running tests, that returns a hardcoded result for requests to a given URL instead of actually doing the network request. This way I would always get consistent results independently of the real web service's response.
I'm currently using Robotium for testing but I'm open to using other tools too.
Yes, you can definitely "fake" responses when using the HttpClient framework. It's quite convoluted, and I will have to leave most of the details up to you, but I will give you a quick overview:
Implement ClientHttpRequestFactory, mainly so you can override the createRequest() method so you can...
Return your custom implementation of ClientHttpRequest, in which you can override the execute() method so you can ...
Return your custom implementation of ClientHttpResponse in which you will finally be able to return your fake response data, e.g. getBody() can return the content of a file, you can hardcode the headers in getHeaders(), etc.
The rest is figuring out how to best tie all these shenanigans to your service layer.
You might give Charles a try for something like this. Sorta a non-code solution.
http://www.charlesproxy.com/
I use the Charles' reverse proxies and the map local tool for things like this.
What you do is point your request at your local box on the reverse proxy port. Charles in turn can be configured to provide a static hard-coded flat file but to your app it looks like a 100% genuine web service response.
There are lots of other cool things you can do with Charles - watch traffic from your android app to and from your server and breakpoints (which allows you to tweak requests and responses before they are sent and received). Definitely worth checking out.
Another option is to use Dependency Injection so that you can change the HttpClient when running the tests. Check out Guice if you are interested.
I'm guessing you are interested in writing functional tests using the standard Android Junit testing framework. So you could just implement the parts of the API you are using on your own webserver and point at that server when running your tests.
If you'd prefer your tests to be self-contained, you could implement an Http server that runs on the device. Examples of using the Http server available in the Android class library are here and here.

Categories

Resources