- CSRF Attacks
- XSS attacks
- Input Data Validation
- SQL Injection Attacks
- File System Protection
- Proper Error Handling
CSRF is the acronym for Cross Site Request Forgery attack and is when and end user is forced to execute unwanted actions on an application they are currently still authenticated on. This can be cause users to transfer funds or other malicious activities. For Example:
Lets say Jim placed this code into a comment and Sam clicks it.
<a href="http://foobarsite.co.uk/process.php?name=jim&amount=999">Visit My Site
If this code was how a banking system transferred money between accounts and Sam was currently logged into foobar banking, then this would carry out the process and move £999 from Sam to Jim. This can also be done using an image, the image will not load correctly but it will still carry out the process. e.g.
The solution is to process any function that changes the database state in POST request, and avoid using $_REQUEST. Use $_GET to retrieve GET parameters, and use $_POST to retrieve POST parameters.
<img src="http://foobarsite.co.uk/process.php?name=jim&amount=999" width="1" height="1"/>
You can also use CRSF tokens or CRSF guards which create a session token which creates a session token which can be passed in a hidden field in a form to ensure the request is coming from the suer signed in.
XSS is the acronym used for Cross-site scripting attacks, this attack is where a user is allowed to inject code into a vulnerable page. This is the result of accepting un-validated input data from a user and the web app displaying it in the browser.
The danger this causes is if a hacker inserts a malicious bit of code that could redirect a user to a phishing website of steal there cookies, if an attacker can obtain a user’s session cookie, they can impersonate that user.
If someone was allowed to enter this into a comment section of a popular webpage and it was parsed as HTML and displayed on everyone viewing the comments.
To prevent this we can do the following:
// sanitize HTML from the comment when the user submits it
$comment = strip_tags($_POST["comment"]);
// escape output sent to the browser
echo "You searched for: " . htmlspecialchars($_GET["query"]);
echo "You searched for: " . htmlentities($_GET["query"])
Input Data Validation
SQL Injection Attacks
An SQL injection attack is the process of sending malicious commands to the database by circumventing security and accessing unauthorized channels. By far the most common such channel is un-sanitized input data. To prevent this it leads back to sanitizing user data and using correct SQL methods to store data. Example is Prepared Statements:
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname, $email);
// set parameters and execute
$firstname = "John";
$lastname = "Doe";
$email = "email@example.com";
File System Protection
File System Seciurity in PHP is given the security built into the web server. This allows you to control which files in the filesystem may be read/written/moved/deleted. Proper attention should be shown with any files which are world readable to ensure that they are safe for reading by all users who have access to that filesystem.
Since the username and the filename are postable from a user form, they can submit a username and a filename belonging to someone else, and delete it even if they're not supposed to be allowed to do so. In this case, you'd want to use some other form of authentication. Consider what could happen if the variables submitted were "../etc/" and "passwd". The code would then effectively read:
// remove a file from the user's home directory
$username = $_POST['user_submitted_name'];
$userfile = $_POST['user_submitted_filename'];
$homedir = "/home/$username";
echo "The file has been deleted!";
Proper Error Handling
Errors are useful but can also show vulnerabilities if shown to the end user so its recommended that in production mode we turn off display_errors and display_start_up_errors settings. error_reporting and log_errors should be on so that we can log errors while hiding those from end users.