Summary
Over the last couple of months this forum has been under attack by unknown people. They have managed to steal all of the email addresses on file for users by using an SQL injection attack.
They quite possibly have also got a copy of the hashed passwords. (See below for more information about this).
No credit card information was taken because the software on this site is Open Source, and thus freely available. There is no need to collect credit card numbers, and therefore they are not stored anywhere in the database.
Alert
I was alerted to this problem by a couple of helpful forum users who took the trouble to register different email accounts for every site they visit. Thus they know if they get spam which site the spam came from. I got reports that spam addressed to these addresses was being received. Furthermore, one user found a file with all the email addresses of all users on it, which proved that all the email addresses had in fact been harvested.
Response
It was initially difficult to see how this had happened, and my initial approach was to change the password for the forum database, and also to force users to change their passwords. However the problem persisted.
In the end it turned out to be an SQL injection attack, which is defeated by a fairly major reworking of how user-supplied data (eg. names, post numbers, etc.) are sent to the database. This has now been done and the forum should be safe against further attacks.
How does SQL injection work?
The basic idea is that you probe a web site to see if somewhere, on some page, the web designers haven't fully validated all input parameters. As an example, here is how you might see if a user is on file:
SELECT * FROM Users WHERE username = '$username' AND password = '$password';
In this case the PHP variables $username and $password would contain the supplied credentials. Now imagine that a user was able to supply this password:
Now the SQL looks like this:
SELECT * from Users WHERE username = '$username' AND password = 'foo' OR '1' = '1';
Since '1' always equals '1' then the test for the password passes, and the user can log in.
This is not how the attackers gained access to this site - I was careful with validating important information like that, but it demonstrates the idea.
It turns out that with fairly sophisticated SQL you can merge something benign (like the documentation of how a function works) with something private (like user email addresses) in such a way that instead of seeing a function description on a page you see a user's email address. This has to be done once per user, however investigation of the server logs show that in October 2016 over 56000 such queries were made.
The fix is to "parameterize" the user input, so that the SQL instructions are isolated from the data like this:
SELECT * from Users WHERE username = ? AND password = ?;
And then you tell the server the values for username and password separately. This stops any SQL imbedded inside the username (or password) as being interpreted as SQL.
In my case I was less careful than I should have been with the pages that supply documentation (scripting documentation). My thinking was that documentation is "read only" so it doesn't really matter what people do with it, and whether or not they request documentation on a valid function name.
I must admit, however, that I didn't expect someone to look for the function named:
execute999999.9'
UNION ALL
SELECT( SELECT
CONCAT('!~!',IFNULL(email,' '),'!~!')
FROM bbuser LIMIT 2374,1),2,3,4,5,6,7,8,9,10,11,12,13,14,15 AND '0'='0
xkcd cartoon
The issue with SQL injection is rather humorously described here:
Exploits of a Mom - xkcd
In that cartoon a mother names her son:
Robert'); DROP TABLE students; --
When typed into the school database, it causes all the student records to be deleted. :)
Hashed passwords
From the start of this forum being written, passwords were hashed. That is, instead of storing the actual password, a "hash" is taken. For example if the password is "swordfish" then the hash is "15B29FFDCE66E10527A65BC6D71AD94D".
When you type in your password, the system hashes what you typed and if it happens to be "15B29FFDCE66E10527A65BC6D71AD94D" (in this case) then you are assumed to know the password.
It is virtually impossible to deduce the original password from the hash, but hashes suffer from a problem called a "dictionary attack". An attacker can pre-hash a lot of common words, like this:
swordfish = 15B29FFDCE66E10527A65BC6D71AD94D
12345 = 827CCB0EEA8A706C4C34A16891F84E7B
password666 = 284EE0E6F057F3F3CDB2A385BA84F342
Now all they have to do is take the hashed password (if they have found it by hacking into a database) and do a look-up to find the original.
A method of slowing down a dictionary attack is to have a salt which is added to the password. You store the salt in the user's database record, and use that when re-hashing the password. The point of the salt is that now you need a separate dictionary for each salt, and making the dictionary takes time. Another method is to make the hashing computationally expensive, so that calculating this dictionary can take a couple of seconds per word, so it could take hours, or weeks even, to find the matching password.
In September 2015 the forum passwords were converted to require a salt. See: http://www.gammon.com.au/forum/?id=13749
In August 2016 all passwords which were not "salted" were reset.
In October 2016 all passwords were reset, forcing users to obtain a new one.
Password security
In general (this doesn't just apply here) you should not use the same password in more than one place. The reason is, that if your password is compromised somewhere, and you use the same password everywhere, then the attackers may now have your banking password. Always use different passwords for each web site. Use a program like KeePass to generate random passwords for you, and save them into a "password file".
Also see Password Strength - another xkcd comic. All the hashing and slowing down of cracking in the world won't help you if your password is "password12345". You still need to choose long, strong passwords.
Compromised web sites
The site Have i been pwned? lists a lot of websites that have been hacked. For example:
- 359,420,698 MySpace accounts
- 234,842,089 NetEase accounts
- 164,611,595 LinkedIn accounts
- 152,445,165 Adobe accounts
- 112,005,531 Badoo accounts
- 93,338,602 VK accounts
- 91,436,280 Rambler accounts
- 68,648,009 Dropbox accounts
- 65,469,298 tumblr accounts
- 58,843,488 Modern Business
That's a lot of breaches. This is why you don't re-use passwords.
Another well-known breach was Sony - apparently they lost a file with over a million passwords in plain text.
Apology
I apologize for inadvertently allowing email addresses to be stolen. This forum software was first written in about 2001 (15 years ago). Since that time major strides have been taken in the way SQL works, and in people devising ingenious ways of working their way into sites. My major time is spent trying to help people with their MUD games, electronics, programming, etc. I don't spend hours every day poring over log files trying to spot security breaches. You can imagine that, even if I had done that 5 years ago, and found nothing for months, that it would get very boring doing it month after month.
There are even GUI tools which I have read about which totally automate the process of hacking into a site. You just "point" the tool at a site, and let it deduce what sort of attacks will work. This lets "script kiddies" hack into a site without really knowing what they are doing.
Suggested fixes
If you are using the same password for multiple sites I suggest you change them. This would apply even if this site wasn't attacked. I can't do much about email addresses being stolen, sorry. The emails are out there. If it's any consolation I get dozens of emails every day from spammers trying to convince me to open an attachment or "verify" my PayPal account.
Password reset
Now that the updated software has been deployed I will reset every password on the forum. You will need to use your email address to get a new password. This is necessary in case the attackers re-gained the password hashes which were reset over the last few days. Passwords now are computationally expensive to deduce by a dictionary attack, but if you use a simple password (like "password") then it wouldn't take long to crack.
Tighter password rules
The forum now validates passwords to conform to certain rules. This is described here:
http://www.gammon.com.au/forum/?id=13862
The idea is to prevent people's accounts from being taken over because they chose a simple password like "password12345". |