dojo web application authentication - javascript

I am attempting to develop a pure javascript web application using Dojo. The problem I face is one of restricting access to portions of the application. Authenticated users should be able to access everything, whereas non authenticated users should only be able to access a login screen.
The issue is that nothing (that I am aware of) will stop a user from opening up a browser javascript terminal and entering something like: app.displayRestrictedContent(); and thus gaining access to a screen intended for authenticated users.
I have implemented an ajax based login; all ajax calls are secured with a session. So while the non-authenticated user can load a restricted screen, they wont be able to fetch data for it. But still, It seems wrong for this screen to be arbitrarily accessible.
Am I trying to do the impossible? It seems silly to write code such as if (user.auth) app.displayRestrictedContent(); when it's so easily circumvented. And this leads me to believe I am missing something rather obvious to everybody else. I can't find much information at all on pure javascript based apps and authentication models.

But still, It seems wrong for this screen to be arbitrarily accessible.
Because it's client-side code. Anything you write in js, or get compiled to js, expect it to be readable by the users.
Am I trying to do the impossible?
you can dynamically load js modules after the user authenticates. So at first, just load 1 login module. When the user logins, if successful, the server return a list of js modules to load, if not, return empty list. It also helps improve load time when the users come to your website.

I'm by no means an expert, but here are some thoughts I've made on this. I don't think you've missed anything (if so, I have too) - I think this is a pretty fundamental issue with all client applications, whether it's a compiled executable or a Javascript.
Of course, the compiled executable is not particularly hampered by it, because it's been made into machine code which is very difficult to read or decompile into anything useful. With Javascript however, the application is often served exactly as you wrote it, and so it's easy to modify and reason about.
That brings me to the first semi-solution: obfuscating your Javascript. If you use Dojo's build tool with the shrinksafe parameter, all unnecessary whitespace is removed and all identifiers are shortened, making the code quite difficult to read. I called this a semi-solution, some may say even that is giving it too much credit - I myself still think it's worth doing. After all, the shrunk code downloads faster too!
The second measure I take in my apps is to separate the different parts into "build layers". For example, in my build profile, I'll have something like
dependencies = {
..
layers: [
{ name: "../myApp/Core.js", resourceName: "myApp.Core",
dependencies: ["myApp.Core", "myApp.Foobar"]
},
{ name: "../myApp/modules/Login.js", resourceName: "myApp.modules.Login",
dependencies: ["myApp.modules.Login", "myApp.modules.LoginUi"...],
layerDependencies: ["../myApp/Core.js"]
},
{ name: "../myApp/modules/Secret.js", resourceName: "myApp.modules.Secret",
dependencies: ["myApp.modules.Secret", "myApp.modules.SecretUi"],
layerDependencies: ["../myApp/Core.js"],
authentication: 42
}
]
}
Now, instead of serving the built JS files directly as static files, I let the requests go through a controller in my server-side application, which checks if the JS layer requires authentication and whether or not the user is logged in with the necessary access.
This does have certain cons. The JS files aren't cached, and if I had all my JS in one build layer, the application would probably load slightly faster. There's of course also a limit to how nuanced it's worthwhile to make the layers. More layers mean more hassle, but also more finely grained module access.
I'd be interested to hear others chime in on this as well. It's a good question.

When a user successfully logins the server should provide him with a session token. The Afterwards, whenever the user requests a resource (either via just redirecting the browser or via AJAX) he shows the server his session token (either by storing it in a cookie and sending it automatically on all requests or by explicitely passing it in the body of an AJAX request)
The server can then use session tokens from the users to control authorizations server-side, rejecting any request with an invalid or outdated token.
https://en.wikipedia.org/wiki/HTTP_cookie#Session_management

Related

Disable client hydration in Nuxt.js or Stop exposing raw data in Nuxt.js

I creating a Web App that using Nuxt.js, with Server-Side Rendering.
I don't want expose my backend data, so I tried to use asyncData and Axios to request to my backend server.
But the Nuxt.js exposed my backend data to client with window.__NUXT__.data variable.
I tried remove this by using render:route hook, But It says
[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside p, or missing . Bailing hydration and performing full client-side render.
So I tried remove the script that making not matching error, But It makes stop working script at my site.
So the question: How to disable the client hydration(client-side virtual DOM tree rendering)? or How to stop exposing raw data?
I used asyncData with this code:
asyncData ({ params, error }: { params: { id: string }, error: Function }) {
return axios.post('(backend)', data).then(res => res.data ? ({ data: res.data }) : error({ statusCode: 400, message: 'Bad request' }));
}
You cannot stop the hydration of your SSR'ed content (not yet at least, it is planned to server only static content pretty soon tho).
Nuxt is aimed to add SSR to your day to day VueJS SPA. If you don't want the hydration, you're probably using the wrong framework here anyway.
Astro may be a better fit, to name just one. You could find more here too.
The DOM mismatch issue is explained here (reasons + solution).
How to hide things on the client side?
Short answer: you can't.
Long answer available here.
If you want to display something on a page, you'll need data.
Nowadays we're using SPAs to have a local state in the browser. Since it's local and under your eyes, the state is living in your browser, so you can't really hide it and also, why would you do that?
If you want to hide the data, maybe don't send it initially or send an image at least.
You could also make some obfuscation, but this will just be a band-aid and not really good on semantics/performance/etc...
If you have some sensitive data that you want to show only to admins or so, you could use some auth and rights checking. More details above, in the long answer.
If you really really want to hide data on plain sight, that is, you want to send data on client-side without exposing it, then you do not have a full solution for that as it is, but there are ways to achieve what you need, choose your preference based on your intent.
Not sending data to the client if you do not want to expose it
Yes, I know you have asked for the diametrically opposite, but, before you read the really, really unconventional and often difficult approaches, first, let's ponder on whether you really need this indeed. The alternative would be to just not send this data to the client at all, but rather work with this sensitive data on the server. It is the scenario you will need 99.9999% of the cases of web-development. (the number is my subjective estimation, not the result of a representative statistical research)
Email, chat, SMS, paper mail, smoke signals, morse messages
You may need to send that information for the client, but this does not automatically mean that you will need to send it to the client-side of your website. You could send the information using some other channel, just make sure that it's trusted and reliable. For this reason I don't really recommend the use of smoke signals.
iframe
Now to the technicalities. Modern browsers protect against the scenario when you have webpage1 opening webpage2 in an iframe if they happen to have a different domain. So, you can create a domain that's different from the one your main page uses and show whatever you want to the client by calling a page of your brand new second domain (via HTTPS, of course), using minimized Javascript and closures. If you need communication between your iframe and your main page, then you can use messaging between the two, see Communication between tabs or windows.
A possible objection may be that one can still see the network tab of his/her browser where the actual received data is being shown as well as the possibility to debug Javascript. Well, bad luck. We cannot send the data to the client without sending it to the client. If this caveat is too much of a risk, then read on.
Encode the content you want to avoid from exposure
Yup, it will create a lot of difficulties and sometimes you will wish you never did it, but you can encode your top secret data and even if the user has access to it, he/she will have no idea what it is. But in this case you will need to face the problem of encrypting/decrypting your data whenever you use it.
You can use visual representation of your data
Like an image, an svg or some other kind of generated captcha-like content, but don't send it a file, because a third-party watcher may just download it. If you generate that inside an iframe, then your data is difficult to mine. Oh, wait, but what if the hacker looks at your screen from behind your chair?
Write your own browser (extension?)
You can implement a browser or a combination of browser extensions that will handle this and use HTTPS. But what if the spy has a lucky day and deciphers it? What if you have a virus?
Bottom-line
By the sheer fact that you are sending data to the client-side you will have to accept some risks. There is no way around it. You can reduce those risks, but it's always safer not sending the data than sending it.

Sending safely JSON to server via an HTML form page

I have an html page that has a form and is communicating to a server via JSON requests, when loading (e.g. in order to remember user's previous answers) and when submit button is pressed (e.g. in order to save his new answers). Every user has a specific user_id that is located as an attribute in the url of the website. I have only HTML pages, CSS and Javascript that makes some simple functions, as well as received and sends the requests.
The problem is that the server needs an api-key for the request to happen, that I need to be kept hidden, but instead is easily discovered when the user sees the source code. I want this specific line to be hidden, but I guess this is not possible without any backend in the game.
I would like to know the easiest and fastest way to get from this state (just frontend, where every piece of information in the source code is totally insecure) to another where the api-key (at least) is not on the open.
I guess the solution is to use a server for that part but I need suggestion on the easiest transition from my code to another. I tried to use GWT, as I am a bit more familiar with JAVA backend application (but not with GWT), but seems like a big trouble, where I need to change my HTML, my Javascript and also the CSS that I have may not be useful, as well as I face a lot of problems when trying to read my parameters.
I know that it is not the best way but I do not have a lot of time to make it work, so sorry if it seems lazy (I am new to this type of programming), but I haven't found anything helpful and I cannot study for 2 weeks in order to be able to begin implementing it.
Is node.js (which is Javascript and I already have implemented the request sending/receiving in this language) easier than GWT for that matter? Will my sensitive data be secure in that way? I would be grateful if there was a similar sample, that I could start using for my implementation, as I haven't find anything that is specifically helpful for my situation.
Thanks in advance!
NodeJs is not javascript, NodeJs is specific javascript "interpreter" whose is purpose is mainly to be executed server-side. If you have an HTML page, it is likely to be loaded in a web browser (client-side), so not in a NodeJs environnement.
Everything that is hard-coded in the javascript of you web page is visible from the client, there is no way around that. So yes, you need some server-ish thing somewhere.
If you are not to manage a server by yourself or via PaaS, you can go for a serverless architecture. For instance, If you consider AWS which I know the most, you can easilly add some user management to your web page using Aws Cognito User Pool. Once a user is connected and have the good permission, he can be granted access to some other resources via a JWT token that you send along with your request.

Storing auth data on the client side

I have an application which uses Backbone JS to render its views (among other things like models etc.).
Parts of my application should only be displayed to admin users, but the only way for Backbone templates to know this is for some JS variable/localStorage/Cookie to be set to indicate such.
The first worry here would, of course, be security. I am only really storing things like User.id, User.isAdmin etc. in here. Furthermore, since the only things limited to administrators would involve server-side involvement, changing User.isAdmin = true on the client side will just give them the interface options, but none of the power.
I know that using Cookies for this sort of thing is probably frowned upon, and with good reason, since Cookies are sent to and fro across all HTTP requests creating unnecessary overheads.
Therefore my question is, how best should I tell my client-side application about User authentication data. I am using jStorage (http://www.jstorage.info) for localStorage access, but it does not use SessionStorage. Would the latter be more appropriate than the former?
Speaking generally, you need roles and possibly privileges on the server. This way, even if a nefarious user tweaks the client, user cannot actually access or modify restricted data, because if they try, they still havent modified the role on the server. If you audit log access, you will know fairly quickly if a user tries something for which they don't have privileges.
The worst that can happen under a scheme like this is the user could see what the admin screens look like. This still might be a breach, since they might see buttons that could inform them how the system works.
If you need to protect that, you could delay the loading of the templates for the "Admin Section" of your app until after a users role has been verified. So all restricted sections are almost loaded as a separate app (or an actual separate app). That way, even if the user tries to fool the client to load the admin section, when the request goes to the server you don't return the module, since the server will not show the user as having admin privileges.

How to create basic authentication, login system for a web tool made in node.js and socket.io, without using express

I have a web tool developed, which uses node.js and socket.io. it's a one page website and uses node.js for getting data from social media website and display on the same page. I would like to add a site specific login system for the website but don't want to use 'Express' or 'Passport' as it adds lots of overload to the website while it is not needed.
I am newbie with node.js and would like to know if I need to have a login system made with node.js to maintain session of the logged in user?
Note: I need to maintain session to log user data such as login time, search query and may be heatmap.
Thanks in advance. If needed I can explain specific part of the question in detail.
Using something like Express or Passport (or at least some of connect's middleware) will definitely be easier in the long run (if your app grows), but if you want to go the 'manual' route, here are some starting points:
Cookie Parser: You won't want to send the auth details with every request as a parameter, so you'll want to put the session details in a cookie. You can set cookies manually using headers, or with a node module that wraps the API neatly.
Session Storage: You can put all the "login time, queries and heatmap data" in cookies, but it would be neater to just send a session id in the cookie in each request and save the other data server-side in a database. Options are mongoose, redis, etc.
Since reading the source is very educational, go read connect's cookieParser and cookieSession. It's not a lot of code and the API docs include the actual source, so it's very easy to learn from. Enjoy! :)
From how you are phrasing this question, I believe the overhead from using Express modules (Passport or similar) is the least of your worries ;-)
First you need to figure out which mechanisms you want to use.
For authentication, will you use a username/password combo, or will you be using a third party service like Google, Facebook, Twitter etc ("OAuth" like)? Unless you use some third party service, you also need to handle registration (and possibly verification of email address etc). Even for username/password combos, will you roll your own or use the browser based "basic-auth" mechanisms?
After authenticating you need a session mechanism to store some session token to recognize (and verify server side) that you have been authenticated. They are typically stored in browser cookies, which can easily be persisted for as long as you need, and are verified with each relevant request with tokens in a database on the server side.
And finally, you need a logout mechanism and a "I forgot my password" procedure (which may very well be manual initially...).
If all this is fairly new to you, I suggest trying to use something ready-made first (you mention Passport yourself), and then when you've mastered the basics, feel free to replace it with your own. The "upside" of using Passport or Everyauth is that they cover a lot more options that you realistically will be able to write yourself, so once you've adapted your system to use one of those, adding Facebook logins and similar will be a lot easier (somebody already figured out most of the stuff for your).
To be honest, most of the modules that handle such things in the Node ecosystem are fairly thin wrappers on top of whatever solution you decide to use, so the overhead will most likely not be substantial and you will most likely need a good understanding of the issues anyway to use them. At the other end of the spectrum are ready-made-systems like Drupal etc where everything just works, but then you're somewhat boxed in as far as making your own system.
There are use-cases where rolling your own from scratch is absolutely necessary, but there's nothing stopping your from doing this later when/if necessary (and after you've mastered the basics with the help of code that others wrote).
Best of luck!

Dual login: One login, 2 servers

Okay, this just feels plain nasty, but I've been directed to do it, and just wanted to run it past some people who actually have a clue, so they can point out all the massive holes in it.....so here goes.....
We've got this legacy site & a new public beta-test one. Apparently it's super cereal that moving from one to the other is seamless, so in a manner of speaking, we need a single signon solution.
As we're not allowed to put any serious development into the legacy site (It's also in old school ASP, a language I don't care to learn.) I can't do a proper single sign-on solution, so I proposed the following: On login, the legacy site performs an AJAX post to the login controller of the new beta site, logging the user in there, it then simply proceeds with the login on the legacy site as normal. This may not be acceptable as there's code to prevent a user from being logged on twice, I'm not sure if it's been written to apply across sites.
The other idea I had was to pass a salted hash of the user's details across with their username when they try to access the 2nd site. If the hash matches the details of the user, then access is granted. This would need ASP development obviously as generating the hash on the client side would only serve to enhance the idiocy even further.
Does anyone have any thoughts?
The old ASP site must have some concept of a session if it requires a logon. You will, at a minimum, need to understand how to provide the session information to the legacy site and splice some code in to keep it copacetic if both sites need to be kept up indefinitely.
"Classic" ASP isn't so bad if you can read/write VB6, VBA, VBScript or VB.net. It probably won't be difficult to graft session initialization provided the code is half way decent.
Consider creating a common logon page for both sites + either an automatic redirect based on either the requested URL (I'm guessing the old and new sites have distinct URLs) or cookies passed with the request (the old site, if it used cookies, could identify a legacy user). This common logon page could initialize session on both the legacy site (only if required by user type) and on the new site. This will allow you to keep your new logon process unencumbered by the legacy process while maintaining the old as long as required.
Bear in mind that your first approach (AJAX request from one site to the other) won't work if the sites are on different domains, because of javascript security restrictions.
You might be able to work around this by using a hidden iframe for the post like this, but it's getting a little hacky.

Categories