I have written a game.
It is an async turn based game where each person logs in at any time in the day, submits their orders, and at some time at the end of the day, the present turn is resolved.
However, the client side needs to know how to resolve previous turns, because it has to display it visually with all its many nuances. I have written this turn resolution in javascript.
Unfortunately, there is a secrecy element to the present turn. So I cannot just send all the data for the present turn to someones machine, get it to use its javascript functions of turn resolution in the code, then send it back to the database for everyone else to gather when they log in. Why not? Because that one person could catch the data, see the secret bits from other players, before allowing it to be sent back.
That means I have to completely rewrite my javascript code in PhP, so the secret turn resolution of the present turn can be done in private on the server.
So here is my question. To help me having to write my turn resolution code twice, once in javascript for the client (who needs the visual interpretation from the turn resolution) and again in php so the secret stuff of the present turn can be done in private, is there any way my php code can call my javascript turn resolution code from the php page?
Ie, I want my php page to be able to call a javascript function in a js file, which is all done on the server.
Do you really need to do it in PHP ?
If your hosting solution support node.js, you can reuse directly your javascript inside your server-side app.
It's called isomorphic javascript. (see : http://isomorphic.net/)
Another way to do it, would be to embed a javascript engine and call it from PHP (e.g : https://github.com/phpv8/v8js)
Related
I'm updating a database via PHP with data that's being sent via ajax. Is there a way to tell whether the script that is sending the data is called by the page on which it is included (remotely hosted), or just being hacked into the JS Console by someone who's "inspected my elements" and trying to pull a fast one?
Thanks in advance...
Danny
There really is no way of telling between either of them, but you can make the job much harder to do.
But since you say that 'it won't start wars', working off of that, there are a few ways of 'securing' it.
Step 1 : Creating 'Verification' calls
If you aren't already, the very first step would be to implement a few preliminary AJAX calls that retrieve certain variables which are later used in the calls that follow, for example:
Call #1 Retrieves Security-Token
Call #2 Creates a cookie Security-Token-2
Call #3 Call to your php script with Security-Token encrypted with Security-Token-2
What your page would then do, would decrypt the sent text with the 'token' stored in the cookie and use that.
Step 2 : Adding extra logic into javascript
You can add some encoding-decoding logic into the javascript,
I'm not saying this is going to be hard to break, but It might be tough, especially if you obfuscate your code (We all know obfuscation is no good, but bear with me)
Step 3 : Don't keep any names
Another thing you can do is remove all the names from the AJAX variables, or better yet, the names can be different every time.
If you want to go even further, you can encrypt the names, and plus to the encryption add a component of randomness by introducing an IV, and storing the IV in the cookies (maybe even encoded for added security).
(EDIT) Found the 'dynamic name generation' solution I was looking for:
Dynamic Field Names in PHP
The solution was initially designed to fight spambots which 'autofill' certain fields, and if the field names look random it doesn't know which fields are 'traps', however you could use it to generate the names for your AJAX calls.
In the end though, it is always possible to crack, all one needs is enough time and money.
This is a youtube guide by phpcademy (now codecourse) that throughly explains how to prevent CSRF (Cross Site Request Forgery) in PHP.
It involves generating a new random token every time a form is submitted.
Afterwards you check if a token has been posted. If not, the request is not authentic.
EDIT: you needn't be worried about people seeing the token when inspecting the page, as you have your own (server side) way of validating your token.
say, my PHP script needs some time to calculate its operations. I need to keep the client informed about the operation progress. An example can be PHP based file download, where I need to provide to client estimated time needed to finish the download, and the amount of data that needs to be copied.
In PHP I can calculate all the needed information. However, how to regularly update the client with this info?
Ideally, I would like to dynamically update JavaScript variable from within my PHP script. I read that this is not possible, so what options do I have then?
Possibilities that come to my mind:
Should I do regular AJAX calls from within my JavaScript into the PHP script to get the progress info?
Should I study for me yet unknown COMET methodology
Do the two above possibilities make sense? Is there any other more practical solution available?
Thank you in advance.
Yes, both of those options make sense.
There are lots of different COMET-style techniques, but one of the simplest is a long-running iframe. You have a PHP page that monitors the progress of the operation, and outputs something like this at regular intervals:
<script>parent.updateProgress(relevantUpdateInfo);</script>
...where relevantUpdateInfo is the information about the progress, and updateProgress is a global function on the page containing the iframe that shows the updated information in the UI.
When outputting the script tags, be sure to flush the output.
I use PHP and Javascript. In my website some results are processed server side some client side.
Using javascript only, prevents your website from being crawled correctly by search engines and using PHP only prevents correct real time response.
The problem is how to grantee both js functions and PHP functions give the same result? for example suppose there is a function which gives relative time:
JS:
function relative_time(timestamp)
{
...
}
PHP:
function relative_time($timestamp)
{
...
}
Keeping both functions matched with each other is not easy since I want to edit both. For example if both give us:
one year ago
And I change PHP only, to give me:
a year ago
Then JS is not updated too. Is there any standard way to ensure both will act in the same way?
unfortunately js function cannot be called on server side.
If there is some complicated logic, you should implement it server-side and just pull the results via AJAX. That way you only need to maintain the PHP code and provide a kind of AJAX API for access via JS.
I think you just need to make a decision where it is to be done, because if they do vary which is to be dominant ? (that's the one that should be doing it)
Also, how are you saving server load by doing it in both locations ?
Avoid this by making a decision for which code is to do it, failing that, Put a note in you code at both locations reminding yourself to update both locations ?
I'd like to be able to have Javascript code manipulate a persistent JSON object in the browser, and have it synchronise with the server, and other clients in real time.
I'm already using MVC separation.
I'd like to be able to do something like this:
function sendMessageToUser(username, message){
messageID = window.model.userMessages[username].messages.length;
window.model.userMessages[username].messages[messageID] = message;
window.requestModelSync();
}
in this example, window.model is a JSON object that is syncronised periodically or on demand, with errors upon collisions, so 'heavy' client code can handle such an event (it is not caught in the example, but if another user messaged the same user at the same time before syncs occurred, an error might be raised by the sync library).
The view code would be called upon a model change and would re-render the messages for the user - in real time.
Are there any libraries that do this already that are somewhat simple, and open-source?
Assuming it's not so secure, I'd like to add cookie based user authentication and key / value validation to it, assuming it doesn't exist already - while still using JSON, with no schema's or models required to start hacking.
I've seen Robert Sayre's sync.js which could be a key building block but I'd like to see something more fully formed, and preferably in use already. I.E: COMET, collision avoidance / resolution strategies, low bandwidth use etc already implemented.
If it doesn't exist I'd be happy to work on such a plugin with people skilled in Python and Javascript.
I've seen http://persistencejs.org/plugin/sync - it is not JSON, they end up defining their own model class.
I don't want to use something as complex as Apache Wave's API's either. Simplicity for prototyping is a key goal.
Firebase is a good candidate for solving your problem.
There isn't a native Python library, but there is a Python wrapper around the REST API
See:Firebase
Firebase home page
I'm implementing a simple game in Javascript, and am interested in having an online highscores table for it, so that players can compete against one another. I've two concerns about this:
What is the simplest server-side program I need for this purpose? I don't need a full-fledged "web application", just something simple that gets POST requests with highscores, updates a database and sends back lists of scores. I'm familiar with Django. What are your suggestions?
How can I make the highscores table reasonably secure? I'm aware that making it bulletproof against competent and dedicated hackers is difficult, but I wouldn't want anyone with access to the Javascript sourcecode to be able to submit fictitious scores too simply. Any tools for this purpose?
It's going to be pretty hard to secure the high scores. I mean, it's not enough to ensure that it comes from your page, because if, say, the JavaScript function is submitHighScore(n) then they can always type javascript:submitHighScore(10000000) in the address bar on that page and have it work.
What comes to mind is perhaps some sort of hash function that generates specific codes that match certain levels in the game. When submitting the score it would also submit this hash, so users would have had to get to this level in order to get that equivalent score.
Another option would be for the game to pull in some kind of key that only works temporarily, so as you went along the key would change and then the score would be submitted to a central server intermittently.
Keep in mind that really determined individuals can always just track the data being sent to your data and decompile it.
You could go the Broderbund route and ask the player trivia questions which are validated server-side to ensure they really did pass the level they said they did...something like "What color was the monster in the previous level?"
To submit score securely, sign it (you'd also need to ensure that the score isn't faked before it's signed and sent, but that's another problem).
Hide a secret in JS code, and send highscore + hash(highscore + secret) to the server. The hash could be MD5/SHA1 — there are easy to find JS implementations.
Of course it won't stand anyone carefully analysing the JS code, but at least someone won't be able to submit fake highscore just by tampering with HTTP traffic.
On hiding stuff in JS:
You can't really hide it (it's ultimately futile like DRM), but you can try hard to obfuscate it and make debugging painful.
Don't put the secret as a literal in the source code - compute it at run time combining results of several functions, local and global-ish variables.
Minify all code, remove sourcemaps.
Add bits of code that don't do anything, but seem to be important, to make debugging more confusing.
Don't put anything in global scope, but do rely on shared mutable state by passing closures and arrays around.
Rely on Date and timers to cause race conditions to make your code produce wrong results if it's paused in the debugger (just don't make it too tight to allow it to run on slow machines).
If the game is deterministic (like a puzzle game), then users could submit highscore in form of a log of steps taken to win (user's input) that you'd replay on the server to calculate the score.
This would change attack from finding/emulating score-submitting function to witing AI or hacking the game itself to make it easier to play (but still within its basic rules).
1.) Any CGI script that can talk to a database and understand JSON, or other format of your choice, will do the work.
However, if you're familiar with Django, building your server on top of Django would be the most simple, in the sense of what you have to learn and how much application code you have to write. Seemingly simple CGI script can turn out rather complex if you write it from scratch.
I found django-piston to be a handy Django app to quickly write a REST-style API server. It supports JSON so it should be easy to interface with your JavaScript game.
2.) The most casual cracker will go for a replay attack and its variants: peek at the page source and execute a JavaScript function, intercept HTTP requests and resend it (should be easy with a Firefox add-on like Tamper Data).
To counteract the former, you can obfuscate the source code and HTTP body;
Minify the JavaScript code
Encode the message you send to the server with Base64 or other encoding algorithm
The latter can be prevented by requiring all update requests to include an one-time password ("session token" in the Wikipedia article) that was recently acquired from the server.
I am thinking about this myself. What seems to be the most reasonable solution to me is this:
1) Sessions, to disallow tampering with the scoretable outside the game.
2) Log every action in the game and send it to the score server. The server will then calculate if those actions actually give such score. If you also log the time spent playing the game, you can further minimize the chance of an attacker to bother himself enough to break your game. This will also enable you to make a replay script like Arcade servers with hi-score tables have and in case of a suspicious score, you can watch the replay and decide for yourself if the score is real. The cheater would have to use a clever bot to play your game - and unless you have a game for real prizes, noone will try that hard.
If the cheater won't even analyze your code, sessions will stop him. If he reads your code, he would quickly break anything similar to hashed scores, secrets, tokens and whatsoever. But if you make the game-logging script thorough enough, he will give up.
In answer to your question:
1.) This depends on your environment and coding preference. PHP, Python, ASP.NET are a few that come to mind. Sense you already know Python (from your profile) you can use a Python CGI script to do this or use one of the many frameworks for Python (Zope, Django, Pylons,...).
see: http://www.python.org/doc/essays/ppt/sd99east/index.htm
for info on Python CGI.
2.) A few tricks for security: (none or full-proof)
Hidden Text Box in HTML with encoded value that server checks to match a cookie to ensure high score comes from your page.
Server Script only accepts values from a specific domain
You could use a combination of one of the methods above, as well as simply requiring the user to be registered to be able to post high scores. Non registered users could view their current score compared to existing high scores, but in order to post your high score online, you must have already logged in with your registered account, or provide it when the app goes to update the score online.
A simple message along the lines of "Your high score is X, and ranks ### in the high score table. To post this score online, please register with us first".
The better I think, is to make the calculation of the score directly into the python files of your django app.
Instead of calculate it in the javascript file. You send the datas to compare with your data basis with a POST request, then you calculate the score and you store it in your data basis. Like this, you don't make circulate the score across the web to your servers. Which is completely safe because you are only doing local stuffs.