امنیت یکی از مهمترین بخشهای توسعه هر برنامه وب است. یک برنامه PHP ممکن است از نظر عملکرد کاملاً درست کار کند، اما اگر ورودیهای کاربر، احراز هویت، Session، Database و خروجیها به شکل صحیح مدیریت نشده باشند، میتواند در معرض آسیبپذیریهای امنیتی قرار بگیرد.
به همین دلیل یادگیری PHP فقط به یادگیری Syntax، متغیرها، توابع، OOP و اتصال به Database محدود نمیشود. یک برنامهنویس PHP باید بداند چگونه برنامهای بنویسد که در برابر حملات و سوءاستفادههای رایج مقاوم باشد.
در این مقاله با مهمترین اصول امنیت PHP آشنا میشویم و یک نقشه راه برای امنسازی برنامههای PHP ایجاد میکنیم.
در این آموزش موضوعاتی مانند موارد زیر را بررسی خواهیم کرد:
- امنیت PHP چیست؟
- چرا امنیت برنامههای PHP اهمیت دارد؟
- اعتبارسنجی ورودیها
- SQL Injection
- Prepared Statement
- XSS
- CSRF
- امنیت Password
- Session Security
- Cookie Security
- Session Fixation
- Session Hijacking
- File Upload Security
- امنیت API
- مدیریت خطاها
- جلوگیری از افشای اطلاعات حساس
- HTTPS
- امنیت Headerها
- مدیریت فایلها
- مدیریت دسترسی کاربران
- Rate Limiting
- لاگ و مانیتورینگ
- اشتباهات رایج امنیتی در PHP
# امنیت PHP چیست؟
امنیت PHP به مجموعه روشها و اصولی گفته میشود که برای محافظت از برنامههای نوشتهشده با PHP در برابر دسترسی غیرمجاز، سرقت اطلاعات، تغییر دادهها، اجرای کد مخرب و سایر حملات استفاده میشوند.
امنیت فقط به خود زبان PHP مربوط نمیشود.
یک برنامه PHP معمولاً با بخشهای مختلفی مانند:
Browser
↓
Web Server
↓
PHP
↓
Database
↓
File System
↓
External APIs
ارتباط دارد.
بنابراین امنیت برنامه باید تمام این لایهها را پوشش دهد.
# چرا امنیت در PHP مهم است؟
فرض کنید یک سایت فروشگاهی با PHP ساختهایم.
کاربر میتواند:
- ثبتنام کند
- Login کند
- محصول خریداری کند
- اطلاعات پروفایل خود را تغییر دهد
- سفارشهای خود را مشاهده کند
- فایل آپلود کند
اگر برنامه این دادهها را بدون کنترل دریافت کند، مهاجم ممکن است بتواند:
- اطلاعات کاربران را مشاهده کند
- Query مخرب اجرا کند
- Session کاربر دیگری را سرقت کند
- کد JavaScript اجرا کند
- فایل مخرب آپلود کند
- اطلاعات Database را تغییر دهد
- به بخشهای غیرمجاز دسترسی پیدا کند
بنابراین امنیت باید از ابتدای طراحی برنامه در نظر گرفته شود، نه اینکه بعد از تکمیل پروژه به آن اضافه شود.
# اصل مهم امنیت PHP: به ورودی کاربر اعتماد نکنید
یکی از مهمترین اصول امنیتی این است:
> هر دادهای که از کاربر دریافت میکنید، باید بالقوه غیرقابل اعتماد در نظر گرفته شود.
مثلاً:
$_GET['id']
یا:
$_POST['email']
یا:
$_COOKIE['token']
همگی دادههایی هستند که نباید بدون بررسی استفاده شوند.
حتی اگر کاربر معمولی قصد خرابکاری نداشته باشد، داده اشتباه یا غیرمنتظره میتواند باعث خطا یا رفتار نامناسب برنامه شود.
# ورودیهای خارجی در PHP
دادهها میتوانند از منابع مختلفی وارد برنامه شوند:
$_GET
$_POST
$_COOKIE
$_FILES
$_SERVER
همچنین دادههایی که از:
- API
- Database
- Webhook
- فایل
- Queue
- سرویسهای خارجی
دریافت میشوند نیز باید بر اساس نیاز برنامه بررسی شوند.
# Validation چیست؟
Validation یا اعتبارسنجی یعنی بررسی کنیم دادهای که دریافت کردهایم، شرایط مورد انتظار ما را دارد یا خیر.
مثلاً اگر کاربر باید سن خود را ارسال کند:
$age = $_POST['age'] ?? null;
نباید صرفاً فرض کنیم $age حتماً یک عدد معتبر است.
میتوانیم بررسی کنیم:
$age = filter_input(
INPUT_POST,
'age',
FILTER_VALIDATE_INT
);
سپس نتیجه را بررسی کنیم:
if ($age === false || $age === null) {
echo "سن وارد شده معتبر نیست.";
}
# Validation و Sanitization چه تفاوتی دارند؟
این دو مفهوم گاهی با یکدیگر اشتباه گرفته میشوند.
Validation
بررسی میکند داده معتبر است یا خیر.
مثلاً:
آیا ایمیل معتبر است؟
آیا سن عدد است؟
آیا مقدار یکی از گزینههای مجاز است؟
Sanitization
داده را برای استفاده در یک Context مشخص پاکسازی یا تغییر میدهد.
اما نکته مهم این است که Sanitization نباید جایگزین Validation شود.
همچنین برای خروجی HTML بهتر است به جای تکیه بر Sanitization عمومی، خروجی را متناسب با Context آن Escape کنیم.
# SQL Injection چیست؟
یکی از شناختهشدهترین آسیبپذیریهای برنامههای وب، SQL Injection است.
فرض کنید Query را با اتصال مستقیم ورودی کاربر بسازیم:
$id = $_GET['id'];
$sql = "SELECT * FROM users WHERE id = $id";
این روش میتواند خطرناک باشد، زیرا ورودی کاربر مستقیماً وارد Query شده است.
روش صحیح استفاده از:
Prepared Statements
است.
مثلاً با PDO:
$stmt = $pdo->prepare(
'SELECT * FROM users WHERE id = :id'
);
$stmt->execute([
'id' => $id
]);
در این روش داده کاربر از ساختار Query جدا میشود.
مقاله بعدی این کلاستر میتواند به صورت کامل به SQL Injection در PHP اختصاص پیدا کند.
# Prepared Statement چیست؟
Prepared Statement یکی از مهمترین ابزارهای مقابله با SQL Injection است.
مثلاً:
$stmt = $pdo->prepare(
'SELECT * FROM users WHERE email = :email'
);
$stmt->execute([
'email' => $email
]);
در اینجا مقدار $email به عنوان داده Query پردازش میشود، نه بخشی از ساختار SQL.
البته استفاده صحیح از Prepared Statement باید در کنار سایر اصول امنیتی انجام شود.
# XSS چیست؟
Cross-Site Scripting یا XSS یکی دیگر از آسیبپذیریهای رایج برنامههای وب است.
فرض کنید کاربر مقداری وارد کند که شامل HTML یا JavaScript مخرب باشد و برنامه آن را بدون Escape در صفحه نمایش دهد.
مثلاً:
echo $_GET['name'];
این کار میتواند خطرناک باشد.
برای خروجی HTML معمولاً باید مقدار را Escape کنیم:
echo htmlspecialchars(
$_GET['name'] ?? '',
ENT_QUOTES,
'UTF-8'
);
نکته بسیار مهم:
Escape باید متناسب با Context خروجی انجام شود.
برای مثال روش Escape در:
HTML
HTML Attribute
JavaScript
URL
CSS
لزومًا یکسان نیست.
# CSRF چیست؟
CSRF مخفف:
Cross-Site Request Forgery
است.
در این نوع حمله، مهاجم تلاش میکند مرورگر کاربر را وادار به ارسال درخواست ناخواسته به سایت مقصد کند.
این موضوع بهخصوص در سیستمهایی که Authentication آنها با Cookie انجام میشود اهمیت دارد.
یکی از روشهای رایج مقابله با CSRF استفاده از Token است:
Form
↓
CSRF Token
↓
Server
↓
Token Validation
↓
Process
در فریمورکهایی مانند Laravel، مکانیزمهای آمادهای برای این کار وجود دارد.
# امنیت Password در PHP
Password یکی از مهمترین بخشهای هر سیستم Authentication است.
رمز عبور را نباید به صورت Plain Text در Database ذخیره کنیم.
اشتباه:
$password = $_POST['password'];
INSERT INTO users (password)
VALUES ('$password');
روش صحیح استفاده از:
password_hash()
است.
مثلاً:
$password = $_POST['password'];
$hash = password_hash(
$password,
PASSWORD_DEFAULT
);
سپس Hash را در Database ذخیره میکنیم.
برای بررسی Password:
if (password_verify($password, $hash)) {
echo "Password is correct";
}
این موضوع را باید از SQL Injection و سایر مباحث امنیتی جدا در نظر گرفت.
# چرا نباید Password را Encrypt کنیم؟
در طراحی سیستم Password معمولاً هدف این نیست که رمز را به شکل قابل بازگشت ذخیره کنیم.
Password باید به شکل Hash مناسب ذخیره شود.
یعنی:
Password
↓
Hash
↓
Database
نه:
Password
↓
Encryption
↓
Database
زیرا سیستم Authentication معمولاً نیازی ندارد که Password اصلی را دوباره بازیابی کند.
# Session Security در PHP
Session نقش مهمی در سیستمهای Login دارد.
در PHP معمولاً:
session_start();
را اجرا میکنیم و وضعیت کاربر را در:
$_SESSION
نگه میداریم.
اما Session نیز باید امن مدیریت شود.
یکی از اقدامات مهم بعد از Login موفق:
session_regenerate_id(true);
است.
این کار برای کاهش ریسک Session Fixation اهمیت دارد.
# Session Fixation چیست؟
در Session Fixation مهاجم تلاش میکند Session ID مشخصی را به کاربر تحمیل کند.
اگر بعد از Login همان Session ID بدون تغییر ادامه پیدا کند، ریسک حمله افزایش پیدا میکند.
به همین دلیل پس از Authentication موفق بهتر است Session ID را بازتولید کنیم:
session_regenerate_id(true);
# Session Hijacking چیست؟
Session Hijacking به سرقت Session معتبر کاربر مربوط میشود.
اگر مهاجم Session ID معتبر کاربر را به دست آورد، ممکن است بتواند خود را به جای کاربر معرفی کند.
برای کاهش این ریسک:
- HTTPS استفاده کنید
- Session Cookie را Secure کنید
- HttpOnly را فعال کنید
- SameSite را درست تنظیم کنید
- Session ID را افشا نکنید
- بعد از Login Session ID را تغییر دهید
- Logout را به شکل صحیح پیادهسازی کنید
# امنیت Cookie در PHP
Cookie نیز باید با توجه به حساسیت اطلاعات به شکل صحیح تنظیم شود.
مثلاً:
setcookie('token', $token, [
'expires' => time() + 3600,
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);
در اینجا:
Secure
Cookie فقط روی HTTPS ارسال میشود.
HttpOnly
JavaScript معمولی نمیتواند Cookie را مستقیماً از طریق document.cookie بخواند.
SameSite
ارسال Cookie در سناریوهای Cross-Site را کنترل میکند.
# HTTPS و امنیت PHP
HTTPS یکی از پایههای امنیت برنامههای وب است.
در HTTP معمولی، ارتباط بین مرورگر و سرور رمزنگاری نمیشود.
در HTTPS، ارتباط با استفاده از TLS محافظت میشود.
به صورت ساده:
HTTP
Browser
↓
Internet
↓
Server
در مقابل:
HTTPS
Browser
↓
Encrypted Connection
↓
Server
برای سایتهایی که Login، Password، Session یا اطلاعات حساس دارند، استفاده از HTTPS یک ضرورت عملی امنیتی است.
# File Upload و امنیت PHP
آپلود فایل یکی از قسمتهایی است که باید با دقت زیادی پیادهسازی شود.
مثلاً این کد به تنهایی کافی نیست:
move_uploaded_file(
$_FILES['file']['tmp_name'],
'uploads/' . $_FILES['file']['name']
);
چون نام فایل و نوع فایل نباید بدون بررسی مورد اعتماد قرار بگیرند.
در سیستم Upload باید مواردی مانند:
- حجم فایل
- MIME Type
- Extension
- نام فایل
- محل ذخیره
- دسترسی فایل
- امکان اجرای فایل
- نوع فایلهای مجاز
بررسی شوند.
همچنین بهتر است نام فایل ذخیرهشده را خود برنامه تولید کند.
مثلاً:
$filename = bin2hex(random_bytes(16)) . '.jpg';
البته Extension نباید صرفاً بر اساس نام فایل ورودی تعیین شود و نوع واقعی فایل نیز باید با توجه به نیاز برنامه بررسی شود.
# چرا نام فایل کاربر را نباید مستقیم استفاده کنیم؟
فرض کنید کاربر فایلی با نام:
profile.php
آپلود کند.
اگر فایل مستقیماً در مسیر قابل اجرای Web Server ذخیره شود، میتواند خطرناک باشد.
به همین دلیل طراحی محل ذخیره فایل بسیار مهم است.
در بسیاری از معماریها بهتر است فایلهای Upload شده:
- خارج از مسیر قابل اجرای مستقیم قرار بگیرند
- یا با تنظیمات مناسب Web Server سرو شوند
- و نوع فایلهای قابل آپلود محدود شود
# مدیریت دسترسی کاربران
Authentication و Authorization یکی نیستند.
Authentication
یعنی:
این کاربر چه کسی است؟
Authorization
یعنی:
این کاربر اجازه انجام چه کاری را دارد؟
مثلاً کاربر وارد سیستم شده است:
Authentication = موفق
اما ممکن است اجازه حذف کاربران را نداشته باشد:
Authorization = رد
بنابراین فقط بررسی Login کافی نیست.
# یک اشتباه رایج در Authorization
مثلاً:
if (isset($_SESSION['user_id'])) {
deleteUser($_GET['id']);
}
این کد فقط بررسی میکند کاربر وارد شده است.
اما بررسی نمیکند که آیا این کاربر اجازه حذف User را دارد یا خیر.
ساختار مناسبتر:
if (!isset($_SESSION['user_id'])) {
exit('Unauthorized');
}
if ($_SESSION['role'] !== 'admin') {
exit('Forbidden');
}
deleteUser($_GET['id']);
در پروژههای واقعی باید Authorization بر اساس نیاز سیستم به شکل دقیقتری طراحی شود.
# امنیت API در PHP
اگر با PHP API میسازید، موارد امنیتی بیشتری باید در نظر گرفته شوند.
مثلاً:
Authentication
Authorization
Validation
Rate Limiting
Input Handling
Output Handling
CORS
HTTPS
Logging
همچنین نباید صرفاً به این دلیل که API از JSON استفاده میکند تصور کنیم امن است.
JSON فقط Format داده است.
# Rate Limiting چیست؟
Rate Limiting یعنی محدود کردن تعداد درخواستهایی که یک کاربر، IP یا Token در یک بازه زمانی میتواند ارسال کند.
مثلاً:
100 requests / minute
میتواند یک قانون نمونه باشد.
Rate Limiting برای Endpointهایی مانند:
/login
/register
/password-reset
/api
اهمیت زیادی دارد.
# جلوگیری از Brute Force
در حملات Brute Force مهاجم تلاش میکند Passwordهای مختلف را امتحان کند.
مثلاً:
admin@example.com
password1
password2
password3
...
برای کاهش این ریسک میتوان از مواردی مانند:
- Rate Limiting
- محدودیت تعداد Login ناموفق
- افزایش تأخیر
- CAPTCHA در شرایط مناسب
- Monitoring
- هشدارهای امنیتی
استفاده کرد.
# اطلاعات حساس را در Error نمایش ندهید
در محیط Development ممکن است بخواهیم خطاها را کامل ببینیم.
مثلاً:
ini_set('display_errors', '1');
اما فعال بودن نمایش خطاهای کامل در Production میتواند اطلاعاتی درباره برنامه افشا کند.
ممکن است Stack Trace یا مسیر فایلها نمایش داده شوند.
بنابراین تنظیمات Development و Production باید متفاوت باشند.
# Development و Production
در Development ممکن است:
display_errors = On
مناسب باشد.
اما در Production معمولاً نباید خطاهای داخلی برنامه به کاربر نهایی نمایش داده شوند.
به جای آن:
User
↓
Generic Error
و جزئیات خطا:
Application
↓
Log
ذخیره میشوند.
# Logging در امنیت PHP
Log میتواند برای بررسی رخدادهای امنیتی بسیار مهم باشد.
مثلاً:
Login Failed
Login Successful
Password Reset
Permission Denied
Suspicious Request
API Rate Limit
را میتوان ثبت کرد.
اما نباید اطلاعات حساس را بدون دلیل داخل Log ذخیره کنیم.
مثلاً:
Password
Credit Card
Session Token
Secret API Key
نباید صرفاً برای Debug در Log نوشته شوند.
# مدیریت Secretها
کلیدهای API، Password Database و Secretهای برنامه را نباید مستقیماً در Git قرار دهیم.
اشتباه:
$dbPassword = 'MySuperSecretPassword';
بهتر است Configuration از Environment دریافت شود:
$dbPassword = $_ENV['DB_PASSWORD'] ?? null;
در پروژههای PHP معمولاً میتوان از فایل Environment و ابزارهای مناسب Configuration استفاده کرد.
نکته مهم این است که فایلهایی مانند:
.env
نباید به شکل عمومی از طریق Web قابل دسترسی باشند.
# جلوگیری از افشای فایلهای حساس
نباید فایلهایی مانند:
.env
.git/config
composer.json
backup.sql
database.sql
بدون نیاز از طریق Web قابل دسترسی باشند.
به خصوص:
.env
ممکن است شامل اطلاعاتی مانند:
DB_PASSWORD
API_KEY
APP_SECRET
باشد.
بنابراین Web Server باید به گونهای تنظیم شود که فایلهای حساس در دسترس عموم قرار نگیرند.
# Directory Traversal چیست؟
Directory Traversal زمانی رخ میدهد که مهاجم بتواند با استفاده از مسیر دستکاریشده به فایلهایی خارج از محدوده مجاز دسترسی پیدا کند.
مثلاً دادهای مانند:
../../config.php
میتواند در صورت پیادهسازی اشتباه خطرناک باشد.
بنابراین اگر برنامه بر اساس ورودی کاربر فایل میخواند، نباید مسیر را مستقیماً به فایل سیستم بدهیم.
# اجرای مستقیم فایلهای PHP
اگر برنامه اجازه آپلود فایل میدهد، باید مراقب فایلهایی با Extensionهای قابل اجرا مانند:
.php
.php8
.phtml
باشیم.
در صورت امکان، فایلهای Upload شده نباید در مسیری قرار بگیرند که Web Server بتواند آنها را به عنوان PHP اجرا کند.
# امنیت Command Execution
PHP امکان اجرای دستورات سیستم را در اختیار برنامهنویس قرار میدهد، اما استفاده از این قابلیت با ورودی کاربر بسیار خطرناک است.
مثلاً:
exec($_GET['command']);
یک الگوی بسیار خطرناک است.
اگر واقعاً نیاز به اجرای Command باشد، باید:
- Commandهای مجاز محدود شوند
- ورودی کاربر مستقیماً وارد Shell نشود
- Permissionهای سیستم محدود باشند
- مسیرها و Argumentها به شکل مناسب کنترل شوند
# امنیت cURL و درخواستهای خارجی
اگر PHP به APIهای خارجی متصل میشود، باید مواردی مانند:
- HTTPS
- Timeout
- Certificate Verification
- اعتبارسنجی Response
- محدودیت Redirect
- مدیریت خطا
را در نظر گرفت.
همچنین نباید URL کاملاً تحت کنترل کاربر را بدون کنترل به Server-side HTTP Client بدهیم.
این موضوع میتواند در بعضی معماریها با ریسکهایی مانند SSRF مرتبط شود.
# SSRF چیست؟
SSRF مخفف:
Server-Side Request Forgery
است.
در این نوع آسیبپذیری، مهاجم تلاش میکند سرور را وادار کند به آدرسهایی که خودش انتخاب کرده درخواست ارسال کند.
مثلاً برنامهای داریم:
/api/fetch?url=...
اگر Server بدون محدودیت هر URL را درخواست کند، میتواند خطرناک باشد.
بنابراین در چنین Endpointهایی باید مقصدهای مجاز و قوانین دسترسی مشخص شوند.
# Security Headers
بعضی Headerهای HTTP میتوانند به بهبود امنیت مرورگر کمک کنند.
برای مثال:
Content-Security-Policy
X-Content-Type-Options
Referrer-Policy
Permissions-Policy
Strict-Transport-Security
هر Header کاربرد خاص خود را دارد.
مثلاً:
X-Content-Type-Options: nosniff
به مرورگر اعلام میکند که MIME Type را به شکل حدسی تغییر ندهد.
اما Security Headerها جایگزین اصلاح آسیبپذیریهای اصلی برنامه نیستند.
# Content Security Policy چیست؟
CSP یا:
Content Security Policy
یکی از مکانیزمهای امنیتی مرورگر است که میتواند مشخص کند منابع مختلف صفحه از چه Sourceهایی اجازه بارگذاری دارند.
برای مثال میتوان سیاستی تعریف کرد که Scriptها فقط از منابع مشخصی بارگذاری شوند.
CSP میتواند در کاهش اثر بعضی سناریوهای XSS مفید باشد، اما تنظیم اشتباه آن ممکن است عملکرد سایت را مختل کند.
# اصل Least Privilege
یکی از اصول مهم امنیت:
Least Privilege
است.
یعنی هر بخش از سیستم فقط به اندازه نیاز خود Permission داشته باشد.
مثلاً اگر برنامه فقط نیاز به خواندن اطلاعات Database دارد، نباید حتماً کاربر Database دسترسی کامل به:
DROP
DELETE
ALTER
داشته باشد.
همین اصل درباره:
- فایلها
- کاربران سیستم
- API Keys
- Database
- سرویسها
نیز کاربرد دارد.
# Database User جداگانه
بهتر است Application با یک Database User مشخص کار کند.
مثلاً:
cms_user
و Permissionهای آن فقط به نیاز برنامه محدود شوند.
این روش بهتر از آن است که Application با یک کاربر Database دارای دسترسی کامل کار کند.
# امنیت Dependencyهای PHP
اگر از Composer استفاده میکنیم، پروژه ممکن است وابستگیهای زیادی داشته باشد.
مثلاً:
vendor/
شامل Packageهای مختلف است.
آسیبپذیری در یک Dependency نیز میتواند روی برنامه تأثیر بگذارد.
بنابراین باید:
- Packageها را بهروز نگه داریم
- تغییرات Version را کنترل کنیم
- Dependencyهای غیرضروری را حذف کنیم
- آسیبپذیریهای شناختهشده را بررسی کنیم
# چرا Composer اهمیت امنیتی دارد؟
Composer فقط ابزار نصب Package نیست.
وابستگیهای پروژه بخشی از سطح حمله برنامه هستند.
مثلاً:
Application
↓
Package A
↓
Package B
↓
Package C
اگر یکی از Dependencyها آسیبپذیر باشد، باید اثر آن روی پروژه بررسی شود.
# امنیت با Obfuscation متفاوت است
گاهی تصور میشود اگر کد PHP را پیچیده یا Obfuscate کنیم، برنامه امن میشود.
اما:
Obfuscation ≠ Security
امنیت واقعی باید با روشهایی مانند:
- Validation
- Authorization
- Prepared Statements
- Output Encoding
- CSRF Protection
- Secure Session
- Secure Cookie
- HTTPS
- Least Privilege
ایجاد شود.
# چکلیست امنیت PHP
قبل از انتشار یک برنامه PHP در Production، این موارد را بررسی کنید:
ورودی
- آیا تمام Inputها Validation میشوند؟
- آیا به داده کاربر اعتماد مستقیم نداریم؟
- آیا Uploadها کنترل میشوند؟
Database
- آیا از Prepared Statement استفاده میکنیم؟
- آیا Database User دسترسی بیش از نیاز دارد؟
Password
- آیا Passwordها با
password_hash()ذخیره میشوند؟ - آیا با
password_verify()بررسی میشوند؟
Authentication
- آیا Session بعد از Login بازتولید میشود؟
- آیا Logout به شکل صحیح انجام میشود؟
- آیا Session Timeout مناسب وجود دارد؟
Cookie
- آیا Cookieهای حساس
Secureهستند؟ - آیا
HttpOnlyفعال است؟ - آیا
SameSiteمتناسب با نیاز تنظیم شده است؟
XSS
- آیا خروجیها متناسب با Context Escape میشوند؟
CSRF
- آیا درخواستهای حساس CSRF Protection دارند؟
API
- آیا Authentication و Authorization وجود دارد؟
- آیا Rate Limiting وجود دارد؟
File
- آیا فایلهای Upload شده کنترل میشوند؟
- آیا فایلهای قابل اجرای PHP در مسیر Upload قابل اجرا هستند؟
Server
- آیا HTTPS فعال است؟
- آیا فایلهای حساس Web-accessible نیستند؟
- آیا Errorهای داخلی در Production نمایش داده نمیشوند؟
Secret
- آیا Passwordها و API Keyها در Git قرار نگرفتهاند؟
- آیا
.envاز Web قابل دسترسی نیست؟
Dependency
- آیا Dependencyهای پروژه بهروز و کنترلشده هستند؟
# معماری یک برنامه PHP امنتر
امنیت را میتوان در چند لایه تصور کرد:
User
↓
HTTPS / TLS
↓
Web Application
↓
┌─────────┴─────────┐
↓ ↓
Authentication Validation
↓ ↓
Authorization Input Control
↓ ↓
└─────────┬─────────┘
↓
Database
↓
Least Privilege
امنیت واقعی معمولاً حاصل یک ویژگی خاص نیست؛ بلکه نتیجه ترکیب چندین لایه دفاعی است.
# آیا PHP ذاتاً ناامن است؟
خیر.
PHP یک زبان برنامهنویسی است و امنیت برنامه فقط به زبان وابسته نیست.
بسیاری از مشکلات امنیتی ناشی از مواردی مانند:
- کدنویسی نادرست
- عدم Validation
- Query ناامن
- Authorization ناقص
- مدیریت ضعیف Session
- تنظیمات اشتباه Server
- Dependency آسیبپذیر
هستند.
بنابراین استفاده از PHP به تنهایی به معنی ناامن بودن برنامه نیست.
# امنیت PHP را از کجا شروع کنیم؟
اگر تازه میخواهید امنیت PHP را یاد بگیرید، پیشنهاد میشود این ترتیب مفهومی را دنبال کنید:
1. Input Validation
↓
2. SQL Injection
↓
3. Prepared Statements
↓
4. XSS
↓
5. CSRF
↓
6. Password Security
↓
7. Session Security
↓
8. Cookie Security
↓
9. File Upload Security
↓
10. API Security
↓
11. Server Security
با یادگیری این مباحث، درک بسیار بهتری از امنیت برنامههای PHP به دست خواهید آورد.
# جمعبندی
امنیت PHP یک موضوع واحد نیست، بلکه مجموعهای از اصول و تکنیکهایی است که باید در تمام بخشهای برنامه رعایت شوند.
مهمترین اصولی که در این مقاله بررسی کردیم عبارتاند از:
- اعتماد نکردن به ورودی کاربر
- Validation
- Prepared Statements
- جلوگیری از SQL Injection
- جلوگیری از XSS
- محافظت در برابر CSRF
- Hash کردن Password
- مدیریت امن Session
- مدیریت Cookie
- استفاده از HTTPS
- کنترل File Upload
- Authorization
- Rate Limiting
- مدیریت Secretها
- جلوگیری از افشای Error
- Security Headers
- Least Privilege
- مدیریت Dependencyها
امنیت را نباید یک مرحله جداگانه بعد از پایان برنامهنویسی در نظر گرفت.
بهتر است از همان زمان طراحی Database، فرمها، Authentication، API و سیستم Upload، اصول امنیتی را وارد معماری برنامه کنیم.
در ادامه این کلاستر، هرکدام از آسیبپذیریهای مهم را میتوان به صورت مستقل و عملی بررسی کرد. یکی از مهمترین آنها SQL Injection در PHP است که در مقاله بعدی میتوانیم آن را با مثالهای عملی، Queryهای ناامن و روش استفاده صحیح از PDO و Prepared Statements بررسی کنیم.
سوالات متداول
امنیت PHP چیست؟
امنیت PHP مجموعهای از اصول و روشهایی است که برای محافظت از برنامههای PHP در برابر دسترسی غیرمجاز، دستکاری داده، اجرای کد مخرب، سرقت Session و سایر آسیبپذیریها استفاده میشود.
مهمترین آسیبپذیریهای PHP چیست؟
برخی از آسیبپذیریهای مهم برنامههای PHP شامل SQL Injection، XSS، CSRF، مشکلات Session، آپلود فایل ناامن، ضعف Authorization و افشای اطلاعات حساس هستند.
آیا PHP زبان امنی است؟
امنیت برنامه فقط به زبان برنامهنویسی وابسته نیست. نحوه طراحی و پیادهسازی برنامه، Dependencyها، Web Server، Database و تنظیمات امنیتی نیز نقش مهمی دارند.
چگونه از SQL Injection در PHP جلوگیری کنیم؟
یکی از روشهای اصلی استفاده از Prepared Statements است. در PHP میتوان با PDO از Queryهای Parameterized استفاده کرد.
چگونه Password را در PHP امن ذخیره کنیم؟
برای ذخیره Password باید از تابع:
password_hash()
و برای بررسی آن از:
password_verify()
استفاده شود.
چگونه Session در PHP را امن کنیم؟
استفاده از HTTPS، Cookieهای Secure و HttpOnly، تنظیم مناسب SameSite، بازتولید Session ID بعد از Login و Logout صحیح از اقدامات مهم هستند.
آیا Validation به تنهایی امنیت برنامه را تضمین میکند؟
خیر. Validation فقط یکی از لایههای امنیتی است. یک برنامه امن به مجموعهای از مکانیزمها مانند Authentication، Authorization، Prepared Statements، Output Encoding، CSRF Protection و تنظیمات صحیح Server نیاز دارد.
آیا استفاده از Framework امنیت برنامه را تضمین میکند؟
خیر. Frameworkهایی مانند Laravel امکانات امنیتی بسیار خوبی ارائه میکنند، اما نحوه استفاده برنامهنویس از این امکانات همچنان اهمیت دارد. استفاده نادرست از Framework نیز میتواند باعث ایجاد آسیبپذیری شود.
آیا HTTPS به تنهایی برای امنیت PHP کافی است؟
خیر. HTTPS از ارتباط بین Client و Server محافظت میکند، اما مشکلاتی مانند SQL Injection، XSS، Authorization ناقص یا Upload ناامن را به خودی خود حل نمیکند.
مهمترین اصل امنیتی در PHP چیست؟
یکی از اصول بنیادی این است که به دادههای خارجی اعتماد نکنیم و هر داده را متناسب با Context استفاده، اعتبارسنجی، پردازش و در صورت نیاز Escape کنیم.





