Sending and receiving encrypted data from a javascript app - javascript

I have an interactive html5 app that let's people customize products on the client-side. As a user is customizing, the price updates based on individual component prices.
Once this is done, the person hits checkout, I send the customization to the server, and the server takes over the checkout process.
Obviously sending price data to the server is pointless, since anyone could spoof the POST data. So, I tried writing a server side script that will regenerate the price according to the components selected (sent to the server with the customization data), and show that on checkout instead. However, the server side calculation is proving very difficult, due to complex customizations offered; and it seems like I have to rewrite the entire client-side customization logic on the server-side (which is a lot of work).
Before I continue writing the server-side script I wanted to know if it is at all possible to send the price data to the server in a way (asymmetric key auth perhaps) that cannot be spoofed?

Never trust the information clients send you.
To answer your question, it is possible to use encryption to send data from the client to the server. However, the problem here is the data being encrypted can be modified even before the encryption. So, encryption is not really the solution. The client might modify the data before encryption and the server will not know this if there are no server-side checking.
Even with public-private key encryption, this will still be unsafe. There will only be an assurance that your data will not be tampered from the user to the server. It cannot be spoofed by third parties but your user can spoof it, thereby making the encryption pointless. So, do not trust the user to send you valid legitimate information.
You should really double check everything in the server. And you will not need encryption unless privacy is an issue (which probably is based on your description). This can easily be solved by using https.
The client-side javascript you created can serve as immediate feedback to the users, they see prices as they make changes to the forms. This is good because they do not need to wait for the server to process the information, which the server should upon submission of the form.

You should never never never trust client-side code. If you want to spare yourself the headache of rewriting your client-side code, you could just put the relevant JavaScript on the server and call it from your server code (Not that I'm suggesting you should do that). Another thing I would recommend doing is recalculating the price based on the contents of a full postback once the user is done with their customization, and then displaying the recalculated price to the user in order to allow them to confirm it. That way if any client-side shenanigans have occurred, the user will get the real price anyway, and I'm sure that if it differs even slightly from the previous price, your support people will hear all about it.

Related

Ruby on Rails: Is it better to apply validations on model or through JavaScript? [duplicate]

Which is better to do client side or server side validation?
In our situation we are using
jQuery and MVC.
JSON data to pass between our View and Controller.
A lot of the validation I do is validating data as users enter it.
For example I use the the keypress event to prevent letters in a text box, set a max number of characters and that a number is with in a range.
I guess the better question would be, Are there any benefits to doing server side validation over client side?
Awesome answers everyone. The website that we have is password protected and for a small user base(<50). If they are not running JavaScript we will send ninjas. But if we were designing a site for everyone one I'd agree to do validation on both sides.
As others have said, you should do both. Here's why:
Client Side
You want to validate input on the client side first because you can give better feedback to the average user. For example, if they enter an invalid email address and move to the next field, you can show an error message immediately. That way the user can correct every field before they submit the form.
If you only validate on the server, they have to submit the form, get an error message, and try to hunt down the problem.
(This pain can be eased by having the server re-render the form with the user's original input filled in, but client-side validation is still faster.)
Server Side
You want to validate on the server side because you can protect against the malicious user, who can easily bypass your JavaScript and submit dangerous input to the server.
It is very dangerous to trust your UI. Not only can they abuse your UI, but they may not be using your UI at all, or even a browser. What if the user manually edits the URL, or runs their own Javascript, or tweaks their HTTP requests with another tool? What if they send custom HTTP requests from curl or from a script, for example?
(This is not theoretical; eg, I worked on a travel search engine that re-submitted the user's search to many partner airlines, bus companies, etc, by sending POST requests as if the user had filled each company's search form, then gathered and sorted all the results. Those companies' form JS was never executed, and it was crucial for us that they provide error messages in the returned HTML. Of course, an API would have been nice, but this was what we had to do.)
Not allowing for that is not only naive from a security standpoint, but also non-standard: a client should be allowed to send HTTP by whatever means they wish, and you should respond correctly. That includes validation.
Server side validation is also important for compatibility - not all users, even if they're using a browser, will have JavaScript enabled.
Addendum - December 2016
There are some validations that can't even be properly done in server-side application code, and are utterly impossible in client-side code, because they depend on the current state of the database. For example, "nobody else has registered that username", or "the blog post you're commenting on still exists", or "no existing reservation overlaps the dates you requested", or "your account balance still has enough to cover that purchase." Only the database can reliably validate data which depends on related data. Developers regularly screw this up, but PostgreSQL provides some good solutions.
Yes, client side validation can be totally bypassed, always. You need to do both, client side to provide a better user experience, and server side to be sure that the input you get is actually validated and not just supposedly validated by the client.
I am just going to repeat it, because it is quite important:
Always validate on the server
and add JavaScript for user-responsiveness.
The benefit of doing server side validation over client side validation is that client side validation can be bypassed/manipulated:
The end user could have javascript switched off
The data could be sent directly to your server by someone who's not even using your site, with a custom app designed to do so
A Javascript error on your page (caused by any number of things) could result in some, but not all, of your validation running
In short - always, always validate server-side and then consider client-side validation as an added "extra" to enhance the end user experience.
You must always validate on the server.
Also having validation on the client is nice for users, but is utterly insecure.
Well, I still find some room to answer.
In addition to answers from Rob and Nathan, I would add that having client-side validations matters. When you are applying validations on your webforms you must follow these guidelines:
Client-Side
Must use client-side validations in order to filter genuine requests coming from genuine users at your website.
The client-side validation should be used to reduce the errors that might occure during server side processing.
Client-side validation should be used to minimize the server-side round-trips so that you save bandwidth and the requests per user.
Server-Side
You SHOULD NOT assume the validation successfully done at client side is 100% perfect. No matter even if it serves less than 50 users. You never know which of your user/emplyee turn into an "evil" and do some harmful activity knowing you dont have proper validations in place.
Even if its perfect in terms of validating email address, phone numbers or checking some valid inputs it might contain very harmful data. Which needs to be filtered at server-side no matter if its correct or incorrect.
If client-side validation is bypassed, your server-side validations comes to rescue you from any potential damage to your server-side processing. In recent times, we have already heard lot of stories of SQL Injections and other sort of techniques that might be applied in order to gain some evil benefits.
Both types of validations play important roles in their respective scope but the most strongest is the server-side. If you receive 10k users at a single point of time then you would definitely end up filtering the number of requests coming to your webserver. If you find there was a single mistake like invalid email address then they post back the form again and ask your user to correct it which will definitely eat your server resources and bandwidth. So better you apply javascript validation. If javascript is disabled then your server side validation will come to rescue and i bet only a few users might have accidentlly disable it since 99.99% of websites use javascript and its already enabled by default in all modern browsers.
You can do Server side validation and send back a JSON object with the validation results for each field, keeping client Javascript to a minimum (just displaying results) and still having a user friendly experience without having to repeat yourself on both client and server.
Client side should use a basic validation via HTML5 input types and pattern attributes and as these are only used for progressive enhancements for better user experience (Even if they are not supported on < IE9 and safari, but we don't rely on them). But the main validation should happen on the server side..
I will suggest to implement both client and server validation it keeps project more secure......if i have to choose one i will go with server side validation.
You can find some relevant information here
https://web.archive.org/web/20131210085944/http://www.webexpertlabs.com/server-side-form-validation-using-regular-expression/
I came across an interesting link that makes a distinction between gross, systematic, random errors.
Client-Side validation suits perfectly for preventing gross and random errors. Typically a max length for any input. Do not mimic the server-side validation rule; provide your own gross, rule of thumb validation rule (ex. 200 characters on client-side; a specific n chars less than 200 on server-side dictated by a strong business rule).
Server-side validation suits perfectly for preventing systematic errors; it will enforce business rules.
In a project I'm involved in, the validation is done on the server through ajax requests. On the client I display error messages accordingly.
Further reading: gross, systematic, random errors:
https://answers.yahoo.com/question/index?qid=20080918203131AAEt6GO
JavaScript can be modified at runtime.
I suggest a pattern of creating a validation structure on the server, and sharing this with the client.
You'll need separate validation logic on both ends, ex:
"required" attributes on inputs client-side
field.length > 0 server-side.
But using the same validation specification will eliminate some redundancy (and mistakes) of mirroring validation on both ends.
Client side data validation can be useful for a better user experience: for example, I a user who types wrongly his email address, should not wait til his request is processed by a remote server to learn about the typo he did.
Nevertheless, as an attacker can bypass client side validation (and may even not use the browser at all), server side validation is required, and must be the real gate to protect your backend from nefarious users.
If you are doing light validation, it is best to do it on the client. It will save the network traffic which will help your server perform better. If if it complicated validation that involves pulling data from a database or something, like passwords, then it best to do it on the server where the data can be securely checked.

Can client-side .js decryption enhance security?

By a parent-company-wide mandate, I need to structure my web-app that any personally identifiable client information will only be shown to users if the user clicks on a "View" button in the field.
(This isn't a high-level security thing, and it doesn't need ultra-high level encryption. All authenticated and authorized of the app will be able to view the data. The mandate is for the data to be stored encrypted and not decrypted until just prior to display to the end-user. The intent is to eliminate any employee from having easy access to a screen full of sensitive info that could make large-scale information stealing easy for even tech un-savvy. "Locks keep honest people honest.")
The obvious challenge of doing this in javascript is that both the ciphertext and the key would need to be used to decrypt the value, and they'd both have to come from the server(s) via HTTPS. Implemented poorly, the web-app could make the encrypted date easier to get in clear-text since it could expose the keys and shared secrets used by the encryption algorithm.
At minimum, I can send a guid to the client as a limited time one-use-only token to allow them to access an HTTPS web service that would return one item of clear-text data per click of a view button. (Which technically does nothing to enhance security except throttling the speed that the data could be stolen.)
Are there known methods for web apps to use splitting data between an initial request, and a later AJAX request to enhance the data security? I certainly could roll my own system for the AJAX view requests that could use things like time of day, session key, etc. to validate requests, but I'm not sure if that would really get me any benefit -- I would still end up with two options: Responding to the AJAX request via HTTPS with the clear text, or sending both the cipher text and the decryption keys/secrets to a browser to decrypt with.
NOTE: Keep in mind, the only point here is to stop non-techie employees from being tempted to do bad things with "easy-stealing" data. I'm totally comfortable if anyone wants to debunk or prove whether any techniques actually benefit security or are just busy-work that are equally vulnerable.

Node.js File Security

I'm about to start creating a website that takes values of form inputs(dropdowns, radial boxes, etc.) from the client(no user accounts involved) and performs calculations besed off of these values. These calculations are rather sensitive and I know client side javascript can't be made secure.
Is it possible to pull these client side values and run the calculations server side with node.js? If so, how secure is that? What other precautions can be taken?
If that's not possible or secure, what are some alternative solutions?
You have a couple options for sending the data to your server and then performing the calculations there.
You can put the data into a form and you can submit the form to your server. The server will then receive all the data from the form and it can do whatever it wants with the data. The server can then return a new page with whatever results you want to show and the browser will show the results page.
You can collect the data from your web page and send it to your server with an Ajax call made via Javascript. The server will receive the data from the Ajax call and can do whatever calculations it wants with the data. It can then return whatever data is appropriate from the Ajax call and the client will receive that data in Javascript and can then display it in the new page (or do whatever else is appropriate).
Code to make calculations on your server will be as safe as the security is on your own server (which can be made plenty secure). Server-based code is not normally available to the outside world.
If you are concerned about security of the data or result in transit, then you can use https between your webpage and your server.
When you ask about "security", folks can provide better answers/info if you say more about what you're trying to protect, why you're trying to protect it and what types of threats you're trying to protect it from. Security is best designed and implemented for very specific reasons and you haven't provided any of those type of specifics.

Prevent XSS on client-side (Pure Javascript)

i got a simple project but is giving me headaches because Client-Side programming is not my thing. Basically i got a login page and the client wants that i prevent XSS attacks not allowing users not submit malicious code on username/password fields. I would do it on server side easily, but they do not want give to us access.
Any chance to someone give me hints how can i do this? Even tough i know the basics of javascript/HTML, my experience ir nearly null.
I know that are several questions about this topic, but sincerely, i got lost with all information
Best Regards
Actually you simply cannot make any reliable XSS prevention on the client side. The attacker simply disables JavaScript, and all your complicated code is non-existent. Any client-side validation is only for the convenience of the users, nothing more.
Update: The above I wrote, is true about second order (a.k.a. stored) XSS. First order XSS attacks (when the attacker creates a forged URL) can be mitigated using JavaScript.
You prevent XSS on the client in the same way that you prevent it on the server. (Note this only protects against input that is directly processed on the client, and not against code that gets submitted to the server and then passed back to a client).
Make sure you know what data format any given variable holds
Treat any user input including data from forms, data from URLs, etc) as plain text
Encode it appropriately for where ever you put it, using native methods for handling the data where possible
For example, if you wanted to display the fragment id in a div you would:
div.appendChild(document.createTextNode(location.hash));
Do not just allow raw input to be parsed as HTML:
// DANGER
div.innerHTML = location.hash;
This, of course, only protects the page from data submitted to the client side code.
There is no way to use client side code to prevent malicious data from being submitted to the server side code. The client has total control over the client side code, so it can be bypassed very easily.
If you read input from outside the server and then output it to a webpage then you must have server side protection from XSS.

Ajax Security

We have a heavy Ajax dependent application. What are the good ways of making it sure that the request to server side scripts are not coming through standalone programs and are through an actual user sitting on a browser
There aren't any really.
Any request sent through a browser can be faked up by standalone programs.
At the end of the day does it really matter? If you're worried then make sure requests are authenticated and authorised and your authentication process is good (remember Ajax sends browser cookies - so your "normal" authentication will work just fine). Just remember that, of course, standalone programs can authenticate too.
What are the good ways of making it sure that the request to server side scripts are not coming through standalone programs and are through an actual user sitting on a browser
There are no ways. A browser is indistinguishable from a standalone program; a browser can be automated.
You can't trust any input from the client side. If you are relying on client-side co-operation for any security purpose, you're doomed.
There isn't a way to automatically block "non browser user" requests hitting your server side scripts, but there are ways to identify which scripts have been triggered by your application and which haven't.
This is usually done using something called "crumbs". The basic idea is that the page making the AJAX request should generate (server side) a unique token (which is typically a hash of unix timestamp + salt + secret). This token and timestamp should be passed as parameters to the AJAX request. The AJAX handler script will first check this token (and the validity of the unix timestamp e.g. if it falls within 5 minutes of the token timestamp). If the token checks out, you can then proceed to fulfill this request. Usually, this token generation + checking can be coded up as an Apache module so that it is triggered automatically and is separate from the application logic.
Fraudulent scripts won't be able to generate valid tokens (unless they figure out your algorithm) and so you can safely ignore them.
Keep in mind that storing a token in the session is also another way, but that won't buy any more security than your site's authentication system.
I'm not sure what you are worried about. From where I sit I can see three things your question can be related to:
First, you may want to prevent unauthorized users from making a valid request. This is resolve by using the browser's cookie to store a session ID. The session ID needs to tied to the user, be regenerated every time the user goes through the login process and must have an inactivity timeout. Anybody request coming in without a valid session ID you simply reject.
Second, you may want to prevent a third party from doing a replay attacks against your site (i.e. sniffing an inocent user's traffic and then sending the same calls over). The easy solution is to go over https for this. The SSL layer will prevent somebody from replaying any part of the traffic. This comes at a cost on the server side so you want to make sure that you really cannot take that risk.
Third, you may want to prevent somebody from using your API (that's what AJAX calls are in the end) to implement his own client to your site. For this there is very little you can do. You can always look for the appropriate User-Agent but that's easy to fake and will be probably the first thing somebody trying to use your API will think of. You can always implement some statistics, for example looking at the average AJAX requests per minute on a per user basis and see if some user are way above your average. It's hard to implement and it's only usefull if you are trying to prevent automated clients reacting faster than human can.
Is Safari a webbrowser for you?
If it is, the same engine you got in many applications, just to say those using QT QWebKit libraries. So I would say, no way to recognize it.
User can forge any request one wants - faking the headers like UserAgent any they like...
One question: why would you want to do what you ask for? What's the diffrence for you if they request from browser or from anythning else?
Can't think of one reason you'd call "security" here.
If you still want to do this, for whatever reason, think about making your own application, with a browser embedded. It could somehow authenticate to the application in every request - then you'd only send a valid responses to your application's browser.
User would still be able to reverse engineer the application though.
Interesting question.
What about browsers embedded in applications? Would you mind those?
You can probably think of a way of "proving" that a request comes from a browser, but it will ultimately be heuristic. The line between browser and application is blurry (e.g. embedded browser) and you'd always run the risk of rejecting users from unexpected browsers (or unexpected versions thereof).
As been mentioned before there is no way of accomplishing this... But there is a thing to note, useful for preventing against CSRF attacks that target the specific AJAX functionality; like setting a custom header with help of the AJAX object, and verifying that header on the server side.
And if in the value of that header, you set a random (one time use) token you can prevent automated attacks.

Categories

Resources