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.
Related
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.
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.
I have a Flash based game for the browser which sends users' scores to a php backend script which stores the score and the user id in the database.
Now I have a url like www.example.com/update.php?score=200&uid=234
The problem is that this is very much exposed to an intelligent user, and he can use this url to store whatever score he wants in the DB. Also there's no real user authentication, and I don't intend to have one either, because it's really a tiny game.
How can I stop someone from calling the above url and updating his score on his own.
You might want to read about the "Marblecake" hack of an online polling system.
Substitute the concept of "submitting a vote" with "submitting a score" and you'll see that any client-side control is bound to fail.
While a good step might be to encrypt the score or use an HMAC to prevent tampering, your encryption will be done in the Flash client and the Flash app can be reverse-engineered for the key (it increases the effort required to cheat, but won't prevent cheating).
In order to minimize cheating, you'd have to move the scoring logic to the server and you'd have to run sanity checks or otherwise validate players' actions; otherwise, the approach to cheating would be executing invalid actions that lead to more points rather than just reporting the final score. (That last bit is vague since it's not clear what kind of game this is.)
At the very least, you should be able to tie score updates to a specific user so that cheaters can only affect their own score and not others'. I can only think of ways to bound the effect of cheating, such as rate limiting so that if an average game is N minutes, the server only accepts around 60/N score updates per hour . Or use some other metric/time period. But for what you describe as a tiny game that's probably not worth the effort -- especially since it only bounds the problem, it doesn't solve it.
You can't.
This isn't a question of CSRF anymore. Because you don't have any authentication whatsover, anybody on earth can update everybody else's score. There is just no way to prevent that from happening.
If you are concerned about security, authenticate the user. That will atleast prevent an attacker from updating scores en masse.
Then, fix your CSRF problem. With each of those urls, you need to append a unique token.
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.
I am making a game where the battle system uses javascript to battle. At the end of the battle you either win or lose. If the user wins, I need to update the mysql database with the XP they earned.
The best way I can think of doing this is to have the javascript run an ajax function when the user wins that POSTs something like addxp.php?amount=235, but if I do that then the user can easilly look at the source and see that they can just enter in that page themself to update their xp without battling. But this is the only way I know how to do it?
Help please :-/
If you rely on the code running on the client's web browser to update the battle results, you do not have control over that code. Many javascript and flash games that have a high score board that depend on the browser sending in the high score registration are vulnerable to this. There is no real easy way around this.
You can try to obfuscate things somewhat, but someone who's interested enough is going to be able to fairly easily get around this.
As knoopx mentioned in his comments, the only sure-fire way to get around this is to do computations server-side. For example, the client browser sends user actions to the server, and the server is the one that determines the outcome of the battle, inserts the result into the mySQL db, and sends the result back to the client. This is obviously a major architectural change and you'll have to decide whether it's worth it.
This one is tricky and unfortunately there is no easy solution. I can give you some advice that helped me when I was creating a flash-game with a cash-prize. It worked quite well for me, but again - it was by no means full proof.
First of all do some thinking about the highest score it would be possible to achieve over a given time period. For example, you could say that the highest score you could reasonably get after playing for 1 minute is 200 points.
Each time someone starts playing the game, you do an AJAX call to your server to obtain a game ID. At set intervals (say 10 seconds), you make your game phone home with the game ID and the latest score. This way the only way to cheat would be to create a script that periodically contacts the server with a slowly incrementing score that falls under your maximum. Not a difficult thing to do, but at least now we're entering the territory where we've eliminated the casual louts with TamperData and a few minutes to kill boredom with.
Another thing you can do when you send back the current score is the current status of the gameboard. This isn't so useful for catching cheats live, but it's a very good tool you can use when awarding a prize to check that the high-score is a genuine one. This adds another layer of complexity to your system and hopefully make some of the more slightly-hard-core louts get bored and find something else to do.
My last suggestion is this - you in no way make your users immediately aware of what you're doing. That is to say, that if someone's score falls above your high-score/time threshold, you do nothing to let them know that they've tripped your cheat-detector. In the game I created, I even recorded their high-score along with their cookie. When getting the highscores from your database you SELECT * FROM scores WHERE cheated = FALSE OR cookie = userscookie. This way, unless they clear their cookie and check again, it will appear (only to them) that their hack attempt was successful.
Oh and one last thing; minify your javascript. This will obfuscate the code and make it very hard to read. Again, someone determined enough can easily circumvent this and look at your code, but it's all about making your system complex enough that people won't bother.
Unfortunately the web's strongest point can sometimes also be its weakest. It is the nature of the WWW that source code is open and available for anyone to read, which means that keeping secrets from your users is very hard if not impossible.