Create a secure layer to hide web service from non-authenticated users, in an React App - node.js

I'm working in a React application that basically resets the password to non authenticated users. The problem is, in order to do that with Ajax, I'm exposing the service url (which is not secure, and I can't work over that, since that part of the project belongs to other company).
My idea was (I've never done this before so I'm not sure this is the way to go) to create some sort of REST service in the middle that "hides" the real service from the user, so I call it and "he" calls the actual server, giving me the data I need.
But, I need to secure this new service so only my app can use it, right?. If this is a good way to do it, how can I implement this with non authenticated users?. If don't, what can I do to solve this problem?
I'm open to any ideas, I was planning to use Node.js but I have zero experience with this particular matter.
Any help is very welcome, thanks in advance!

If you cant make any changes in the existing service and it lies in non secure env, then your thinking is correct. Its better to create a REST service which is called from UI, and that REST service in turn should call your existing service.
Now, if you dont have any feature to authenticate user, then I'm not sure how you can make that REST service secure. Even if you create a REST service, it wont solve your purpose if you dont have any means in place to authenticate user. Even that REST service will be exposed and wont solve your purpose.
If you have a functionality to authenticate user, like creating a session or capturing some details initially before you call this service or a login screen etc, which will serve as a way to verify user before you access other services, then you have a solution.

If you need to authenticate the users, the most current practice is to use e-mails - assuming that only the user has access to his email. (this is also the cheapest one).
When you generate the url is when you need to be careful. Basically, you need to ensure that it is unique, not publicly published, and associated with a particular user - for a short amount of time. The common and most straight-forward way to do it is by appending tokens to the url. Now, there are several crypto requirements connected to the token generation, I would advice not creating your own code for this functionally. As an example of one time use token, we can check https://www.rfc-editor.org/rfc/rfc6750.
However, as you tagged Liferay on this thread, you could consider using the UserLocalService to generate the emails.
Or get inspiration from this code for URL generation:
Date expirationDate = null;
if ((passwordPolicy != null) &&
(passwordPolicy.getResetTicketMaxAge() > 0)) {
expirationDate = new Date(
System.currentTimeMillis() +
(passwordPolicy.getResetTicketMaxAge() * 1000));
}
Ticket ticket = ticketLocalService.addDistinctTicket(
companyId, User.class.getName(), user.getUserId(),
TicketConstants.TYPE_PASSWORD, null, expirationDate,
serviceContext);
StringBundler sb = new StringBundler(6);
sb.append(serviceContext.getPortalURL());
sb.append(serviceContext.getPathMain());
sb.append("/portal/update_password?p_l_id=");
sb.append(serviceContext.getPlid());
sb.append("&ticketKey=");
sb.append(ticket.getKey());
passwordResetURL = sb.toString();

Related

How to prevent new user's registration on JHipster

I want to create a closed community. So I wold have a lot of users but all of them will be invited by myself or somebody.
Moreover I want them to have only one option to login - social accounts.
I've implemented this functionality but for me it looks like set of hack:
1) forbid /api/register endpoint to prevent self registration by the registration form
2) Do not create new user if it is still has not been created (here SocialService#createUserIfNotExist)
3) Modify some email templates
My questions now are:
1) Is it is right way or you can suggest better solution?
2) Do you think that it may be a good option for further JHipster generator?
The most important thing is first to block the backend calls to the /api/register endpoint by blacklisting it using .denyAll() in the security configuration. This will right away reject any request with HTTP 401 Unauthorized.
Secondarily you can work backwards and remove frontend and backend call.
Open the corresponding route file (I think it's account ) and delete the entry to register, then open the login HTML file and delete the part referring to the registration. That should do the trick

How to allow only one user to register with Stormpath

Context: I have never work with Stormpath before and want to fully learn how to do certain stuff. To practice I'm creating my own portfolio, including the CMS.
My question is, how can I restrict the registration of accounts to a handful of specific emails using Google API (only me should be able to add and remove content from my own portfolio).
E.g. Allow ONLY example1#gmail.com and example2#gmail.com to register.
I could do it manually, but I do not want to do that. Steps I would like to follow are:
Specify emails
User tries to access the CMS
User is prompted to login or register
Only if user is in the specified list of emails, user can register using Google's API.
I do understand this is a very general question that involves several fields: Google's API, Stormpath, not to mention Express and Node, but maybe someone else solved this problem and I can see some code. Thanks.
I'm the author of the express-stormpath library which I'm assuming you're using. There's nothing out-of-the-box that does this, so I'd like to point out the best way to do this:
Create a custom registration route, and model it after the built-in stuff here: https://github.com/stormpath/stormpath-express/blob/master/lib/controllers.js#L143
In your custom registration route code, add in some code that checks to see if the email address supplied by the user is a valid one or not.
If not, reject their request.
Now, in the real world you probably wouldn't want to do this sort of thing (it's a lot of extra work, and doesn't buy you much). What you'd probably want to do instead is: completely disable account registration on your website. This way, only YOU can create an account using the Stormpath dashboard on https://stormpath.com, but login still works on your site so that you can log in.
Does that make sense?
So basically, what I'm suggesting is that you disable registration on your site by saying:
app.use(stormpath.init(app, {
enableRegistration: false, // this will disable the registration page / functionality
// ...
}));
Hopefully this helps =)

How to restrict Chrome Apps to only work on specific computers?

I'm developing a POS Client using Chrome (packaged) Apps. It will run locally on the installed computers and interact with the server via web service. This app should only run on specific computers at the stores.
I know I can go to each store and install the .crx file in which case I don't have to publish the app to Chrome Web Store. However, I want it to be published to Chrome Web Store so that I can take advantage of its auto-updating feature.
What should I do to make sure that the app can only run at the stores' computers? (I can go the the stores and setup anything needed at the first installation).
Options I have thought of:
Create some secret key and enter it to the app at the first time of running.
Build a small tool (winforms application) to generate time-based tokens and install it on the computers. The staff will need to enter the token each time opening the app.
Any better idea how to accomplish this?
You said the app needs to talk to a web service to work. That's the key to a simple approach. (Assume you don't care whether the staff acquires a nonfunctional copy of the client app.)
At startup, app checks for existence of a validation of some kind stored in chrome.storage.local. If it exists, startup continues.
If the validation is missing, the app checks for existence of a GUID stored in chrome.storage.local.
If the GUID is missing, generate and store one using something like window.crypto.getRandomValues().
Ask the server for a validation by sending the GUID and getting a response.
If a validation comes back, save it in chrome.storage.local and go back to the start of this sequence.
Otherwise tell the user to get lost.
A full-strength version of this approach would have some additional features:
Use an HMAC(GUID, secret) for the validation. I'm assuming the staff aren't tech superstars, so something simple like a boolean would probably suffice.
Optionally add a per-launch step that sends up the GUID and validation and confirms it's still valid each time.
When the validation is requested, you might prompt for the secret key you mentioned in your question. In normal cases this would be needed only at provisioning time.
In case you haven't figured it out yet, the server is now acting like a simple licensing server, so it's up to you to decide how to decide whether the validation request succeeds. Maybe it allows only N validations to exist at once, or after you're done provisioning you hardcode future validations to fail. Maybe it limits validation requests to certain IP addresses. You get to choose.
That's the gist. It's a simple DRM system that is easier to manage than the enter-secret-at-installation method, but that won't withstand an attack of more than 30 minutes (since a smart attacker will just inject another machine's GUID and HMAC validation into the duplicate machine's chrome.storage.local).

Access without Logging in

Im using GWT, GAE to make a web app.
I looked at a bunch of tutorials regarding implementing a login system but most of those tutorials implement it so it's mandatory to login to access the web app. How would I go about making it so that anyone can access the app but if they want to use account specific functionality, they they have the option of signing up for an account.
There are two parts to it.
First, in your client code you check if a user is logged in. If so, you allow access to the "closed" parts of the app. If not, you show a link/button to login and hide tabs/views that are accessible to authorized users.
Second, in your server code you specify which requests do not require authentication and which do require it. This is necessary if a user somehow figures out how to send a request without using your client code.
For example, in my code some requests have checkSession() called at the very beginning. If no authentication object is found for this user in session, this method throws LoginException to the client. If the authentication object is present, the request continues to execute normally and returns requested data to the client.
Further to Andrei's answer, if you want a framework to manage the sessions for you, you can use GWT-Platform, which has an excellent Gatekeeper feature.
I use it for mine and I have a LoggedInGatekeeper class. Simply add #UseGatekeeper(LoggedInGatekeeper.class) to the constructor of each presenter proxy and it checks if the user is logged in. If you want anyone to be able to access that page simply annotate with #NoGatekeeper. Easy!
It takes a bit of setting up but it's a great MVP framework. There are maven archetypes and samples etc.
Hope this helps.

Facebook Javascript SDK security

I'm in the process of using the facebook javascript sdk to provide user login functionality for a website.
What I'd like to do is simply take the logged in user's unique facebook id and then put/fetch data to/from a mysql database using the id to determine what data is available to said user.
However I don't really feel like this is very secure. Whilst I'm not storing anything sensitive like credit-card details etc, I'd obviously prefer it to be as secure as practically possible.
My fear is that with javascript being what is it, someone could fake the facebook id and just pull whatever they wanted.
I'm aware that the php sdk would provide a solid solution to this problem, but i like the javascript one mainly because it's easy to use and I have the basis of it set up (I admit it, I'm lazy).
So, my questions are:
Would this set up be as insecure as I feel it might be?
Is there anything I can do to improve the security of such a system, other than switching to the php sdk?
Thanks!
Facebook Ids are pretty hard to make up (at most a user will only know their own). Depending on what you store in the database (which will not be anything that the user cannot get on their own, unless you ask for extended permissions)
If you are worried about a user trying to get information from the database, add an access token or signed request to each row and us that and facebook id to get data. That will greatly increase security.
EDIT
There are few occasions where you get a signed request from a user:
* A signed_request is passed to Apps on Facebook.com when they are loaded into the Facebook environment
* A signed_request is passed to any app that has registered an Deauthorized Callback in the Developer App whenever a given user removes the app using the App Dashboard
* A signed_request is passed to apps that use the Registration Plugin whenever a user successfully registers with their app
Signed requests will contain a user id only if the use has accepted permissions though, and are not passed again if the user enters the application, and accepts permissions (meaning that the signed request would not contain the ID). Because of this saving an access token may be a better idea. Here is more on the signed request
Also the signed request is in the url (param = "signed_request"). I always parse it through c# but I am sure you can at least get one through javascript
It's pretty easy to spoof the origin using curl. I'd imagine Facebook has another mecanism in place to make this possible. If you inspect their code, it appears that they generate an iframe and pass requests through. If I had to guess, they have setup the requests to only be made from the Facebook domain, and ensure that the iframe can only be embedded in a page that has a white listed domain.

Resources