Final Notes
Final presentations next week!
You game needs to be running online, have playable gameplay and support online profiles.
We'll have a small guest audience (Paula, Dave, Advisory board members, and possibly industry friends)
Be prepared to give 15 to 25 minute presentation.
- Explain what your game is, how it plays, what inspired you, etc.
- Walk us through parts of your development process, highlight the parts that were most interesting to you, etc.
- A couple of things on what went right, what went wrong, what you learned along the way, what you would do differently, etc.
Node.js Error Handling
Things that could go wrong
- The http request could encounter an error
- The json parse might fail, maybe from a bad format
- The database store might fail
- Your code sucks and do something like calling a non existent function.
There are a variety of patterns you can use for error handling. Using a third-party library may 'force' you into a certain pattern, though it's best to stick to a single style to keep code clearer.
A reasonable write-up on Node.js error handling patterns: http://snmaynard.com/2012/12/21/node-error-handling/
Exceptions
- Log any exception you catch, this is your best bet for debugging things once it's out in the wild!
- Any unhandled exception will crash your server.
- Exception handling in asynchronous functions may mean that a surrounding catch block isn't actually in the stack at the point of the error.
- Generally, throwing exceptions and using try catch is not a preferred practice.
Event Emitters
- Node.js API Documentation - http://nodejs.org/api/events.html#events_class_events_eventemitter
- An object that can register for and emit events, could be used for robust error handling.
- Very similar pattern to our game engine's Evented system.
Error Objects
- When a function encounters an error it returns a new Error("")
- Check result to see if it is an instanceof Error
Domains (Node 0.8)
- Node.js API Documentation - http://nodejs.org/api/domain.html
- Allows you to deal with exceptions and errors in a single place (similar to try catch in synchronous code)
- Seems to be a new feature that is work-in-progress, so be prepared for possible changes.
Security
Or, a short story on why you should never trust your users.
No client-side solution is going to be 100% secure. Security issues can kill your user base overnight.
Simple case study - Angry Birds HTML5 hacked within an hour: http://wesbos.com/all-levels-html5-angry-birds/
Our biggest concerns in game development? Cheating and jeopardizing personal user-data.
A quick guide on the Top-ten threats affecting HTML5
Cross-site scripting attack (or XSS)
- Wikipedia entry - http://en.wikipedia.org/wiki/Cross-site_scripting
- Imagine someone's username as: "</td><script>...</script><td>"
- When you go to render that in an HTML page, you've just sent malicious code to the client!
- Countermeasures:
- Escape all user input
- List of characters to escape - http://www.theukwebdesigncompany.com/articles/entity-escape-characters.php
Query-injection attack
- User hijacks an SQL query to do something like delete.
- Imagine someone has this as a username: "a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't"
- not a problem in mongodb because it does not do parsing
Cookie poisoning
- Cookies can store information about a user to speed up authentication
- Modifying the contents of a cookie to bypass security measures or gain unauthorized information about another user and steal their identity.
- Countermeasures include using encryption, or using a digital signature
Cross-site request forgery (CSRF)
- Wikipedia entry - http://en.wikipedia.org/wiki/Cross-site_request_forgery
- exploits a target site's trust on a users identity, and tricks the user into sending an HTTP request to the target site with negative effects.
- example: a user is logged in to their bank account, and another site has code that would withdraw money from the account
- Countermeasures:
- require a secret, user-specifid token in all form submissions and side-effect URLs; an attacker's site cannot put the right token in its submissions
- require the client to provide authentication data in the same http request used to perform any operation with security implications
- limit the lifetime of session cookies
HTML & CSS injections
- Not all malicious code has to be javascript (supposedly)
- Similar to XSS - if you don't escape user input like your high score entries then you could be sending malicious code to other users.
- http://i8jesus.com/?p=10
Cheating and Piracy!
- You have a scoreboard, or other feature that the user could manipulating by hacking at your code.
- ie, client sends a score to the server, and since the server trusts it we just add the value to the database. It would be easy for the user to fake a score and handwrite the ajax request.
- Or, because you send all of your source code to the client, it could be easy for them to take it and put it up on their own site!
- Countermeasures:
Obfuscation
- Understanding your code is the first step to hacking, so this makes it harder.
- Minify your code to make it less readable. This also makes your code download faster. This is only a small amount of protection.
- Google closure compiler: http://closuretools.blogspot.com/
Encryption
- Encrypt your JSON objects before sending them through ajax
- JWT - JSON Web Token: an encryption key used by Google In-App Payments.
- Node.js module - https://github.com/hokaccha/node-jwt-simple
- Client sends server a special identifier (like a player id) and sends it to the server
- Server generates and sends back a JWT
- Client must encrypt JSON objects using JWTF before sending them to the server
- Server decrypt JSON to make sure it is valid.
Back-end
- Keep your code on the server. By running the simulation on the server, just like we would a multiplayer game, the client can't do anything malicious!
- Scores are generated by the server, so they can be trusted.
- Finding the right combination of server/client workload requires creativity.
- Case study: Word Wars - while playing the client needs to know if a word is valid or not. Each time the client attempts a word you could send it to the server (which would be laggy) or you could send the entire word list to the client (easy to cheat!). They went with the latter but had the server hash the word list before sending it. Finally, the client sends the all the found words to the server to validate the score.
Non HTML5 game security issues
These issues are usually (but might not necessarily be) related to native application development. Unintended behavior is your worst enemy!
- Overflow - an operation can result in a number that is too large for the data structure's size (ie, 32 bits for integer).
- Bots - automated operatons that can be performed faster or more accurately than a human being.
- Buffer overrun - User input could contain malicious code that would overwrite stack data.
In summary - never, ever, under any circumstance, trust your users.
Auxiliary notes
Quintus Engine
- Look what I found - http://html5quintus.com/
Achievements
- I feel like with writing a web server, authenticating users, and using a database we've reached our limit in workload and possibly code fatigue.
- The concept is very simple, and the code very similar to our leaderboard code.
- Implementation suggestions:
Server side:
- Store achievement information in a database collection (id, name, description, icon, more?)
- Store achievement progress in the User collection (earned, progress in percentage or count)
- Write an ajax function for returning all of the achievements in JSON
- Write a function for awarding a specific achievement and returns JSON to say whether the award was successful
Client side:
- Write a simple function that displays an achievement (name, description, icon, ) using DOM or in-game text and sprites.
- Create an achievement object that can be created by our gameplay code
- .id - used to know which achievement this object references. Could have the other properties too.
- .Award() - sends the ajax request and uses a callback to trigger the notification is it succeeded
- .Show() - shows the notification with the name, description, etc of the achievement type.
- Get and activate the appropriate achievement whenever specific gameplay conditions occur (specific score reached, enemies killed).
Web-Sockets
- Useful for real-time multiplayer (updating positions, sending actions), but can also be used for general purpose client/server communication (updating scores, awarding achievements)
- Has cross-domain support (vs. ajax which doesn't) means your game can be hosted on many sites with a server running on another.
Utilizing existing online services vs. writing a server application
- Robust game features with Clay.io
- Player profiles, Leaderboards, Achievements, Payments, Social Integration, Analytics, Encryption, etc
- They also have hosting and a cross-platform marketplace, so this could replace using Heroku as well, though we wouldn't get hands on experience writing a server application.
- Would seem that it makes a lot of the work simplier, so we can focus more on the concepts and have more features in our games when we're done.
- What do you think about future classes using it? (ie, I know there's a lot of work so the time savings is great but the value of understanding server-side programming and the server/client relationship)
Parting notes
- http://i.imgur.com/PaeBJ.jpg
- More things you wished we talked about?
- Feedback forms