Securing a single page application built on react/react-router - reactjs

I've been putting together a single-page application using React and React-Router and I can't seem to understand how these applications can be secured.
I found a nice clear blog post which shows one approach, but it doesn't look very secure to me. Basically, the approach presented in that post is to restrict rendering of components which the user is not authorized to access. The author wrote a couple more posts which are variations on the idea, extending it to React-Router routes and other components, but at their hearts all these approaches seem to rely on the same flawed idea: the client-side code decides what to do based on data in the store at the time the components are composed. And that seems like a problem to me - what's to stop an enterprising hacker from messing around with the code to get access to stuff?
I've thought of three different approaches, none of which I'm very happy with:
I could certainly write my authorization code in such a way that the client-side code is constantly checking with the server for authorization, but that seems wasteful.
I could set the application up so that modules are pushed to the client from the server only after the server has verified that the client has authority to access that code. But that seems to involve breaking my code up into a million little modules instead of a nice, monolithic bundle (I'm using browserify).
Some system of server-side rendering might work, which would ensure that the user could only see pages for which the server has decided they have authority to see. But that seems complicated and also seems like a step backward (I could just write a traditional web app if I wanted the server to do everything).
So, what is the best approach? How have other people solved this problem?

If you’re trying to protect the code itself, it seems that any approach that either sends that code to the client, or sends the code able to load that code, would be a problem. Therefore even traditional simple approaches with code splitting might be problematic here, as they reveal the filename for the bundle. You could protect it by requiring a cookie on the server, but this seems like a lot of fuss.
If hiding the internal code from unauthorized users is a requirement for your application, I would recommend splitting it into two separate apps with separate bundles. Going from one to another would require a separate request but this seems to be consistent with what you want to accomplish.

Great question. I'm not aware of any absolute best practices floating around out there that seem to outstrip others, so I'll just provide a few tips/thoughts here:
a remote API should handle the actual auth, of course.
sessions need to be shared, so a store like redis is usually a good idea, esp. for fast reads.
if you're doing server-side rendering that involves hydration, you'll need a way to share the session state between server and client. See the link below for one way to do universal react
on the client, you could send down a session cookie or JWT token, read it into memory (maybe using redux and keep it in your state tree?) and maybe use middleware (a la redux?) to set it as a header on requests.
on the client, you could also rely on localStorage to save the cookie/JWT
maybe split the code into two bundles, one for auth, one for the actual app logic?
See also:
https://github.com/erikras/react-redux-universal-hot-example for hydration example
https://github.com/erikras/react-redux-universal-hot-example/issues/608

As long as the store does not contain data that the user is not authorized to have, there shouldn't be too much of a problem even if a hacker checks the source and sees modules/links that he shouldn't have access to.
The state inside the store as well as critical logic would come from services and those need to be secured, whether it's an SPA or not; but especially on an SPA.
Also: server-side rendering with Redux isn't too complex. You can read about it here:
http://redux.js.org/docs/recipes/ServerRendering.html
It's basically only used to serve a root html with a predefined state. This further increases security and loading speeds but does not defy the idea behind SPAs.

Related

How to deal with authorization/authentication in that case?

Here at work we have a portal with like 6 systems lying under, each one has its own backend API, built with .NET Core, the frontend is React by the way.
The situation :
Today we have a single API that is used for both Authentication and Authorization (i will call it LoginAndProfileAPI) and its is used globally for all of the systems, here's my attempt to describe how it works :
As Is
we have this global,
The Issue :
Now we have a necessity to have local user management inside each system so that the local admins for that system can manage the access level/permission/profiles only of the profiles related to that application, we also need to turn our Auth process a little bit more standard, separating Authorization and Authentication a little bit more.
What would you guys do in this situation, what i came across until now was :
The idea i had, but stil needs some shape
but it kinda looks like a mess tho.
Does anyone have a clue of how can i be more standard with this
Edit :
Would that be best scenario ?
Looks pretty much like a more minimalistic/lightweight approach !!!
#WandererAboveTheSea suggestion about it
(did i get it right ?)
Here is a cleaner image :
JWT Auth Example
What looked kinda odd to me was that it seems like JWT is beeing used for both Authentication and Authorization
JWT is meant to be stateless and lite weight. Your using JWT for authorization is the correct approach.
You can improve on the following part.
After getting the username you are making database calls to get the user profile which you can avoid by adding those details to JWT itself. So that part can be simplified.
Information Exchange: JSON Web Tokens are a good way of securely transmitting information between parties.
Apart from this rest of the design looks good.

What's the best way to prevent React app being scraped?

I'm still very new to React so forgive me if the question is too naive. To my understand, React usually requires an API to do XHR requests. So someone with very basic tech background can easily figure out what the api looks like by looking at the network tab in web browser's debug console.
For example, people might find a page that calls to api https://www.example.com/product/1, then they can just do brute force scraping on product id 1 - 10000 to get data for all products.
https://www.example.com/api/v1/product/1
https://www.example.com/api/v1/product/2
https://www.example.com/api/v1/product/3
https://www.example.com/api/v1/product/4
https://www.example.com/api/v1/product/5
https://www.example.com/api/v1/product/6
...
Even with user auth, one can just use same cookie or token when they login to make the call and get the data.
So what is the best way to prevent scraping on React app? or maybe the api shouldn't be designed as such, hence I'm just asking the wrong question?
Here are some suggestions to address the issue you're facing:
This is a common problem. You need to solve it by using id's that are GUID's and not sequentially generated integers.
Restricting to the same-origin won't work because someone can make a request through Postman or Insomnia or Curl.
You can also introduce rate-limiting
In addition, you can invalidate your token after a certain number of requests or require it to be renewed after every 10 requests
I think no matter what you do to the JavaScript code, reading your API endpoint is the easiest thing in the world(Wireshark is an easy, bad example), once it is called upon from the browser. Expect it to be public, with that said, protecting it it is easier than you might anticipate.
Access-Control-Allow-Origin is your friend
Only allow requests to come from given urls. This may or may not allow GET requests but it will always allow direct access on GET routes. Keep that in mind.
PHP Example
$origin = $_SERVER['HTTP_ORIGIN'];
$allowed_domains = [
'http://mysite1.com',
'https://www.mysite2.com',
'http://www.mysite2.com',
];
if (in_array($origin, $allowed_domains)) {
header('Access-Control-Allow-Origin: ' . $origin);
}
Use some form of token that can be validated
This is another conventional approach, and you can find more about this here: https://www.owasp.org/index.php/REST_Security_Cheat_Sheet
Cheers!

Serve REST-API data in web-page without exposing API-endpoint

I am beginner in MEAN stack.
When invoking unauthenticated REST API (no user log-in required), API end-points are exposed in the JS files. Looked through forums that, there is no way to prevent abusers using the API end-point directly or even creating their own web/app using those end-points. So my question is, are there any way to avoid exposing the end-points in the JS files?
On a similar note, are there any ways, not to use REST calls on front-end and still be able to serve those dynamic content/API output data in a MEAN stack? I use EJS.
There's no truly secure way to do this. You can render the page on the server instead, so the client only sees HTML (and some limited JS).
First, if you don't enable CORS, your AJAX calls are protected by the browser, i.e. only pages served from domain A can make AJAX calls to domain A.
Public API providers like Google Maps protect themselves by making you use an API key that they link to a Google account.
That key is still visible in the JS, but - if abused - can be easily disabled.
There's also pseudo-security through obfuscation, i.e. make it harder for an attacker to extract a common secret you are using the encrypt the API interaction.
Tools like http://javascript2img.com/ are far from perfect, but makes attackers spend a lot of time trying to figure out what your code does.
Often that is enough.
There are also various ways to download JS code on demand which can then check if the DOM it runs in is yours.

Downsides using front-end frameworks for API handling? Performance and security

So, while practising all the new tech. Angular 2, AngularJS, Firebase, Loopback, NodeJS etc .. I'm kind of confused on some topics that people don't really talk about. It might go into too much detail, but I'll try to split it as much as I can.
Part 1 -- Performance
I like the approach of: MyApp (Web, Mobile, ..) --> API <-- Database
Okay, we perform API requests to the same server over HTTP which is slower, but for small projects this should be a non issue right? Or are there any other solutions for this matter?
I know they often just do: MyApp --> Framework <-- Database and add an API interface which calls the correct actions to get the necessary logic/data out to eg. a mobile app
-- End Part 1
Part 2 -- Security
So, assume we have an API up and running either with Lumen, LoopBack or anything else like a realtime Firebase database (not really an API). Then we can connect with it over HTTP requests via Angular, jQuery... If a user inspects our source code, they can easily see how we handle data in the backend. How can this be secured in a way that only the necessary applications have control over the API (OAuth2 ?) and also that we limit the insight of users into our API.
-- End Part 2
Thanks.
Okay, I thought, it's a "too broad" question, but actually, it has a short answer.
Performance
Irrelevant. If you gotta fetch data, you gotta fetch data. Be it API call or some custom action in your laravel code (or something). Same HTTP stuff.
Security
... where a user can check the source code of the API calls.
Security through obscurity doesn't work. Always consider that your client is compromised. Use proper authentication/authorization methods (OAuth and the like). So even if a malicious user knows (which he will) your api endpoint signatures (or whatever you were trying to hide), he can't abuse them.

Backbone restrict routes from user in permission based app

This is more of a request for pattern and discussion rather than a simple one-off question. I have a backbone app where user can be part of different roles. The routes are defined as usual:
routes:
"": "showHomePage"
"import": "showImportPage"
I would like the import page to be accessible only to certain user roles. I imagine I can do something like this:
showImportPage: ->
if not MyApp.CurrentUser.can_import
return
Which indeed works. Of course, as you can imagine, this is easily exploited by just using Chrome console, and even if I don't show the link anywhere it's quite simple to just go in the address bar and type it.
Even though the above should be enough to stop a normal user, my question is: how could I secure that route from being accessed?
The opinion I have until now is that the only way is to refer back to the server before serving that route, either by checking a special URL or by simply re-fetching the User model before accessing... I have this hitch, though, that this will basically defeat the purpose of the whole idea behind a "single-page-app", if every url must be authenticated by the server and I need to show the usual ajax spinner before allowing the user to navigate... I know the amount of data going back and forward is minimal (only the json user info or even less), but still...
What are your opinion or solutions if you ever had to face this problem?
I think your question is a great one.
I made a PhoneGap app using BackboneJS and Jquery mobile so I faced the same problems you are facing now.
I think authorization can't live solely on the client side since it is inherently wrong. What lives at the client, is fully controlled by the client, and that's something no one can change.
Sending a request to the server does not break the single-app-page paradigm as long as the request gets the minimal data needed and all logic/view components are located on the client.
Keep in mind that if you have sensitive data in that page that you don't want regular users to see, it also must be sent from the server after verifying the authorization of the request, so it is not only a JSON of the user info that must be sent, it is the data itself as well.
I wish someone else would prove me wrong here, but as far as it goes for me that's the deal.

Resources