Discuss Scratch

jvvg
Scratcher
1000+ posts

ITopic: How to keep a website safe

For general advice, you should see LS97's awesome guide instead. This topic is about technical stuff
First AT ITopic on 2.0!
Note: while most advice in this article can be used in most languages, the specific functions I list are for PHP.

1. Escaping data
1a. Escaping data in SQL
Whenever inserting data in MySQL, always be sure to escape it. Otherwise, a hacker can mess with it. For example, they could log in with the username ‘ OR username=’jvvg' and then get ahold of any account. To prevent that, always escape user-submitted data that's put into MySQL.
If a number is expected (and inserting into an INT field), then I would recommend using the intval() function.
If a string is expected, I would recommend using the escape function for whatever database you are using. For MySQL, it is the mysql_real_escape_string() function, for MySQL Improved, it's mysqli_real_escape_string().

1b. Escaping data when outputted
Often, user-submitted data is outputted on the page. Instead of displaying it exactly as written, you should escape it. If you don't, someone could put something like <meta http-equiv=“refresh” content="0; url=http://virussite.com" /> on the page. That would be kind of a problem. So, to avoid it, you should HTML-escape it.
I use a function like this:

Code:

function clearHTML($text, $linebreaks = false) {
$text = htmlspecialchars($text);
if ($linebreaks) {
$text = preg_replace('/\R/u', "\n", $text);
}
return $text;
}
So, whenever displaying user-submitted data, use that function.

2. NEVER, EVER directly evaluate user-submitted code
I didn't think I'd need to put this, but somehow people still do. Putting any kind of user-submitted data of any kind in the eval() function is a REALLY BAD IDEA. No matter what precautions you take, a hacker can probably figure out a way to evaluate whatever they want and use that to get sensitive information or damage the site.
Instead of using eval('2 +' . $_POST['add']);, use 2 + $_POST['add'].

3. Be careful when storing data in files
While data can be stored with files, be careful. It is an easy means to hack a site. So, you should always check filenames for anything and everything that could compromise your security (e.g. “/”, “.”, etc.). Otherwise, you will have some rather big problems.

4. ENCRYPT SENSITIVE STUFF!!!
A while ago, Yahoo got hacked, and thousands of passwords were stolen because they were stored unencrypted. You probably don't want that to happen to your site. So, whenever storing a password, just take the simple step of hashing it somehow. The crypt() function is pretty good, just remember to specify a salt string in the code, or it won't be much help. The hash() function is also pretty good, and supports several algorithms. The md5() and sha1() functions are ok, but I have read they are not quite as secure, and I have had problems with them malfunctioning in the past.

5. Log IPs
Whenever someone does something on the site (e.g. submits a forum post, writes a comment), log the IP address. In the case that something bad is submitted, this will make it much easier to find out who did it and put a stop to it. In PHP, you can get the current user's IP address with $_SERVER['REMOTE_ADDR'];

6. Flood protection
I know many people complain about the 60/180 second rule on Scratch. However, it is a very good shield against spam. In any site you make, some sort of flood protection should be implemented. It may be annoying to users, but will save you and the other moderators on your site a lot of time for removing spam and will prevent a massive amount of spam clogging up the server.

7. Save backups
You never know when something can go wrong with your site. No matter how “foolproof” your code seems or “guaranteed” your web host seems, stuff can go wrong. If anybody remembers, LS and I lost all of Mod Share due to web host problems, and if we didn't have a backup, we would have lost the entire website.
At least once a week, you should download a complete backup of your site code (if it has changed since the week before), all stored files (like project files and thumbnails for Mod Share), and any database files. Many web hosts support easy backups (i.e. one click to back up everything), and those are quite useful. If not, download all files off of FTP (or copy them to an external drive if your site is stored on your own server), and then go into phpMyAdmin (if you use MySQL) and export the database. Always store these backups in a safe place.

8. Restrict admin stuff
Let me start with a common quote: “Security through obscurity is not security at all!”
On some sites, admin pages are accessible by everyone, regardless of whether they are logged in or not. They were restricted by not giving people the URL. This is not security at all, because finding the URL of the page is very easy. On all pages that are restricted, don't just not show the link, actually restrict the page so that it will either show a 403 or 404 error, depending on how you want to do it.

Also, if you use MySQL and your server allows it, only allow connections to the database from the IP of your webserver. If you use phpMyAdmin, either password the app (not just the database password) or only make it accessible from certain IP addresses, if possible. This way, even if someone has the database password, they can't access critical data.

If you have anything else you want me to add, just ask.

Last edited by jvvg (Aug. 20, 2013 17:41:05)



Professional web developer and lead engineer on the Scratch Wiki
Maybe the Scratch Team isn't so badWhy the April Fools' Day forum didn't work last year
bobbybee
Scratcher
1000+ posts

ITopic: How to keep a website safe

One thing I always like to do is disable remote MySQL connections and restrict the PMA folder to certain IPs (or at least don't put it in the root of the server :3). This way, even if the attacker has the DB pass, they can't get in.

“Ooo, can I call you Señorita Bee?” ~Chibi-Matoran
jvvg
Scratcher
1000+ posts

ITopic: How to keep a website safe

bobbybee wrote:

One thing I always like to do is disable remote MySQL connections and restrict the PMA folder to certain IPs (or at least don't put it in the root of the server :3). This way, even if the attacker has the DB pass, they can't get in.
Done.


Professional web developer and lead engineer on the Scratch Wiki
Maybe the Scratch Team isn't so badWhy the April Fools' Day forum didn't work last year
ClayChips
Scratcher
500+ posts

ITopic: How to keep a website safe

BUMP! Wow. A bump that goes all the way from 8th page to 1st page, what a powerful bump!

ClayChips, once had a legendary account called fetchydog567 now just a noob. Waiting to become just the same as his old account. But now, as the time goes by, I know now that i'm not a noob! I'm back! :D



StarscreamClone
Scratcher
1000+ posts

ITopic: How to keep a website safe

LS97's guide is here if you need a link.

Somewhere in my 20s | He/It
Workin' on my degree in computer science and cognitive science, and the future president of 2036!

Surge is my imaginary husband - he's the guy in my icon!
scimonster
Scratcher
1000+ posts

ITopic: How to keep a website safe

You should probably fix the bracket issues. I was thinking “2 + $_POST”? But $_POST is an array, not number! Then i realized you meant $_POST['something'] (upon quoting i see $_POST['add']. Same with $_SERVER['REMOTE_ADDR'].

I knew about mysql_real_escape_string, but i never thought numbers would be a problem.

Retired Community Moderator
BTW, i run Google Chrome 41.0.2272.101 on a Linux system - Ubuntu 14.04. NEW: iPad 4th gen. w/retina.

418 I'm a teapot (original - to be read by bored computer geeks)
THE GAME (you just lost)
; THE SEMICOLON LIVES ON IN OUR SIGS
jvvg
Scratcher
1000+ posts

ITopic: How to keep a website safe

scimonster wrote:

You should probably fix the bracket issues. I was thinking “2 + $_POST”? But $_POST is an array, not number! Then i realized you meant $_POST['something'] (upon quoting i see $_POST['add']. Same with $_SERVER['REMOTE_ADDR'].

I knew about mysql_real_escape_string, but i never thought numbers would be a problem.
Arrg, the annoying bracket forum bug…
I did type them, it's just not showing.


Professional web developer and lead engineer on the Scratch Wiki
Maybe the Scratch Team isn't so badWhy the April Fools' Day forum didn't work last year
corgisquidman
Scratcher
18 posts

ITopic: How to keep a website safe

Not mentioning PDO? Give it some love!

moo.
corgisquidman
Scratcher
18 posts

ITopic: How to keep a website safe

Also - always always always ALWAYS use password_hash and password_verify to encode passwords!
Documentation:
http://php.net/manual/en/function.password-hash.php
http://php.net/manual/en/function.password-verify.php

moo.
DigiTechs
Scratcher
500+ posts

ITopic: How to keep a website safe

Another thing to note: Instead of manually sanitising your values, you're probably better off using prepared statements due to how they automatically sanitise values (Well, I think they do, anyway) - it's only a few characters until you accidentally forget to sanitise your values

I do, in fact, have my own site; it's here.
I'm also working on a thing called Fetch. Look at it here!
@thisandagain pls explain. @thisandagain pls explain. @thisandagain pls explain. @thisandagain pls explain. @thisandagain pls explain.
kristianmischke
Scratcher
25 posts

ITopic: How to keep a website safe

nice topic, im getting into ruby and ruby on rails, do you know of any the equivalent functions you stated above?
(thanks in advance)
monIy00
Scratcher
85 posts

ITopic: How to keep a website safe

jvvg wrote:

For general advice, you should see LS97's awesome guide instead. This topic is about technical stuff
First AT ITopic on 2.0!
Note: while most advice in this article can be used in most languages, the specific functions I list are for PHP.

1. Escaping data
1a. Escaping data in SQL
Whenever inserting data in MySQL, always be sure to escape it. Otherwise, a hacker can mess with it. For example, they could log in with the username ‘ OR username=’jvvg' and then get ahold of any account. To prevent that, always escape user-submitted data that's put into MySQL.
If a number is expected (and inserting into an INT field), then I would recommend using the intval() function.
If a string is expected, I would recommend using the escape function for whatever database you are using. For MySQL, it is the mysql_real_escape_string() function, for MySQL Improved, it's mysqli_real_escape_string().

1b. Escaping data when outputted
Often, user-submitted data is outputted on the page. Instead of displaying it exactly as written, you should escape it. If you don't, someone could put something like <meta http-equiv=“refresh” content="0; url=http://virussite.com" /> on the page. That would be kind of a problem. So, to avoid it, you should HTML-escape it.
I use a function like this:

Code:

function clearHTML($text, $linebreaks = false) {
$text = htmlspecialchars($text);
if ($linebreaks) {
$text = preg_replace('/\R/u', "\n", $text);
}
return $text;
}
So, whenever displaying user-submitted data, use that function.

2. NEVER, EVER directly evaluate user-submitted code
I didn't think I'd need to put this, but somehow people still do. Putting any kind of user-submitted data of any kind in the eval() function is a REALLY BAD IDEA. No matter what precautions you take, a hacker can probably figure out a way to evaluate whatever they want and use that to get sensitive information or damage the site.
Instead of using eval('2 +' . $_POST['add']);, use 2 + $_POST['add'].

3. Be careful when storing data in files
While data can be stored with files, be careful. It is an easy means to hack a site. So, you should always check filenames for anything and everything that could compromise your security (e.g. “/”, “.”, etc.). Otherwise, you will have some rather big problems.

4. ENCRYPT SENSITIVE STUFF!!!
A while ago, Yahoo got hacked, and thousands of passwords were stolen because they were stored unencrypted. You probably don't want that to happen to your site. So, whenever storing a password, just take the simple step of hashing it somehow. The crypt() function is pretty good, just remember to specify a salt string in the code, or it won't be much help. The hash() function is also pretty good, and supports several algorithms. The md5() and sha1() functions are ok, but I have read they are not quite as secure, and I have had problems with them malfunctioning in the past.

5. Log IPs
Whenever someone does something on the site (e.g. submits a forum post, writes a comment), log the IP address. In the case that something bad is submitted, this will make it much easier to find out who did it and put a stop to it. In PHP, you can get the current user's IP address with $_SERVER['REMOTE_ADDR'];

6. Flood protection
I know many people complain about the 60/180 second rule on Scratch. However, it is a very good shield against spam. In any site you make, some sort of flood protection should be implemented. It may be annoying to users, but will save you and the other moderators on your site a lot of time for removing spam and will prevent a massive amount of spam clogging up the server.

7. Save backups
You never know when something can go wrong with your site. No matter how “foolproof” your code seems or “guaranteed” your web host seems, stuff can go wrong. If anybody remembers, LS and I lost all of Mod Share due to web host problems, and if we didn't have a backup, we would have lost the entire website.
At least once a week, you should download a complete backup of your site code (if it has changed since the week before), all stored files (like project files and thumbnails for Mod Share), and any database files. Many web hosts support easy backups (i.e. one click to back up everything), and those are quite useful. If not, download all files off of FTP (or copy them to an external drive if your site is stored on your own server), and then go into phpMyAdmin (if you use MySQL) and export the database. Always store these backups in a safe place.

8. Restrict admin stuff
Let me start with a common quote: “Security through obscurity is not security at all!”
On some sites, admin pages are accessible by everyone, regardless of whether they are logged in or not. They were restricted by not giving people the URL. This is not security at all, because finding the URL of the page is very easy. On all pages that are restricted, don't just not show the link, actually restrict the page so that it will either show a 403 or 404 error, depending on how you want to do it.

Also, if you use MySQL and your server allows it, only allow connections to the database from the IP of your webserver. If you use phpMyAdmin, either password the app (not just the database password) or only make it accessible from certain IP addresses, if possible. This way, even if someone has the database password, they can't access critical data.

If you have anything else you want me to add, just ask.

MD5 and SHA1 are no longer secure. Often simply typing the hash into Google will give you the original data. Also it is more secure to use prepared statements in mysql than just escaping it.
bjskistad
Scratcher
1000+ posts

ITopic: How to keep a website safe

(Posting to bookmark)

Kumquat was Here
liam48D
Scratcher
1000+ posts

ITopic: How to keep a website safe

bjskistad wrote:

(Posting to bookmark)
Wait, what? Why? Can't you just make a browser bookmark?

202e-202e-202e-202e-202e UNI-CODE~~~~~
-Radical-
Scratcher
500+ posts

ITopic: How to keep a website safe

bump

Sincerely, probably me. Maybe myself. Or sometimes I.

Signature last updated on 5/15/16
Jonathan50
Scratcher
1000+ posts

ITopic: How to keep a website safe

-Radical- wrote:

bump
Why?

Not yet a Knight of the Mu Calculus.
Jonathan50
Scratcher
1000+ posts

ITopic: How to keep a website safe

In C/C++ and other languages, bounds checking?

You don't want this to happen:
HTTP/1.1 POST /api/comment
Content-length: 90

hi

HTTP/1.1 200 Ok
Content-length: 90
Content-type: text/html

hi}ytiVQx#secret stuff!!:@HOu#)TZl)W Wrnu!@Y((1O9,sI8CDDHDXX~DD,MM

Last edited by Jonathan50 (April 26, 2016 04:35:54)


Not yet a Knight of the Mu Calculus.
DigiTechs3
New to Scratch
51 posts

ITopic: How to keep a website safe

Jonathan50 wrote:

In C/C++ and other languages, bounds checking?

You don't want this to happen:
HTTP/1.1 POST /api/comment
Content-length: 90

hi

HTTP/1.1 200 Ok
Content-length: 90
Content-type: text/html

hi}ytiVQx#secret stuff!!:@HOu#)TZl)W Wrnu!@Y((1O9,sI8CDDHDXX~DD,MM

If you're using a ‘smart’ library for using HTTP handling in C/C++ (like you should be doing) that shouldn't happen. The bug is in OpenSSL; not the HTTPD level.
bjskistad
Scratcher
1000+ posts

ITopic: How to keep a website safe

liam48D wrote:

bjskistad wrote:

(Posting to bookmark)
Wait, what? Why? Can't you just make a browser bookmark?
Bookmarking to my topics….

Kumquat was Here
Jonathan50
Scratcher
1000+ posts

ITopic: How to keep a website safe

DigiTechs3 wrote:

If you're using a ‘smart’ library for using HTTP handling in C/C++ (like you should be doing) that shouldn't happen. The bug is in OpenSSL; not the HTTPD level.
I'm not talking about heartbleed, although heartbleed was caused by the same programming mistake. Don't make the same mistake that the OpenSSL developers made, whether you do it in a C server, a FastCGI program, a firewall, a TLS library, or any other sort of program.

Not yet a Knight of the Mu Calculus.

Powered by DjangoBB