I have an array of hidden input boxes that carry especially sensitive data, and the form is submitted to a third party application on click of a button.
The values of these inputs are set server-side. The page that has these inputs is a confirmation page, and the user clicks the button to confirm the transaction and the data in the hidden input boxes is posted.
This is inherently very insecure, as anyone with half decent knowledge of javascript could load devtools and use javascript to change the values of the hidden inputs before submitting the data. The page even conveniently has jQuery loaded! Ha! (I tested this myself).
This is running on a private application with a limited user set and hasn't been a problem so far, but the same architecture is now required on a more public space, and the security implications of shipping this would be a little scary.
The solution would be to post the data server-side, but server-side posting does not work (at least not in a straightforward way) because of how the third party application is set up. The alternative would be to somehow prevent javascript (and of course by extension jQuery) from changing the values in the input boxes.
I was thinking of implementing (using setInterval) a loop that basically checked if the input values were the same as the original, and if not, changed it back, effectively preventing the values from being changed.
Would my proposed method be easily beatable? Perhaps there is a more elegant and simple way to stop javascript from editing those specific input values?
** EDITS
For anyone coming here along this path:
After multiple considerations, and an inability to sign my data with keys from the third party application, I resorted to manually posting the data server-side from my application (a ruby on rails app).
It may take some fiddling to get the right payment page to display after the posting happens, and I haven't tested it yet, but in theory this will be the way to make sure everything is submitted server side and the user never gets a chance to tamper with it.
For Ruby on Rails apps, there are some good insights at this question.
This answer also shows how to use the hacky autosubmitting form that I mentioned in the comments, but this may be prone to the same vulnerabilities as #dotnetom replied. (See comments)
Thanks again to everyone who contributed.
You solution based on the setInterval and other javascript functions will not work. Person with a dev tools can easily disable it from the console. If there is no way to send these parameters from the server, the only option I see is to generate signature with some public key from all the parameters need to be sent. The third party application can validate this signature and check that parameters are genuine.
But again, it is not possible if you have no control over third party application..
See an example from twitter: https://dev.twitter.com/oauth/overview/creating-signatures
If someone wanted to change the value of those input fields, they could just disable JS (and in this way get around your checking algorithm) and update the input values inside the HTML.
This can quite easily be done with FireBug, for example. No JS needed.
If sensitive data is involved, there will probably be no way to get around server-side posting or at least server-side validation.
I was thinking of implementing (using setInterval) a loop that
basically checked if the input values were the same as the original,
and if not, changed it back, effectively preventing the values from
being changed.
Attacker can easily overcome this by
overriding the method which is doing this periodic checking. Check this solution
Setting up a browser extension which can change values after setInterval() has changed it
Disable JS.
Basically client-side validation is just to ensure that server-side call can be avoided to reduce network trips, it cannot be a final frontier to protect the integrity of your data. It can only be done on server-side, which is an environment user cannot manipulate.
I know this is an older post, but it piqued my interest because of related (but not the same) issues with javascript security.
Just thinking about the logic of a solution for the OP, and assuming I understood correctly...
The server sets the vals, the user confirms, and the confirm goes to a 3rd party. The problem is that the vals could be edited before post to the 3rd party.
In which case, a possible workable solution would be;
Store the vals on the originating server with a unique ID
Send the confirmation back to the originating server for validation
Originating server forwards to the 3rd party if validation = true
In the event the 3rd party needs to send data back to the user, and it is not possible to let the server act as a go between, (which really it should) then you are a bit compromised.
You can still send data back to originating server with an AJAX type true fale response to the user.
Obviously, a malicious user could intercept the AJAX response using javascript edits but, (assuming the 3rd party app is looking for some kind of user ID), you would flag that ID as invalid and alert the 3rd party app before the AJAX response is delivered to the user.
otoh, hidden input boxes asside, the bigger consideration should be manipulation of the client side javascript itself.
One should have a validation wrapper for any sensitive functions or variables, to ensure those have not been modified.
Related
I am building a school project which is a website and I have a form and I'm using javascript as my validation. Is there any chance that if the user turned off their javascript, they can submit their form empty? or I better use php as my validation?
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 making "sticky" forms where the server remembers what was entered in each field and fills it back 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, for example?
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.
FOR MORE REFERENCE
Any frontend validation is just for better User Experience, and you can only trust the backend with sensitive logic.
Basically any data can arrive from the frontend, and you should always assume that your users are malicious ("all input is evil"), and validate on the backend.
Javascript validation is not secure at all, people can either turn off their Javascript or edit your code. Anyone who is set on getting around your validation will have an easy time doing so. PhP validation is the better option. since a user can't just turn off your PhP or change it.
What you could do if you want to make the validation look fancy, is have front and back end validation in place.
You can use html5 tags, they are pretty easy to use. Like you can use :
PATTERN attribute to define the regular expressions,
required for required fields and many others.
All of the html based validations, I must say all of them, can be fixed via tools like firebug. You might need to apply the validation on server side as well if you want to make it really really robust. I would recommend you to go for some MVC frameworks like
YII or may be code igniter
They are pretty easy to use and very powerful specially scaffolding features.
Before asking the question, I admit that this method is uberly discouraged and not secure. I am aware that to achieve this is through SSL.
However, I am developing an HTML5 apps (and it seems that implementing the SSL approach would take a lot of time) and I would like to know the best way to POST a form content.
i.e I have the following form
<form id="someform" name="someform" method="POST" action="some/server/url">
The way this form is submitted (currently) is using ajax $("#someform).serialize() and so on..
Using this implementation I am facing with (at least) these 2 immediate problems:
User could use tools (i.e TamperData | a firefox addons) to modify the posted content (Interception-and-modify).
User could forge the data by sending 'fake'submission (Forging)
I am wondering if there is somehow I could at least (obfuscate the POST-ed) value.
I came across with this great http://www.jcryption.org/ tools, but not sure how should I implement it to workaround the problem I am facing.
ps: again I am aware that relying on client-side script is way less secure compared with handling all execution from within the server-side.
framework + language I am using is: CodeIgniter + PHP + JavaScript (jquery)
1st Amendment:
I am sure there is at least a work around using this theory
First, I am not too worried about the confidentiality part of my data, that is the POST-ed value will not give any valuable information even if someone else knows what it is.
What concerns me though is the integrity and the authenticity of the POST-ed value. This is simply means that no one else should tamper the information once its being transmitted (once the submit button is clicked), nor anyone could forge or create a fake value (spoofing the server).
This theory leads to digital signature, where (again in theory) I should somehow sign the POST-ed value using server PUB-key, then hash the POST-ed value using the server PUB-key and finally send both the original POST-ed value along with the hashed value.
Prior sending the POST-ed value, the client MUST request for the server PUB-key, so the client can hash the POST-ed value. The server could probably store the PUB-key information along with SESSION information.
Then the server will have to (again) hash (this time with the server PRI-key) the original POST-ed value (sent by client) and compare the two hashed value. If those value is the same, it simply means it is authentic.
Now the part which I am yet to understand is the HOW.....
is there any tools/frameworks/plugins/tutorial/example on how to do this? since it would be too much for me (not to mention the limited amount of time I have) for developing the whole Public-Key-Infrastructure from scratch
Take one step further and realize that a user can encrypt faked data as well.
And SSL won't help against such a tampering.
That's a web-development axiom: everything can be faked on the client side. Period.
So, instead of encrypting anything, just verify your input on the server side, like every other site does.
Use sessions to store the data that a user should have no access to.
User
Spoofed Form Submissions
You will get full info here
I've been looking for better ways to secure my site. Many forums and Q/A sites say jquery variables and HTML attributes may be changed by the end user. How do they do this? If they can alter data and elements on a site, can they insert scripts as well?
For instance I have 2 jquery scripts for a home page. The fist is a "member only" script and the second is a "visitor only" script. Can the end user log into my site, copy the "member only" script, log off, and inject the script so it'll run as a visitor?
Yes, it is safe to assume that nothing on the client side is safe. Using tools like Firebug for Firefox or Developer Tools for Chrome, end users are able to manipulate (add, alter, delete):
Your HTML
Your CSS
Your JS
Your HTTP headers (data packets sent to your server)
Cookies
To answer your question directly: if you are solely relying on JavaScript (and most likely cookies) to track user session state and deliver different content to members and guests, then I can say with absolute certainty that other people will circumvent your security, and it would be trivial to do so.
Designing secure applications is not easy, a constant battle, and takes years to fully master. Hacking applications is very easy, fun for the whole family, and can be learned on YouTube in 20 minutes.
Having said all that, hopefully the content you are containing in the JS is not "mission-critical" or "sensitive-data". If it is, I would seriously weigh the costs of hiring a third party developer who is well versed in security to come in and help you out. Because, like I said earlier, creating a truly secure site is not something easily done.
Short Answer: Yes.
Anything on the users computer can be viewed and changed by the user, and any user can write their own scripts to execute on the page.
For example, you will up vote this post automatically if you paste this in your address bar and hit enter from this page:
javascript: $('#answer-7061924 a.vote-up-off').click();
It's not really hacking because you are the end user running the script yourself, only doing actions the end user can normally do. If you allow the end user on your site to perform actions that affect your server in a way they shouldn't be able to, then you have a problem. For example, if I had a way to make that Javascript execute automatically instead of you having to run it yourself from your address bar. Everyone who came to this page would automatically upvote this answer which would be (obviously) undesired behavior.
Firebug and Greasemonkey can be used to replace any javascript: the nature of the Browser as a client is such that the user can basically have it do anything they want. Your specific scenario is definitely possible.
well, if your scripts are public and not protected by a server side than the Hacker can run it in a browser like mozilla.
you should always keep your protected content in a server side scripting and allow access by the session (or some other server side method)
Yes a user can edit scripts however all scripts are compiled on the user's machine meaning that anything they alter will only affect their machine and not any of your other visitors.
However, if you have paid content which you feed using a "members-only" script then it's safest if you use technology on the server to distribute your members-only content rather than rely on the client scripts to secure your content.
Most security problems occur when the client is allowed to interact with the server and modify data on the server.
Here's a good bit on information you can read about XSS: http://en.wikipedia.org/wiki/Cross-site_scripting
To put it very simply:
The web page is just an interface for clients to use your server. It can be altered in all possible ways and anyone can send any kind of data to your server.
For first, you have to check that the user sending that data to your server has privileges to do so. Usually done by checking against server session.
Then you have to check at your server end that you are only taking the data you want, and nothing more or less and that the data is valid by validating it on your server.
For example if there is a mandatory field in some form that user has to fill out, you have to check that the data is actually sent to server because user may just delete the field from the form and send it without.
Other example is that if you are trying to dynamically add data from the form to database, user may just add new field, like "admin", and set it to 1 and send the form. If you then have admin field in database, the user is set as an admin.
The one of the most important things is to remember avoid SQL injection.
There are many tools to use. They are made for web developers to test if their site is safe. Hackbar is one for example.
I want to block non-browser clients from accessing certain pages / successfully making a request.
The website content is served to authenticated users. What happens is that our user gives his credentials to our website to 3rd party - it can be another website or a mobile application - that performs requests on his behalf.
Say there is a form that the user fills out and sends a message. Can I protect this form so that the server processing the submission can tell whether the user has submitted it directly from the browser or not?
I don't want to use CAPTCHA for usability reasons. Can I do it with some javascript?
You can raise the bar using javascript, but anything a browser does, an automated system can do. At the very worst, they could automate a browser, but there will almost certainly be some easier way to simulate the operation.
In any case they can record the requests that the browser sends using a proxy, and work out whatever tricks you have the javascript do.
In terms of what springs to mind (to raise the bar) (using javascript):
Change the location that the submit goes to.
Change field names around at submit time.
Hide fields that look like should be filled in.
Encrypt/obfuscate form contents at submit time.
Change GET to POST.
Another usability problem is that anybody who has javascript disabled won't be able to use the service at all. That might impact usability more than a CAPTCHA.
There is no reliable way to detect the HTTP agent - you will break the form for some browsers in any case - unless you can force users in to using a very limited set of browsers (but this can be spoofed again).
IMO, trying to limit the software that can be used to access the form, you should make sure that there is a real human controlling that software. Unfortunately there is no better way than captchas for doing this, unless all customer have access to biometric scanners.
There is only one way to do this, analyzing vendor string looking for browsers admitted, but if someone fakes the vendor string theres no way to keep away from submissions.
To know if a navigator is mozilla based with javascript :
var isMoz = window.navigator.userAgent.match(/^Mozilla/)?true:false;
with php you could try native function get_browser
I'm still debating whether I want to do this or not but what I'm considering is preventing users from entering hyperlinks into a HTML form in my app. This is to avoid spammy links from showing up for other uses of the app since the app is based on user generated content.
This is a Rails app, so I could do some backend validations on the model after the form is submitted by the user.
But I was wondering whether it might be preferable to perform the check in jQuery/JavaScript before any submission takes place. This way the user could be notified immediately without any backend processing.
Which would be preferable here - client-side or server-side validation?
You only have control over data when it arrives at your server. If you use JavaScript to try to strip out spam, then spammers are just going to turn JavaScript off.
Build a server side solution.
Once you have that, think about duplicating the work client side to make things nicer for users.
Use both.
Client side validation lowers stress on the server when the client has the JavaScript turned on.
Server-side is your last line of defense which should be there for the case the user has JavaScript turned off.
You say :
so I could do some backend validations
on the model after the form is
submitted by the user.
No ! You must do validations on the backend !
Javascript can be disabled, forms posting can be forged ; so you always need to develop validations / filtering / whatever security measure you want on the backend/server.
Only then, you can eventually add some JS thing, so your application is more user-friendly.
Both............
You should use both, use jQuery validation plugin on the client, and whatever method is appropriate on the back-end (I don't know ROR).
An ajaxy validation solution could perform server-side validation while the client is inputting information, and provide feedback/prevent submission accordingly.
Hope that helps.
Spammers often uses some kind of script that analyses the form and builds form data and posts on it's own, so client script is totally useless against most spamming.
JavaScript validation is great as a way to hold the hands of non-malicious users. "The passwords you entered don't match", "looks like an invalid e-mail address, please double-check", etc.
The downside of JavaScript is that there is no way to verify that it ran, nor that it ran as intended. A malicious user, or one with a glitchy browser plugin, or one with an overzealous firewall/content blocker, a spambot without JavaScript, a user with NoScript enabled, or any number of other situations can result in your validation never beeing triggered.
As such, your server should always validate data if validation is necessary. JavaScript can be a first line of defence, but it can never be the final one.