Objective:

The objective of this lesson is to introduce learners to fundamental security practices in PHP. By the end of this lesson, participants should be able to:

Description:

2.1 Sanitizing Input to Prevent SQL Injection

2.1.1 Introduction to SQL Injection

Explain the concept of SQL injection and the potential risks associated with unsanitized input.

<?php
// Example of a vulnerable SQL query
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
?>

2.1.2 Using Prepared Statements

Introduce the concept of prepared statements as a secure way to handle database queries.

<?php
// Example of using a prepared statement
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username AND password = :password");
$stmt->bindParam(':username', $username);
$stmt->bindParam(':password', $password);
$stmt->execute();
?>

2.2 Securing Against Cross-Site Scripting (XSS) Attacks

2.2.1 Understanding XSS Attacks

Explain how XSS attacks occur when user input is not properly sanitized before being displayed.

<?php
// Example of a vulnerable echo statement
$userInput = $_GET['input'];
echo "User input: $userInput";
?>

2.2.2 HTML Encoding

Teach the importance of HTML encoding to prevent XSS attacks. Encourage the use of functions like htmlspecialchars.

<?php
// Example of using htmlspecialchars to prevent XSS
$userInput = $_GET['input'];
echo "User input: " . htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
?>

2.3 Securing File Uploads

2.3.1 File Upload Security Measures

Explain potential security risks associated with file uploads and the importance of proper handling.

<?php
// Example of basic file upload handling
$targetDir = "uploads/";
$targetFile = $targetDir . basename($_FILES["file"]["name"]);
move_uploaded_file($_FILES["file"]["tmp_name"], $targetFile);
?>

2.3.2 File Type Verification

Implement file type verification to ensure that only allowed file types are accepted during uploads.

<?php
// Example of file type verification
$allowedTypes = ['jpg', 'jpeg', 'png', 'gif'];
$uploadedFileType = strtolower(pathinfo($_FILES["file"]["name"], PATHINFO_EXTENSION));

if (!in_array($uploadedFileType, $allowedTypes)) {
    echo "Only JPG, JPEG, PNG, and GIF files are allowed.";
}
?>

2.4 User Authentication Best Practices

2.4.1 Hashing Passwords

Discuss the importance of password hashing for secure storage.

<?php
// Example of password hashing
$password = $_POST['password'];
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
?>

2.4.2 Password Hash Verification

Teach how to verify hashed passwords during the authentication process.

<?php
// Example of verifying hashed passwords
$storedHashedPassword = "hashed_password_from_database";
$userInputPassword = $_POST['password'];

if (password_verify($userInputPassword, $storedHashedPassword)) {
    echo "Password is correct.";
} else {
    echo "Password is incorrect.";
}
?>

2.5 Practice Exercise

Task:

  1. SQL Injection Prevention:
    • Create a PHP script named login.php that handles user authentication.
    • Use prepared statements to prevent SQL injection.
<?php
// login.php

// Establish database connection (replace with your database credentials)
$pdo = new PDO('mysql:host=localhost;dbname=your_database', 'your_username', 'your_password');

// Get user input
$username = $_POST['username'];
$password = $_POST['password'];

// Prepare and execute a secure SQL query
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username AND password = :password");
$stmt->bindParam(':username', $username);
$stmt->bindParam(':password', $password);
$stmt->execute();

// Fetch the user from the database
$user = $stmt->fetch(PDO::FETCH_ASSOC);

if ($user) {
    echo "Login successful. Welcome, " . $user['username'] . "!";
} else {
    echo "Invalid username or password.";
}
?>

XSS Prevention:

<!-- comment_form.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Comment Form</title>
</head>
<body>
    <form action="process_comment.php" method="post">
        <label for="comment">Leave a comment:</label>
        <textarea name="comment" rows="4" cols="50"></textarea>
        <button type="submit">Submit Comment</button>
    </form>
</body>
</html>
<?php
// process_comment.php

// Get user input
$userComment = $_POST['comment'];

// Display the user comment using htmlspecialchars to prevent XSS attacks
echo "User Comment: " . htmlspecialchars($userComment, ENT_QUOTES, 'UTF-8');
?>

File Upload Security:

<!-- upload_form.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>File Upload Form</title>
</head>
<body>
    <form action="process_upload.php" method="post" enctype="multipart/form-data">
        <label for="file">Select file:</label>
        <input type="file" name="file" id="file">
        <button type="submit">Upload File</button>
    </form>
</body>
</html>
<?php
// process_upload.php

// Define allowed file types
$allowedTypes = ['jpg', 'jpeg', 'png', 'gif'];

// Get file information
$fileName = $_FILES["file"]["name"];
$uploadedFileType = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));

// Check if the file type is allowed
if (in_array($uploadedFileType, $allowedTypes)) {
    // Move the uploaded file to the desired location (replace with your upload directory)
    $targetDir = "uploads/";
    $targetFile = $targetDir . basename($fileName);
    move_uploaded_file($_FILES["file"]["tmp_name"], $targetFile);
    echo "File uploaded successfully.";
} else {
    echo "Only JPG, JPEG, PNG, and GIF files are allowed.";
}
?>

User Authentication:

<!-- register.php -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>User Registration</title>
</head>
<body>
    <form action="register_process.php" method="post">
        <label for="username">Username:</label>
        <input type="text" name="username" required>

        <label for="password">Password:</label>
        <input type="password" name="password" required>

        <button type="submit">Register</button>
    </form>
</body>
</html>
<?php
// register_process.php

// Get user input
$username = $_POST['username'];
$password = $_POST['password'];

// Hash the password before storing it (replace with your preferred hashing method)
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);

// Store the username and hashed password in the database (replace with your database logic)
// Note: Ensure to properly secure your database interactions
echo "Registration successful. User created with username: " . $username;
?>

Additional Notes: