SmartCloud OAuth2.0 Registering applications - mobile

I am busy writing an mobile application that connects with IBM SmartCloud. Since I want to use OAuth 2.0 I find it difficult to handle the Secret Key and the Client ID.
Since I have to Register the Application within the IBM SmartCloud console, and copy the Client ID and Secret Key to the App I am creating... Well that ain't the biggest problem, but when someone wants to use my app on another environment he doesn't have the same Secret Key and Client Id.
What is the best way to deal with this, because I want to make it usable for others, and not only for my use.

You may want to refer to the ibmsbt.openntf.org - the sources include directory includes a project for iOS. It's tested with IBM Connections On Premises
http://www.openntf.org/main.nsf/project.xsp?r=project/Social%20Business%20Toolkit%20SDK/releases/F07E34DFDDA6C06686257C6B006C6393
The project uses a callback to a custom PROTOCOL/URL : ibmsbt://myapp?code=
For IBM Connections/SmartCloud, you'll want to register an OAuth2 Key.
When you register you'll want to register your application, ibmsbt://myapp/
Then You can use these endpoints and parameters:
https://apps.na.collabserv.com/manage/oauth2/token/manage/oauth2/authorize?response_type=code&client_id=app_20085940_1384885218905&callback_uri=ibmsbt%3A%2F%2Fmyapp%2Fcallback
https://apps.na.collabserv.com/manage/oauth/authorizeToken?oauth_token=OAUTH_TOKEN

Related

Exposing API Endpoints in Frontend Application

I am building a frontend application using react and I am wondering whether it is risky to expose API endpoint URLs (ex: https://myapi.com/v1/getitems) on GitHub, assuming that the endpoint has several security measures that are not exposed such as CORS and JWT Token Bearer Authentication. I would assume not, since, if someone were to take the endpoint and send requests, they would need a token and be allowed to do so by CORS.
Is there any security risk in doing so?
Yes. Don't add the base url of your api on github in plain view. Even though you might have CORS and Authorization, that doesn't stop a malicious actor to keep spamming your back-end.
What you do is create a .env file in your root folder. You can use a library like #beam-australia/react-env and there are others as well.
You add in the .env file the values that are important for your environment and that are usually secrets, and you want them to not be visible in your code. You do it like so:
API_URL="https://myapi.com/v1"
And then you access this variable in your code with env("API-URL") ( in the #beam-australia/react-env case, but others libraries work the same). Keep in mind that you need to add .env in .gitignore so that the .env file is not pushed to github.
Regarding requests, you can make one like so:
fetch(`${env("API_URL}/getitems`)
This way your code will be stripped of the API's base url and if someone sees your code it will see only the endpoint, not the full url.
Publishing the code of the API is risky on its own. Somebody can find a vulnerability in it and instantly hack it. If you add the address of the API to the code you help this kind of attacks. They can get the address with some investigation; OSINT and social engineering too, but better to reduce the attack surface.
As of the secrets, they must never be near to the code, because you or another developer can accidentally publish it. It happened too many times with many developers, so better to take this seriously. If you want to keep the address in secret, then you must extract it from the code and put it in the configuration of the production environment which is imported from a totally different location than your code. Using environment variables like Alex suggested is a good idea for this. Nowadays it is common to use docker, which has a way to manage secrets, so you don't need to reinvent the wheel: https://docs.docker.com/engine/swarm/secrets/ Another aspect that the configuration belongs to the actual instance. In OOP terms you want to describe the injected properties of an object in its class or in a global variable, which is an antipattern.
As of client side REST clients like javascript applications running in the browser or Android/iOS apps, you must not publish your secrets along with the REST client, otherwise it is not a secret anymore. In that case you need a server side part for the REST client and for example sign and encrypt JWT there with a secret key. It is your decision whether this server side part of the REST client sends the HTTP request to the REST API and in that case you can hide the URI of the REST API or it just manages the JWT and the client side part of the REST client sends it. If the server side part of the REST client sends the HTTP request to the REST API, then you can even use traditional sessions with session cookies between the client side and the server side parts of the REST client, but you cannot use them between the server side part of the REST client and the REST API where the communication must be stateless. Though it does not make much sense to have a separate REST API if you don't have multiple different REST clients in this scenario e.g. browser clients for JS and JSless browsers, Android and iOS clients, fully automated clients running on servers, etc. So don't confuse the REST client - REST API relationship with the browser - HTTP server relationship, because they are not necessarily the same. Most of the REST clients run on servers, not in the browser.

How to protect web client ID in GCP source code

My GAE app publishes some APIs in GCP and uses the following structure:
# Replace the following lines with client IDs obtained from the APIs
# Console or Cloud Console.
WEB_CLIENT_ID = '????????????.apps.googleusercontent.com'
ALLOWED_CLIENT_IDS = [WEB_CLIENT_ID, endpoints.API_EXPLORER_CLIENT_ID]
SCOPES = [endpoints.EMAIL_SCOPE]
#endpoints.api(name=API_NAME,
version=API_VERSION,
description='An API to manage languages',
allowed_client_ids=ALLOWED_CLIENT_IDS,
scopes=SCOPES)
My doubt is if someone picks this source code from my machine or GitHub project. He or she can access the APIs using the discovered web client id.
What’s the best practice in this case?
I acknowledge that the client can expose the ID and someone have access to it. But I believe that is another matter.
There are many ways you can do this. One way is to always check in a default value for the client ID, so that when people check out your code, they have to modify it to deploy it. You can also move the client ID to its own module and not check it in at all, and make the expectation that they create their own module with their own client ID. This avoids having a modified state for a checked in file all of the time.
The client ID itself is not sufficient information to generate a valid token. The cryptography involved will prevent such a person from accessing your API.

How to use generated clientid with Google cloud endpoints for authenticating 3rd party users without redeploying app

In my case we work with other companies which would consume our APIs along with our internal javascript client. I think we need to create a web client id for javascript client. But when exposing APIs externally, is it correct to generate new web client id per company? If so do we have to update clientid each time and redeploy application?
I'm following this documentation and in their example client ids are hardcoded, if I need to give access to new 3rd party users, then I need to generate new client id for them but I'd expect to not redeploy application.
Update: I've created a feature request as per #Alex's suggestion below.
Unfortunately the docs at https://cloud.google.com/appengine/docs/python/endpoints/auth very specifically say, and I quote,
Because the allowed_client_ids must be specified at build time, you
must rebuild and redeploy your API backend after adding or changing
any client IDs in the authorized list of allowed_client_ids or
audiences
so it appears that your perfectly-reasonable use case is very explicitly not covered at this time.
I recommend you visit said page and enter a feature request via the "Write Feedback" link (around the upper right corner of the page) as well as entering a feature request on the Endpoints component of the App Engine feature tracker, https://code.google.com/p/googleappengine/issues/list?can=2&q=component=Endpoints&colspec=ID%20Type%20Component%20Status%20Stars%20Summary%20Language%20Priority%20Owner%20Log -- we monitor both, but with different processes, so trying both is best.
Sorry to be a bearer of bad news. For now, it seems the only workaround is to distribute to the other companies one of a bunch of client ids generated in advance (you can only change the valid bunch when you re-deploy, sigh) and perhaps add some extra, app-layer authorization check of your own -- exactly the kind of work endpoints should be doing on your behalf:-(.
You can use an asterisk as the client ID, that will allow any client to call it without redeploying your API backend. Not sure if this is a documented feature or not, but it works (at least) with both Python and Java.
#Api(name = "myapi",
version = "v1",
scopes = {"https://www.googleapis.com/auth/userinfo.email"},
description = "My flashy API",
clientIds = {"*"})
public class MyAPI { ... }

WCF security between WinForms client and Shared Host webserver

Ok,
I have developed this WinForms client, which interacts with a server (ASPX Application) by means of WCF calls. I would now like to deploy the server to my shared webhost, but I'm kinda new to WCF and especially the security possibilities behind it.
The goal is to kind of secure the WCF service, so that not everybody that knows or finds out the endpoint address can call it. Rather, only my WinForms client must be able to call the WCF service.
I do not need authentication on a user basis, so no authentication is required from the user of the client. But I want only instances of this WinForms client to be able to interact with the service. The information passed between server and client is not very sensitive, so it's not really required to secure it, but it's a plus if it can easily be done.
Is this possible with a Shared Host (IIS) environment (no HTTPS at disposal) ? What bindings and options should I use ? I suppose wsHttpBinding, but how would I setup the security options ?
Using .NET 4.0
Thanks
From what I understand, you have an internet-facing service which you want to limit to only your client app to be able to call - correct? Or do you envision other clients (like PHP, Ruby etc.) also wanting to call into your service at some point?
To secure your message, you have two options in WCF - message or transport security. Over the internet, with an unknown number of hops between your client and your service, transport security doesn't work - you're left with message security (encrypting the message as it travels across the 'net). For this to work, you typically add a digital certificate to your service (only server-side) that the client can discover and use to encrypt the messages with. Only your service will be able to decrypt them - so you're safe on that end.
The next point is: who can call your service? If you want to be totally open to anyone, then yes, you need wsHttpBinding (or the RESTful variant - webHttpBinding). If you want to allow non-.NET clients, you're typically limited to no authentication (anyone can call), or username/password schemes which you will validate on the server side against a database of valid users.
If you only want to allow your own .NET client in, then you can do several things:
disable metadata on your service; with this, you would "hide" your endpoints and the services they provide - someone using a "metadata scanner" (if that exists) wouldn't be able to just stumble across your service and find out what methods it provides etc. This however also makes it impossible for another developer outside your organization to do an Add Service Reference to your service.
you could define and use a custom binary http binding - only other clients with this setup could even call your service. The binary http binding would bring some speed improvements, too. See this blog post on how to do this.
you need to somehow identify those callers that are allowed in - one possible method would be to put an extra header into your WCF messages that you then check for on the server side. This would simply make sure that a casual hacker who discovers your service and figures out the binary http binding would still be rejected (at least for some time). See this blog post here on how to implement such a message inspector extension for WCF.
the ultimate step would be to install a digital certificate on the client machine along with your service. You would then set up your client side proxy to authenticate with the service using that certificate. Only client machine that have that certificate could then call into your service.
It really depends on how far you want to go - WCF gives you a lot of options, but you need to decide how much effort you want to put into that .
The first thing you need to ask your self is: "What can someone do to your WCF service if they connected their own customized client?" Look at all of the functionality that is being exposed via WCF and assume that it could be accessed at will. You have absolutely no control over the client, and you will never have this ability.
HTTPS is beautiful, its a damn shame that your forced to be vulnerable to OWASP A9: Insufficient Transport Layer Protection. If it where up to me, I would move to a different host that cared about security. If you are throwing usernames and passwords over the network, then your putting your users in danger.
One of the biggest problems I have seen with a WCF service is that they had a "executeQuery()" function that was exposed. The developer allowing the client to build queries to be executed by the server. This approach is fundamentally flawed as you are just handing your database over to an attacker. This type of vulnerability isn't SQL Injection, it falls under CWE-602: Client-Side Enforcement of Server-Side Security.
Along the same lines as CWE-602 is OWASP A4: Insecure Direct Object References. Could an attacker fool your WCF service into thinking its another user by providing a different user id? Are you trusting the client to tell the truth?
The next classification of vulnerabilities that you must take into consideration is OWASP A1: Injection, other wise known as "Taint and Sink". For instance if you are exposing a function where one of its parameters is being used in a CreateProcess() which is invoking cmd.exe. This parameter could be controlled by the attacker, and there for this variable is "tainted", the call to CreateProcess() is a "sink". There are many types of vulnerabilities along these lines, including but not limited to; SQL Injection, LDAP Injection, XPATH Injection. These types of vulnerabilities affect all web applications.

Using a subdomain to identify a client

I'm working on building a Silverlight application whereas we want to be able to have a client hit a url like:
http://{client}.domain.com/
and login, where the {client} part is their business name. so for example, google's would be:
http://google.domain.com/
What I was wondering was if anyone has been able, in silverlight, to be able to use this subdomain model to make decisions on the call to the web server so that you can switch to a specific database to run a query? Unfortunately, it's something that is quite necessary for the project, as we are trying to make it easy for their employees to get their company specific information for our software.
Wouldn't it work to put the service on a specific subdomain itself, such as wcf.example.com, and then setup a cross domain policy file on the service to allow it to access it?
As long as this would work you could just load the silverlight in the proper subdomain and then pass that subdomain to your service and let it do its thing.
Some examples of this below:
Silverlight Cross Domain Services
Silverlight Cross Domain Policy Helpers
On the server side you can check the HTTP 1.1 Host header to see how the user came to your server and do the necessary customization based on that.
I think you cannot do this with Silverlight alone, I know you cannot do this without problems with Javascript, Ajax etc. . That is because a sub domain is - for security reasons - treated otherwise than a sub-page by the browsers.
What about the following idea: Insert a rewrite rule to your web server software. So if http://google.domain.com is called, the web server itself rewrites the URL to something like http://www.domain.com/google/ (or better: http://www.domain.com/customers/google/). Would that help?
Georgi:
That would help if it would be static, but alas, it's going to all be dynamic. My hope was to have 1x deployment for the application, and to use the http://google.domain.com/ idea to switch to the correct database for the user. I recall doing this once when we built an asp.net website, using the domain context to figure out what skin to use, etc.
Ates: Can you explain more about what you are saying... sounds like you are close to what I am trying to come up with. Have you seen such a tutorial for this?
The only other way I have come up with to make this work is to have a metabase that when the user logs in, it will switch them to the appropriate database as required... was just thinking as well that telling Client x to hit:
http://ClientX.domain.com/ would have been sweeter than saying to hit http://www.domain.com/ and login. It seemed as if they were to hit their name, and to show it personalized for them right from the login screen would have been much more appealing for the client base.
#Richard B: No, I can't think of any such tutorial that I've seen before. I'll try to be more verbose.
The server-side approach in more detail:
Direct *.example.com to the same IP in your DNS settings.
The backend app that handles login checks the Host HTTP header (e.g. the "HTTP_HOST" server variable in some platforms). That would contain the exact subdomain.example.com that the client used for reaching your server. Extract the subdomain part and continue...
There can also be a client-side-only approach. I don't know much about Silverlight but I'm assuming that you should be able to interface Silverlight with JavaScript. You could read document.location with JavaScript and pass it to your Silverlight applet, whereon further data fetching etc. logic would rely on the subdomain that was passed in by JavaScript.
#Ates:
That is what we did when we wrote the ASP.Net system... we pushed a slew of *.example.com hosts against the web server, and handled using the HTTP headers. The hold-up comes when dealing with WCF pushing the info between the client and the server... it can only exist in one domain...
So, for example, when you have {client}.example.com and {sandbox}.example.com, the WCF service can't be registered to both. It also cannot be registered to just *.example.com or example.com, so that's where the catch 22 is coming in at. everything else I have the prior knowledge of handling.
I recall a method by which an application can "spoof" another domain name in certain instances. I take it in this case, I would need to do such a configuration? Much to research yet I believe.

Resources