Securely submit form using JavaScript / PHP - javascript

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

Related

Is my authentication system secured?

I want to implement an authentication system by following good practices, i want it as simple as possible and secured (im not going to implement some magic hashing function or something to feel a hero..) just wanting to use already known hash but not sure the right way of using it.
I read some articles on how Lastpass (a password management company) mange to handle their authentication and i loved their idea.So i wanted to implement my own authentication based on it.
Basically im creating an authentication key from the password on the client side (so the password is never sent as a plan text to the server).
that authentication key im sending to the server than do some hashing operations also in the server side and compare the result to the one inside the database.
On my client side:
auth_key = PBKDF2(SHA256, password+username, last_login_fe_salt, fe_rounds)
explanation - hashing password+username+last_login_fe_salt text fe_rounds times
last_login_fe_salt -> a random salt sent to the user once he/she input their username in text field -
To be honest, not sure how this last_login_fe_salt is efficent for the cryptography against Dictionary attacks but atleast two people having the same password will send different hashes on their network.
any hacker can get this data by asking from the server, i can add server side limitations (req/s if it makes some difference etc.. let me know what you think) also adding captcha might be a good idea. When a user logged in successfuly the server generates a new random string and saves in into the database.
*I didnt see any explanation which salt Lastpass uses on their client side hashing, they are using PBKDF2 algorithm that needs a salt parameter.
fe_rounds -> number of rounds given by the server when typing username -
its fixed for everybody and configurable by the server, also in articles i read about Lastpass they dont explain from where they receive the client side number of rounds...
so now we send auth_key as is to the server...
On my server side
now we are creating a new hash to compare the one inside the db.
Why another hash? if i understand correctly we bind the hash for server side data, like a combination of a password (that only the user knows) and server data.
db_auth=PBKDF2(SHA256, auth_key, user_be_salt, 100,000+user_configurable_rounds)
user_be_salt -> a random number that saved in db known only to the server and the ones who obtain the database, this changes on every successful login.
user_configurable_rounds -> number of iterations, every user can choose the amount of iterations (like in Lastpass) so attacker need also to guess the number or iterations?
I would be happy to hear what do you think about this authentication system, if its wrong than explain to me why and tell me what Lastpass do because i did not understand their entire authentication flow.
Most of what you're doing is useless from a security perspective. Lastpass has unusual security requirements -- don't treat them as a source of best practices.
If the client is responsible for hashing, and all of the parameters to that hashing are fixed, the hash effectively becomes the password. An attacker doesn't need to know the original password; they can simply pass the hash to the server.
Generally speaking, there is no way to verify a password over a network without either sending the password across the network (for traditional password authentication protocols), or having the server store the password in plaintext (for less commonly used protocols like SRP). Of the two, the former is preferable, as it's possible to secure the password in transit using protocols like SSL/TLS, whereas protocols like SRP require the plaintext of the password to operate.
Tweaking the PBKDF round count, either on the client or server side, is pointless. Set a fixed round count that makes the hash slow, but not so slow that it will place an undue load on the client or server. (100,000 rounds is probably excessive for a server-side hash. It takes roughly half a second to verify a password with those settings, so just two login requests per second would use 100% of one core on your server!)

How to prevent javascript from changing input value

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.

How to stop from data post from browser console?

I have been thinking over this issue from past few months. Recently, I have started with complete JS Built front-end, where the forms are posted using Ajax.
I have a doubt, how to recognize on the server side, from where the data is coming from. Is it coming from actual form event or it is coming from browser console.?
What I have tried:
Creating a two way handshake: Before posting the form, the Application will contact the server, and the server will send a token inside the cookie, which will be sent back with the form post. But, even if we post by browser console, that cookie will go carrying the token. So, Failed.
Binding Hidden Field: But if someone, is posting the data from browser console, he would definitely look for the hidden fields as well. Basically, he'll replicate my AJAX to send the same request, in the same fashion. FAILED!!
I am not able to figure out this part. Can anyone help?
Thanks in advance.
Rule #1 of programming for the Internet: Never trust anything from the client. EVER.
Rule #2 of programming for the Internet: Never trust anything from the client. EVER.
Rule #3 of programming for the Internet: You can not make the client trustworthy.
I know the first rule is duplicated twice, but it is worth it.
There is simply no way to do what you intend to do.
A person who wishes to send data to your server, via an AJAX request or a POST request, can easily do any of the following:
Modify the form using browser tools or a proxy and force-feed in whatever information he wants.
Capture the entire transaction, through a tool like fiddler2, and change the values and re-send them. No browser needed.
Modify the code running from your site to send (or allow) whatever data he wishes to send.
Use a tool like Curl to fake an browser and send whatever information he wishes to.
There is simply no way of knowing, on your server, where that information came from.
From a security point of view, you simply can not trust anything -- ever.
Validate the credentials, give the user a login token (usually a cookie) and then still be suspicious of everything the client sends you. If there is something that shouldn't be changed or updated, make sure your back-end doesn't allow it to be changed or updated.
We have tons of code in our application that looks like this:
if (user.HasPermission("MayUpdateFirstName") {
record.FirstName = FormData.FirstName
}
That way, if FirstName is passed in, and the user can't modify it, then it doesn't get modified.

Verifying the validity of the data sent from WebApp to Web Service

I am building a WebApp which connects to my server through a web service.
Users (there is no login) which use the webapp can send their scores to the
server.
The code is written mostly in javscript, so anyone can read it.
As I know there is no 100% gurantee method of doing this, I am just looking for ideas
how to make it as hard as possible for users to send false scores.
Ideas?
10X!
EDIT
The server side web service is an asmx (.net) web service hosted on an IIS.
I can modify it as needed.
I'd say the best thing to do would be to have a webservice call that generates a guid on the the serverside, which is passed back. This becomes your session token. It's stored on the database or in cache on the server
Each subsequent call requires the passing of the token back to the server, which validates the token. If they pass a bad token you don't update.
This will only insure that the calls come from the correct process. They won't be able to spoof the entry with a single call
For a process (you seem to be talking about a game?) with a limited number of interaction points, you can record each user interaction and play it back to check that it results in a certain score at the server side (either in real time or later on for suspicious scores).
Otherwise (and this is typically impractical for an real-time action game where there are too many interaction points), there is not much you can do. You can have the game digitally sign the information it is submitting... but given that you are giving the full code including signing key to the client side, it is still easy for an attacker to obtain the key and sign invalid scores.
At this point you get yourself into an obfuscation arms race - how much can you make the client-side code unreadable and difficult to unravel, to prevent attackers from obtaining the key? You can never win this game, only deter the casual attacker. And ultimately you have to protect the entire client-side process from alteration, to stop all other forms of cheating (eg using Firebug to change variables like score or lives).

Password protected website with JavaScript

I have a quetion which may be simple/dumb or not :). In other words I have no idea if is fair enough or a completely foolish idea. Just some free thoughts.
What if I make my login via JavaScript with pass in it (yes I know), but pass will be hased by Secure Hash Algorithm. For instance:
I generate a pass with SHA which looks like
var = 0xc1059ed8... //etc
and paste into the code. There will be also two functions. One will compare two values (given by me with user's) and second will generate sha form user's input.
Is this could be safe theoritically or this is a horrible pattern and stupid idea? Can JS handle it?
EDIT: I didn't mean serious autentication like banking one. Just when I have my pics and want only to a few ppl to watch them and 99,9% of ppl on earth can't watch them :)
thx for responses
Sorry, no dice :) Secure authentication is not possible with client-side Javascript alone, because a positive authentication result could be faked. You will always need a server-side instance to authenticate against.
The common answer is that 'no, you can't do client side authentication' and for conventional scenarios that is correct, but I can think of at least two ways to make it work:
Use the SHA password hash to redirect to a static HTML page (0xc1059ed8...html). As long as the virtual directory doesn't allow file listing, no one will be able to guess the name of the file you want to protect. This gets clumsy really fast though.
Use an implementation of an encryption algorithm (AES, etc) in Javascript to decrypt a block of text that makes up the actual content of your page. Really only practical for one highly valuable page though.
Server side authentication is really the best, but it is incorrect to say that client side can't be done.
You cannot secure your site with Javascript alone. You will need some way to authenticate requests on the server.
Because all your javascript code is plainly visible to all consumers of your site. All a potential attacker would need to do is view souce of your website and they can bypass the password checking bit of your javascript and view the content behind it.
You need to have security implemented on the server-side, period the end. ASP.NET has a built-in way to do this called "Forms Authentication." Or you could use Session variables in a php script.
Your JS source will be visible anyway and anyone can fake it easily. You have to do a server side validation
Since the hash will reside on the user's computer (in the browser), i'd say it's a terrible idea. It will be easy to manipulate it.
You can use such a pattern to hide the password over a plaintext link and avoid https to login , but not as it stands.
The problem is that an attacker can steal the hashed password and use that to login to the server, and she does not need the real password.
This can be thwarted by a challenge response where the server sends with the page a "salt" : a big random number which is jumbled up with the password and then hashed, so the response is always different.
Unfortunately this has the effect that the server now needs to have plaintext passwords, which is a bad idea (ok, there are some tricks around this). So you might have to end up with a sending a salt, hashing your password, jumbling the hash with the salt by hashing it again and sending that to the server. The server hashes the stored hash of the password from the user db with the salt and compares both.
With security things get complicated real quickly and in complicated things opportunities lurk for the bad guys. A reason more to use well tested patterns, algorithms with a proven track record and libraries which have carefully implemented these.
And in any case it will be the server hwo has final say who can get access.
You'd be better off with no attempt at authentication at all -- at least that way you wouldn't give anybody the dangerous illusion that something involved might be secure.
Assuming you're dealing with a shared-secret situation, authentication is really pretty easy. You use a fairly simple challenge-response algorithm. Basically, the client sends a message to the server saying it wants to log in. The server responds by sending back a random number. The client encrypts that random number with the correct password, and sends it back. The server encrypts the random number itself, and compares the result to what the client sent. If they match, authentication has succeeded -- you've confirmed that the client has the right password.
The advantages of this: first, the password itself is never sent over the wire in any form, so an attacker has virtually no material to use in attempting to discover the password. Second, since the server generates a new random number for every login, an attacker cannot successfully authenticate by re-sending the packets it captured from a previous login.
Nearly any server with any sort of aspirations to security will already have something like this built in. It's purely a question of setting up your client to interact correctly with the form supported by the server(s) you care about.

Categories

Resources