Security For Open Source Web Projects?
PoissonPilote writes "I'm currently developing a multi-player, browser-based game, using the good old HTML, JavaScript, PHP, and MySQL combination. Progress is good so far, and the number of players is slowly but steadily increasing. At the beginning of the project, I decided to put the entirety of my game under the MIT license, so that anyone could study the code or even start their own server for the game. However, with the increasing popularity of my project, I am starting to worry about security issues. Even though I consider myself decent at web development and am pretty sure I'm not making any classic mistakes (SQL injection, cross-site scripting, URL forgery, etc.), I am no web security expert. I didn't find any relevant examples to compare my game to, as most open source games are written in a compiled language, and no web server is at stake in those cases. Some web developer friends told me not to release the source code at all; others told me to release it only when the game will be shut down. Naturally, I'm not satisfied by either of these solutions. What approach would you recommend?"
Use VB 6.0 MS-SQL Server 2000 and IIS 5.0, can't go wrong there.
PHP + Security considerations, this is going to get ugly.
However, I will chime in...
"Even though I consider myself decent at web development and am pretty sure I'm not making any classic mistakes (SQL injection, cross-site scripting, URL forgery, etc.)"
Lets hope so. If you used something else maybe you wouldn't have to be "pretty sure". It will bite you, history shows.
The entirety of the game state should be stored on the server and all user inputs should be validated on the server.
This won't stop people from botting your game, but it will keep the major chunk of blatant cheating to a minimum (at least on unmodified servers).
If you have the resources, you can always hire someone who might know more about it. If not, you could try relying on people's goodwill, and tell them upfront that "I need help with security".
Finally, didn't Google develop a system to test web application security? I'm pretty sure there was a story about it on Slashdot. There may be other solutions out there that will help you to at least plug the most obvious holes.
Clever signature text goes here.
Probably you want to sandbox your webserver, put it into a VM, run it as some user other than root obviously, have a HW or OpenBSD/PF based firewall sit in front of it and redirect requests to your VMs network, make sure no other services are running that can be accessed from the outside excluding the VM, probably add SSL to it (we just had a discussion on self signed certificates a little while ago here and what kind of POS it is to work with browsers in that case). I mean, it's a game, nobody is going to point and laugh at you if it has some web security issues, but you are not exactly explaining your architecture here either, you probably would be better off sandboxing it into a VM like that.
You can't handle the truth.
Don't make the mistake of thinking that obscurity (that is, making your code secret) guarantees security.
Also note that there are very secure projects (such as OpenBSD) which are released under the MIT license.
Closing the source does not make security holes go away. It may make them *marginally* harder to find, but probably not much harder for experienced attackers. What closing the source does do is make it harder or impossible for people who know something about securing such things to help you.
Disaster Planning has nothing to do with the code base (thought the code can make recovery easier) but it has much to do with security. If you can prevent security breaches with good coding, great but most of us have to suppose that we missed something so being able to deal with problems once they arise is just as crucial as preventing them in the first place.
For example: keep backups (snapshots) of player state on a separate machine unreachable from the webserver. ie the other machine logs into the webserver and copies data out. This way should the unfortunate happen you zap the webserver instance and restore from backup loosing at most the snapshot interval worth of game play. Yes some players will be upset but they won't all be starting over from scratch.
Some times this is called depth or security beyond a crunchy shell, but I like to think of it in terms of the big picture model where great gameplay, security, and disaster recovery are all pieces of the picture and without all the pieces the product is incomplete. (Kinda like Windows not having an ssh command line client, it's not a usable OS for me until I've installed an ssh client)
You didn't make clear what you were trying to secure in the first place. Are you securing against someone doesn't exploit your game in order to get control of the server itself? Are you securing against someone cheating within the game? Securing user data from tampering? Each of these has different costs when breached.
Assume your server will be rooted. Minimize the damage that can be caused, and maximize the information you can get to defeat the next attack. So:
Have everything backed up to something physically separated from the target.
Have lots of logging to analyze in the event of an attack.
If you have other more conventional stuff you want to keep up, have a spare server with everything minus the game ready to switch in after an attack.
"Who is the Journal of Quantum Physics going to believe?" --Stephen Hawking
For every person out there who finds a hole in your code and tries to exploit it, there will be someone who will help and patch any holes - if they exist.
i would definitely check out mod security. it has injection detection which is good for any web application and a open source one is no different.
If you do all of the above, your app might still not be "secure", but breaking it will be a PITA.
I worked on an OSS browser based MMOG in the late 1990's up until 2003 when someone compromised the OpenBSD server it was being hosted on. As many people who play to win the game, there are more who pride themselves on beating the system. And folks take these games way too seriously.
Not only do you have to keep up with security with your programming, you have to keep on top of your system security. Being a good programmer is almost secondary to being a good systems admin as I learned. That means subscribing and reading all the US-CERT warnings that come out, updated to the latest version of PHP/MySQL as security patches are released, and paying attention to any subsystem/process that is running on the server as well making sure that DNS/BIND, Apache, and anything else running is also up to date.
When my system was compromised, it was one of the other system utilities that was the angle of attack. Something I didn't even bother to notice at the time. Not the game or any of the core software that was being used. After 3 years of constantly battling the people trying to beat the system, the 20 - 30 hours of my free time it was taking to manage it wasn't worth the modest revenue coming in so I put the code up on sourceforge and walked away.
"The problem with socialism is eventually you run out of other people's money" - Thatcher.
Some say using a framework can help prevent known vulnerabilities in your code. That way you don't worry about security as much. On the other hand you may be like me and not like frameworks as much. I use a set of classes and validation techniques I have learned over the years. You should do risk management when operating the game. Even the top game developers like Blizzard deal with security holes.
For a start, consider using LIDS
(The name is a misnomer because it prevents alteration of protected components (even as root).)
What one fool can do, another can. (Ancient Simian Proverb)
Hiding the source just means people who are smarter than you can't help you.
It almost sounds like you're looking for some sort of magic IDS or IPS. They don't work like that. Your security is all what you do. Security should a factor for every piece of code written, before implementing some function or even line of code you should think about how secure it is and in what ways it could possibly be misused.
With secured code you can think about other things. Keep your servers patched. Use an enterprise type distribution. Limit installed software and of course disable/remove unnecessary services. Limit remote access to only the hosts that you know will need it.
I've been doing managed services for quite some time. Our customers get root access and can do what they want. The majority of compromises are due to bad code. Weak passwords come in second. Compromises dues to OS or standard services are practically nonexistent.
It has to be said: Don't use PHP if you value security or maintainability.
Yes, you can build a decent framework on top of PHP, so that you won't be vulnerable to SQL injections. By the time you do, you lose any speed advantage (or "ease-of-use" advantage) PHP had over Ruby on Rails. Given that, if you think Rails is too slow, your only real alternative is something like Java, and I'm not even sure Java with a full stack is any better.
Yes, you need to know what you're doing. The question is whether the platform makes it easier or harder for you to do it right. Rails has built-in countermeasures to request forgery, and even the built-in ORM makes it rare that you have to (or want to) write raw SQL, let alone use string interpolation. HTML-escaping in your templates is a single keystroke, and you can get template engines that make it the default.
That said, depending how much of this game has been written, porting to another language may be out of the question. But let's put it this way: Would you write a web app in a language that makes it possible for you to implement a buffer overflow? That is, would you use C?
Don't thank God, thank a doctor!
If you pay a qualified expert, they ought to be able to point you in the right direction. I would want to meet them physically though.
That story you mention sounds like the Jarlsberg one. The idea is you learn to secure your web application by exploiting a demonstrably weak one, so you learn your lesson. If you have the time, I definitely recommend working through it all. (story Jarlsberg homepage)
Another area to look at is simply your web server configuration. Your web application never runs in isolation. You have databases, web servers, sever side languages and other web applications that you use that are exploitable. Try to do as much checking as you scan for any obvious flaws, use tools to help you.
Run configuration file scanners for Apache, PHP*. Although I must stress I have not tried any of these, I just know they exist. I found these by just searching 'php scanner' and 'apache configuration scanner'.
Obviously they do not replace simply being careful or a whitehat's opinion and not trusting tools blindly. (A black hat probably doesn't release all his tools) Also try some generic vulnerability scanners which look for insecure installations that your web host may have installed like web mail and phpMyAdmin.
Just remember the environment.
Slashdot needs Geekcode | Can anyone recommend any good SCIFI? My tastes: Foundation, Startide Rising, CITY, Ringworld,
I highly recommend you read the announcing security vulnerabilities section of Producing Open Source Software book. You'll probably want to read the whole thing, however!
You got me before my morning (afternoon) coffee so here are some haphazard thoughts:
1) You're writing a PHP/MySQL app. It doesn't matter if it's a game or the next big social networking site. There are holes common to all web apps (check out the OWASP Top 10). There are also holes common in PHP code, such as remote file inclusion. There are things you can do wrong with JavaScript. Learn about them, learn about how to prevent them and write your code accordingly. Security should be part of development, not something you tack on afterward. This means using good coding convention (i.e using parametrized queries instead of concatenation, always encoding output, etc) and ensuring that any design decision you make does not compromise the security of your application. Make sure security is multi-layered as well. For example, even if you think your app is 100% free of SQL injection (wrong assumption!), you still need to make sure you've properly hashed user passwords in the database in case they're exposed. (Side note: please don't use MD5 for this; look into bcrypt, or at least many rounds of SHA-256 or such.)
2) Harden your environment. No amount of hardening will stop all attacks, but it may help mitigate their impact, and if you're lucky, it may thwart some script kiddies or automated scripts. Running PHP? Harden the crap out of your php.ini (magic_quotes_gpc, turn off fopen() for URLs, etc). Think about installing the Suhosin patch. Just don't get complacent; there are ways around all these protections and they are not a substitute for secure code! You may also consider a web-app firewall (WAF), in the vein of mod_security, but don't fully rely on these either. If you're publishing code for others to use, don't ever count on your users to implement these same protections in their environment.
3) Web app scanners can help, especially if you're a novice with security, but once again, they will not catch everything (probably not even a lot of things.) There's skipfish, NetSparker and free versions of some of the more commercial scanners.
4) I know your question was whether to publish your code. I say "Yes", but this is a personal opinion -- I just happen to think it will give security dudes more of a chance to audit your code, and attackers will find your vulnerabilities anyway, through poking at your app and fuzzing even if nothing is published.
I hope that helps a little!
We could probably have a more detailed discussion looking at the actual source. That's one of the advantages of Open Source. There's some good advice here already, but for what you're doing I would lean heavily on making it as easy and painless as possible to recover from an incident. Let's say you have a major incident.
If you run it all in a VM you'll lose some performance, but you can snapshot it, kill it and ship the snapshot to a local machine for forensics while directing everyone to a "Maintenance in Progress" page.
When you're ready to come back up you can restore from a previous snapshot apply the patches that fix the hole and move on with life.
Obviously game state makes this harder, so alot depends on what you can do to make the app support this.
Anyway, your project sounds cool. I'd like to see it.
[-- Trust the Monkey --]
95% of PHP coders are interested in solving a problem, not security. This means that the PHP community is less likely to find and complain about insecure implementation from the core PHP team.
Obviously, there are exceptions to this statement, just like fantastic, secure code can be written in VB or Python or Ruby. It just happens that isn't the usual outcome, but it could happen. It could, seriously.
I trust nothing the user sends
I trust nothing the user sends
I don't trust the SAs as I was one
I dont trust the NAs as I was one
I don't trust the DBAs as I was one
After I have all the functionality I need
My to do:
I keep everything sensitive _encoded_ to increase effort (not encrypted, performance for the end user is balanced against the privacy)
I dont keep logs or any information not needed as an attacker can use those logs against you, the system and the users (contrary to what other posters said)
I try to avoid having personally identifiable information of the users, it is not needed unless the user needs it
I seek to separate any information which may betray my user's identity from their actions in the event of a compromise event, you might know the who, but not the what or the what but not the who
my marketing does not require information on users in particular, but only in aggregate, I will collect more average revenue on an aggregate basis and avoid the creepy factor
my goal is only to make it a severe pain in the ass, not to stop them, as any motivated attacker is unstoppable
While we all appreciate your aversion to slashvertisement, I'm sure some of us would enjoy seeing what you've put together and/or contribute. Since it's in response to an explicit request for the information, can you point us at your project?
That green slime had it coming.
Security solution doesn't need to mean zero vulnerabilities. In addition to preventing attacks, you should focus on detection and recovery aspects.
Assume you will be attacked, will you be able to notice it? Write statistics systems to display player progress over time (or income per day, etc) and make sure you can spot unusual cases. Keep logs of events to track down what exactly happened so you can figure out how the suspicious players did what they did, etc...
Also, something will go wrong eventually. Can you do full rollback of one day or two? What will players think of it, how can you compensate for the time your players lost? Imagine someone hacks your database and changes stuff, can you track the propagation of the damage? If someone illicitly made millions of in-game cash, where did that go to? Etc etc...
You cant stop all attacks, so focus your effort on other aspects of risk management.
For encryption check out http://phpseclib.sourceforge.net/
"LGPL-licensed pure-PHP implementations of an arbitrary-precision integer arithmetic library, fully PKCS#1 (v2.1) compliant RSA, DES, 3DES, RC4, Rijndael, AES, SSH-1, SSH-2, and SFTP."
Great to have if you're not sure others will have mcrypt or other options installed on their server.
It's fortunate you're using PHP... with all the segfaults I see in php, combined with the way php cripples your efforts, your game server probably won't be up long enough for anyone to hack. :-)
Anyway, check into FastCGI, I've never used it with PHP, but it supposedly works with php too.
The upshot being, you can theoretically, run the FastCGI process in a chrooted environment, separate from the web server. (in fact, using FastCGI, you could run your application on a completely different machine from the web server (or a BSD jail, etc..)
This provides some degree of security, as people who might break in will not have access to other web stuff. (good luck getting PHP and it's million mile list of libraries in a chrooted environment..) In the case of real languages, FastCGI is really, really fast too. (if you plan for it) because you can pre-allocate data structures and hang on to objects for multiple requests.
Use the OWASP Application Verification Standard - this gives you an insight to the controls you need to work on first. A game should be at Level 2B.
http://www.owasp.org/index.php/Category:OWASP_Application_Security_Verification_Standard_Project
Don't worry about the language snobs - ANY language and ANY framework can be secured as long as you do the right thing in terms of design. Where you can go wrong is trusting untrustable data - such as that obtained from the browser without first canonicalizing, validating and ensuring that it meets business logic requirements (such as not being able to pass through walls, or avoiding object collision algorithms, asset or stat manipulation, or score manipulation. The client is completely untrustworthy, and you should be writing your code with that in mind 100% of the time.
I lean towards publishing the code. The only secrets you really need to protect are master authentication tokens in (say) config.php and authorization tokens in flight. So don't publish the master config.php secrets in SVN or similar, but everything else should be completely open.
Andrew van der Stock
1) First, you have to protect your users. I'd say there are three things to worry about here:
- SQL Injection. "Little Bobby Tables". This one is easy - use bind variables for all sql, and don't -ever- have dynamically interpreted sql with user inputs.
- Cross Site Scripting ("XSS"). This one is harder. If you ever display something to one user that could have been entered by another user, user b can own user a with some html. It's very hard to check for bad html because it can be disguised in various ways. A whitelist filter of allowed html is safer than a blacklist, but you still have to manage to consistenly scrub input.
- The fact that passwords are essentially inadequate, but it's hard and/or expensive to come up with anything better. So force decent passwords, remind your users not to give them to their friends, and anticipate there will be some level of "my angry ex boyfriend deleted all my stuff" support requests so history logs of important actions and the ability to roll stuff back will be useful.
- There *are* more types of things that can be done ("clickjacking", "sidejacking", dns poisoning) but I think the above cover most problems you really need to plan on.
2) Next, you have to protect your game.
- Malicious users. It's particularly easy to be a malicious user with HTML - the web app provides a nice form variable "itemid=12", I can change it to "itemid=1", poof I have your super wizard staff. You can't trust your users, ever, so write your app so that impossible things aren't permitted.
- Bots - if there is any instance where user activity is rewarded, somebody will find a way to automate it. It's a problem from a purely technical server load perspective, and it's also a problem from an upsetting good users viewpoint. Good luck here.
is competition good, or is duplication of effort bad?
My job is the same as the person asking the question, although we don't release to open source.
The above, I would say, barring a few minor points is correct.
I'll add a little bit. I'm assuming that it says to use magic_quotes_gpc. Don't.
It may seem labour intensive, but you're better off escaping each string as required with the escape routine for where you're sending it.
magic_quotes_gpc is dangerous. It's generic, so not really the best thing in many specific cases (all cases are specific to something) and it's not always clear where you need to use it. It doesn't apply in many places. I've seen many programmers caught out by this. For example, taking some data from user input from where it is escaped (ie _REQUEST) and storing it somewhere (database, local file, anywhere) then retrieving it later from that source, finally putting it back, assuming that it was escaped in the same way it was when retrieved from use input (actually this can happen without magic_quotes_gpc but not as easily as with proper escaping you're actually always keeping in mind what needs to be escaped rather than believing in magic). It might seem convenient, but in the long run, well there is no long run, you can't win a marathon by sprinting all the way. It will also be a nightmare to get rid of it later on as it isn't explicit in the code as to where it is being used. Furthermore, it's useless for stuff like query('SELECT * FROM table WHERE id='.$_GET['id']); Ensure that you always use the optimal escaping function for whatever system your data is from and for. Ensure you are aware of all the relevant functions such as shell escaping functions, database specific escaping functions/prepared statements, html escaping functions, javascript escaping functions (json will usually do), url escaping functions, etc. If a programmer can't handle that, they're in the wrong career and need to be doing something simpler (e.g. basic html, helpdesk, data input as long as it doesn't need thought and is limited to manual copying+pasting from paper to database as c&p is about as much as these people are good for). Besides that, you'll have to use these escape functions explicitly anyway when getting data from pretty much anywhere other than the user so there's no point confusing everyone and mixing it up. There is no real magic. Also, actually consider checking the user input it what is is supposed to be. If you do that, you often won't even need to escape. You could use magic_quotes_runtime to try to escape stuff from other sources, but besides having to know what sources it affects (many wont be), it'll also drive you up the bloody wall when you need to pass it to something that doesn't need it to be escaped or escaped differently, having to constantly unescape, annoying enough with only gpc.
Finally:
I could give out a hundred [+- some] examples/tips and justifications (angry justifications as I've had to fix a lot of bs code, I really hate other PHP "programmers"). However, that's beside the point. I recommend, that if you don't know this stuff, find people who do and have one or more of them review your code before release. Ideally, a benign hacker (ie white hat or whatever they call it). Your security concern is that someone will read the code to find bugs, that wouldn't be found so easily without such access. So give it out to someone (trustworthy) that will do the same, in a benign manner before releasing it to the public. Release it fully to the public once no one that you've given the challenge to can find a way to hack it within a reasonable amount of time. After such a process, it could still have security issues but they would be allot harder to find.
Additionally, turn on warnings and notices (in the log). I've found that by doing this and fixing everyone, many otherwise uncaught bugs get fixed and the resulting code is more exact. Being exact is important, the more scope you give for a script to accept anything other thant what it's supposed to accept, the more scope for abuse. Many warnings and
Check out the OWASP site for a good introduction to web security topics/techniques. There is plenty of information across the site to give you a start on what you should be doing.
You'll want to look at implementing things like:
To add to that, I guess magic_quotes_gpc is deprecated in PHP 5.x anyway, so you're right that it's not worth using. But there are settings within php.ini that can help harden PHP, though as I've said, it's absolutely no substitute for well-written code.
Here are a few pointers, mostly around PHP web app security:
- http://www.owasp.org/ - the Open Web Application Security Project has a comprehensive list of things to cover - see their http://www.owasp.org/index.php/PHP_Top_5 (top 5 PHP issues) in particular
- http://www.sitepoint.com/article/php-security-blunders/ Top 7 PHP security blunders - use =htmlspecialchars= for output of variables to page and do MySQL string escaping
- http://www.phpbuilder.com/columns/ian_gilfillan20050707.php3 - ensure include files can't be reached directly from HTTP.
- http://it.slashdot.org/comments.pl?sid=1121901&cid=26797895 - use http://us2.php.net/manual/en/function.filter-var.php -PHP Filter features]] (only in PHP 5.2.0 onwards)
- http://sucuri.net/ - monitors your site for free to detect compromises that affect readable pages
Final point: don't "filter out" dangerous characters, this is never ending and can never be done - instead, for any given parameter or input field, define the valid characters (e.g. alphanumeric, date, etc) and specifically allow ONLY those characters. This 'filtering in' approach is far safer.
Well, having been an open source developer for almost the 10 years, I know a bit about this. Firstly you need to code as securely as you can. Do the research, make sure you know whats going, and audit your own code thoroughly.
Don't believe no one else is looking, because they are. I've had one person ask me a few innocent questions about my code, then email a back a week later to say I'd passed their security audit just fine. I've also been unlucky enough - just once - to have the full disclosure email about a security vulnerability. And yes, that feels bad.
Do your very best; don't worry, and enjoy being part of the open source community.
If you decide to go the route and publish your code, you could at least make an effort to set up the infrastructure to handle bug reports and issue reports from those who discover vulnerabilities. As long as you are proactive in following up any reports, people filing security-related bug reports will feel that they are being listened to, and won't be discouraged from reporting again. Because you want to use a MIT licence, there are plenty of free open-source hosting solutions who will be happy to host your code, provide you with a source code management server and an issue tracker and mailing list.
The other commenters have also given good advice on securing your server and limiting any damage that might arise from an attack. I would only add that you might wish to get someone to perform a code review on vulnerable modules before you release it, in order to minimise making any exploitable bugs apparent.
Does your game really require a server? Servers increase cost for open source projects, so I would run as much code as possible on the clients. Granted that you need the server to set up the games, but all actions could be refereed indepently by several clients. If they don't agree, this may mean that someone is using a hacked client, and a warning should be displayed. The more players participate in such a peer-to-peer game, the more clients would have to be hacked in order cheat, but of course a single vulnerability in your system may still be fatal for security.
Please, do allow multiple logins. Did you see any big website forbidding it? Gmail allows it, slashdot too, wikipedia too, even ssh does.
There is a website that I need to use. The problem arise when it just tells you "you are already logged in. Try again in 15 minutes". There are times when the site is so slow (imagine hundreds of people trying to access this website at the same time, and its not built using scaleable tools), so you can wait hours until you can actually log in.
Cool! Is that included by default? Oh, I checked Wikipedia, nevermind.
Watching it closely it seems overly complex. And a patch. I am so going to waste my time building my own LFS...
Wake me up when Linux is secure by default.
I do security code reviews for PHP/mysql projects in my day job. I like to help with open source projects in my spare time.
Doug
Take off every 'sig' !!
Open-source web apps like CMSs, e-commerce apps and ERP apps manage to maintain security, so theres no reason a web based game couldn't, just adopt their tactics. Try to attract a community of developers and users, maintain a bug tracking system, etc.