Cyber Security · मराठी आवृत्ती
PHP + MySQL app: prepared statements वापरूया
या page मध्ये
आता form मधून students data insert करून database मधून list दाखवणारा छोटा app बनवू. हा शिकण्यासाठीचा lab app आहे. Sample password, verbose DB errors, authentication/CSRF validation ची मर्यादा यामुळे हा code थेट production मध्ये deploy करू नका.
Database आणि app user
sudo mysql <<'SQL'
CREATE DATABASE IF NOT EXISTS appdb;
CREATE USER IF NOT EXISTS 'appuser'@'localhost' IDENTIFIED BY 'App@Pass123';
CREATE USER IF NOT EXISTS 'appuser'@'127.0.0.1' IDENTIFIED BY 'App@Pass123';
GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.* TO 'appuser'@'localhost';
GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.* TO 'appuser'@'127.0.0.1';
USE appdb;
CREATE TABLE IF NOT EXISTS students (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
city VARCHAR(50) NOT NULL
);
INSERT INTO students (name, city) VALUES ('Shahrukh','Pune'), ('Zoya','Nagpur'), ('Amir','Nashik');
SQL
appdb database, appuser ची local host entries आणि SELECT/INSERT/UPDATE/DELETE permissions दिल्या आहेत. App root म्हणून connect होत नाही. Students table मध्ये id, name, city आहे. Script पुन्हा चालवल्यास seed INSERT पुन्हा होऊ शकतो; IF NOT EXISTS आधीच्या user चा password update करत नाही.
Application files
sudo tee /var/www/phpapp/db.php > /dev/null <<'EOF'
<?php
$dsn = "mysql:host=127.0.0.1;dbname=appdb;charset=utf8mb4";
$user = "appuser";
$pass = "App@Pass123";
try {
$pdo = new PDO($dsn, $user, $pass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
} catch (PDOException $e) {
http_response_code(500);
die("Database connection failed: " . htmlspecialchars($e->getMessage()));
}
EOF
sudo tee /var/www/phpapp/index.php > /dev/null <<'EOF'
<?php
require __DIR__ . "/db.php";
if ($_SERVER["REQUEST_METHOD"] === "POST" && !empty($_POST["name"]) && !empty($_POST["city"])) {
$stmt = $pdo->prepare("INSERT INTO students (name, city) VALUES (?, ?)"); // prepared = safe from SQL injection
$stmt->execute([$_POST["name"], $_POST["city"]]);
header("Location: /");
exit;
}
$rows = $pdo->query("SELECT id, name, city FROM students ORDER BY id")->fetchAll(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>PHP + MySQL on EC2</title></head>
<body style="font-family:Arial;max-width:700px;margin:30px auto">
<h1>Students (PHP + MySQL)</h1>
<table border="1" cellpadding="6">
<tr><th>ID</th><th>Name</th><th>City</th></tr>
<?php foreach ($rows as $r): ?>
<tr><td><?= $r["id"] ?></td><td><?= htmlspecialchars($r["name"]) ?></td><td><?= htmlspecialchars($r["city"]) ?></td></tr>
<?php endforeach; ?>
</table>
<h3>Add student</h3>
<form method="post">
<input name="name" placeholder="Name" required>
<input name="city" placeholder="City" required>
<button type="submit">Add</button>
</form>
<p>Served by PHP <?= phpversion() ?> on <?= gethostname() ?></p>
</body></html>
EOF
sudo chmod 640 /var/www/phpapp/db.php
# let the PHP process user read db.php: apache (AL2023/CentOS php-fpm & httpd) or www-data (Ubuntu)
sudo chown root:apache /var/www/phpapp/db.php # Ubuntu: sudo chown root:www-data /var/www/phpapp/db.php
sudo restorecon -Rv /var/www/phpapp 2>/dev/null # CentOS only (harmless elsewhere)
curl -s http://localhost/ -H "Host: $(curl -s https://checkip.amazonaws.com)" | head -20
db.php: PDO connection तयार करतो. charset utf8mb4 वापरतो; connection error ला 500 देतो. Source code lab मध्ये actual exception message browser ला दाखवतो; production मध्ये generic error दाखवून details protected logs मध्ये लिहा. index.php: POST मधून name/city घेऊन prepared INSERT करतो, redirect करतो आणि SELECT results table मध्ये दाखवतो.
Sample App@Pass123 password फक्त lab साठी आहे. वास्तविक secrets web root/code repository बाहेर ठेवून सुरक्षित secret management वापरा. db.php च्या 640 permissions आणि PHP worker च्या actual group ownership तपासा: source मध्ये apache किंवा www-data. SELinux restorecon त्या system वर लागू आहे का पाहा.
दोन महत्त्वाचे protections
$pdo->prepare(... ?, ?) आणि execute parameters SQL structure पासून input वेगळं ठेवतात. या parameterized query साठी SQL injection risk कमी होतो; प्रत्येक dynamic SQL fragment ला योग्य सुरक्षित हाताळणी आवश्यक आहे. htmlspecialchars() इथे HTML text output encode करतो. XSS protection साठी output context महत्त्वाचा—JavaScript/URL/CSS contexts साठी वेगळे rules लागतात.
PHP download किंवा raw code दिसतो?
Handler mapping missing असल्यास PHP source file म्हणून serve होऊ शकतो—हा गंभीर leak आहे. FPM service बंद/चुका असल्यास configured handler मधून बहुतेक 502 येतो. दोन्ही वेगळी लक्षणं आहेत. Active PHP location, socket, FPM status आणि Nginx logs तपासा. Ubuntu service name actual installed version वर ठरतो.
Debug साठी echo "<?php phpinfo();" | sudo tee /var/www/phpapp/info.php वापरल्यास ती file लगेच काढा. Public debug page ठेवू नका.
Lab
LEMP server वर app चालवा. Form मधून Ravina—Kolhapur, Salman—Solapur आणि Raja—Sambhaji Nagar या rows जोडा. SELECT * FROM appdb.students; ने verify करा. Input length validation, CSRF protection आणि login हे या छोट्या example बाहेरचे पुढचे improvements आहेत.