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 المتوقع، ممكن تعدّي فحص كامل بمجرد تغيير الهيدر ده.