Security Introduction

JA JASWANT Updated 19 Oct 2026
5 min read ·Lesson 116 of 143
In this post

Why Security Matters In simple terms: Every website that accepts input — a search box, a login form, a file upload — can be attacked. Attackers try to steal data, take over accounts, deface pages, or

Why Security Matters

In simple terms: Every website that accepts input — a search box, a login form, a file upload — can be attacked. Attackers try to steal data, take over accounts, deface pages, or use the server for their own purposes. Most successful attacks exploit a small number of well-known mistakes. Learning those mistakes and their fixes protects your users, your business, and your reputation.

Technically: Web application security is about controlling how untrusted data flows through an application and who may perform which actions. PHP itself is not inherently insecure; vulnerabilities come from how code handles input, output, authentication, sessions, files, configuration, and dependencies. The OWASP Top 10 (Open Worldwide Application Security Project) lists the most critical web application risks and is the standard reference for developers.


The Core Principle: Never Trust Input

Anything that comes from outside your code is untrusted — including data that seems harmless:

SourceExamples
Request data$_GET, $_POST, $_COOKIE, $_FILES, JSON bodies
Request headersUser-Agent, Referer, Host, X-Forwarded-For, custom headers
Data stored earlierProduct names, comments, profile fields entered by users
External systemsAPI responses, webhooks, imported CSV/XML files, emails

The defense has two halves:

Input  ──► validate (is it what we expect?) ──► application logic
Output ◄── encode/escape for the destination (HTML, SQL, URL, shell, JSON)
  • Validate input when it arrives: type, format, length, range, allowed values (see PHP Form Validation, PHP Filters).
  • Escape or parameterize output for the context where it is used: HTML escaping for pages, prepared statements for SQL, escapeshellarg() for shell commands, json_encode() for JSON.

Validation alone is not enough (valid data can still contain < or '), and escaping alone is not enough (an "age" of -5 is not an injection, but it is still wrong).


A Vulnerable Example

The following page contains several classic vulnerabilities in just a few lines:

<?php
// profile.php?id=7 — DO NOT USE
ini_set('display_errors', '1');

$db = new mysqli('localhost', 'root', '', 'shop');
$result = $db->query("SELECT name, bio FROM users WHERE id = " . $_GET['id']);
$user = $result->fetch_assoc();

echo "<h1>Profile of " . $user['name'] . "</h1>";
echo "<div>" . $user['bio'] . "</div>";
echo "<a href='/search?q=" . $_GET['q'] . "'>Back to results</a>";
ProblemVulnerabilityConsequence
$_GET['id'] concatenated into SQLSQL injection?id=0 UNION SELECT email, password_hash FROM users reads private data
Name and bio printed without escapingStored XSSA bio containing <script> runs in every visitor's browser
$_GET['q'] printed into an attributeReflected XSSA crafted link executes JavaScript for whoever clicks it
Connecting as root without a passwordExcessive privilegesOne injection compromises the whole database server
display_errors = 1Information disclosureError messages reveal paths, queries, and structure

The Fixed Version

<?php
// profile.php?id=7
declare(strict_types=1);

require __DIR__ . '/../src/pdo.php';   // least-privilege user, credentials from environment

function e(string $value): string
{
    return htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]);
if (!$id) {
    http_response_code(404);
    exit('Profile not found.');
}

$stmt = pdo()->prepare('SELECT name, bio FROM users WHERE id = ?');
$stmt->execute([$id]);
$user = $stmt->fetch();

if ($user === false) {
    http_response_code(404);
    exit('Profile not found.');
}

$backUrl = '/search?' . http_build_query(['q' => (string) ($_GET['q'] ?? '')]);
?>
<h1>Profile of <?= e($user['name']) ?></h1>
<div><?= nl2br(e($user['bio'])) ?></div>
<a href="<?= e($backUrl) ?>">Back to results</a>

Every fix applies one of the principles: validate the ID, use a prepared statement, escape every output for HTML, build URLs with encoding functions, use a restricted database account, and handle errors without revealing details (with display_errors off in production).


Key Security Principles

PrincipleMeaningExample
Defense in depthSeveral independent layers of protectionPrepared statements and a least-privilege DB user and a web application firewall
Least privilegeGrant only the permissions neededThe app's DB user cannot DROP tables; upload folders are not executable
Secure defaultsThe safe option is the defaultNew accounts have no admin rights; cookies are HttpOnly and Secure
Fail securelyErrors must not open doorsA failed permission check denies access; errors show generic messages
Keep it simpleComplex security logic hides bugsUse proven libraries and framework features instead of custom crypto
Validate on the serverClient-side checks are for convenience onlyAttackers send requests directly, bypassing JavaScript

The Lessons in This Section

LessonProtects Against
Password HashingStolen databases revealing users' passwords
SQL Injection PreventionAttackers reading or changing the database
XSS PreventionMalicious scripts running in users' browsers
CSRF ProtectionOther websites performing actions as your logged-in users
Session SecuritySession hijacking and fixation
Secure CookiesCookie theft and manipulation
File Upload SecurityUploaded files executing code on the server
Filesystem SecurityPath traversal and unauthorized file access
Error Reporting in ProductionInformation disclosure
Hiding PHPRevealing technology details to attackers
Encryption with SodiumExposure of sensitive stored data

Keeping the Platform Secure

Secure code can still be compromised through outdated software:

  • Run a supported PHP version. Each PHP release receives two years of active support and then two years of security fixes. Check the current list at https://www.php.net/supported-versions.php; unsupported versions receive no security patches.
  • Update dependencies. composer audit reports Composer packages with known vulnerabilities; run it regularly and in your deployment pipeline (see Composer).
  • Use HTTPS everywhere. Without TLS, passwords and session cookies travel in plain text.
  • Harden the server. Keep the operating system, web server, and database updated; restrict network access to databases and admin tools.
  • Log and monitor. Record failed logins, permission errors, and unusual activity, and review alerts (see Error Logging).

Common Mistakes

Relying on Client-Side Validation

Effect: Attackers bypass it by sending requests directly.

Fix: Validate every input on the server.

Escaping Input Instead of Output

Effect: Data is stored in an escaped form that is wrong for other contexts, and escaping is forgotten elsewhere.

Fix: Store raw (validated) data; escape when outputting, for the specific context.

"Security Through Obscurity"

Effect: Hidden admin URLs or renamed files give false confidence.

Fix: Protect resources with real authentication and authorization.

Writing Custom Cryptography

Effect: Subtle, exploitable flaws.

Fix: Use password_hash(), random_bytes(), and Sodium.


Best Practices

  • Treat all external data as untrusted; validate input and encode output by context.
  • Use prepared statements, output escaping, CSRF tokens, and secure sessions consistently.
  • Apply least privilege to database users, file permissions, and application roles.
  • Keep PHP, dependencies, and servers updated; use HTTPS everywhere.
  • Learn the OWASP Top 10 and review code with security in mind.

Official reference: https://www.php.net/manual/en/security.intro.php

0 Comments

Reviewed before they appear

No comments yet.

PHP
PHP Home PHP Switch PHP Match Alternative Syntax PHP Loops While Loop Do While Loop For Loop Foreach Loop Nested Loops Break Statement PHP Home PHP Intro PHP Install PHP Built-in Web Server PHP Syntax PHP Tags PHP and HTML PHP Comments PHP Multiline Comments PHP Variables Variables Scope PHP Casting Logical Operators Null Coalescing Operator Spaceship Operator Operator Precedence Continue Statement Modify Strings PHP If...Else...Elseif PHP If Modify Strings PHP If Operators PHP Functions Concatenate Strings PHP If...Else Slicing Strings User-defined Functions Slicing Strings PHP Shorthand if Escape Characters Default Argument Values PHP Nested if Pass by Reference String Interpolation Named Arguments PHP File Upload Variadic Functions Return Values Search in Strings Multibyte Strings Type Declarations in Functions PHP Numbers PHP Math PHP Floats PHP Random Numbers PHP Constants PHP Properties PHP Methods PHP Constructor Constructor Property Promotion PHP Cookies PHP Destructor PHP Access Modifiers Readonly Properties PHP Sessions PHP Inheritance Method Overriding PHP Filters The final Keyword CSRF Protection PHP Filters Advanced Session Security Secure Cookies PHP Magic Constants File Upload Security PHP Callback Functions PHP Operators Filesystem Security PHP JSON Arithmetic Operators Error Reporting in Production Hiding PHP Assignment Operators PHP Configuration (php.ini) Comparison Operators PHP Command Line (CLI) PHP Exceptions Increment / Decrement Operators Migrating to PHP 8 PHP Form Validation PHP Form Required PHP Form URL/E-mail Error Handling Form Input Sanitizing Escaping Output (htmlspecialchars) Custom Error Handler Checkbox, Radio and Select Inputs Sticky Forms PHP Form Complete PHP Date and Time Date Formatting Error Logging HTTP Headers and Redirects Output Buffering Sending Email PHP cURL Consuming REST APIs PHP Generators AJAX PHP AJAX Database AJAX XML AJAX Live Search AJAX Poll AJAX with JSON Security Introduction Password Hashing SQL Injection Prevention XSS Prevention Garbage Collection Project: Simple Blog PHP What is OOP PHP Classes/Objects The $this Keyword Access Array Items Update Array Items Add Array Items Remove Array Items Sorting Arrays Multidimensional Arrays Array Destructuring Array Spread Operator Search in Arrays Merge Arrays PHP Abstract Classes PHP Interfaces Polymorphism PHP Traits PHP Static Methods PHP Static Properties Late Static Binding Magic Methods Object Cloning
Ask about this post
AI Ask about this post

Ask questions about Security Introduction and get answers drawn from it.

Signed-in readers only.