Основы безопасности в PHP: защита приложений

Активный
Статус
Сообщения
516
Лайки
32

8

месяц на сайте

Безопасность критически важна для веб-приложений. Разберем основные принципы.

Защита от SQL инъекций
Код:
<?php
// НЕПРАВИЛЬНО
$username = $_POST["username"];
$sql = "SELECT * FROM users WHERE username = '$username'";

// ПРАВИЛЬНО - Prepared Statements
$stmt = $conn->prepare("SELECT * FROM users WHERE username = ?");
$stmt->bind_param("s", $username);
$username = $_POST["username"];
$stmt->execute();
?>

Экранирование вывода
Код:
<?php
// Экранирование HTML
$userInput = $_POST["message"];
echo htmlspecialchars($userInput, ENT_QUOTES, "UTF-8");

// Для вывода в JavaScript
$jsData = json_encode($userInput);
echo "<script>var data = $jsData;</script>";
?>

Валидация входных данных
Код:
<?php
function validateEmail($email) {
    return filter_var($email, FILTER_VALIDATE_EMAIL);
}

function validateUsername($username) {
    return preg_match("/^[a-zA-Z0-9_]{3,20}$/", $username);
}

function validatePassword($password) {
    return strlen($password) >= 8 && 
           preg_match("/[A-Z]/", $password) &&
           preg_match("/[a-z]/", $password) &&
           preg_match("/[0-9]/", $password);
}

// Использование
$email = $_POST["email"];
if(!validateEmail($email)) {
    die("Неверный email");
}
?>

Хеширование паролей
Код:
<?php
// Создание хеша
$password = "userpassword";
$hash = password_hash($password, PASSWORD_DEFAULT);

// Сохранение в БД
$stmt = $conn->prepare("INSERT INTO users (username, password) VALUES (?, ?)");
$stmt->bind_param("ss", $username, $hash);
$stmt->execute();

// Проверка пароля
$stmt = $conn->prepare("SELECT password FROM users WHERE username = ?");
$stmt->bind_param("s", $username);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();

if(password_verify($password, $row["password"])) {
    echo "Пароль верный";
} else {
    echo "Неверный пароль";
}
?>

Защита от XSS
Код:
<?php
// Всегда экранируйте пользовательский ввод
function sanitizeInput($input) {
    $input = trim($input);
    $input = stripslashes($input);
    $input = htmlspecialchars($input, ENT_QUOTES, "UTF-8");
    return $input;
}

$userInput = sanitizeInput($_POST["message"]);
echo $userInput;
?>

CSRF защита
Код:
<?php
session_start();

// Генерация токена
function generateCSRFToken() {
    if(!isset($_SESSION["csrf_token"])) {
        $_SESSION["csrf_token"] = bin2hex(random_bytes(32));
    }
    return $_SESSION["csrf_token"];
}

// Проверка токена
function verifyCSRFToken($token) {
    return isset($_SESSION["csrf_token"]) && 
           hash_equals($_SESSION["csrf_token"], $token);
}

// В форме
$token = generateCSRFToken();
echo "<input type='hidden' name='csrf_token' value='$token'>";

// При обработке
if(!verifyCSRFToken($_POST["csrf_token"])) {
    die("Ошибка CSRF токена");
}
?>

Ограничение попыток входа
Код:
<?php
session_start();

function checkLoginAttempts($username) {
    $key = "login_attempts_" . $username;
    
    if(!isset($_SESSION[$key])) {
        $_SESSION[$key] = 0;
    }
    
    if($_SESSION[$key] >= 5) {
        return false; // слишком много попыток
    }
    
    return true;
}

function incrementLoginAttempts($username) {
    $key = "login_attempts_" . $username;
    if(!isset($_SESSION[$key])) {
        $_SESSION[$key] = 0;
    }
    $_SESSION[$key]++;
}

function resetLoginAttempts($username) {
    $key = "login_attempts_" . $username;
    unset($_SESSION[$key]);
}

// Использование
if(!checkLoginAttempts($username)) {
    die("Слишком много попыток входа. Попробуйте позже.");
}

// При неудачной попытке
if(!password_verify($password, $hash)) {
    incrementLoginAttempts($username);
    die("Неверный пароль");
} else {
    resetLoginAttempts($username);
}
?>

Безопасные сессии
Код:
<?php
// Настройка безопасных сессий
ini_set("session.cookie_httponly", 1);
ini_set("session.cookie_secure", 1);
ini_set("session.use_strict_mode", 1);

session_start();

// Регенерация ID сессии
function regenerateSession() {
    session_regenerate_id(true);
    $_SESSION["created"] = time();
}

// Проверка таймаута сессии
function checkSessionTimeout() {
    $timeout = 1800; // 30 минут
    
    if(isset($_SESSION["created"]) && 
       time() - $_SESSION["created"] > $timeout) {
        session_destroy();
        return false;
    }
    
    return true;
}
?>

Защита файлов
Код:
<?php
// Ограничение типов загружаемых файлов
$allowedTypes = ["image/jpeg", "image/png", "image/gif"];
$uploadedType = $_FILES["file"]["type"];

if(!in_array($uploadedType, $allowedTypes)) {
    die("Недопустимый тип файла");
}

// Проверка размера
$maxSize = 5 * 1024 * 1024; // 5MB
if($_FILES["file"]["size"] > $maxSize) {
    die("Файл слишком большой");
}

// Безопасное имя файла
$filename = basename($_FILES["file"]["name"]);
$filename = preg_replace("/[^a-zA-Z0-9._-]/", "", $filename);
$target = "uploads/" . uniqid() . "_" . $filename;
?>

Важные моменты:
- Всегда валидируйте входные данные
- Используйте prepared statements для SQL
- Хешируйте пароли правильно
- Защищайтесь от CSRF атак
- Ограничивайте попытки входа

Безопасность - основа надежного приложения!
 

1 человек читают эту тему (Всего: 1, Пользователей: 0, Гостей: 1)

Сверху