Server security: how to avoid attacks and hacks ?

I am planning to make my online game ( Reign of Rebels) available to a wider audience in a few weeks.
I know it needs a lot of visibility to start suffering from attacks, but anyway I want to make this exercise of raising the security.

I have a VPS, ip 64.79.204.148 which runs:
-Mysql
-Tomcat
-My game server (tcp listening on port 9993)

What kind of measures can I take to avoid attacks to my vps, to the website, mysql, etc ?

(PS I gave out the ip and ports just in case you guys want to play hacker, feel free to attack/hack it)

You have mysql listening on its public interface for anyone to connect to. Very bad.

I’m able to attempt to log in to the tomcat manager, though I haven’t bothered trying to guess passwords. You shouldn’t allow untrusted IPs to even hit that URL, or in fact anything that doesn’t match a whitelist expression. Make the whitelist regex generous if you must, just stop short of “/.*”. You can use a servlet filter, but I find it easier to toss a reverse proxy up there.

Can’t see anything else that jumps out at me, I didn’t bother portscanning it and I don’t know your game protocol.

Check every query for the single-quote character, and reject it. You might think I meant checking variables in queries, but I seriously meant any single-quote character in the entire query string.

This should result in an exception:

SELECT * FROM something WHERE name = 'teletubo'

Instead, ensure you use prepared statements:

SELECT * FROM something WHERE name = ?

and pass the “teletubo” string as a parameter.

This will render all those pesky SQL injections that scar the internet useless. Failling to do this will eventually lead to 1 not-quite-properly escaped input value. Don’t think that escaping all user-input is fine. The developers behind SMF think that is a solution, and SMF is open to attacks along hundreds of attack vectors (I browsed the code). Anyway: make SQL injections impossible, not unlikely.

The very same rule applies to template-engines. I’m still baffled at the complete lack of sense all these template-engine developers have. They should enforce the ‘escape type’ to be mandatory:


<div id="${html-attr:some.id}">
   <span>${html-text:some.label}</span>
   <div>
      ${html-ubb:some.reply}
   </div>
</div>

IMHO, that’s the only way to prevent XSS attacks. (You can drop the ‘html-’ prefix if you like…)

SSH security through obscurity: run the SSH daemon on some non-standard port, like 8263.
SSH security by design: only allow logins with (private) keys, not passwords. (physically print out the keys, as an ultimate backup)

As sproingie said: don’t make any administrative service accessible to anybody, regardless of the strength of your password. There will alsways be bugs/security holes (or braindead SQL exceptions) in administrative software, so hardcode some IP addresses that have access to these services. If you move to a new location, login over SSH and add that IP.

Block port 21 on your server, or shutdown the FTP daemon. FTP passwords are sent in plain text over internet. It’s easy to get infected by a virus, don’t think your virusscanner will catch them all for you. Don’t think viruses are only on questionable websites. Websites that you regularly visit, will eventually get hacked. They will likely listen for FTP traffic and steal your password. Do every file transfer with sFTP (again, with private keys).

Never reuse passwords. Don’t think that it’s OK for the server root password to be the same as the mysql root password. Everything must be long and unique, at least 10 characters.

Thank you guys, I’ll implement those securities in my next server update.

However, I didn’t understand this statement:

Why not ? If I escape their ’ ’ , can they still inject sql somehow ??

Yes. It’s actually rather unlikely to get it right by yourself, without reading some docs. This is the main reason SQL injections happen: insufficient escaping, or concating some value to an already escaped value.

(I updated the above post)

What SMF does (which can only mean it’s even crappier), is escaping strings in multiple ways, like both for SQL and for HTML.

If you write " x = 'a' < 'b' " in a textfield, what SMF actually INSERTs into the database is:

x = \'a\' &amp;lt; \'b\'

so the query string looks like:

x = \\\'a\\\' &amp;lt; \\\'b\\\'

After that, the assumption is made that everything in the database is SAFE, both to inject into an SQL query and to dump ‘as is’ in the browser. This is a horrible assumption.

What you should do:

  1. Take user input (call it A)
  2. Escape it to insert into a query (call it B)
  3. In the database, you’ll find A again
  4. Escape A as C when you use it.

Never assume existing data is safe to use anywhere. When you use the variable, escape it for that specific purpose (for SQL, HTML, JSON, CSS, whatever). Make the escaping a mandatory step, so that you can’t forget it – use exceptions for this.

The single quotes was just a quick heuristic to find the easiest of sql injections. There are many more possible. Overall, you should be using prepared statements and never interpolate values, period. Obviously this isn’t always doable when you need to dynamically select tables and columns, but in that case you can still dynamically create just that part, where you can be super-fascist about sanitizing. Better still to design the schema so you never have to do that.

XSS is reasonably easy to stop if you don’t publish user input (i.e. you’re not a blog/forum/board), and escape anything that you don’t intend to be markup. Modern template engines should escape by default. CSRF is the trickier and more subtle one, but as far as I know, using https and https-only cookies for sessions will kill most forms of it dead. You can try CSRFGuard (google it) if you’re extra-paranoid.

Also, disable Tomcat’s cookie-less sessions (the thing that puts JSESSIONID in the URL). They’re an open door to replay attacks.

That’s the problem: they escape it for 1 output type. Escaping for a html-paragraph is not anything like escaping it for an html-attribute, while they will occur within the same template.

Hence my proposal to make the declaration of escape type mandatory:

<div id="${attr:some.id}">
   <span>${html:some.label}</span>
   <div>
      ${ubb:some.reply}
   </div>
</div>

I have written & used such a template engine for years now, and it never let me down. Every variable is escaped in a way that is safe for it’s usage. It also supports escaping the same variable in multiple ways:

<span title="${attr:caption}">${html:caption}</span>

Eh, my experience is they’ll all escape quotes to ’ and ", which should be enough for both attributes and pcdata. Is there an example of otherwise?

Are you sure you want to handle newlines equally in html-attributes, html-paragraphs and json? I don’t.

Further, I use the same templating engine for formatting dates and numbers. It’s powerful stuff.

var json = ${json:some.pojo};

Newline is perfectly safe in attributes, you see them all the time in xsi:schemaLocation attributes. If you want to turn them into

in html, then that’s pretty far outside the scope of mere escaping, and is really more about content generation than simple template substitution.

Not in JSON, javascript doesn’t support multi-line strings.

Again, also way outside the realm of template substitution. Garbage in, garbage out. Who generates JSON with a template engine anyway? Template engines are blunt tools – but every craftsman has at least one hammer in his toolbox. Auto-escaping is more like preventing the head from flying off and smacking you in the face, but it won’t turn it into a chisel :slight_smile:

I guess it’s about dynamic vs. static ‘typing’ (escaping). You can enforce a variable to be an int in the template, for example.

Anyway, we’re drailing the thread, a bit :slight_smile:

[quote]Garbage in, garbage out
[/quote]
is exactly what leads to SQL injection and XSS attacks. It’s our responsibility to handle garbage.

We may have different interpretations of the term ‘template engine’. I like to use it as a tool that does heavy lifting, so that I don’t have to do it in the code that ‘fills’ the template, as to avoid (escaping) bugs.