4

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.

Community
  • 1
  • 1
Martin Nyaga
  • 308
  • 3
  • 10
  • I don't think your proposed solution would stop anyone if they really wanted to change the values, even if it did, a user could theoretically just open fiddler and edit the request, or create a custom request in something like postman. You should implement some server side validation if these field are extremely important. – Robin Mar 11 '16 at 08:35
  • Yes any proposed method would easily be beatable. You simply cannot trust that client side values have not been manipulated. – Dave Pile Mar 11 '16 at 08:35
  • 2
    There is no way to make this secure. The third party service needs to have some signature field that depends on all submitted values, and only process the request if the signature and values are valid – dotnetom Mar 11 '16 at 08:36
  • use Escape ex. javascript escape() or encrpty your information – Visarut Sae-Pueng Mar 11 '16 at 08:37
  • Client side validation is just to make it pretty for a user, stops the AJAX or postback being required for them to see if its valid or not. Server side validation should be used also to prevent any nasty people messing around with stuff. Nothing is secure on the client and everything ca be manipulated in some form. – ste2425 Mar 11 '16 at 08:38
  • I see. How about, getting the form to be submitted, and validated server-side, and then have the server render an intermediate page with the form and auto-submit the form on load? In theory, the page will be rendered only momentarily, since the submit redirects to a page on the third party server. In this way there is no time to edit the request that is sent along. What do you think? – Martin Nyaga Mar 11 '16 at 08:42
  • @Robin see my comment above – Martin Nyaga Mar 11 '16 at 08:51
  • dotnetom's comment is the way you want to go. put another hidden value on the page that contains a public key signed digest of the other hidden values. If someone changes the values, there is little chance they will be able to generate the appropriate signature – Tibrogargan Mar 11 '16 at 08:53
  • @MartinNyaga Once again - this is not secure. User can easily inspect network traffic and send the request with tampered values. Your third party needs signature functionality or you need to send the request from server, where client cannot tamper values. – dotnetom Mar 11 '16 at 08:54
  • I see. Thanks for all your help people. I guess I'll have to either somehow figure out server side posting, and engage with the third party an see if I can sign my data. Thanks again for your help. – Martin Nyaga Mar 11 '16 at 09:41

4 Answers4

2

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

Pavel Morshenyuk
  • 10,891
  • 4
  • 32
  • 38
1

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.

Community
  • 1
  • 1
gurvinder372
  • 66,980
  • 10
  • 72
  • 94
  • How about, getting the form to be submitted, and validated server-side, and then have the server render an intermediate page with the form and auto-submit the form on load? In theory, the page will be rendered only momentarily, since the submit redirects to a page on the third party server. In this way there is no time to edit the request that is sent along. What do you think? – Martin Nyaga Mar 11 '16 at 08:52
  • @MartinNyaga how does it solve your problem? User can still edit the form when it has not been submitted. – gurvinder372 Mar 11 '16 at 10:34
1

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.

Aember
  • 124
  • 1
  • 5
  • How about, getting the form to be submitted, and validated server-side, and then have the server render an intermediate page with the form and auto-submit the form on load? In theory, the page will be rendered only momentarily, since the submit redirects to a page on the third party server. In this way there is no time to edit the request that is sent along. What do you think? – Martin Nyaga Mar 11 '16 at 08:52
  • As I understood the question, the user is supposed to confirm the transaction on the page with the hidden data. If the form is auto-submitted, this takes the confirmation out of the user's hands. – Aember Mar 11 '16 at 08:56
  • The auto submission would happen on a separate page after the payment page, after the user has confirmed. – Martin Nyaga Mar 11 '16 at 09:39
1

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;

  1. Store the vals on the originating server with a unique ID
  2. Send the confirmation back to the originating server for validation
  3. 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.

rockmo
  • 538
  • 4
  • 9