Ionic 1 public api protection to consume only by android smartphones - ionic-framework

I build an ionic app using version 1 some year ago, the app is public no authentication is required.
How can i enable api consume only from the android smartphone ?
If someone decompile the apk they can see the api and consume data from the api
How can i prevent this ?

At the end of the day, there isn't much you can do to completely prevent someone from accessing or scraping data via your public API.
However, here are some ideas that can help mitigate it:
API Key
Store an API Key in your app, and validate the key on the server side before processing the request. This suggestion isn't too helpful if they decompile your app, but at least it's a start in preventing the API from being exposed by just using the app (especially if you make all your HTTP requests over SSL).
IP Address Logging
Setup some code within your mobile app that logs the IP address of the user. Then, when a call is made to your public API - it compares the IP address from the request with the list of IP addresses that have been logged from the mobile app. You can even use timestamps to limit the time frame in which the API will be accessible.
Rate Limits/Usage Quotas
You can put some general rate-limits on your API. Only allow a certain number of requests within a specified time frame from any given IP address, user, device ID, etc.
Hope this helps. I would love to hear more thoughts from other people in the community as well!

Related

API Authentication - Clients (consumers) vs. local users

I work for an ecommerce site and we are looking to expose much of our core functionality via a set of APIs. We plan on re-writing some of our own public facing applications (e.g. the main shop website and our mobile app) to call these new APIs also. We also want to offer some of these APIs out to third-parties who want to integrate with us.
My first question is - what is a suitable authentication method for these APIs? Everything I read is about OAuth, but am I right in saying that this doesn't fit in this case as we're not looking to use another log in system (e.g. Facebook, Google) but rather restrict access to our own API (so maybe an API key or JWT solution would be better?)
Secondly, our current website has it's own user accounts system. How do you offer /user endpoints (like GET user/1235/paymentmethods) in an API like this? Surely the actual user (website customer) needs to authenticate somehow in order for the given API consumer to access their data.
I've spent the last 2 days reading about this but I'm at a loss as to how to go about this! Any help much appreciated.

Google Assistant actions on google

All my hardware is already developed. I use MQTT for communication between my devices, I have lights, fans, heaters and many more ioT appliances. I can controll all of these from my Android application which i have built. I would like to use Google Assistant to control my devices as well. The status of my lights (on/off) are stored in a sql database and when ever a change occurs to the database(detected by the hardware) my hardware can control that specific light. In My Android app i do the same thing which is updating the databases value(on/off) of the light and the change is detected by my hardware platform. Can i use Google Assistant to update a sql database value?
I can create a webserver( ASP.NET C#) and pass the command to the sql database of my relevant customer if google assistant can invoke the username or email, lightID, command to my webserver. Can google assistant do this? If not how would achieve this.
It sounds like you want to take a look at the Actions on Google Smart Home API which will let the Assistants Smart Home controls work with your control server directly.
Without knowing exactly how your database or existing web server are configured or hosted, I can speak only broadly at best. Your web server will need to implement two primary things:
You'll need an OAuth2 server that can issue tokens that represent your users. This is how Google will associate the user's account on the Assistant with your account, and how Google will identify (to you) which user is issuing the command.
You will need to implement a webhook at a URL on your web server. This webhook will be sent a POST message containing a header with a valid auth token (that you issued) and a JSON body. The JSON will contain information about the command that has been issued by the user. Your HTTP reply body will also be JSON. For details of the JSON formats and all the fields that it can send and that you must reply with, consult Google's documentation.
There are a number of different commands (which Google calls "intents") that Google can send you on behalf of the user. You should be able to handle all of them by either querying or modifying your database:
SYNC - A request for what devices this user has, some of their configuration information, and what commands they respect.
QUERY - What is the current state of the devices for this user.
EXECUTE - Change the state on some of the user's devices.
RESYNC - (Future update) A re-request of the user's device info.

How to restrict which Google Home devices can interact with an action?

I want to build a Conversation Action for Google Home device and control its access. Only certain devices can invoke some actions. How can this be done, once the agent is publicly deployed?
Think of Google Home the same way you would think about a web browser and an Action the same as a web page or site. If you wanted to limit what web browsers can access a public site on the Internet, you're somewhat limited.
You could restrict access to certain IP addresses, and this will work in some cases - but it means that access via non-static IP addresses aren't possible, and if (ie - when) a machine gets a new static IP address, you have a lot of work to do. Similarly, the Google Home device can send a random user_id string for each unique user, and you can use this to limit who has access. But this string can change by the user resetting their Google Home device, and when it does, you will have to deal with that.
A better solution on the web is to allow people to log into your site. This way you can have a public facing web page, but only people with accounts can access. You can determine how to hand out accounts, so this is very flexible. The equivalent with Google Home is Account Linking where you will maintain an account as part of an OAuth2 system that you control. Google Home will ask for permission to access your system, and you will issue OAuth2 tokens to Actions - these tokens will be passed back to you for each request, and you can verify that the user has access.
I strongly suggest going with the Authorization Code Flow since this seems to be where Google is focusing on providing additional features - such as signing up to your service through Google Home.

How to secure Rest Based API?

We intend to develop rest based api. I explored the topic but it seems, you can secure api when your client is an app (So there are many ways, public key - private key etc). What about websites / mobile website, if we are accessing rest based api in website which do not use any login for accessing contents ( login would be optional ) then how could we restrict other people from accessing rest based api ?
Does it make sense using Oauth2.0 ? I don't have clear idea of that.
More clear question could be ,How can we secure get or post request exposed over web for the website which doesn't use any login ?
If it's simple get request or post request , which will return you json data on specific input, now i have mobile website , who will access those data using get request or post request to fetch data. Well, some else can also access it , problem is i am not using Login, user can access data directly. But how can we restrict other people from accessing that data.
What do you think is the difference between securing a website that is not using REST vs one that is using REST API?
OAuth provides authorisation capabilities for your site, in a REST architecture this means a user of the mobile application will have to provide their credentials before being allowed to access the resource. The application can then decide on if that user has access to the requested resource. However you've said your website doesn't need use authorisation.
You can use certificates however good luck managing the certificate for each client. My take on it is for your explanation you don't need to secure your website because you will never be able to manage a trust relationship between the client and the server. There are some options though:
You build your own client application that you ship out to people which can verify itself with the server using a packaged certificate with the client. E.g. iOS has this kind of feature if you build for that device.
You provide a capability to download a certificate that is 'installed' in the browser and used when communicating to your REST API
Use something like a handshaking protocol so when a client wants to make the first request it says; 'hi I'm a client can we chat?' And the server responds with 'yes for the next X minutes we can however make sure you send me this key everytime you tell me something YYYYYY' (you can use something like SecureUDID or equivalent for other devices than iOS).
There are probably others but you get the basic idea. Again in my opinion if your resource doesn't need authorisation then you don't need to secure that REST API. Can I ask what kind of data are you exposing via this REST API or functionality your providing? That might help provide a better answer.
You want authorization: only some agents (mobile clients) and/or users should be allowed to access those APIs.
To solve that problem, you need identification: a way for the server to tell who is who (or what), so the right decision can be made.
There are many different way to provide some form of identification, depending how much you care about security.
The simplest is a user agent string, specific to your mobile clients. But it can be faked easily. Slightly harder to fake are client based 'secrets' - embed some kind of secret or key in your mobile client code. You can make it really complicated and secret, but as ramsinb pointed out, you can't get security this way as it would require you to be able to guarantee that the secret you're shipping with the client (wether it's code, algorithm or any other fancy construct) can't be compromised or reverse engineered. Not happening when you don't control the client.
From there, 3 choices:
Security isn't really required, don't bother
Security isn't really required, but you still want to limit access to your API to either legit users/agents or people ready to invest some time hacking your protection - go with a specific user agent or a client embedded secret - don't invest much into it as it won't block people who really want access to get it anyway
Security IS required - and then I don't think there is a way around authentication, wether it's login/password, user specific (device specific?) keys, OpenID, etc... No matter what, you'll have to add to the user burden to some extent, although you can limit that burden by allowing authentication to persist (cookies, storage....)

Signed request from iOS device to web service

We're looking to use the UDID to authenticate a user against server-side web services for an iOS application. My one concern is that users will try to brute force access to another user's account by making auth attempts using random UDID values. I can work on things such as throttling their requests, however I was curious if there is a way to make a "signed" request.
Meaning, is there a way I can certify that the client with UDID foo was generated and sent from the device that UDID foo belongs to, and not some random user with access to curl and a ruby script to call my service multiple times?
I think what I'm looking for is a signed http request. I'm not sure where to start building out such support on either the client or server though.
Those GUIDs are huge. The chance of guessing one seems extremely remote. I'd guess it would take several millennia to come across one 'randomly'.
You are almost surely at more risk of someone sniffing an existing one or using their access to the user's device to obtain it.
Honestly, given how easy it would be to obtain a user's udid, I'd be surprised if Apple didn't recommend against using it that way.
All it takes is for me to email one of your users with a link to my "cool new free game" and bam I've got the udid.
Or, sitting in a coffee shop, and sniffing WiFi traffic - waiting for some ad-sponsored game to send the udid over the wireless for tracking purposes.
But...
How about Client SSL Certificates?
How to use Client Certificate Authentication in iOS App
Or Signed XML Documents?
http://en.wikipedia.org/wiki/XML_Signature
Honestly, there is only so much you can do in this regard.
You'll never be able to stop a truly determined bad guy from cracking open your .ipa and extracting a client side ssl cert - or whatever other mechanism you have to thwart someone.
I'm just saying - since you are distributing the application (this isn't an in-house application running point-to-point over the internet) there is really no way to truly secure the client (mobile) side code - and thus, no way to truly ensure only authorized clients are making requests to your service.
Ultimately, the burden of security is on your services.
You should give a try to HTTP authentication