API testing
زمان مطالعه :1 دقیقه
Server-side parameter pollution &...
Server-side parameter pollution
https://portswigger.net/web-security/api-testing/server-side-parameter-pollution
بعضی سیستمها دارای API های داخلی هستند که به طور مستقیم از اینترنت قابل دسترسی نیستند. Server-side parameter pollution در زمانی رخ میدهد که یک وبسایت ورودی کاربر را در یک server-side request به یک internal APIجاسازی میکند (embeds) بدون رمزگذاری کافی. این به این معناست که یک attacker ممکن است توانایی manipulate یا inject parameters را داشته باشد، که به عنوان مثال:
· parameterهای موجود را نادیده بگیرد.
· رفتار برنامه را تغییر دهد.
· به دادههای غیرمجاز دسترسی پیدا کند.
شما میتوانید هر نوع parameter pollution (آلودگی پارامتر) را با هر نوع ورودی کاربر تست کنید. به عنوان مثال، query parameters، form fields، headers و URL path parameters همگی ممکن است اسیبپذیر باشند.
Note
این آسیبپذیری گاهی به عنوان HTTP parameter pollution شناخته میشود. با این حال، این اصطلاح همچنین برای اشاره به یک تکنیک دور زدن دیواره آتش وب (WAF) نیز استفاده میشود. به منظور جلوگیری از ابهام، در این موضوع فقط به server-side parameter pollution اشاره خواهیم کرد.
علاوه بر این، با وجود نام مشابه، این دسته آسیبپذیری کمترین ارتباطی با server-side prototype pollution دارد.
Testing for server-side parameter pollution in the query string
برای تست server-side parameter pollution در query string، query syntax characters مانند #، & و = را در ورودی خود قرار دهید و مشاهده کنید که برنامه چگونه پاسخ میدهد.
به عنوان یک برنامه آسیبپذیر، میتوانید در یک برنامه که به شما امکان جستجوی کاربران بر اساس نام کاربری آنها را میدهد، جستجو کنید. هنگامی که شما برای یک کاربر جستجو میکنید، مرورگر شما درخواست زیر را ارسال میکند:
GET /userSearch?name=
peter&back=/home
برای دریافت اطلاعات کاربر، سرور با درخواست زیر به یک API داخلی پرسوجو میکند:
GET /users/search?name=
peter&publicProfile=true
Truncating query strings
شما میتوانید از کاراکتر # کد شده به صورت URL برای تلاش در قطع درخواست سمت سرور استفاده کنید. همچنین، برای تفسیر پاسخ، میتوانید یک string پس از کاراکتر # اضافه کنید.
به عنوان مثال، میتوانید query string را به شکل زیر تغییر دهید:
GET /userSearch?name=
peter%23foo&back=/home
front-end سعی خواهد کرد به URL زیر دسترسی پیدا کند:
GET /users/search?name=peter#foo&publicProfile=true
Note
ضروری است که URL کاراکتر # را رمزگذاری کنید. در غیر این صورت برنامه front-end آن را به عنوان یک fragment identifier تفسیر می کند و به API داخلی منتقل نمی شود.
response را برای نشانههایی در مورد اینکه آیا query قطع شده است یا خیر، مورد بررسی قرار دهید. به عنوان مثال، اگر پاسخ نام کاربر peter را برگرداند، ممکن است query سمت سرور قطع شده باشد. اگر پیام خطای Invalid name برگردانده شود، این نشان میدهد که برنامه foo را به عنوان بخشی از نام کاربری در نظر گرفته است. این نشان میدهد که server-side request ممکن است قطع نشده باشد.
اگر توانایی قطع server-side request را دارید، این باعث حذف نیاز به تنظیم publicProfile به مقدار true میشود. ممکن است بتوانید از این ویژگی برای بازگرداندن پروفایلهای کاربری غیرعمومی استفاده کنید.
Injecting invalid parameters
میتوانید از کاراکتر & که به صورت URL-encoded شده است، برای افزودن parameter دوم به server-side request استفاده کنید.
به عنوان مثال، میتوانید query string را به شکل زیر تغییر دهید:
GET /userSearch?name=
peter%26foo=xyz&back=/home
این باعث میشود که server-side request به API داخلی به شکل زیر ارسال شود:
GET /users/search?name=
peter&foo=xyz&publicProfile=true
response را برای نشانههایی در مورد نحوه تجزیه و تحلیل پparameter اضافی بررسی کنید. به عنوان مثال، اگر response بدون تغییر باقی بماند، این ممکن است نشان دهد که parameter با موفقیت تزریق شده است (injected) اما توسط برنامه نادیده گرفته شده است.
برای ساخت تصویر کاملتر، نیاز به آزمایشهای بیشتری دارید.
Injecting valid parameters
اگر توانایی تغییر query string را دارید، میتوانید سعی کنید valid parameter دوم را به server-side request اضافه کنید.
Related pages
برای اطلاعات در مورد نحوه شناسایی parameters که می توانید به query string تزریق کنید، به بخش Finding hidden Parameters مراجعه کنید.
به عنوان مثال، اگر email parameter را شناسایی کردهاید، میتوانید آن را به query string به صورت زیر اضافه کنید:
GET /userSearch?name=
peter%26email=foo&back=/home
این باعث server-side request به API داخلی به شکل زیر میشود:
GET /userSearch?name=
peter%26email=foo&back=/home
پاسخ را برای نشانههایی در مورد نحوه تجزیه additional parameter بررسی کنید.
Overriding existing parameters
برای تأیید اینکه برنامه آیا به server-side parameter pollution دچار شده است یا خیر، میتوانید تلاش کنید تا parameter اصلی را با parameter دومی با همان نام جایگزین کنید.
به عنوان مثال، میتوانید query string را به شکل زیر تغییر دهید:
GET /userSearch?name=
peter%26name=carlos&back=/home
این باعث ایجاد server-side request به API داخلی میشود:
GET/users/search?name=
peter&name=carlos&publicProfile=true
API داخلی دو name parameters را تفسیر میکند. تأثیر این امر به نحوی که برنامه parameters دوم را پردازش میکند، متغیر است و در تکنولوژیهای مختلف وب متفاوت است. به عنوان مثال:
· PHP فقط آخرین parameter را تجزیه و تحلیل میکند. این باعث جستجوی کاربر برای carlos میشود.
· ASP.NET هر دو parameter را ترکیب میکند. این باعث جستجوی کاربر برای peter,carlos میشود که ممکن است منجر به پیام خطای Invalid username شود.
· Node.js / express فقط parameter اول را تجزیه و تحلیل میکند. این باعث جستجوی کاربر برای peter میشود و نتیجهای تغییر نمیکند.
اگر توانستید parameter اصلی را جایگزین کنید، ممکن است بتوانید از آن به عنوان یک آسیبپذیری بهرهبرداری کنید. به عنوان مثال، میتوانید name=administrator را به درخواست اضافه کنید. این ممکن است به شما اجازه دهد به عنوان کاربر مدیر وارد شوید.
Testing for server-side parameter pollution in REST paths
یک API RESTful ممکن است نامها و مقادیر parameter را در URL path قرار دهد، به جای query string. به عنوان مثال، مسیر زیر را در نظر بگیرید:
/api/users/123
مسیر URL ممکن است به شکل زیر تجزیه شود:
· /api نقطه پایانی اصلی API است.
· /users یک منبع را نمایان میکند، در این مورد users.
· /123 یک parameter است، در اینجا شناسه کاربر خاص را نمایان میکند.
یک برنامه کاربر را قادر میسازد تا پروفایلهای کاربری را بر اساس نام کاربری آنها ویرایش کند. درخواستها به نقطه پایانی زیر ارسال میشوند:
GET /edit_profile.php?name=peter
این منجر به server-side request زیر میشود:
GET /api/private/users/peteR
یک attacker ممکن است توانایی داشته باشد که server-side URL path parameters را تغییر دهد تا API را بهرهبرداری کند. برای آزمایش این آسیبپذیری، path traversal sequences را اضافه کنید تا parameters را تغییر دهید و ببینید که برنامه چگونه پاسخ میدهد..
میتوانید URL-encoded - کد شده peter/../admin را به عنوان مقدار پارامتر name ارسال کنید:
GET /edit_profile.php?name=peter%2f..%2fadmin
این ممکن است منجر به server-side request زیر شود:
GET /api/private/users/peter/../admin
اگر server-side client یا back-end API این مسیر را نرمالسازی کند، ممکن است به /api/private/users/admin حل شود
Testing for server-side parameter pollution in structured data formats
یک attacker ممکن است بتواند parameters را برای exploit از آسیبپذیریها در پردازش سرور از سایر فرمتهای structured data ، مانند JSON یا XML دستکاری کند.
یک برنامه را در نظر بگیرید که به کاربران اجازه میدهد پروفایل خود را ویرایش کنند و سپس تغییرات خود را با درخواستی به server-side API اعمال کنند. وقتی نام خود را ویرایش میکنید، مرورگر شما درخواست زیر را ارسال میکند:
POST /myaccount
name=peter
این منجر به server-side request زیر میشود:
PATCH /users/7312/update
{"name":"peter"}
میتوانید تلاش کنید تا access_level parameter را به request اضافه کنید:
POST /myaccount
name=peter","access_level":"administrator
اگر ورودی کاربر به داده server-side JSON بدون اعتبارسنجی (validation) یا sanitization کافی اضافه شود، این منجر به server-side request زیر میشود:
PATCH /users/7312/update
{name="peter","access_level":"administrator"}
این ممکن است منجر به دسترسی مدیریتی کاربر peter شود.
Related pages
برای اطلاعات در مورد نحوه شناسایی parameters که می توانید به query string تزریق کنید، به بخش Finding hidden Parameters مراجعه کنید.
مثال مشابهی را در نظر بگیرید، اما در آن ورودی client-side user در دادههای JSON قرار دارد. وقتی نام خود را ویرایش میکنید، مرورگر شما درخواست زیر را ارسال میکند:
POST /myaccount
{"name": "peter"}
این منجر به server-side request زیر میشود:
PATCH /users/7312/update
{"name":"peter"}
میتوانید تلاش کنید تا پارامتر access_level را به request اضافه کنید:
POST /myaccount
{"name": "peter\",\"access_level\":\"administrator"}
اگر ورودی کاربر بدون رمزگذاری مناسب به دادههای server-side JSON اضافه شود، این منجر به server-side request زیر میشود:
PATCH /users/7312/update
{"name":"peter","access_level":"administrator"}
دوباره، این ممکن است منجر به دسترسی مدیریتی کاربر peter شود.
Structured format injection همچنین ممکن است در esponses رخ دهد. به عنوان مثال، این ممکن است در صورتی رخ دهد که ورودی کاربر به طور ایمن در پایگاه داده ذخیره شده و سپس به پاسخ JSON از back-end API بدون رمزگذاری مناسب تعبیه شود(embedded). معمولاً میتوانید structured format injection را در responses به همان روشی که در requests انجام میدهید، تشخیص دهید و بهرهبرداری کنید.
Note
این مثال زیر در JSON است، اما server-side parameter pollution میتواند در هر قالب داده ساختاریافته رخ دهد. برای مثال در XML، بخش XInclude attacks را در مبحث تزریق XML external entity (XXE) ببینید.
Testing with automated tools
Burp شامل ابزارهای خودکار است که به شما در تشخیص server-side parameter pollution vulnerabilities کمک میکند.
Burp Scanner به طور خودکار تبدیلات ورودی مشکوک را در هنگام انجام حسابرسی تشخیص میدهد. این تبدیلات زمانی رخ میدهند که یک برنامه ورودی کاربر را دریافت کرده، آن را به یک شکلی تغییر میدهد و سپس پردازشهای بیشتری روی نتیجه انجام میدهد. این رفتار به طور لزوم آسیبپذیری را تشکیل نمیدهد، بنابراین برای تستهای بیشتر از تکنیکهای دستی مشخص شده در بالا استفاده خواهید کرد. برای کسب اطلاعات بیشتر، تعریف مسئله Suspicious input transformation را مشاهده کنید.
شما همچنین میتوانید از افزونه Backslash Powered Scanner BApp برای شناسایی server-side injection vulnerabilities استفاده کنید. این scanner ورودیها را به عنوان boring ، interesting یا vulnerable دستهبندی میکند. شما باید ورودیهای interesting را با استفاده از تکنیکهای دستی مشخصشده در بالا بررسی کنید. برای کسب اطلاعات بیشتر، به مقاله Backslash Powered Scanning: hunting unknown vulnerability classes مراجعه کنید.
Preventing server-side parameter pollution
برای جلوگیری از server-side parameter ، از لیست سفید (allowlist) برای تعریف کاراکترهایی که نیاز به رمزگذاری ندارند، استفاده کنید و مطمئن شوید که تمام ورودیهای کاربر دیگر قبل از اضافه شدن به server-side request رمزگذاری شدهاند. همچنین باید مطمئن شوید که تمام ورودیها با فرمت و ساختار مورد انتظار تطابق دارند.
امیر رضا کبریادار
مشاهده مقاله های بیشتر