How to know the exact time a user submitted a form - php

We're building an online test with individually timed questions. The questions are a series of forms which the users must complete within a pre-determined number of seconds. Although the users will see a javascript ticking clock on each question, the actual enforcement of the time limit must happen server-side (otherwise it would be very easy for the user to disable/modify the time limit). However, we are concerned that network latency will unfairly penalize users who submit their answer close to the end of the time limit, close enough for latency to make their response over the time limit.
The sloppy solution seems to be to just allow a few second "grace period" when we check the duration as the answer is received at the server, but this is kind of lame. Is there a secure way to determine precisely when the user clicked "Submit".
If it matters, the web app is written in PHP.

I've actually had to deal with this problem before. What we ended up doing, is marking the time that the request for the page was made, and using a javascript ajax request (on load) from the browser to determine the round-trip time. Averaged out it ends up representing their network latency / computer speed, pretty well.
Obviously if it gets to anything over 15-20 seconds you have a bigger problem, but the most we saw was 3-4 seconds.
You can then use this in a "fairness" evaluation of how much time it actually took them.

Related

What is an acceptable website request duration per page?

I'm building a site in Laravel, and I just started using the debug bar, which gives you some info regarding your request duration and memory usage. I'm curious what the best practices for target request duration? What is realistic? What is too high? Right now, most of my requests have a duration of somewhere in between 150-250ms. I can't seem to find any info anywhere as to what is acceptable.
Here are some guidelines:
0.1 second is about the limit for having the user feel that the system is reacting instantaneously, meaning that no special feedback is necessary except to display the result.
1.0 second is about the limit for the user's flow of thought to stay uninterrupted, even though the user will notice the delay. Normally, no special feedback is necessary during delays of more than 0.1 but less than 1.0 second, but the user does lose the feeling of operating directly on the data.
10 seconds is about the limit for keeping the user's attention focused on the dialogue. For longer delays, users will want to perform other tasks while waiting for the computer to finish, so they should be given feedback indicating when the computer expects to be done. Feedback during the delay is especially important if the response time is likely to be highly variable, since users will then not know what to expect.
If you'd like more information, consider posting a question on the UX Stack Exchange.

How many XMLHttpRequests cause server strain?

I am making a simple PHP and JavaScript multiplayer game. Here is a quick rundown of how it will work: when a user does something, it is submitted with ajax to a php script, which saves a few charachters representing the action taken to a text file on the server. Every so often (to be exact, 430 milliseconds), the other player's computer submits something to another php script, which checks for new content on that text file. If there is new content, it is returned to the client-side and displayed on the other users screen. The only thing is, I am new to ajax, php, and anything server and do not want to crash the server. To make sure I do not crash the server, I need to know if submitting an XMLHttpRequest every 430 millisecoinds is a potential cause of major server strain. Not only that, but BOTH players will submit an XMLHttpRequest every 430 milliseconds. I can easily raise it to 450 milliseconds, but anything beyond that will be a problem.
Well, that depends entirely on your server. If you're running it on a ZX80, I'd be concerned :-)
However, that's only four to six requests a second and modern servers should have no difficulty handling that sort of load.
Of course, if what happens on the server in response to your requests takes more time that the cycle time, you'll run into problems, especially with sustained traffic (no chance to slow down).
This will be inefficient with separate requests, I would suggest taking some time to understand COMET, the term refers to a number of techniques to manage always open bi-direction connections over HTTP.
Here are some useful links I'd start with (I'm not too familiar with COMET for PHP, so I haven't vetted these resource recommendations myself).
http://en.wikipedia.org/wiki/Comet_%28programming%29
Using comet with PHP?
http://www.zeitoun.net/articles/comet_and_php/start

Should i use Sleep() or just deny them

Im implementing a delay system so that any IP i deem abusive will automatically get an incremental delay via Sleep().
My question is, will this result in added CPU usage and thus kill my site anyways if the attacker just keeps opening new instances while being delayed? Or is the sleep() command use minimal CPU/memory and wont be much of a burden on a small script. I dont wish to flat out deny them as i'd rather they not know about the limit in an obvious way, but willing to hear why i should.
[ Please no discussion on why im deeming an IP abusive on a small site, cause heres why: I recently built a script that cURL's a page & returns information to the user and i noticed a few IP's spamming my stupid little script. cURLing too often sometimes renders my results unobtainable from the server im polling and legitimate users get screwed out of their results. ]
The sleep does not use any CPU or Memory which is not already used by the process accepting the call.
The problem you will face with implementing sleep() is that you will eventually run out of file descriptors while the attacker site around waiting for your sleep to time out, and then your site will appear to be down to any other people who tries to connect.
This is a classical DDoS scenario -- the attacker do not actually try to break into your machine (they may also try to do that, but that is a different storry) instead they are trying to harm your site by using up every resource you have, being either bandwidth, file descriptors, thread for processing etc. -- and when one of your resources are used up, then you site appears to be down although your server is not actually down.
The only real defense here is to either not accept the calls, or to have a dynamic firewall configuration which filters out calls -- or a router/firewall box which does the same but off your server.
I think the issue with this would be that you could potentially have a LARGE number of sleeping threads laying around the system. If you detect your abuse, immediately send back an error and be done with it.
My worry with your method is repeat abusers that get their timeout up to several hours. You'll have their threads sticking around for a long time even though they aren't using the CPU. There are other resources to keep in mind besides just CPU.
Sleep() is a function that "blocks" execution for a specific amount of time. It isn't the equivalent of:
while (x<1000000);
As that would cause 100% CPU usage. It simply puts the process into a "Blocked" state in the Operating System and then puts the process back into the "Ready" state after the timer is up.
Keep in mind, though, that PHP has a default of 30-second timeout. I'm not sure if "Sleep()" conforms to that or not (I would doubt it since its a system call instead of script)
Your host may not like you having so many "Blocked" processes, so be careful of that.
EDIT: According to Does sleep time count for execution time limit?, it would appear that "Sleep()" is not affected by "max execution time" (under Linux), as I expected. Apparently it does under Windows.
If you are doing what I also tried, I think you're going to be in the clear.
My authentication script built out something similar to Atwood's hellbanning idea. SessionIDs were captured in RAM and rotated on every page call. If conditions weren't met, I would flag that particular Session with a demerit. After three, I began adding sleep() calls to their executions. The limit was variable, but I settled on 3 seconds as a happy number.
With authentication, the attacker relies on performing a certain number of attempts per second to make it worth their while to attack. If this is their focal point, introducing sleep makes the system look slower than it really is, which in my opinion will make it less desirable to attack.
If you slow them down instead of flat out telling them no, you stand a slightly more reasonable chance of looking less attractive.
That being said, it is security through a "type" of obfuscation, so you can't really rely on it too terribly much. Its just another factor in my overall recipe :)

Game's score is based on a client-side countdown. How to bulletproof it?

I'm working on a game, which has score based on a JavaScript countdown: the faster you finish the level before the countdown reaches zero, the bigger your score is.
How can I make sure it is not somehow altered when I finally receive it from client-side on server-side?
My initial idea is to make two checkpoints: one at the beginning of a level and another at the end. Checkpoint is basically a session sent via AJAX to server-side PHP script which is then timestamped. So after the game is finished on client-side, the score is verified with the one on server-side. Is this kind of protection any good?
Thank you in advance!
EDIT:
I'm also open to any other ways to achieve the desired functionality.
Simply, you store the value in a datetime field in your database. Then, you seed your javascript with that value. Thus, any change on the client side, will not have an effect on the stored time.
However, if you depend on the client side to get a value, you cannot do anything to make sure it's correct. The user can still spoof the ajax request with no real problem. It makes it a bit harded, but certainly doable.
Once your countdown is somehow related to the client side, there is no escape :)
As others have pointed out, there's no way you can be certain that the times have not been tampered with, however there are ways to mitigate the consequences:
If you have a (server-side) system that suspects that scores have been tampered, you can blacklist that IP address or cookie, and not show those scores to other users. Do show the scores to the hacker, though. This has several effects: Firstly, if they think they've beaten you they may move on and leave your code alone. Secondly, if your cheat detection wrongly thinks that a ninja player is hacking, the player will still see their score in the tables as normal (even if other players don't). Consequently, false positives don't matter so much, and you can use fuzzier algorithms, e.g. How does this player's rate of improvement compare to the average? Has he got a bunch of poor scores then suddenly an incredible one? Has my server seen an unusual pattern of hits from this user? Etc.
You could probably set this up so that you could refine your detection algorithms incrementally, and blacklist players after you've got suspicious about them (and un-blacklist false positives).
There are 2 possible scenarios which you might be facing. Let me start with the easy one:
a) If the web application is designed such that the game starts as soon as the page is loaded, your life is going to be simple. The script which sends out the game should timestamp the database with the time at which the game was sent out. This would be the start time. The end time would be recorded when the client sends in a "level completed" message. As time is being recorded at the server side in both the cases, you do not need the client to keep time. However, there is a catch. See The Catch section below.
b) If the client loads the application but the game begins much later when the user hits 'play' etc., your life is going to be a little more difficult. In this scenario, you would need a "level began" as well as a "level completed" message coming from the client. Again, it would be a better idea to keep time at the server and not the client. However, you would need to ensure that the client receives an ACK to the "level began" message before starting the game to ensure that the user does not play a game which is not being recorded by the server. (The "level began" message might never have reached the server).
The Catch: You need to realise that there is no protection possible for the user cheating on his scores! JS is completely open and no matter how you implement your start / end calls to the server, any user can write a script to send similar calls to the server at whatever time interval she wishes to use. Even if you use a session / cookie, these can be easily replicated. (Using a sniffer for instance). Thus, you must realise and accept the design limitations imposed by the HTML/JS architecture and code within these limits. Hence, the best idea is to write code for the users and not to prevent the hackers from sending rogue calls. Make your game fun for the people who would be playing your game and do not worry about the hackers cheating on their scores - they would not be your target audience anyway.
First of all, forget getting the elapsed time from the client side. Any malicious user can alter the sent data.
Server side must be the only authority for storing the time. At the beginning of the level, store the current time in the $_SESSION. At the end of the level, subtract it from the current time and it is the elapsed time for the level.
$_SESSION['start_time'] = time();
$elapsed_time = time() - $_SESSION['start_time'];
You can still show the elapsed time by Javascript for the user's convenience. For the timing differences between the client and the server (which is perfectly possible), you can do synchronization by getting the elapsed_time whenever your client hit the server.
If the level completion span between multiple sessions (like you start the level, leave the site, and come back later to finish it) you have to store it in a persistent data store (database).
You can use a timestamp in a session to store the start date and then send make JavaScript do a request when the player's done (but the second timestamp should come from PHP, or other server-side language, too).
The ony really bullet-proof way is to show nothing to the user and to ask him to tell you every single move, check it with the server and send back what it allows him to know. But this means delay.
You could issue a unique token, that is stored within the user's session and is available to your Javascript code. When starting an AJAX request, pass this token as an additional parameter, so the server can distinguish between legimitate and spurious requests.
This token should be valid for a single request only of course.
In combination with the mentioned solutions (server-based time checks etc.) you should be able to build a solid scoring system.
well, thinking of this problem gives me two ideas:
Attack your own server.
by that i mean, send a request every 1 second, that will save the score.
this way, the "hacker" can not send Start/End time and cheat.
make the requests at a specific time diffrences.
ok, so lets say we started playing, you can send a request at specific time intervals (3.4 sec? )
if a request is not in that time frame then the user is cheating ?
or at least marked as possible cheater.
use a simple string. XD
for start/end time sent to server, offcourse encrypted.
you can try jCryption for encryption.
since as the others said, it is not totaly fail proof ( since we are talking about client side script ) , but at least it will make it a lot harder to cheat.
dunno, its just my two cents.
It is not possible to make it 100% bulletproof, you can only make it harder to hack if it is based on client-side
You can generate a GUID when the page is rendered. You can concatenate this GUID, the start datetime ticks, the session ID, and calculate a hash of them to validate the data when user return.

How long is too long for a script to execute?

What is the max time do you think is acceptable for a web script (PHP for example) to execute before it starts to become an annoyance for the user (on average)? I always thought that if the user has to wait more than 1 second for the page to load (this of course after images and css have been cached..this rule really only applies for subsequent requests) they would start to get annoyed.
42 seconds.
Actually, truth is it more comes down to the age and expectations of the user you are catering to. My parents for example, might be much more tolerant of an extended wait, but are also much more likely to press the button again and again, like they will to a crosswalk or elevator button.
That said the real answer is, how long is too long for the user to go without feedback? Even kicking up a quick hourglass logo, or progress bar, can make all the difference in the world for a user. That said, if the service you are providing should be realtime and act like a desktop app, too long is basically "anything perceptible".
So, cop-out answer... it depends. That said, even a "too long" wait, can be overcome by proper UI design and customer interaction.
Jacob Nielsen cites some research on this:
0.1 second is about the limit for having the user feel that the system is reacting instantaneously, meaning that no special feedback is necessary except to display the result.
1.0 second is about the limit for the user's flow of thought to stay uninterrupted, even though the user will notice the delay. Normally, no special feedback is necessary during delays of more than 0.1 but less than 1.0 second, but the user does lose the feeling of operating directly on the data.
10 seconds is about the limit for keeping the user's attention focused on the dialogue. For longer delays, users will want to perform other tasks while waiting for the computer to finish, so they should be given feedback indicating when the computer expects to be done. Feedback during the delay is especially important if the response time is likely to be highly variable, since users will then not know what to expect.
To serve as inspiration, you could look at how the NetBeans community interpret these values:
0.1 second - navigation and edit actions (e.g. folder expansion, paste in editor, navigation in editor), and painting of all menu bars must finish within this limit
1.0 second - all window and dialog openings must finish within this limit
10 seconds - all actions which are finished later than after 1 second and usually take less than 10 seconds must show some sort of busy indication (e.g. hour glass cursor or "please wait..." text); all actions taking longer than this limit are required to provide progress bar using Progress APIs
Well default limit for a PHP script execution is 30 seconds. If you are just asking from the users perspective then the rule of thumb would be the faster the better...
Anything that takes more than a few seconds of process time should be handled differently, here are some examples
Cache its output server side
Run a Cron job that does the processing
Spawn a faux process with PHP using system()
Take a look at this link:
http://www.simple-talk.com/dotnet/.net-tools/the-cost-of-poor-website-performance/
then just decide the level of frustration your users can reach.
My rule of thumb:
Keep server-side processing under a second in the average case scenario and definitely under 30s in the worst case.
I'd say a couple of seconds before you should call (PHP)ob_flush() and at least send SOMETHING to the client. Otherwise the elevator effect will take over and the user will refresh repeatedly. As for total page load, it doesn't matter as long as you keep the user posted. A progress bar will help with that.
The tried and true strategy is always to manage expectations. Don't make a user second guess you or your application. If, by your benchmarks, the average processing time for a particular page will go beyond, say a 6-second threshold, say so before the user clicks a button. It's much like waiting for a Web site to send you a confirmation e-mail, not knowing when it will arrive, because it was never mentioned that it could take several hours due to traffic beyond the control of the site.
From my experience, you should give the user at least some notice if something's gonna take more than few seconds. Possibly use AJAX with some fancy animation and notice like "This is gonna take a while".
If you cannot use AJAX and your PHP script is taking, for example, more than 10 seconds to load, try to think about a way to optimize it.

Categories