3

I have a website with typing test. User can take a test after login. At the end of the test it sends an ajax and shows the result with accuracy, key per minute, wrong key press etc..

enter image description here

I noticed that somebody created an account on my site and he is always on top score with key per minute 2000 or more than that. I found only one thing to do the trick which is the ajax. Anybody can run the ajax from the console panel with new value like this -

$.ajax({ // this is the main code we have to prevent
 type: 'POST',
 url: '/typingtest',
 //dataType: 'json',
 data:{
  "corrects":2000,
  "incorrects":0,
  "netwpm" : 2000,
  "FixedMistakes" : 0,
  "TotalEntries" : 20000,
  "ErrorRate" : 0,
  "RawSpeed" : 50000,
  "KeySpeed" : 50000,
  "CompleteWords" : 2000,
  "TotalTime" : 1,
  "accuracy" : 200,
  "ajaxSubmit" : "ajaxSubmit"
 },
 success: function(data) {
  window.location.href = data;
 },
 complete: function() {
  // Schedule the next request when the current one's complete
 }
});

And he will get this result -

enter image description here

I have tried with some flag variable to validate on ajax page. But anything done with the js still anybody can see it and easily debug this process to change the values. And then finally he can run the ajax.

Has anyone any idea to prevent this thing to be happen?

Mithun Sen
  • 523
  • 5
  • 19
  • is using flash not an option? when you use javascript in this kind of situation its really easy to hack. – Netorica Mar 13 '14 at 06:18
  • yes. but client requirement is only with js. – Mithun Sen Mar 13 '14 at 06:20
  • 1
    why not change code process? hmm send an ajax request on every key score the user gains just don't forget to queue every request because i think you are sending a raw score from client side to the server side – Netorica Mar 13 '14 at 06:22
  • 1
    @Mahan I was also going to suggest that but it's a bit too much. 100WPM means more than 1 per second... – Alfred Xing Mar 13 '14 at 06:24
  • well that's another consequence of it but before you can display the player's score you must finish all the requests in the queue and i think that wil do the trick – Netorica Mar 13 '14 at 06:25
  • @Mahan but I think that will be slow process. if any user press and hold any key then the ajax will be fired for limitless number of times. Or that could be happen if any user has really fast typing speed. – Mithun Sen Mar 13 '14 at 06:27
  • there is a trick i think where you can prevent the a keypress event when hold. my another suggestion is you must use any somewhat like nodejs for this and socket io that can handle a lot of requests per second – Netorica Mar 13 '14 at 06:30
  • Make sure you undesrtand that Javascript is not a secured language, this is a client one and client can change execution of the local script, it also could send the AJAX request with values that the user wants, the AJAX request is not more than a HTTP request, nothing more, nothing less. With JS, you can NOT catch a trustable count of keystroke. But compiled language may help you, as flash and Java. If you have not choice about the techno, make it very difficult to read & understand. – Loenix Mar 13 '14 at 06:39
  • 1
    _“Anybody can run the ajax from the console panel”_ – anyone can send you an HTTP request using _any_ technique, whether they use AJAX from console or not does not matter one single bit. – CBroe Mar 13 '14 at 07:19
  • @CBroe, ohhh. I know that is not only one area from where anybody can run a ajax or script. I am a developer also. – Mithun Sen Mar 13 '14 at 07:28
  • Well then you should already know that trying to secure your scenario is a fruitless task. – CBroe Mar 13 '14 at 07:29
  • for me or anyone? If you found any mistake on my script u can tell me I will try to change that. Or If u says so for any script like this then 'yes it is'. – Mithun Sen Mar 13 '14 at 07:34

1 Answers1

1

In the case of words per minute, I would suggest:

Before starting the test, make sure your server-side code knows how many words are in the test. It's best to make sure this is somewhat random every time.

Sending a request to the server when the user starts the test in order to get a timestamp of when the test was started.

During the test, count how many words were successfully completed.

Then post again when the test is finished with the number of successfully completed words to get the total elapsed time. Verify with the server that the number of completed words is the same as the number of original words originally given, to make sure that nobody tampered with that number.

This way, the client is not keeping track of any unverifiable information.


Accuracy is a bit harder to verify, but just make sure to set a max value (an accuracy of 200% is definitely impossible!).


In addition, you can try security through obfuscation (see How can I obfuscate (protect) JavaScript?), but this is not the most secure method since experience JavaScripters can still know what's going on.

Community
  • 1
  • 1
Alfred Xing
  • 4,406
  • 2
  • 23
  • 34