1

Does anybody have any idea how to prevent AJAX request hijacking / modifying?

As javascript is public in website source, is it possible to manipulate the sent data, f.i ?.

$.ajax({
    url: endpoint/url,
    data: {
        id: 523658,
        fragile_data: 'it should stay constant'
    }
});
Jon Goodwin
  • 9,053
  • 5
  • 35
  • 54
David C.
  • 201
  • 2
  • 11
  • That's a very bad practice. Try to call a backend service that will call the target endpoint with the sensitive data. – Ele Jan 03 '18 at 22:46
  • so it is no other way I can call this endpoint asynchronously secure? – David C. Jan 03 '18 at 22:53
  • 1
    Are you worried about cross-domain requests? Or that someone could edit in harmful stuff in fragile_data? Or just the fact that fragile_data could be viewed at all? – pastaleg Jan 03 '18 at 22:56
  • I'm not worried these data are viewable, just the fact someone using various tools can stop executing javascript while it starts running and modify i.e. user id or any data provided – David C. Jan 03 '18 at 23:02
  • If there is no way, alteast you can make it private, isolated from global scope.. – bigless Jan 03 '18 at 23:04
  • @bigless I have never heard of private variables in javascript.What do you exactly mean by that? – David C. Jan 03 '18 at 23:12
  • Why the fact that someone can stop executing client-side javascript bothers you? – svgrafov Jan 03 '18 at 23:16
  • @svgrafov it bothering me, as even one out of million malicious user can make a huge harm for all application.... as you can see it is calling the external server database. – David C. Jan 03 '18 at 23:19
  • And what harm do you expect from user? Give an example. – svgrafov Jan 03 '18 at 23:20
  • @svgrafov , for instance, changing id (regardless if its users id or id of any record from database) is not desirable – David C. Jan 03 '18 at 23:23
  • 1
    User himself should be identified not with ID, but with some unique token that can't be guessed for other users. User's rights to perform operations on certain records in database should be checked on your backend. – svgrafov Jan 03 '18 at 23:28
  • what if it's not user id, what if its id of record in database to modify? – David C. Jan 03 '18 at 23:42
  • Check permissions on the back-end to see if user is allowed to modify that record. If so, then don't worry if he "hacked the endpoint". Say I'm about to upvote your question on stack overflow, but I "hack the endpoint" to upvote a different question by changing the id. Well, I'm allowed to upvote either question so stack overflow shouldn't care. – James Jan 03 '18 at 23:54
  • @DavidC. https://stackoverflow.com/questions/8228281/what-is-the-function-construct-in-javascript but this is not solution. Its only better than worst. ;) – bigless Jan 04 '18 at 00:08
  • @bigless self-invoked function that nobody will have time to even manipulate before it executes? ^_^ unfortunately, I'm making ajax request on clicking button – David C. Jan 04 '18 at 00:18

2 Answers2

3

Since you have no control over the client side, never trust the client side.
All you can (and have to) do is to validate data on the server side and probably to authenticate users.

Kosh
  • 16,966
  • 2
  • 19
  • 34
  • actually, I can store user id in $_SESSION arr, that will help a lot.... and compare it on the backend file. But it's still quite risky, what's the common practice for asynchronous loading websites? – David C. Jan 03 '18 at 23:09
  • 1
    I believe there is no big difference between sync and async requests in this context. If you need to authenticate, you can use session cookies, auth tokens and all that jazz. It depends on your specific implementation. – Kosh Jan 03 '18 at 23:17
  • can you give an example of authentication using session cookies? In a case of modifying posting headers there is not a lot I can actually do checking them with cookies – David C. Jan 03 '18 at 23:28
  • Looks like stackoverflow.com uses session cookies successfully. – Kosh Jan 03 '18 at 23:32
  • What if it's not user ID, but id of new record in database I asynchronously retrieved, and then in the process I want to use it to pass to another ajax request? – David C. Jan 03 '18 at 23:44
  • Since you have that ID of new record at backend, you do not have to send it there again. It's already there. – Kosh Jan 04 '18 at 00:25
0

There isn't a way

As part of standard security principle, you should always assume that any information coming from the client cannot be trusted. It must first be passed through a filter and checked to make sure it meets a certain specification. For example, if you ask for an email address and password, you should always encode the field before sending and then check the field server-side to be sure it actually meets an email address syntax. You should also trim it of any extra characters so that you don't fall victim to one of the classic blunders such as

test.user@email.com"; DROP TABLE Users; --

The same applies to AJAX requests. Always sanitise your inputs and always check that any IDs coming back are legitimate (and possible match to a lookup item if they are supposed to).

If you are short on time, there are a bunch of external plugins or frameworks you can get that are free and open source to help prevent attacks on fields such as client-side validators (make sure an email is in a field before it's submitted etc.) as well as checking items server-side to prevent against XSS and SQLi attacks and the likes of. These plugins won't be perfect, but they'll do a large portion of the work for you and allow you to speed up the process a little

Horkrine
  • 1,365
  • 12
  • 24