فصل ۶: OWASP Top 10
آموزش کامل ده آسیبپذیری بحرانی OWASP Top 10 نسخه ۲۰۲۱ با توصیف، مثال واقعی، کد آسیبپذیر و اصلاحشده و روش پیشگیری برای هر مورد.
OWASP چیست؟
OWASP (Open Web Application Security Project) یک بنیاد غیرانتفاعی است که ابزارها، اسناد و چارچوبهای آزاد برای بهبود امنیت نرمافزار ارائه میدهد. شناختهشدهترین پروژهٔ آن، OWASP Top 10 است که هر سه تا چهار سال، ده ریسک امنیتی بحرانی در اپلیکیشنهای وب را فهرست میکند.
نسخهٔ ۲۰۲۱، فهرست قبلی ۲۰۱۷ را بازنویسی کرد و سه مورد جدید (A04 Insecure Design، A08 Software/Data Integrity Failures، A10 SSRF) اضافه شد. این فهرست بر اساس دادههای واقعی از ۵۰۰ هزار اپلیکیشن و نظرسنجی متخصصان امنیتی گردآوری شده.
OWASP Top 10 حداقلهاست
OWASP Top 10 نقطهٔ شروع است، نه نقطهٔ پایان. یک اپلیکیشن ممکن است هیچکدام از این ده مورد را نداشته باشد و همچنان آسیبپذیر باشد. برای ارزیابی کامل از OWASP ASVS (Application Security Verification Standard) استفاده کنید.
فهرست خلاصهٔ OWASP Top 10 2021
| ردیف | نام | تغییر از ۲۰۱۷ |
|---|---|---|
| A01 | Broken Access Control | صعود از پنجم به اول |
| A02 | Cryptographic Failures | تغییر نام از Sensitive Data Exposure |
| A03 | Injection | نزول از اول به سوم |
| A04 | Insecure Design | جدید |
| A05 | Security Misconfiguration | صعود از ششم |
| A06 | Vulnerable Components | صعود از نهم |
| A07 | Authentication Failures | تغییر نام |
| A08 | Software/Data Integrity Failures | جدید |
| A09 | Logging/Monitoring Failures | تغییر نام |
| A10 | SSRF | جدید |
A01 — Broken Access Control
توصیف: محدودیتهای اجازهٔ دسترسی بهدرستی اعمال نشدهاند. کاربر میتواند به داده یا عملکرد خارج از اختیار خود دست یابد.
مثال واقعی: در ۲۰۱۹، USPS به دلیل آسیبپذیری API، دادهٔ ۶۰ میلیون کاربر را در معرض قرار داد؛ هر کاربر با تغییر پارامتر id میتوانست مشخصات دیگران را ببیند.
کد آسیبپذیر:
@app.route('/api/orders/<int:order_id>')
def get_order(order_id):
# هیچ بررسی مالکیت نمیشود
order = Order.query.get(order_id)
return jsonify(order.to_dict())کد اصلاحشده:
@app.route('/api/orders/<int:order_id>')
@login_required
def get_order(order_id):
order = Order.query.get_or_404(order_id)
if order.user_id != current_user.id and not current_user.is_admin:
abort(403)
return jsonify(order.to_dict())پیشگیری: اعمال کنترل دسترسی در سمت سرور برای هر درخواست، استفاده از RBAC یا ABAC، deny-by-default.
A02 — Cryptographic Failures
توصیف: دادهٔ حساس با الگوریتم ضعیف یا بدون رمزگذاری منتقل یا ذخیره میشود.
مثال: ذخیرهٔ رمز عبور با MD5، استفاده از TLS 1.0، یا کلید hardcoded در کد.
کد آسیبپذیر:
import hashlib
def store_password(password):
return hashlib.md5(password.encode()).hexdigest()کد اصلاحشده:
import bcrypt
def store_password(password):
return bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=14)).decode()پیشگیری: AES-256 برای داده، TLS 1.3 برای انتقال، Argon2 برای رمز عبور، مدیریت کلید با KMS. هرگز کلید رمزگذاری را در کد منبع قرار ندهید.
A03 — Injection
توصیف: ورودی نامعتبر کاربر به مفسر (SQL، OS، LDAP) ارسال میشود و دستورات مخرب اجرا میشوند.
مثال واقعی: حملهٔ SQL Injection به Sony Pictures در ۲۰۱۱ منجر به سرقت ۱ میلیون حساب کاربری شد.
کد آسیبپذیر:
# Python
query = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'"
cursor.execute(query)کد اصلاحشده (پارامتری):
# Python
query = "SELECT * FROM users WHERE username = ? AND password = ?"
cursor.execute(query, (username, password))نمونهٔ SQL Injection آموزشی:
-- پرسوجوی آسیبپذیر
SELECT * FROM users WHERE username = 'admin' OR '1'='1' -- ' AND password = '...';
-- نتیجه: شرط همیشه درست، ورود بدون رمزتنها روی سیستم مجاز
تست SQL Injection یا هر حملهٔ دیگر را فقط روی سیستمهایی انجام دهید که مالک آن هستید یا اجازهٔ کتبی دارید. حتی اسکن یک سایت بدون اجازه میتواند جرم محسوب شود و پیگرد قانونی داشته باشد. از محیطهایی مانند DVWA، Juice Shop یا HackTheBox استفاده کنید.
پیشگیری: کوئری پارامتری، ORM معتبر، اعتبارسنجی ورودی، اصل کمینهدسترسی برای کاربر دیتابیس.
A04 — Insecure Design
توصیف: ضعف در طراحی معماری که با وصلهٔ کد قابلحل نیست؛ نیاز به بازطراحی دارد.
مثال: فراموشی رمز با سوال امنیتی قابلحدس (نام مادر، شهر تولد)، یا سیستم انتقال اعتبار بدون تأیید دو مرحلهای.
پیشگیری: مدلسازی تهدید در فاز طراحی (به فصل ۲ مراجعه کنید)، الگوهای طراحی امن، user stories با سناریوهای misuse، محدودیت نرخ در سطح طراحی.
A05 — Security Misconfiguration
توصیف: تنظیمات ناامن پیشفرض، پیام خطای verbose، سرویسهای غیرضروری فعال، یا وصلههای نصبنشده.
مثال: Elasticsearch بدون احراز هویت روی اینترنت، که منجر به نشت میلیونها رکورد شده است.
پیکربندی آسیبپذیر:
# /etc/elasticsearch/elasticsearch.yml
network.host: 0.0.0.0
http.port: 9200
xpack.security.enabled: falseپیکربندی سختشده:
network.host: 127.0.0.1
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: trueپیشگیری: سختسازی پیشفرض، disable سرویسهای غیرضروری، حذف صفحات پیشفرض، مدیریت وصلهها، استفاده از ابزارهایی مانند CIS Benchmarks.
A06 — Vulnerable and Outdated Components
توصیف: استفاده از کتابخانه یا فریمورک دارای آسیبپذیری شناختهشده.
مثال واقعی: نفوذ Equifax از طریق آسیبپذیری CVE-2017-5638 در Apache Struts که وصلهٔ آن دو ماه پیشتر منتشر شده بود.
ابزارهای اسکن:
# اسکن پروژهٔ Node.js
npm audit
# اسکن پروژهٔ Python
pip-audit
safety check
# اسکن image داکر
trivy image myapp:latest
# اسکن کد جاوا
mvn org.owasp:dependency-check:checkپیشگیری: SBOM (Software Bill of Materials)، اشتراک در CVE، وصلهسازی خودکار در CI/CD، قفلکردن نسخهها با lock file.
A07 — Identification and Authentication Failures
توصیف: ضعف در مکانیزم احراز هویت: رمزهای ضعیف، نبود MFA، جلسهٔ غیرقابلانقضا.
مثال: نگهداشتن session cookie بدون انقضا، یا امکان brute-force بدون rate limit.
پیشگیری: MFA اجباری، مدیریت نشست با انقضا، rate limiting روی ورود، بررسی رمز در برابر لیست لو رفته. برای جزئیات بیشتر به فصل ۴ مراجعه کنید.
A08 — Software and Data Integrity Failures
توصیف: کد یا داده از منبع نامعتبر و بدون تأیید اصالت بارگذاری میشود.
مثال واقعی: حملهٔ SolarWinds که در آن، مهاجمان زیرساخت build را هدف قرار دادند و کد مخرب را در بهروزرسانی رسمی قرار دادند.
پیشگیری: امضای باینری، lock فایل وابستگی، تأیید hash دانلود، زیرساخت build ایزوله، استفاده از SBOM و reproducible builds.
A09 — Security Logging and Monitoring Failures
توصیف: عدم ثبت رخدادهای امنیتی یا عدم مانیتورینگ آنها؛ بنابراین نفوذ ماهها بیتشخیص میماند.
مثال واقعی: در نفوذ به Target در ۲۰۱۳، سیستم alerts امنیتی رخداد را شناسایی کردند اما تیم مانیتورینگ آنها را نادیده گرفت.
نمونهٔ لاگنویسی ساختاریافته:
import logging
import json
from datetime import datetime
logger = logging.getLogger("security")
def log_login(user_id, success, ip):
logger.info(json.dumps({
"event": "login_attempt",
"user_id": user_id,
"success": success,
"ip": ip,
"timestamp": datetime.utcnow().isoformat()
}))پیشگیری: لاگنویسی ساختاریافته (JSON)، ارسال به SIEM، alert بر اساس anomali، نگهداری لاگ حداقل یک سال، تست منظم آدرسهای بحرانی.
A10 — Server-Side Request Forgery (SSRF)
توصیف: سرور از سمت کاربر URL دریافت میکند و آن را fetch میکند، بدون اینکه اعتبارسنجی کند.
مثال واقعی: حملهٔ Capital One در ۲۰۱۹ به سرقت ۱۰۶ میلیون رکورد، از طریق SSRF به metadata سرویس AWS و سپس دسترسی به S3 bucket.
کد آسیبپذیر:
import requests
@app.route('/fetch')
def fetch(url):
return requests.get(url).text # هر URL کاربر اجرا میشودکد اصلاحشده:
from urllib.parse import urlparse
import ipaddress
import requests
ALLOWED_SCHEMES = {"http", "https"}
def is_safe_url(url):
p = urlparse(url)
if p.scheme not in ALLOWED_SCHEMES:
return False
try:
ip = ipaddress.ip_address(p.hostname)
if ip.is_private or ip.is_loopback or ip.is_reserved:
return False
except ValueError:
if p.hostname in ["localhost", "metadata.google.internal"]:
return False
return True
@app.route('/fetch')
def fetch(url):
if not is_safe_url(url):
abort(400)
return requests.get(url, timeout=5).textپیشگیری: allowlist دامنه، غیرفعالکردن دسترسی به metadata سرور (AWS IMDSv2)، فایروال خروجی، اعتبارسنجی scheme و IP.
جدول خلاصهٔ OWASP Top 10 2021
| ردیف | نام | ریسک اصلی | اولویت رفع |
|---|---|---|---|
| A01 | Broken Access Control | دسترسی غیرمجاز | بحرانی |
| A02 | Cryptographic Failures | نشت داده | بحرانی |
| A03 | Injection | اجرای کد مخرب | بحرانی |
| A04 | Insecure Design | نقص طراحی | بالا |
| A05 | Security Misconfiguration | سوءپیکربندی | بالا |
| A06 | Vulnerable Components | وابستگی مخرب | بالا |
| A07 | Authentication Failures | جعل هویت | بالا |
| A08 | Integrity Failures | عدم تأیید اصالت | متوسط |
| A09 | Logging Failures | عدم تشخیص نفوذ | متوسط |
| A10 | SSRF | سوءاستفاده از سرور | بالا |
تمرین عملی: SQL Injection در محیط آموزشی
DVWA (Damn Vulnerable Web Application) یک اپلیکیشن عمداً آسیبپذیر است که برای آموزش طراحی شده.
# اجرای DVWA با Docker
docker run -d -p 8080:80 vulnerables/web-dvwa
# ورود با admin/password روی http://localhost:8080مراحل آزمایش:
۱. به بخش SQL Injection بروید.
۲. در فیلد User ID، مقدار 1 را وارد کنید. پاسخ عادی.
۳. مقدار 1' OR '1'='1 را وارد کنید. تمام کاربران نمایش داده میشوند.
۴. مقدار 1'; DROP TABLE users; -- را وارد کنید. اگر پیکربندی شدید باشد، جدول حذف میشود.
۵. حالا سطح امنیتی را از low به high تغییر کنید و تفاوت را ببینید.
هشدار قانونی
اجرای این آزمایشها فقط روی localhost یا محیطهای آموزشی مجاز مجاز است. تلاش برای SQL Injection روی هر سایت عمومی، حتی با نیت آزمایش، در اکثر کشورها از جمله ایران جرم است و میتواند تا چند سال حبس در پی داشته باشد. همیشه قبل از هر آزمایش، مجوز کتبی از مالک سیستم بگیرید.
خلاصه و گام بعدی
OWASP Top 10 نقشهٔ راهی برای امنیت اپلیکیشنهای وب است. هر یک از این ده مورد را در پروژهٔ خود بررسی و رفع کنید. برای عمق بیشتر به OWASP ASVS، OWASP Testing Guide و OWASP Cheat Sheet Series مراجعه کنید. مهمترین اصل: کنترل دسترسی سمت سرور، کوئری پارامتری، و وصلهسازی منظم میتواند بیش از ۹۰ درصد این ریسکها را پوشش دهد.
در فصل بعد با بدافزار و حملات آشنا میشوید؛ آناتومی ویروسها، تروجانها، باجافزارها و روتکیتها.
این صفحه در تاریخ ۸ تیر ۱۴۰۵ بهروزرسانی شده است.