3

I have the following ajax call which checks to see if the user is a paid member, if yes it runs certain functions accordingly. This works but i'm concerned about security. What if someone alters this ajax code in console forcing #button to run the functions in success without having to do any post. Can i prevent this while still using jQuery ajax.

$('#button').click(function() {
    $.ajax({
        url:'checkplan',
        type:'POST',
        success:function(data){
            if(data == 'paid')
                //grant access and run some functions
    }
})
Pinkie
  • 10,126
  • 22
  • 78
  • 124
  • You need to be sure your web server doesn't return anything the user shouldn't be able to see. Which means only returning the data associated with these "certain functions" after the user has already been validated as having access. – nnnnnn Feb 20 '12 at 23:22
  • FYI, this line of code `$('#button').on(function() {` needs an event (I assume you meant click) to be like this: `$('#button').on('click', function() {`. – jfriend00 Feb 20 '12 at 23:28
  • @jfriend, this was a typo. I fixed it. – Pinkie Feb 20 '12 at 23:32

3 Answers3

5

Ultimately your server needs to always enforce proper authentication. You cannot rely on the client to enforce anything because it can always be compromised (if not in your web page, in a custom-built web page). So, when you get logged in, your server needs to return some sort of token or set a cookie that contains some sort of token and only future requests of the server that have that token or cookie should be honored.

You can use logic in the client to present a nicer interface to the user (showing them logged in operations only after they've been authenticated, showing appropriate log in or log out options, etc...), but you can't use the client to actually provide security.

Many REST APIs have a login method that returns a sessionID and all other API requests require that sessionID. The server then checks that sessionID on every request to see if it's for a valid logged in user and to see if it's still valid (sessionIDs are usually only good for some time period if not used regularly).

Many web apps use a cookie to that all future page views and form submissions will be able to present to the server that they are logged in and authenticated properly because of the presence of the appropriate sessionID in the cookie.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Is there a way i hide the success functions if user is not a paid member – Pinkie Feb 20 '12 at 23:25
  • 1
    @Pinkie you are misunderstanding how this works. You can never protect against manipulation on the JavaScript side of things. That's why you need to make sure the *server* shows nothing to users who aren't logged in. – Pekka Feb 20 '12 at 23:28
  • The problem is i'm using jQuery ui Dialog with buttons that are created on the fly when a dialog is opened. I want some of those dialog buttons to only be available to paid members. That is why i'm went the ajax way, but unfortunately it's not secure. What are my alternatives. – Pinkie Feb 20 '12 at 23:30
  • You can hide the controls in the UI pretty easily - but that will not be secure (it will be pretty UI). I don't know jQuery UI, but if you put either a `loggedIn` or `notLoggedIn` class on the main dialog div based on the status, then you can use CSS to hide other controls when notLoggedIn is set. To repeat, this makes the UI make sense - it does not implement security. Only the server can implement security by checking for a login token or cookie on every operation. – jfriend00 Feb 20 '12 at 23:39
  • See my comment on akiler's answer – Pinkie Feb 20 '12 at 23:54
  • @Pinkie - From your other comments, creating the gallery involves a server operation, right? It's that server operation that you need to check on the server for some proper auth token in order to be secure. It should be easy for you to not offer the create gallery UI if the user is not authenticated, but that is NOT how you implement security. – jfriend00 Feb 20 '12 at 23:59
2

Pinkie what you should do rather than make this check on the client-side is never render code that is meant only for paid users on the client-side, like others mention, this imposes severe security holes since it's very simple to forge ajax requests with merely a firebug console.

Likewise, just "hiding" markup isn't going to cut it for you, so display:none; won't really accomplish anything in securing your website.

What I'd recommend is two-fold: firstly, don't even render javascript on the client that isn't meant for the user who is visiting. In this case you might even want to consider invoking a partial action method that decides whether or not to render what js code to the client, depending on the user credentials.

Secondly, there is only so much that can be done on the client-side, this means: every single method on the server side that is sensitive to the user's credentials should verify that the user is indeed allowed to access this functionality, and not just guess that if he's accessed that method, he must be.

Update

In the case you mention where you render a jquery UI dialog, as long as the buttons point to functionality thata verifies on the server-side that the user is who he claims to be, then you are "safe" (even though it's not the cleanliest code on the earth); what you should really be doing is render those buttons based on whether the user has the credentials you require.

Instead of checking if they have the required credentials in your ajax call, you should be making a query to fetch the portion of HTML / JS you were going to be rendering.

bevacqua
  • 47,502
  • 56
  • 171
  • 285
  • Check my comment on jfriend's answer above. – Pinkie Feb 20 '12 at 23:33
  • Not rendering the controls on the client side does not provide the necessary security as URLs/forms can be examined and then manufactured by a rogue client. A check for an authentication token has to be implemented on the server. This problem cannot be solved in the client. The normally functioning client can offer a clean UI based on the accurate state, but it cannot implement security. – jfriend00 Feb 20 '12 at 23:45
  • I am checking server side if member is paid using ajax. On success the functions in success must run on the client side. It's hard to make them run on the server side. The button basically allows the paid user to create a gallery for all his selected images. If user is not a paid member, and tried to click on the button, then it shouldn't allow him to create the gallery. I"m not seeing an alternative to making this Dialog button only available to paid members. – Pinkie Feb 20 '12 at 23:45
  • Just make sure the call to the server which actually saves the image gallery checks whether the user can have one. – bevacqua Feb 21 '12 at 00:36
1

If you're performing security checks like this client-side then there's nothing to stop the clients either modifying the Ajax URL (to return 'paid'), or just bypassing your JavaScript with their debugger to do what they want by jumping to your '//grant access and run some functions' section.

Let them perform those actions client-side if they wish, but always have a check in place server-side when the data is sent back before it is processed and stored to the database, or attempts to empty someone's bank account or such; the server-side validation checks are the only validation checks you can trust.

Never trust clients.

edit: jfriend00's answer is better :).

Community
  • 1
  • 1
akiller
  • 2,462
  • 22
  • 30