Content-Type و Accept — إزاي المتصفح والسيرفر بيتفقوا على “شكل” البيانات
ليه محتاجين الهيدرز دول؟
تخيل إنك بتبعت طرد بالبريد. مش كفاية إنك تكتب العنوان بس (زي الـ URL)، لازم كمان تكتب على الطرد “المحتوى: زجاج، تعامل بحذر” عشان اللي هيستلمه يعرف يتعامل معاه إزاي. في عالم الـ HTTP، الهيدرز اللي بتعمل الوظيفة دي هي Content-Type وAccept.
Content-Type — إيه شكل البيانات اللي بتتبعت؟
هيدر بيُستخدم في الـ Request أو الـ Response عشان يحدد نوع البيانات الموجودة في الـ Body.
| Content-Type | المعنى |
|---|---|
text/html |
ملف HTML |
application/json |
بيانات JSON |
application/x-www-form-urlencoded |
بيانات فورم تقليدية (POST من HTML form عادي) |
multipart/form-data |
بيانات فيها ملفات (رفع ملفات) |
text/plain |
نص عادي غير منسق |
application/xml |
ملف XML |
POST /api/login HTTP/1.1
Host: example.com
Content-Type: application/json
{
"username": "islam",
"password": "123"
}
Accept — إيه شكل الرد اللي بتفضّله؟
هيدر بيُستخدم في الـ Request فقط عشان يحدد نوع البيانات اللي العميل (المتصفح أو أداة زي Postman) يتقبلها في الرد.
| Accept value | المعنى |
|---|---|
text/html |
يقبل ملفات HTML |
application/json |
يفضّل الردود بصيغة JSON |
*/* |
يقبل أي نوع من البيانات |
image/png,image/jpeg |
يفضّل الصور من نوع PNG أو JPG |
GET /api/data HTTP/1.1
Host: example.com
Accept: application/json
السيرفر هنا يُفضّل الرد بصيغة JSON، لكن مش ملزَم دايمًا — بعض السيرفرات بترجع 406 Not Acceptable لو نوع البيانات اللي طلبته مش مدعوم أصلًا.
الفرق بين الاتنين في جملة واحدة
| Header | من بيرسله؟ | الهدف |
|---|---|---|
Content-Type |
العميل أو السيرفر | وصف شكل البيانات المُرسلة فعليًا (الـ Body) |
Accept |
العميل بس | تحديد الشكل المفضّل للرد |
ليه الموضوع ده مهم أمنيًا؟ — قصة الـ Content-Type Confusion
الأهمية الحقيقية للموضوع بتظهر لما السيرفر يثق في الـ Content-Type اللي بعته العميل من غير ما يتحقق فعليًا من شكل البيانات. تخيل endpoint معمول يقبل بس application/json، لكن السيرفر مش بيتحقق فعليًا من نوع الـ parser اللي هيستخدمه بناءً على المحتوى الفعلي — النقطة دي فتحت باب لهجوم مشهور جدًا اسمه JSON Hijacking، وكمان لثغرات إعادة تفسير المحتوى في تطبيقات كتير بتقبل أنواع مختلفة (زي XML) وتديها لـ parser مش مؤمّن، وده بيوديك لثغرات زي XXE (XML External Entity) لو الـ Content-Type اتغير لـ application/xml وقُبل السيرفر التبديل ده.
مثال هجومي كلاسيكي: تجاوز فلتر عن طريق تغيير Content-Type
لو endpoint بيتحقق من الـ body بمنطق مخصص لـ application/json بس (زي فحص regex على المحتوى)، لكن بعدين بيمرر الداتا لـ parser عام بيفهم أكتر من نوع، فممكن تجرب:
POST /api/comment HTTP/1.1
Host: target.com
Content-Type: application/xml
<?xml version="1.0"?>
<!DOCTYPE data [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<comment>&xxe;</comment>
لو الفحص الأمني اتكتب بافتراض إن الداتا هتيجي JSON بس، وماكانش فيه تحقق صارم إن الـ Content-Type المُعلن فعلًا بيطابق الـ backend logic المتوقع، ممكن تعدّي فحص كامل بمجرد تغيير الهيدر ده.