Passing a JS variable to PHP Safely - javascript

I making a javascript game where the player builds up a score against a count down timer. When the timer runs out I display a form that show the score and lets the user enter they username (arcade style). I'm going to use the POST method send the user score to a php file that will store it somehow (database,textfile. or something). How do I prevent people from fiddling with the JS code and passing some new value thru that isn't the correct score (or something that isn't malicious).
At the very least, what are the safest methods on the PHP/reviving end to at least only accept and integer value?

That's a well known and difficult problem. I'm not sure it ever has a good solution. The user is the client is JS, so they have 100% control over what's sent to the server.
The only thing you can do and force, is server side validation. Don't just send the score. Send the path, the method, the steps, etc. Starting a session/game/level should also happen on the server, because the timestamp could be faked from the client.
You can make the whole game in JS, but start and end it on the server and remember all the steps. This might mean double step/path validation: JS (instantly) and server.
(I had the same problem with http://games.webblocks.nl/110 which stores steps (clicks) in g_stack.)

Related

How to notify the front-end of a website of the status of a back-end processing job?

I currently face the following issue:
After a user has uploaded his images, all images are processed through a script that optimizes every image (compresses it and removes EXIF-data).
I got everything working, the only problem is that the proces takes quite some time. I want to notify the user of the job status, e.g. a percentage of the processed images.
Currently, the user has to wait without knowing what's up in the back-end. What is the best way to accomplish this? I've thought about AJAX-calls, but I honestly have no idea where to start with implementing this, also because it looks like I need multiple calls (kinda like a heartbeat call on the processing job).
The application I am developing in is a Laravel application, I've made an API controller which handles incoming files via AJAX calls.
Any help is appreciated, thanks.
Laravel has Broadcasting for this. It uses websockets, redis or pusher to send events to the client.
This way you can send the client a message when the processing is done without them having to refresh a webpage all the time.
You'd be better off reading about the principle of how it's done, for example: Progress bar AJAX and PHP
Essentially the way it's done is that the job (processing images in your case) happens on the server through PHP. Your script will need to produce some sort of output to show how far through it is, e.g. echo some value for the percentage progress. The PHP script itself is responsible for producing this output, so you must work out how to calculate it and then code that in. It could be that it takes the number of images to be processed into account, and when each one is successfully processed, it adds 1 to a counter. When the counter equals the number of images, 100% done, or possibly some error messages if something went wrong.
On the frontend you could have an ajax script which reads the output from the PHP script. This in turn could update a progress bar, or div with some sort of percentage message - the value used coming from your PHP script.
Laravel - and other frameworks - have built-in methods to help. But you'd be better understanding the principles of how it works, such as on the link I posted.

How do I prevent website user from seeing certain information until a certain condition is met.

So this is what I would like my website to do:
The website will generate a random number between 1 and 10,000.
The website user will then guess the number that the website generated by imputing their guess into a text-box.
If the user gets the number wrong a new number is generated and the user has to guess again.
If the user gets the number right a code-number is revealed.
My problem is that if the user simply inspects the java script they will be able to see the code-number within the script. How do i prevent the website user from manipulating the javascript code to know which number the website generated? also, how do I prevent the user from accessing the code by looking at the javascript? Do i need to use php or something?
Thanks for taking the time to read my question.
first of all you don't have to generate the number until they actually guess it.
function guess(number){
var rand=Math.random()*10000;
if(number==rand){
//success
}else{
//failure
}
}
This way no number is generated until they guess and you can't inspect that.
Also thinking outside the box: Based on the conditions, the number from the guess is irrelevant. If the number changes every time, they have a 1/10,000 chance every time to guess correctly. You simply have to write a function that only succeeds once every ten thousand times. However if they are looking at the source, they might feel betrayed by this.
If you put all your game logic on the client side, the client will be able to hack your game. All major web browsers come with a debugger which could easily manipulate and navigate your client side code in a variety of different ways.
That is why the server side should be responsible for these kinds of checks and validation. If the client had to submit the number to your server, the answer could be generated on the server side where it would be safe from any tampering.

Javascript + PHP + mySQL

I am a beginner doing a single player browser game as a hobby mostly to learn javascript + php + mySQL.
For some reason I want front end to be done exclusively with javascript (drawing levels, inventory, etc.) Broadly speaking, I will be heavily manipulating DOM using jQuery.
In the backend there is a mySQL database. In the middle there is PHP which I see serving two purposes: i) speak to DB , ii) validate logic and respond to requests coming from front end (i.e javascript).
For example, intended flow is:
user wants to open a door and interacts with a relevant element in the browser - clicks on it.
Action requires validation. AJAX call to PHP saying “user wants to open the door”.
PHP check with DB to see if the user has got a key in inventory, does some backend logic checks to ensure that the right door can be opened and responds, e.g. with “1” , meaning that the user has got the right key and action is "valid". PHP could also tag this door's status in DB as "unlocked" which means that player does not need a key to pass through it again. Key is removed from inventory record in DB.
Javascript receives PHP response and renders inventory and location anew (e.g. image of a key is now missing in player’s inventory and the door is drawn differently), could possibly start a dialog on screen and perform other DOM manipulations.
I would really appreciate some advice on how to handle the “session part” of such setup. Obviously, if there is a number of players playing the game at the same time, PHP needs to look up records in DB relevant for the player, which would be normally used by userid attribute in $_SESSION.
I understand that javascript can only operate with cookies and not with sessions. I would think that a cookie could be generated with some random ID and this random ID would be written to DB. Then, when AJAX posts to PHP, this ID would be included into the post and used to look up things in DB. Then PHP would respond and front end would be changed accordingly to the player affected but not for everyone else. Am I on the right track?
Would be most happy to have some small piece of code which could illustrate this or another solution.
On another note, would such setup be OK in terms of performance or should I consider fully using .php and leave JS do to some minor job (e..g initial validation of forms before posting, etc.)?

Safest way to update game score from client to server database? Javascript

So I have this game that is completely run on the client. No server interaction what so ever apart from downloading the initial scripts to play the game. Anyway at the end of the game I would like for the client to send me back the scores which should be updated in the server database. Now I have come to accept the fact that there is no way on earth I can hide this from a hacker and send the scores unaltered. But I would like to know till what level can I modify the whole process that it virtually becomes pretty infeasible for the hacker manipulate the data which is being sent. For sure I would not like the score to be sent as plain text from client machine and I don't want my server to perform complex decryption algorithm. What is the best way hence to achieve considerable amount of security that every tom dick and harry doesn't hack the scores... I hope someone could provide a nice little way that I could work on... :) Thanks
So my ideal result should be -> have trusted result from a calculation (of score) made by an untrusted party (the player)!
-Edit-
Someone told me something about hiding the data in a picture get request. Like, I am implementing this game on canvas (html5). So he asked me at the end of the game to fetch a game over image from my server, and they request should contain the hashed score. I did not exactly understand the complete process but if you could explain it, would be really glad! :)
coda^ so you can mask the requests nicely
shouvik how do I do it!?
coda^ you can compose the checksum you want to submit. like 12312312a12313a232 is your md5 which contains the score. bring in an asset into the canvas like
coda^ server.com/images/md5_hash_of_score/congratulations.png
coda^ which you can rewrite server side via htaccess
You seem to know this already, but just to stress; you cannot stop someone doing this; you can only make it as hard as possible!
Assume you currently submit the score as:
/submit_score.php?score=5
Someone watching in Firebug can easily distinguish where the score is submitted, and to alter it. submit_score.php gives it away, as does the name of the parameter. The score is a easily distinguishable integer.
Change the end point: /interaction.php?score=5
Change the parameter name: /interaction.php?a=5
It's getting harder for the user to work out what is going on.
Now you can make the score harder (again, harder, not impossible), to change. First, you can encrypt it (obviously you'll need to be able to decrpt it later).
Base 64 encode it.
Numbers -> Letters (1=a, 2=b, etc).
Reverse the order of the score representation.
You name it, you do it. So you now have interaction.php?a=e.
The next thing you can do is hash the score with something else. Send the hash with the score, and recalculate it on the server. For example, md5() the score with a random string, and send the score (encoded), the string, and the hash in the request:
/interaction.php?a=e&str=abcde&hash=123456789abcefbc
When the request hits the server, do:
if (md5($_GET['a'] . $_GET['str']) !== $_GET['hash']) exit;
Obviously people can (relatively) easily go through your JavaScript code and see what's going on; so make it harder for them there. Minify and Obfuscate the code.
If you make it hard enough for someone, they're going to try understand your JavaScript, try using Firebug, not understand what's going on, and not bother; for the sake of getting a few extra points on your game.
Use something like OAuth to authorize the request from client to server.
The header contains a token which matches to the body of the request. if these two doesn't match, then discard the request. Don't need to decrypt at server side, instead encrypt the body and check if the result obtained at server side and the token matches the same to find if the body was modified
"Now I have come to accept the fact that there is no way on earth I can hide this from a hacker and send the scores unaltered."
Oh yes, there is!
You can use RSA or any other public key encryption method (also called assymetric cryptography).
Create a set of (public and private) keys for the server.
Have your client code include your server's public key.
At the end of the game, the client code, encrypts the score (with this key) and sends both (plain score and encrypted score) to server.
Server decrypts and checks if plain score and decrypted one are same.
If yes, accept score.
If not, reject (there's a hacker or network error in the middle).
-------UPDATE-----------CORRECTION--------------
As Ambrosia, pointed out, my approach fails completely with this kind of attack.
What you actually want is to have a trusted result from a calculation (of score) made by an untrusted party (the player). No easy way to achieve this.
See this: http://coltrane.wiwi.hu-berlin.de/~fis/texts/2003-profit-untrust.pdf
Also this one: http://www.cse.psu.edu/~snarayan/publications/securecomputation.pdf
And this (which needs a subscription to the ACM digital library): http://portal.acm.org/citation.cfm?id=643477.643479
Can you use ajax to send the score (and any identifiers) to the server? Unless they have something like firebug open they won't see it happening.
var url = '/savescores.asp?userID=fredsmith&score=1098';
createRequest();
request.open('GET', url, true);
etc
Make the client send you the credentials (or some sort of session information in case you don't have logon credentials) and do that over SSL (https). This way you have both authentication and integrity control. Very easy and extremely lightweight for both server and client.

Countdown Timer to activate a controller method

I am building a survey page where users have a limited time to answer all their questions. The time given is stored in the model as #test.time_allowed, which is an integer representing seconds.
I need to have a simple and non-user-tamperable way to get a timer to display on the view and execute a controller action when it winds down to 0. How can I accomplish this?
I'm a relative beginner so any specific answers would be really helpful. Thank you.
---UPDATE---
#Bryan:
I assume there is a tamper proof way if the timing is done server side? For example, there might be a javascript timer on the client side as you suggested, but upon submission can't the submission time be checked against the time of the window's initial load?
Since data coming back from the client can never be fully trusted, the server must somehow know what the timestamp of the originally generated form was. This could be done by saving variables in the session or database, but this is problematic. Instead, the server can place a timestamp in the form, either encrypted, or signed, to ensure the client has not altered it. The server can then reject the submission as necessary. On the client, separate logic can handle the UI portion, giving the user feedback on the time limit, but ultimately this only loosely coupled to the server handling.
Details:
The server should generate two form fields: one with the system timestamp time = Time.now.to_i to track when the form was generated, and another with a signature Digest::MD5.hexdigest(time.to_s.concat('Some-secret-string-1234')) (note using the same time value here for the timestamp form field and signature form field). This validates that the form is submitted with a server-generated timestamp that has not been altered by the client.
You might also send another form field with the time limit.
On the client, read the timestamp, use setTimeout and the time limit to generate a countdown or whatever you want to do on the front end.
When the form is submitted, authenticate the timestamp submitted with the form by regenerating the MD5 signature using the same method as before. Make sure it matches the signature submitted by the form. Then, add the timestamp to the timeout, and make sure it's later than the current server time. If so, you have a valid submission, within your time constraint.
You probably will need to give a little more leeway on the timeout at the server than on the client, maybe a few seconds, to account for network delays, otherwise the user might see one second remaining, click submit, and then by the time the server request is received, it will seem like the timer has expired.
Be sure to add require 'digest/md5' to get access to MD5.
Using MD5 signatures like this is a great way to verify that a client has not altered key parameters in a form in a stateless manner, whatever you would like them to be. A good addition to your bag of tricks.
Good luck!
There's no 100% tamper proof way of implementing this since you would need to do this using JavaScript which can be turned off or manipulated by a sufficiently malicious user.
However if you aren't concerned about these issues you could simply set a timeout on the page to submit the form after the number of seconds have elapsed. To do this you would need something similar to the follow. Obviously timeInMilliseconds would need to be generated into the page from the template on the server side.
window.setTimeout(function() {
document.forms['survey_form'].submit();
},
timeInMilliseconds);
Create model for ongoing surveys, and add after_create filter that will set deadline to Time.now + survey_duration. Keep logic that will deny late sending of answers in model.

Categories

Resources