I'm thinking about creating an RIA version of a traditional web application. In a traditional web app, most of the code is on the server, obviously, out of touch of the client. There I would have, at very least, conditional code to check if the current user has permissions to do something, or what form fields to display.
In a RIA, all code is running in the browser. So I have, it seems, two choices.
If I need to display a form, grab it dynamically from the server. This works, but it makes the server do more work than just marshal back and forth JSON.
Bring back the account data from the server, and do all authorization code on the client. I took a quick peak at basecampmobile, and seems they are doing something like this.
My question is, does hiding this information behind a closure really protect it, or is this "security by obscurity"?
I would do authorization on the server and the client. The client authenticate with the server and the server returns only data belonging to that client/user nothing else. Then on the client you check the authorization on specifics to update the UI accordingly.
Remember you can always jump into the dev tools and see the network traffic so we are not even talking about obscurity here...
When you work on a thick client, you should check for user security both on the server and client because client can be hacked easily.
I don't like RIA services role based authorization. It feels much more intuitive to use access based authorization like what SQL Server has, and it doesnt force you to re-implement the security at client side. For example instead of saying x, y, and y can access this createCustomer(..) method, it is more intuitive to say someone with the "Create" right can access this method.
I have an open source framework that faciliates this type of authorization read more here. It is called saf-framework.
Related
I need to send a particular header parameter in all ajax calls which is a very confidential information. I don't want from the end user to see any of the requests made in network tab of any browser. Is there any way to prevent it? or is it possible to make ajax calls directly from node server which doesn't go through browser?
Any call made on the client side cannot be hidden, as it's "client" side of the website. Even if you'd success to hide it in browser, any software could monitor it with tools such as network sniffers / monitors, WireShark for instance.
So the answer is no
When you go to a restaurent and order something, can the waiter subsequently make you forget your last instruction/order? The answer is NO, same as the answer to this question.
It all starts with client making a request to the server, hence client is the driving force of the whole interaction. Server just serves as per the instructions from client (and maliciously does some extra work on its own, say auditing, database update, cookie addition etc.).
Hence there is no way a 'server' can restrict client to see its own instructions.
Just simply don't send sensitive information directly via headers. Encrypt them via your client side code and add them within cookies or any other HTTP header(s).
Quoting from internet:
Client/server architecture is a producer/consumer computing
architecture where the server acts as the producer and the client as a
consumer. The server houses and provides high-end, computing-intensive
services to the client on demand. These services can include
application access, storage, file sharing, printer access and/or
direct access to the server’s raw computing power.
Client/server architecture works when the client computer sends a
resource or process request to the server over the network connection,
which is then processed and delivered to the client. A server computer
can manage several clients simultaneously, whereas one client can be
connected to several servers at a time, each providing a different set
of services. In its simplest form, the internet is also based on
client/server architecture where web servers serve many simultaneous
users with website data.
Never trust to client. Ever. Never ever. Doesn't matter what you do assume its been cracked. Hackers have all the tools and complete control of the client and all software running on it. Assume they've written their own network stack, their own TLS implementation, their own browser, their own operating system...
If you need to keep it secure, keep it on your servers. If you need to communicate 'privileged' information (assuming you remember that once you've sent it to a client they can access it) don't, tokenise it on your server and send them the token. And if you're generating tokens make sure they're very random and utterly opaque - don't encrypt anything in the token because you should assume they can crack that too, regardless how secure you think the library you are using is (assume it'll one day be cracked).
Never expose the confidential data on the client-side.
The best practice is to encrypt your confidential data on the server-side, send it to the client, and decrypt on the server end when the client sends you back.
If you don't want encryption or this confidential information is result of user actions itself then make a key-value pair in a database, where the key is something which can be exposed to the client (let's say username) and value is the confidential information. Hence now we have 1-1 mapping, so fetch this confidential information on server-side from database using the key we are getting from the frontend.
I hope this will help.
Good Luck!!
This is a design question for AngularJS websites that access a REST API. Since all the AngularJS code can be viewed from the client side (assuming obfuscation is not completely secure) how do you hide the API access credentials (the API key and password or even a JWT)?
This can be extended to a broader question about how other application logic can be hidden in an AngularJS website?
My research led me to some insights, one of which was
http://billpatrianakos.me/blog/2016/02/15/securing-api-keys-in-a-javascript-single-page-app/
But this has me more confused now, since the post suggests an SPA connecting to a REST API is not a good architecture. I thought it was and now can't figure what the right approach is.
The closest I can come to an answer is this resource:
https://developers.facebook.com/docs/facebook-login/security#appsecret
Facebook, is pretty good with their security and say:
Never include your App Secret in client-side or decompilable code.
Use unique short-term tokens on clients.
In short, do not keep API secrets on the client side
Answering the discussion in comments for sake of not being brief:
And then my question would be "what then is the correct architecture for SPAs and server side code (or database access)?".
There's no one correct architecture, it depends on the size and scope of your project. It will also depend on what frontend and backend frameworks you choose. Those choices also will depend on how many other APIs you are calling, or what other developers or you are most familiar with.
Speaking more specifically about security though, ideally you'd like to set up a session for the user which consists of a token that the user uses to identify himself. This is usually generated for each user by the server when they login. Generally this is provided by the framework you are working in, but even if it isn't, it's fairly simple to build. You will want to prevent cross origin requests (making sure the user is actually on YOUR frontend) and have secure connections (setting up SSL and https, though this can get complicated). You will generally want to run your JS code through something like Uglify to prevent it from being too easy to look through, but this does NOT guarantee that people cannot take that code and un-uglify it.
As the other answers have suggested, you should never keep API keys or any secrets in the client source code. There is no way to hide anything on the client, and obfuscation != security.
If you are looking to architect secure authentication/authorization into your app, you will want to return a JWT to the AngularJS application. You can then pass this JWT as a Bearer token to your API which will verify the validity of the token and allow the API to authorize access to the AngularJS application.
As for where to store the JWT token, you can store it in either Local Storage or in a cookie. There are serious considerations between choosing whether to store the token in either of these locations.
If security is your concern, I would look into the OAuth 2.0 Implicit Flow.
Don't put API keys in your client side source code. Keep them on your server, and have your client make a request to YOUR server, which then calls out to external APIs for data.
I am building my first node.js webapp. I don't need to manage users registrations. I just need an admin page wich easly allow updating the content of some pages.
I have almost finished the development phase but there is something about security I would like to clarify.
ADMIN PAGE: there are 2 level of security:
1) The admin page is linked to mywebsite.com/hexadecimal_string .
Maybe it's very stupid but the admin page is a "secret" page. Linking
it to mywebsite.com/admin is too much common. Do you think that using
an hexadecimal string can be considered a first level of security?
2) Of course there is a password for admin, stored in my database. If
the password is right, a temp cookie is setted. Maybe I should
encrtypt this password while is posted but I'm not planning to use
https. Is there a way, different by using https, to make the posting
of the password more secure ?
CORS: I don't need CORS but there is a thing that is making me crazy:
In the homepage everyone can post some data to server (we are talking about newsletter emails and others personal datas)
suppose someone reads the javascript code of the home page(in particular the ajax urls) in same way and he tries to post data to the same urls but using a personal script that skip the validation phase. Of course I did the validation to server also but I'd like to not accept any req coming from personal scripts written by other than me. The server should respond only to requests coming from my javascripts, tha anyone can run accessing to www.mywebsite.com. All other requests coming from different scripts will recieve 500-server error.
Now, I read about lot's of people that is tryng to ALLOW CORS. So I was supposing that cors is disabled by default but I tried to post data from another website to mine and the data have been sent without problem and the server responds 200. Why? Can I manage this thing?
There are other common things that I need to analyze and manage for security in my situation??
Since you don't want to use https and are looking for an alternative to that I presume you don't want the password to be sniffed in transit. I suggest a simple encryption decryption algorithm might work out for you. For the second issue, you can add a validation string which the client JS will pass along with other parameters while hitting your server API's. If you generate this string each time the client loads some specific page, then duplication of string will also be tackled.
In case you don't want at all to maintain any sort of db on server side, then attach a hidden HTML field to the API hits. This hidden field again you can encrypt and sent. If you broadcast this field periodically from the server, replication of the field will not be possible.
Also in CORS, you cannot request for data from a cross domain. CORS block comes in place when the browser gets a reply back from the server. Only posting of data does not cause any issue.
I'm developing a single page app with Backbone.js and I was asking myself some question.
When I'm developing an app that relies on render pages on server I do know how to show some parts or not depending on the user is admin or not (just an example).
But now, I'm using Backbone.js and underscore templating to create the views... so.... I could create a cookie that says... ok... is the admin, but anyways, someone smart-enough could just change the cookie value. I'm able to solve it just creating a check in the server side that the user is allowed to do that.
Other chance I'm thinking about is to ask the server for this concrete pieces of code and just paste them in the right site
What do you think?
Thanks
Your scenario is not entirely clear to me, but in general: If the server divulges "secret" information or allows restricted actions without having verified itself that the user is allowed to see something/do something, that's a security hole. Authentication will have to happen in the established ways: user logs in on the server and receives a secure (enough) token, e.g. a session cookie. The server then only sends information that the user is allowed to see to the client and only allows actions the user is allowed to do.
Anything client-side is always, by definition, insecure. A secure client-side-only authentication system does not exist. The server must not take the client's word for who he is. No critical action must be performed on the client without the server being able to verify that action.
Currently I have developed a site which is used for handle financial transactions. I have seen that some of my customers have done JavaScript injection attacks and have done some transactions which are not possible. As a example I have checked his cash balance before he place the order. But some of them did change that by running the following javascript in the address bar. They have taken the varible name by looking in to page source.
javascript:void(document.accounts.cashBalence.value="10000000")
Since this is critical I want to fixed it quickly. So is there a way to prevent JavaScript injection attacks?
You can obfuscate or hash variable names and/or values. However,
Don't use JavaScript, do every logic in the server-side instead.
In the end it's not even a problem of Javascript. Your server talks to the outside world using HTTP. It sends data using HTTP and receives data using HTTP. Anybody can request data from it using HTTP and anybody can send data to it using HTTP.
Think about this again:
Anybody can send data to your server through the very simple protocol that is HTTP.
The HTML and Javascript you're sending to people's browsers is just a nice help, an interface, to allow them to easily send data to your server. They could do the same using the curl command on their command line or by telnet'ing into port 80 and talk really low-level to it.
If your server blindly obeys any and all commands sent to it without checking their validity, you have no security whatsoever. Security and validity checks belong on the server, not on the client side interface. Because HTML and Javascript aren't the only interface to your server, nor are they in any way protectable and hence trustworthy.
Javascript runs in the user's browser. You ultimately have no control over it and should not trust it. Any verification you do in the browser is merely for the user's convenience so they can be alerted of problems as early as possible.
The backend code that accepts the order should do the authoritative check of the user's balance.
No client-side scripting (including Javascript) is good for verification, It should all be done on the server-side.
It is too unreliable to trust it specially if it is for financial records!!
It should be used for a better "user experience". Form validation while typing or whatever but not this!
Have found that if you make it to where server only excepts out going data not incoming data it works best but that poses a problem, if you are using a website that takes user input on the connected client then your preaty much screwed I sugset a simple java script line that in a sence makes it to where before you can send any java script you have to enter a basic set of variables so in a sence just have a login page start with somthing like this
System.out.printin ("Welcome, Would you like to login to edit?")
Then { System.in = "Yes"}
To prevent Javascript injection, you should have a Validation Feature whenever you allow your user to enter something. Try to use libraries that determine Javascript scripts that are entered to the form.
Also when displaying user inputs, you should Escape Texts to display it as is and will not be evaluated by the browser.
Utilize your server, your should place your business logic to the server and not to the client whether using Javascript or not. All data sent to the client are just view and should not process any business logic.