تزریق کد (Code Injection) یک نوع حمله امنیتی است که در آن مهاجم کدی را به برنامهای وارد میکند که به طور غیرمجاز اجرا میشود. این کد میتواند به برنامه آسیب برساند، دادهها را سرقت کند، یا حتی کنترل کامل سیستم را به دست آورد. انواع مختلفی از تزریق کد وجود دارد که در ادامه به برخی از رایجترین آنها اشاره میکنیم:
در حمله تزریق SQL، مهاجم کدهای SQL را به ورودیهای برنامه (مانند فرمهای جستجو یا ورود) وارد میکند. اگر برنامه ورودیها را به درستی اعتبارسنجی نکند، کد SQL مهاجم اجرا شده و میتواند به پایگاه داده دسترسی یابد. این نوع تزریق میتواند به خواندن، تغییر، یا حذف دادههای پایگاه داده منجر شود.
فرض کنید یک فرم ورود به سیستم وجود دارد که از این کد برای بررسی اعتبار کاربران استفاده میکند:
SELECT * FROM users WHERE username = '$username' AND password = '$password';
اگر مهاجم مقدار $username
را به صورت ' OR '1'='1
وارد کند، کد SQL به صورت زیر تغییر میکند:
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '';
این پرس و جو همیشه درست است و به مهاجم اجازه میدهد وارد سیستم شود.
در حمله XSS، مهاجم کدی (معمولاً جاوا اسکریپت) را به وبسایتها یا وباپلیکیشنها وارد میکند. این کد میتواند در مرورگر سایر کاربران اجرا شود و دادههای حساس مانند کوکیها را به سرور مهاجم ارسال کند.
فرض کنید وبسایت شما یک فرم کامنت دارد که کاربران میتوانند نظرات خود را وارد کنند و این نظرات به صورت مستقیم بر روی وبسایت نمایش داده میشود. اگر ورودیهای کاربران به درستی اعتبارسنجی یا پاکسازی نشوند، یک مهاجم میتواند کد زیر را به عنوان نظر وارد کند:
<script>alert('Hacked!');</script>
در این حالت، کد جاوا اسکریپت که درون تگ <script>
نوشته شده است، در مرورگر تمامی کاربرانی که به این صفحه مراجعه کنند، اجرا میشود. به عبارت دیگر، زمانی که سایر کاربران صفحهای که شامل این کامنت است را بارگذاری میکنند، مرورگر آنها کد جاوا اسکریپت را به عنوان بخشی از صفحه اجرا میکند. این کد به سادگی یک پنجره پیام (alert) با متن «Hacked!» نمایش میدهد. چنین حملاتی که به نام XSS (Cross-Site Scripting) شناخته میشود، میتواند اطلاعات حساس کاربران را به سرقت ببرد یا حتی برای فعالیتهای مخرب دیگر استفاده شود.
در حمله تزریق فرمان، مهاجم دستورات سیستمعامل را به ورودیهای برنامه وارد میکند. اگر برنامه این ورودیها را به درستی اعتبارسنجی نکند و دستورات را به سیستمعامل ارسال کند، مهاجم میتواند دستورات دلخواه را اجرا کند.
فرض کنید برنامهای طراحی کردهاید که از دستور ping
برای بررسی دسترسی به یک مقصد استفاده میکند و مقصد را از ورودی کاربر دریافت میکند:
ping $destination
اگر مهاجم ورودی را به صورت زیر وارد کند:
google.com; rm -rf /
دستور rm -rf /
که به حذف تمام فایلهای سیستم منجر میشود، نیز اجرا خواهد شد. این مشکل به دلیل عدم فیلتر کردن ورودی کاربر است که به مهاجم اجازه میدهد دستورات اضافی را اجرا کند.
برای جلوگیری از حملات تزریق کد، اقدامات زیر میتواند مؤثر باشد:
این اقدامات به کاهش خطرات تزریق کد و محافظت از امنیت برنامههای وب و سیستمها کمک میکند.
برای جلوگیری از حملات تزریق کد، میتوانید اقدامات زیر را به کار ببرید:
تمام ورودیهای کاربر باید به طور دقیق اعتبارسنجی و تصفیه شوند. در اینجا نمونهای از اعتبارسنجی ورودی با استفاده از زبان برنامهنویسی PHP آورده شده است:
<?php
// تابعی برای اعتبارسنجی ورودی
function validateInput($input) {
// حذف تگهای HTML و اسکریپتها
$input = htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
return $input;
}
// مثال استفاده
$userInput = $_POST['user_input'];
$validatedInput = validateInput($userInput);
?>
در پایگاههای داده، استفاده از جملات آماده به جلوگیری از تزریق SQL کمک میکند. نمونهای از استفاده از جملات آماده در PHP با پایگاه داده MySQL:
<?php
// اتصال به پایگاه داده
$mysqli = new mysqli('localhost', 'user', 'password', 'database');
// آمادهسازی و اجرای جملات آماده
$stmt = $mysqli->prepare('SELECT * FROM users WHERE email = ?');
$stmt->bind_param('s', $userEmail);
$userEmail = $_POST['email'];
$stmt->execute();
$result = $stmt->get_result();
?>
خروجیهای تولید شده از ورودیهای کاربر باید به درستی کدگذاری شوند تا از XSS جلوگیری شود. در اینجا نمونهای از کدگذاری خروجی با استفاده از PHP:
<?php
// تابعی برای کدگذاری خروجی
function encodeOutput($output) {
return htmlspecialchars($output, ENT_QUOTES, 'UTF-8');
}
// مثال استفاده
echo encodeOutput($userInput);
?>
برنامهها باید از اجرای دستورات سیستمعامل به صورت مستقیم از ورودیهای کاربر خودداری کنند. به جای استفاده از ورودی کاربر در دستورات سیستم، از روشهای ایمنتری استفاده کنید. به عنوان مثال، در PHP:
<?php
// اجتناب از اجرای دستورات سیستم با ورودی کاربر
$command = escapeshellcmd('ping ' . escapeshellarg($destination));
$output = shell_exec($command);
echo $output;
?>
علاوه بر موارد اصلی که ذکر شد، انواع دیگری از حملات تزریق کد نیز وجود دارد که ممکن است در سناریوهای مختلف به کار روند. در ادامه، به برخی از این موارد اشاره میکنم:
چگونگی عمل:
در حمله تزریق LDAP، مهاجم کدهای LDAP (Lightweight Directory Access Protocol) را به ورودیهای برنامه وارد میکند. این حمله میتواند به تغییر یا جستجو در دایرکتوریهای LDAP منجر شود.
مثال:
فرض کنید برنامهای برای جستجوی کاربران در دایرکتوری LDAP از کد زیر استفاده میکند:
(&(uid=$uid)(userPassword=$password))
در این مثال، متغیرهای $uid
و $password
به عنوان ورودی در جستجو استفاده میشوند. اگر مهاجم مقدار $uid
را به صورت زیر وارد کند:
admin)(|(uid=*
در این صورت، عبارت جستجو به شکل زیر خواهد شد:
(&(uid=admin)(|(uid=*)(userPassword=$password)))
این نوع تزریق باعث میشود که جستجو به همه کاربران دایرکتوری باز شود، زیرا قسمت (|(uid=*)
باعث میشود که جستجو شامل تمام مقادیر uid
شود. برای جلوگیری از این نوع حملات، ورودیهای کاربر باید به درستی فیلتر و اعتبارسنجی شوند.
چگونگی عمل:
در حمله تزریق XML، مهاجم دادههای XML مخرب را به ورودیهای برنامه وارد میکند. این حمله میتواند به آسیب به دادههای XML، افشای اطلاعات حساس، یا ایجاد حملات XML External Entity (XXE) منجر شود.
مثال:
اگر برنامهای از دادههای XML ورودی استفاده کند و مهاجم دادههای زیر را ارسال کند:
<user><name>John</name><password>pass</password></user>
مهاجم میتواند دادههای XML را تغییر داده و به اطلاعات حساس دسترسی پیدا کند.
چگونگی عمل:
در حمله تزریق JSON، مهاجم دادههای JSON مخرب را به ورودیهای برنامه وارد میکند. این حمله میتواند به تغییر یا حذف دادههای JSON منجر شود و همچنین میتواند منجر به حملات دیگر مانند XSS یا تزریق SQL شود.
مثال:
اگر برنامهای از دادههای JSON برای ذخیرهسازی استفاده کند و مهاجم دادههای زیر را ارسال کند:
{"user": "admin", "role": "admin", "action": "delete"}
مهاجم میتواند به تغییر دسترسیها یا حذف دادهها بپردازد.
چگونگی عمل:
در حمله تزریق URL، مهاجم پارامترهای URL را به صورت مخرب وارد میکند. این حمله میتواند به تغییر رفتار برنامه یا دسترسی به اطلاعات حساس منجر شود.
مثال:
اگر برنامهای از پارامترهای URL برای تعیین مقصد استفاده کند و مهاجم پارامترهای زیر را ارسال کند:
http://example.com/page?redirect=http://malicious.com
مهاجم میتواند کاربران را به سایتهای مخرب هدایت کند.
چگونگی عمل:
در حمله تزریق فیلد فرم، مهاجم دادههای مخرب را به فیلدهای فرم وارد میکند. این دادهها میتواند به تغییر رفتار برنامه، افشای اطلاعات، یا اجرای کدهای مخرب منجر شود.
مثال:
اگر فیلد فرم برای ارسال ایمیل از کد زیر استفاده کند:
<form action="/send-email" method="POST"> <input type="text" name="email" /> <input type="submit" /> </form>
اگر مهاجم مقدار فیلد email
را به صورت زیر وارد کند، کد جاوا اسکریپت اجرا خواهد شد:
malicious@example.com<script>alert('XSS')</script>
برای جلوگیری از انواع مختلف تزریق کد، اقدامات مشابه با موارد ذکر شده برای SQL Injection و XSS باید انجام شود:
این اقدامات میتواند به کاهش آسیبپذیریها و حفاظت از برنامهها در برابر انواع مختلف حملات تزریق کد کمک کند.
علاوه بر انواع ذکر شده، حملات تزریق کد میتوانند به صورتهای دیگری نیز پیادهسازی شوند. در ادامه، به برخی از انواع دیگر حملات تزریق کد اشاره میکنم:
چگونگی عمل:
در این حمله، مهاجم کدهای سیستمعامل را به ورودیهای برنامه وارد میکند. این کدها ممکن است توسط برنامه به سیستمعامل ارسال شوند و اجرای آنها میتواند به دسترسی غیرمجاز به سیستم یا اجرای دستورات مخرب منجر شود.
مثال:
اگر برنامهای از ورودی کاربر برای اجرای دستورات سیستمعامل استفاده کند، و مهاجم ورودی را به صورت ; ls -la
وارد کند، این دستور به همراه دستور اصلی اجرا شده و لیست فایلهای سیستم را نمایش میدهد.
چگونگی عمل:
در این حمله، مهاجم دادههای مخرب را به هدرهای HTTP وارد میکند. این دادهها ممکن است به ایجاد پاسخهای HTTP غیرمجاز یا تغییر رفتار مرورگر منجر شود.
مثال:
اگر برنامهای از ورودی کاربر برای تنظیم هدرهای HTTP استفاده کند و مهاجم ورودی را به صورت Set-Cookie: sessionId=malicious
وارد کند، ممکن است کوکیهای مخرب ایجاد شود که به حملات دیگر منجر میشود.
چگونگی عمل:
در این حمله، مهاجم دادههای YAML مخرب را به ورودیهای برنامه وارد میکند. این نوع حمله میتواند به تفسیر نادرست دادههای YAML و اجرای کدهای مخرب منجر شود.
مثال:
اگر برنامهای از YAML برای پیکربندی استفاده کند و مهاجم دادههای زیر را ارسال کند:
user: admin
password: !include /etc/passwd
ممکن است فایلهای سیستمی به دادههای YAML وارد شوند.
چگونگی عمل:
در این حمله، مهاجم به ورودیهای JSONP دادههای مخرب وارد میکند. این دادهها میتوانند به اجرای کدهای جاوا اسکریپت مخرب منجر شوند.
مثال:
اگر برنامهای از JSONP برای دریافت دادهها استفاده کند و مهاجم ورودی را به صورت زیر ارسال کند:
callbackFunction({"data": "<script>alert('XSS')</script>"});
کد جاوا اسکریپت ممکن است در مرورگر اجرا شود.
چگونگی عمل:
در این حمله، مهاجم دادههای مخرب را به موتورهای قالب (Template Engines) وارد میکند. این حمله میتواند به اجرای کدهای جاوا اسکریپت، PHP، یا سایر زبانهای برنامهنویسی که توسط موتور قالب پردازش میشود، منجر شود.
مثال:
اگر برنامهای از موتور قالب برای تولید صفحات وب استفاده کند و مهاجم ورودی را به صورت {{7*7}}
وارد کند، ممکن است خروجی آن به 49
تبدیل شود.
برای محافظت در برابر این نوع حملات، میتوانید از اقدامات زیر استفاده کنید:
این اقدامات میتواند به کاهش آسیبپذیریها و محافظت از سیستمها در برابر انواع مختلف حملات تزریق کد کمک کند.
هنوز انواع دیگری از حملات تزریق کد وجود دارد که ممکن است در برخی سناریوها و برنامهها به کار روند. در ادامه، به برخی از این موارد اشاره میکنم:
چگونگی عمل:
در حمله CRLF Injection، مهاجم کاراکترهای خاصی مانند \r\n
(Carriage Return Line Feed) را به ورودیها وارد میکند. این کار میتواند به تغییر هدرهای HTTP، ایجاد حملات HTTP Response Splitting یا دیگر انواع تزریق دادهها منجر شود.
مثال:
اگر برنامهای از ورودی کاربر برای تولید هدرهای HTTP استفاده کند و مهاجم ورودی را به صورت X-Header: value\r\nSet-Cookie: sessionId=malicious
وارد کند، ممکن است هدرهای HTTP به صورت غیرمجاز تغییر یابند.
چگونگی عمل:
در حمله تزریق XPath، مهاجم کدهای XPath را به ورودیهای برنامه وارد میکند. این کدها میتوانند به دسترسی غیرمجاز به دادههای XML یا تغییر آنها منجر شوند.
مثال:
اگر برنامهای از XPath برای جستجوی دادههای XML استفاده کند و مهاجم مقدار ورودی را به صورت admin' or '1'='1
وارد کند، پرس و جو میتواند به همه دادههای XML دسترسی پیدا کند.
چگونگی عمل:
در حمله RCE، مهاجم کدی را به سیستم هدف ارسال میکند که به طور از راه دور اجرا میشود. این کد میتواند هر چیزی از اجرای دستورات سیستمعامل تا اجرای برنامههای مخرب باشد.
مثال:
اگر برنامهای از ورودیهای کاربر برای اجرای اسکریپتها یا دستورات استفاده کند و مهاجم ورودیهای مخرب را ارسال کند، ممکن است کد مهاجم به طور از راه دور اجرا شود.
چگونگی عمل:
در حمله تزریق Object، مهاجم دادههای مخربی را به ورودیهای برنامه ارسال میکند که توسط سیستم به عنوان اشیاء (Objects) تفسیر میشود. این حمله میتواند به اجرای کدهای مخرب یا تغییر دادههای داخلی برنامه منجر شود.
مثال:
اگر برنامهای از دادههای سریالی (serialized) برای ذخیرهسازی استفاده کند و مهاجم دادههای سریالی مخرب ارسال کند، این دادهها ممکن است به اشیاء برنامه تبدیل شوند و به اجرای کد مخرب منجر شوند.
چگونگی عمل:
در حمله تزریق Template Engine، مهاجم دادههای مخرب را به قالبهای موتورهای قالب (Template Engines) ارسال میکند. این حمله میتواند به اجرای کدهای مخرب که توسط موتور قالب پردازش میشود، منجر شود.
مثال:
اگر برنامهای از موتور قالب برای تولید صفحات وب استفاده کند و مهاجم دادههایی مانند {{7*7}}
ارسال کند، ممکن است این دادهها به عنوان کد قابل اجرا تفسیر شود.
برای محافظت در برابر این نوع حملات، موارد زیر را در نظر داشته باشید:
این اقدامات میتواند به کاهش آسیبپذیریها و محافظت از برنامهها و سیستمها در برابر انواع مختلف حملات تزریق کد کمک کند.
علاوه بر انواع حملات تزریق کد ذکر شده، چند نوع دیگر از حملات نیز وجود دارد که ممکن است در برخی سیستمها یا سناریوها رخ دهد. در اینجا به برخی دیگر از این موارد اشاره میکنم:
چگونگی عمل:
در حمله تزریق Markdown، مهاجم کدهای Markdown مخرب را به ورودیهای برنامه ارسال میکند. این کدها ممکن است به تولید محتوای HTML یا سایر زبانهای توصیفی منجر شوند که میتواند منجر به اجرای کد مخرب در مرورگر شود.
مثال:
اگر برنامهای از Markdown برای پردازش ورودیهای کاربر استفاده کند و مهاجم ورودیهای زیر را ارسال کند:
[Link](javascript:alert('XSS'))
این لینک ممکن است در مرورگر کاربر به عنوان یک لینک فعال تبدیل شود و اجرای کد جاوا اسکریپت را ممکن کند.
چگونگی عمل:
در حمله تزریق XPath، مهاجم میتواند کدهای XPath را به ورودیهای برنامه ارسال کند. این حمله میتواند به دسترسی غیرمجاز به دادههای XML یا تغییر دادهها منجر شود.
مثال:
اگر برنامهای از XPath برای جستجو در دادههای XML استفاده کند و مهاجم ورودی زیر را ارسال کند:
' or '1'='1
این ورودی میتواند به جستجو در تمامی دادههای XML بدون محدودیت منجر شود.
چگونگی عمل:
در حمله تزریق YAML، مهاجم دادههای YAML مخرب را به ورودیهای برنامه ارسال میکند. این نوع حمله میتواند به آسیب به دادههای YAML، اجرای کدهای مخرب، یا بهینهسازی غیرمجاز منابع منجر شود.
مثال:
اگر برنامهای از YAML برای پیکربندی استفاده کند و مهاجم دادههای زیر را ارسال کند:
user: admin
password: !!python/object/apply:os.system ['rm -rf /']
مهاجم ممکن است به اجرای دستورات سیستمعامل دست یابد.
چگونگی عمل:
در حمله تزریق NoSQL، مهاجم دادههای مخرب را به ورودیهای NoSQL ارسال میکند. این حمله میتواند به تغییر پرسوجوهای NoSQL یا افشای دادههای حساس منجر شود.
مثال:
اگر برنامهای از MongoDB استفاده کند و مهاجم ورودی زیر را ارسال کند:
{"username": {"$ne": null}, "password": "password123"}
این پرس و جو میتواند به دسترسی به تمامی کاربران با رمز عبور معین منجر شود.
چگونگی عمل:
در حمله RFI و LFI، مهاجم میتواند فایلهای غیرمجاز را به برنامه وارد کند. RFI به بارگذاری فایلهای از راه دور و LFI به بارگذاری فایلهای محلی سیستم هدف منجر میشود.
مثال:
اگر برنامهای از ورودی کاربر برای بارگذاری فایلها استفاده کند و مهاجم URL زیر را ارسال کند:
http://malicious.com/malicious_file.php
این فایل ممکن است بر روی سیستم هدف بارگذاری و اجرا شود.
برای محافظت در برابر این نوع حملات، میتوانید اقدامات زیر را انجام دهید:
این اقدامات میتواند به کاهش آسیبپذیریها و حفاظت از برنامهها در برابر انواع مختلف حملات تزریق کد کمک کند.
OWASP (Open Web Application Security Project) مجموعهای از آسیبپذیریهای امنیتی وب است که به طور دورهای بهروزرسانی میشود. نسخههای اخیر OWASP Top 10 شامل آسیبپذیریهای زیر است. در ادامه، هر یک از این موارد را به تفصیل توضیح میدهم:
چگونگی عمل:
حملات تزریق، از جمله تزریق SQL، Command Injection، و XML Injection، زمانی رخ میدهند که دادههای ورودی مهاجم به طور مستقیم در درخواستهای سیستم وارد شوند. این دادههای مخرب میتوانند منجر به اجرای کدهای غیرمجاز یا افشای دادههای حساس شوند.
مثال:
در حمله تزریق SQL، مهاجم میتواند ورودیای مانند ' OR '1'='1
را وارد کند که به اجرای یک پرسوجوی SQL غیرمجاز منجر میشود.
پیشگیری:
- استفاده از پارامترهای آماده (Prepared Statements) و ORM
- اعتبارسنجی و تصفیه ورودیهای کاربر
- استفاده از اصول کمترین امتیاز
چگونگی عمل:
این آسیبپذیری زمانی رخ میدهد که سیستم احراز هویت ضعیف باشد و مهاجم بتواند به حسابهای کاربری دسترسی غیرمجاز پیدا کند. این ممکن است به دلیل ضعف در مدیریت رمزهای عبور، استفاده از توکنهای پیشبینیپذیر یا ضعف در مدیریت جلسهها باشد.
مثال:
رمزهای عبور ضعیف، توکنهای قابل پیشبینی یا عدم استفاده از چندمرحلهای (Two-Factor Authentication) میتواند به دسترسی غیرمجاز منجر شود.
پیشگیری:
- استفاده از رمزهای عبور قوی و رمزنگاری شده
- پیادهسازی احراز هویت دو مرحلهای (2FA)
- مدیریت صحیح جلسات کاربری
چگونگی عمل:
این آسیبپذیری زمانی رخ میدهد که دادههای حساس مانند اطلاعات کارت اعتباری، رمزهای عبور یا دادههای شخصی بدون محافظت مناسب ذخیره یا منتقل شوند. این میتواند به افشای دادههای حساس منجر شود.
مثال:
ذخیرهسازی رمزهای عبور به صورت متن ساده یا استفاده از پروتکلهای غیرامن برای انتقال دادهها.
پیشگیری:
- رمزنگاری دادههای حساس در حال انتقال و ذخیرهسازی
- استفاده از پروتکلهای امن مانند TLS
- پیادهسازی سیاستهای امنیتی برای محافظت از دادهها
چگونگی عمل:
این آسیبپذیری زمانی رخ میدهد که برنامههای پردازشکننده XML قادر به پردازش درخواستهای خارجی مانند فایلهای محلی یا منابع وب هستند، که میتواند به افشای دادهها یا حملات DoS منجر شود.
مثال:
استفاده از XML برای بارگذاری دادههای خارجی به طور ناامن که میتواند به افشای فایلهای سیستم یا حملات شبکه منجر شود.
پیشگیری:
- غیر فعال کردن پردازش خارجی در پردازش XML
- استفاده از پارامترهای امن و تستهای امنیتی
چگونگی عمل:
این آسیبپذیری زمانی رخ میدهد که کنترلهای دسترسی به درستی پیادهسازی نشدهاند و مهاجم میتواند به منابع یا عملیاتهایی که برای آنها مجاز نیست دسترسی پیدا کند.
مثال:
عدم بررسی مجوزها برای دسترسی به اطلاعات خصوصی کاربران دیگر یا تغییر دادهها.
پیشگیری:
- پیادهسازی کنترلهای دسترسی مناسب
- استفاده از سیاستهای امنیتی قوی
- تستهای امنیتی منظم
چگونگی عمل:
این آسیبپذیری زمانی رخ میدهد که تنظیمات امنیتی مناسب برای سیستمها، سرورها یا برنامهها اعمال نشود. این میتواند به نشت اطلاعات، حملات DoS یا سایر مشکلات امنیتی منجر شود.
مثال:
پیکربندی ضعیف در سرورهای وب، سیستمهای پایگاه داده یا استفاده از تنظیمات پیشفرض ناامن.
پیشگیری:
- استفاده از پیکربندیهای امن و به روز
- انجام ارزیابیهای امنیتی منظم
- حذف تنظیمات پیشفرض و دسترسیهای غیرضروری
چگونگی عمل:
حملات XSS زمانی رخ میدهند که مهاجم کد جاوا اسکریپت مخرب را به صفحات وب وارد کند و این کد به مرورگر کاربران دیگر ارسال شود. این حملات میتوانند به سرقت اطلاعات جلسات یا اجرای کدهای دلخواه منجر شوند.
مثال:
مهاجم میتواند کد جاوا اسکریپت را در فیلدهای ورودی وب سایت وارد کند که به سرقت کوکیها یا تغییر محتوای صفحه منجر میشود.
پیشگیری:
- استفاده از اعتبارسنجی و تصفیه ورودیها
- استفاده از مکانیزمهای امنیتی مانند CSP (Content Security Policy)
- استفاده از escaping مناسب برای نمایش دادهها
چگونگی عمل:
این آسیبپذیری زمانی رخ میدهد که برنامهها دادههای سریالی شده (serialized) را از منابع غیرمعتبر پردازش کنند. این میتواند به اجرای کدهای غیرمجاز یا تغییر رفتار برنامه منجر شود.
مثال:
اگر برنامهای دادههای سریالی شده غیرمعتبر را بارگذاری کند، مهاجم میتواند دادههای مخرب را وارد کند که به اجرای کد دلخواه منجر میشود.
پیشگیری:
- اعتبارسنجی دادههای سریالی شده
- استفاده از روشهای امن برای پردازش دادهها
- پیادهسازی سیاستهای امنیتی برای کنترل دادههای ورودی
چگونگی عمل:
این آسیبپذیری زمانی رخ میدهد که برنامهها از کامپوننتهای نرمافزاری با آسیبپذیریهای شناخته شده استفاده کنند. این میتواند به بهرهبرداری از آسیبپذیریها و نفوذ به سیستمها منجر شود.
مثال:
استفاده از نسخههای قدیمی کتابخانهها یا فریمورکها که آسیبپذیریهای شناخته شده دارند.
پیشگیری:
- بهروز نگهداشتن کامپوننتها و کتابخانهها
- نظارت بر آسیبپذیریهای شناخته شده و اصلاح به موقع
- استفاده از ابزارهای امنیتی برای بررسی آسیبپذیریهای کامپوننتها
چگونگی عمل:
این آسیبپذیری زمانی رخ میدهد که سیستمها به درستی فعالیتهای غیرعادی یا سوءاستفادهها را لاگ نکرده و نظارت نکنند. این میتواند به شناسایی دیرهنگام حملات و عدم واکنش مناسب منجر شود.
مثال:
عدم ثبت لاگ از فعالیتهای مشکوک یا عدم نظارت بر لاگها برای شناسایی حملات ممکن.
پیشگیری:
- پیادهسازی لاگگذاری و نظارت مناسب
- تحلیل منظم لاگها برای شناسایی حملات
- پاسخ به حوادث و نظارت بر فعالیتهای مشکوک
برای شبیهسازی و یادگیری حملات OWASP، معمولاً از محیطهای آزمایشگاهی و ابزارهای مخصوص استفاده میشود. در اینجا، توضیحاتی همراه با نمونه کدهای مربوط به هر آسیبپذیری OWASP Top 10 ارائه میشود. توجه داشته باشید که اجرای این کدها باید فقط در محیطهای آزمایشگاهی و برای اهداف آموزشی باشد.
شبیهسازی حمله تزریق SQL:
فرض کنید برنامهای دارید که ورودیهای کاربر را مستقیماً در یک پرسوجوی SQL قرار میدهد.
کد آسیبپذیر (Python + SQLite):
import sqlite3
def search_user(username):
conn = sqlite3.connect('test.db')
cursor = conn.cursor()
query = f"SELECT * FROM users WHERE username = '{username}'"
cursor.execute(query)
results = cursor.fetchall()
conn.close()
return results
# ورودی کاربر
username = "' OR '1'='1"
print(search_user(username))
توضیح: در این کد، ورودی کاربر مستقیماً به پرسوجوی SQL اضافه میشود. با استفاده از ورودی ' OR '1'='1
، مهاجم میتواند تمام رکوردهای جدول را به دست آورد.
پیشگیری: استفاده از پارامترهای آماده:
def search_user(username):
conn = sqlite3.connect('test.db')
cursor = conn.cursor()
query = "SELECT * FROM users WHERE username = ?"
cursor.execute(query, (username,))
results = cursor.fetchall()
conn.close()
return results
شبیهسازی آسیبپذیری احراز هویت ضعیف:
فرض کنید برنامهای دارید که رمزهای عبور را به صورت متن ساده مقایسه میکند.
کد آسیبپذیر (Python):
def authenticate(username, password):
stored_password = 'password123' # رمز عبور ذخیره شده
if password == stored_password:
return "Authenticated"
else:
return "Authentication Failed"
# ورودی کاربر
print(authenticate('user', 'password123'))
توضیح: در این کد، رمز عبور به صورت متن ساده مقایسه میشود، که منجر به ضعف امنیتی میشود.
پیشگیری: استفاده از هش رمز عبور و فریمورکهای احراز هویت امن:
import hashlib
def authenticate(username, password):
stored_password_hash = hashlib.sha256('password123'.encode()).hexdigest()
input_password_hash = hashlib.sha256(password.encode()).hexdigest()
if input_password_hash == stored_password_hash:
return "Authenticated"
else:
return "Authentication Failed"
شبیهسازی ذخیرهسازی رمز عبور به صورت متن ساده:
کد آسیبپذیر (Python):
def store_password(password):
with open('password.txt', 'w') as file:
file.write(password)
# ذخیرهسازی رمز عبور
store_password('password123')
توضیح: در این کد، رمز عبور به صورت متن ساده در فایل ذخیره میشود.
پیشگیری: استفاده از رمزنگاری برای ذخیرهسازی رمز عبور:
from cryptography.fernet import Fernet
key = Fernet.generate_key()
cipher_suite = Fernet(key)
def store_password(password):
encrypted_password = cipher_suite.encrypt(password.encode())
with open('password.enc', 'wb') as file:
file.write(encrypted_password)
# ذخیرهسازی رمز عبور
store_password('password123')
شبیهسازی حمله XXE:
کد آسیبپذیر (Python + lxml):
from lxml import etree
def parse_xml(xml_data):
parser = etree.XMLParser(resolve_entities=True)
tree = etree.fromstring(xml_data, parser)
return tree
xml_data = """<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]<
<foo>&xxe;</foo>"""
print(parse_xml(xml_data))
توضیح: در این کد، XML به طور غیرامن پردازش میشود و ممکن است به افشای فایلهای سیستم منجر شود.
پیشگیری: غیرفعال کردن پردازش خارجی:
def parse_xml(xml_data):
parser = etree.XMLParser(resolve_entities=False)
tree = etree.fromstring(xml_data, parser)
return tree
شبیهسازی کنترل دسترسی ضعیف:
کد آسیبپذیر (Python):
def get_user_info(user_id):
# فرض کنید تمام کاربران به اطلاعات دیگر کاربران دسترسی دارند
user_info = {'1': 'Alice', '2': 'Bob'}
return user_info.get(user_id, 'User not found')
# ورودی کاربر
print(get_user_info('2')) # Bob
توضیح: در این کد، هیچ بررسی برای دسترسی به اطلاعات کاربران دیگر وجود ندارد.
پیشگیری: اعمال کنترلهای دسترسی مناسب:
def get_user_info(user_id, current_user_id):
if user_id != current_user_id:
return 'Access Denied'
user_info = {'1': 'Alice', '2': 'Bob'}
return user_info.get(user_id, 'User not found')
شبیهسازی پیکربندی ناامن:
کد آسیبپذیر (Python):
import os
def list_files():
files = os.listdir('/')
return files
print(list_files()) # نمایش تمام فایلهای سیستم
توضیح: در این کد، پیکربندی امنی برای محدود کردن دسترسی به فایلها وجود ندارد.
پیشگیری: محدود کردن دسترسی به فایلها و منابع:
def list_files(directory):
allowed_dirs = ['/home/user']
if directory not in allowed_dirs:
return 'Access Denied'
files = os.listdir(directory)
return files
شبیهسازی حمله XSS:
کد آسیبپذیر (JavaScript):
<html>
<body>
<form action="" method="get">
Enter your name: <input type="text" name="name">
<input type="submit">
</form>
<div>
Hello, <script>document.write(location.search.split('name=')[1])</script>
</div>
</body>
</html>
توضیح: در این کد، ورودی کاربر بدون فیلتر شدن به HTML اضافه میشود و ممکن است به اجرای کدهای مخرب منجر شود.
پیشگیری: استفاده از فیلتر کردن و محافظت در برابر XSS:
<html>
<body>
<form action="" method="get">
Enter your name: <input type="text" name="name">
<input type="submit">
</form>
<div>
Hello, <span id="greeting"></span>
</div>
<script>
document.getElementById('greeting').textContent = new URLSearchParams(window.location.search).get('name');
</script>
</body>
</html>
شبیهسازی دسیریالسازی ناامن:
کد آسیبپذیر (Python):
import pickle
def deserialize_data(serialized_data):
return pickle.loads(serialized_data)
data = pickle.dumps({'key': 'value'})
print(deserialize_data(data))
توضیح: در این کد، دادههای دسیریالسازی شده به صورت مستقیم بارگذاری میشوند که میتواند به اجرای کدهای مخرب منجر شود.
پیشگیری: محدود کردن دادههای دسیریالسازی شده و استفاده از روشهای امنتر:
import json
def deserialize_data(serialized_data):
return json.loads(serialized_data)
data = json.dumps({'key': 'value'})
print(deserialize_data(data))
شبیهسازی استفاده از کامپوننتهای آسیبپذیر:
توضیح: استفاده از کتابخانههای آسیبپذیر بدون بهروزرسانی مناسب ممکن است خطرناک باشد.
پیشگیری: استفاده از ابزارهای بررسی آسیبپذیری و بهروزرسانی مداوم کامپوننتها.
شبیهسازی فقدان ثبت و نظارت کافی:
کد آسیبپذیر (Python):
def process_request(request):
# هیچ ثبت یا نظارت روی درخواستها وجود ندارد
pass
توضیح: در این کد، هیچ ثبت یا نظارتی روی درخواستهای ورودی وجود ندارد که میتواند به عدم شناسایی حملات منجر شود.
پیشگیری: اضافه کردن ثبت و نظارت مناسب:
import logging
logging.basicConfig(filename='app.log', level=logging.INFO)
def process_request(request):
logging.info(f'Request received: {request}')
# پردازش درخواست
pass
این مقاله فقط برای اهداف آموزشی و تحقیقاتی ارائه شده است و استفاده از آن باید در محیطهای آزمایشگاهی و به صورت مسئولانه انجام شود.
در اینجا به شبیهسازی حملات OWASP Top 10 در Node.js، React.js، PHP و SQL پرداخته میشود. هر مثال نشاندهنده آسیبپذیریهای خاصی است و روشهای پیشگیری برای هر کدام ارائه شده است.
کد آسیبپذیر:
const mysql = require('mysql');
const express = require('express');
const app = express();
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'test'
});
app.get('/search', (req, res) => {
const query = `SELECT * FROM users WHERE username = '${req.query.username}'`;
connection.query(query, (error, results) => {
if (error) throw error;
res.json(results);
});
});
app.listen(3000);
توضیح: در این کد، ورودی کاربر مستقیماً به پرسوجوی SQL اضافه میشود، که میتواند منجر به حمله SQL Injection شود.
پیشگیری:
app.get('/search', (req, res) => {
const query = 'SELECT * FROM users WHERE username = ?';
connection.query(query, [req.query.username], (error, results) => {
if (error) throw error;
res.json(results);
});
});
کد آسیبپذیر:
import React from 'react';
function App() {
const params = new URLSearchParams(window.location.search);
const name = params.get('name');
return (
<h2>Hello {name}</h2>
);
}
export default App;
توضیح: در این کد، دادههای ورودی به صورت مستقیم در JSX قرار میگیرد و ممکن است به اجرای کد جاوا اسکریپت منجر شود.
پیشگیری:
import React from 'react';
import sanitizeHtml from 'sanitize-html';
function App() {
const params = new URLSearchParams(window.location.search);
const name = sanitizeHtml(params.get('name'));
return (
<h2>Hello {name}</h2>
);
}
export default App;
کد آسیبپذیر:
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$username = $_GET['username'];
$query = "SELECT * FROM users WHERE username = '$username'";
$stmt = $pdo->query($query);
$results = $stmt->fetchAll();
print_r($results);
?>
توضیح: در این کد، ورودی کاربر مستقیماً در پرسوجوی SQL استفاده میشود و میتواند به حمله SQL Injection منجر شود.
پیشگیری:
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$username = $_GET['username'];
$query = "SELECT * FROM users WHERE username = :username";
$stmt = $pdo->prepare($query);
$stmt->bindParam(':username', $username);
$stmt->execute();
$results = $stmt->fetchAll();
print_r($results);
?>
کد آسیبپذیر:
SELECT * FROM users WHERE username = 'admin' OR '1'='1';
توضیح: این پرسوجو به دلیل استفاده از ورودی غیرمطمئن، میتواند تمام رکوردها را بازگرداند.
پیشگیری:
SELECT * FROM users WHERE username = ?;
کد آسیبپذیر:
const express = require('express');
const session = require('express-session');
const app = express();
app.use(session({
secret: 'secret',
resave: true,
saveUninitialized: true
}));
app.post('/login', (req, res) => {
req.session.user = req.body.username;
res.send('Logged in');
});
app.listen(3000);
توضیح: در این کد، مدیریت جلسه به صورت غیرامن پیادهسازی شده است.
پیشگیری:
app.use(session({
secret: 'secret',
resave: false,
saveUninitialized: false,
cookie: { secure: true, httpOnly: true }
}));
کد آسیبپذیر:
<?php
$password = $_POST['password'];
$stored_password = 'password123'; // رمز عبور ذخیره شده به صورت متن ساده
if ($password === $stored_password) {
echo 'Authenticated';
} else {
echo 'Authentication Failed';
}
?>
توضیح: رمز عبور به صورت متن ساده مقایسه میشود.
پیشگیری:
<?php
$password = $_POST['password'];
$stored_password_hash = password_hash('password123', PASSWORD_BCRYPT);
if (password_verify($password, $stored_password_hash)) {
echo 'Authenticated';
} else {
echo 'Authentication Failed';
}
?>
کد آسیبپذیر:
const fs = require('fs');
function storePassword(password) {
fs.writeFileSync('password.txt', password);
}
storePassword('password123');
توضیح: رمز عبور به صورت متن ساده در فایل ذخیره میشود.
پیشگیری:
const crypto = require('crypto');
const fs = require('fs');
function storePassword(password) {
const cipher = crypto.createCipher('aes-256-cbc', 'password');
let encrypted = cipher.update(password, 'utf8', 'hex');
encrypted += cipher.final('hex');
fs.writeFileSync('password.enc', encrypted);
}
کد آسیبپذیر:
<?php
$password = $_POST['password'];
file_put_contents('password.txt', $password);
?>
توضیح: رمز عبور به صورت متن ساده ذخیره میشود.
پیشگیری:
<?php
$password = $_POST['password'];
$encrypted_password = password_hash($password, PASSWORD_BCRYPT);
file_put_contents('password.enc', $encrypted_password);
?>
کد آسیبپذیر:
const xml2js = require('xml2js');
const fs = require('fs');
fs.readFile('input.xml', (err, data) => {
if (err) throw err;
xml2js.parseString(data, (err, result) => {
if (err) throw err;
console.log(result);
});
});
توضیح: فایل XML بدون پیکربندی مناسب تجزیه میشود و میتواند منجر به حمله XXE شود.
پیشگیری:
const xml2js = require('xml2js');
const fs = require('fs');
const parser = new xml2js.Parser({
xmlns: true,
explicitArray: false,
explicitRoot: false,
preserveChildrenOrder: true,
normalizeTags: true,
tagNameProcessors: [xml2js.processors.firstCharLowerCase],
valueProcessors: [xml2js.processors.stripPrefix]
});
fs.readFile('input.xml', (err, data) => {
if (err) throw err;
parser.parseString(data, (err, result) => {
if (err) throw err;
console.log(result);
});
});
کد آسیبپذیر:
<?php
$xml = simplexml_load_file('input.xml');
print_r($xml);
?>
توضیح: فایل XML بدون پیکربندی مناسب بارگذاری میشود و ممکن است به حمله XXE منجر شود.
پیشگیری:
<?php
libxml_disable_entity_loader(true);
$xml = simplexml_load_file('input.xml');
print_r($xml);
?>
کد آسیبپذیر:
const express = require('express');
const app = express();
app.get('/admin', (req, res) => {
res.send('Admin Page');
});
app.listen(3000);
توضیح: دسترسی به صفحه مدیریت بدون بررسیهای لازم انجام میشود.
پیشگیری:
app.get('/admin', (req, res) => {
if (req.user && req.user.role === 'admin') {
res.send('Admin Page');
} else {
res.status(403).send('Forbidden');
}
});
کد آسیبپذیر:
<?php
if ($_SESSION['role'] === 'admin') {
echo 'Admin Page';
} else {
echo 'Access Denied';
}
?>
توضیح: دسترسی به صفحه مدیریت بر اساس وضعیت نشست انجام میشود بدون بررسیهای دقیقتر.
پیشگیری:
<?php
session_start();
if (isset($_SESSION['user']) && $_SESSION['user']['role'] === 'admin') {
echo 'Admin Page';
} else {
header('HTTP/1.0 403 Forbidden');
echo 'Access Denied';
}
?>
با پیادهسازی روشهای پیشگیری مناسب، میتوان خطرات ناشی از آسیبپذیریهای OWASP Top 10 را کاهش داد و امنیت برنامهها را بهبود بخشید.
علاوه بر OWASP Top 10، چندین مسئله امنیتی دیگر نیز وجود دارد که مهم است با آنها آشنا شوید. در اینجا به برخی از موارد الزامی دیگر میپردازیم:
توضیح: حملات CSRF زمانی اتفاق میافتند که مهاجم کاربر را مجبور میکند درخواستهایی به سرور ارسال کند که در آنها کاربر اعتبارسنجی شده است.
پیشگیری:
const csrf = require('csurf');
const cookieParser = require('cookie-parser');
app.use(cookieParser());
app.use(csrf({ cookie: true }));
app.get('/form', (req, res) => {
res.render('form', { csrfToken: req.csrfToken() });
});
app.post('/submit', (req, res) => {
// Handle form submission
});
session_start();
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
$csrf_token = $_SESSION['csrf_token'];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!hash_equals($csrf_token, $_POST['csrf_token'])) {
die('Invalid CSRF token');
}
}
توضیح: Clickjacking به مهاجم این امکان را میدهد که کاربران را فریب دهد تا روی عناصر پنهان شده در صفحه وب کلیک کنند.
پیشگیری:
X-Frame-Options
برای جلوگیری از بارگذاری سایت شما در iframeهای خارجی استفاده کنید.
const helmet = require('helmet');
app.use(helmet.frameguard());
header('X-Frame-Options: DENY');
توضیح: IDOR زمانی رخ میدهد که مهاجم بتواند به منابعی دسترسی پیدا کند که به آنها اجازه داده نشده است، با تغییر پارامترهای URL.
پیشگیری:
app.get('/profile/:userId', (req, res) => {
const userId = req.params.userId;
if (req.session.userId !== userId) {
return res.status(403).send('Access Denied');
}
res.send(`Profile of user ${userId}`);
});
session_start();
$userId = $_GET['userId'];
if ($_SESSION['userId'] !== $userId) {
die('Access Denied');
}
echo "Profile of user $userId";
توضیح: عدم استفاده از روشهای امنیتی مناسب میتواند به آسیبپذیریهای مختلف منجر شود.
پیشگیری:
const crypto = require('crypto');
const algorithm = 'aes-256-cbc';
const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);
function encrypt(text) {
let cipher = crypto.createCipheriv(algorithm, Buffer.from(key), iv);
let encrypted = cipher.update(text);
encrypted = Buffer.concat([encrypted, cipher.final()]);
return { iv: iv.toString('hex'), encryptedData: encrypted.toString('hex') };
}
$key = 'your-secret-key';
$iv = random_bytes(openssl_cipher_iv_length('aes-256-cbc'));
$ciphertext = openssl_encrypt('data', 'aes-256-cbc', $key, 0, $iv);
توضیح: حملات DoS به منظور ایجاد بار زیاد بر روی سرور و عدم دسترسی به خدمات انجام میشوند.
پیشگیری:
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
});
app.use(limiter);
استفاده از ابزارهایی مانند Fail2Ban یا تنظیمات خاص سرور.
توضیح: پیکربندی اشتباه سیستم میتواند منجر به آسیبپذیریهای امنیتی شود.
پیشگیری:
const helmet = require('helmet');
app.use(helmet());
استفاده از فایلهای پیکربندی امن و بهروز.
توضیح: امنیت API شامل محافظت در برابر حملات مانند انکار دسترسی و اطلاعات حساس است.
پیشگیری:
app.use('/api', (req, res, next) => {
if (!req.headers.authorization) {
return res.status(401).send('Unauthorized');
}
next();
});
if (!isset($_SERVER['HTTP_AUTHORIZATION'])) {
http_response_code(401);
exit('Unauthorized');
}