OWASP Top 10: أخطر الثغرات الأمنية التي يجب أن يعرفها كل مطوّر
الأمن السيبراني

OWASP Top 10: أخطر الثغرات الأمنية التي يجب أن يعرفها كل مطوّر

قائمة OWASP Top 10 للثغرات الأمنية الأكثر خطورة على الويب — شرح عربي مع أمثلة وطرق الحماية.

م
مؤسس LahbabiGuide
4 دقائق قراءة
شارك:

ما هي OWASP؟

OWASP (Open Worldwide Application Security Project) منظّمة غير ربحية تُصدر قائمة دورية لأخطر ثغرات التطبيقات الويب. القائمة تُحدَّث كل 3-4 سنوات وتُعتبر المرجع الأول للمطوّرين.

كل مطوّر يجب أن يعرف هذه القائمة — ليس لحفظها، بل لفهم كيف يُهاجَم الكود وكيف يحمي نفسه.

1. Broken Access Control

المشكلة الأولى — مستخدم يصل لبيانات غير مسموح له بها.

مثال

js
// ❌ لا يتحقّق من ملكية البيانات
app.get("/api/users/:id", async (req, res) => {
  const user = await db.users.findById(req.params.id);
  res.json(user);
});

أيّ مسجّل دخول يستطيع رؤية بيانات أيّ مستخدم.

الحلّ

js
app.get("/api/users/:id", auth, async (req, res) => {
  if (req.user.id !== Number(req.params.id) && !req.user.isAdmin) {
    return res.status(403).json({ error: "ممنوع" });
  }
  const user = await db.users.findById(req.params.id);
  res.json(user);
});

2. Cryptographic Failures

حفظ البيانات الحسّاسة بدون تشفير صحيح.

أمثلة سيّئة

  • كلمات السر كنصّ مكشوف في قاعدة البيانات
  • رموز المصادقة بدون HTTPS
  • استخدام MD5/SHA1 لكلمات السر

الحلّ

  • bcrypt أو argon2 لكلمات السر
  • HTTPS في كل مكان (Let's Encrypt مجاني)
  • مفاتيح تشفير في متغيّرات بيئة، ليس في الكود
js
import bcrypt from "bcrypt";

// عند التسجيل
const hash = await bcrypt.hash(password, 12);
await db.users.create({ email, password: hash });

// عند تسجيل الدخول
const valid = await bcrypt.compare(password, user.password);
إعلان

3. Injection (SQL, NoSQL, Command)

بيانات المستخدم تدخل مباشرة في استعلام أو أمر.

SQL Injection

js
// ❌ كارثة أمنية
const sql = `SELECT * FROM users WHERE email = '${email}'`;
db.query(sql);

هاكر يُدخل: ' OR '1'='1 → يحصل على كل المستخدمين.

الحلّ: Parameterized Queries

js
// ✅ آمن
db.query("SELECT * FROM users WHERE email = $1", [email]);

// أو استخدم ORM (Prisma, Sequelize)
await prisma.user.findFirst({ where: { email } });

4. Insecure Design

المشكلة ليست في التنفيذ بل في التصميم نفسه:

  • استرداد كلمة سر بإرسالها بالبريد (يجب رابط مؤقّت)
  • عدم تحديد محاولات تسجيل دخول (brute force)
  • عدم تقييد العمليات الخطرة بتحقّق إضافي

الحلّ

  • Threat modeling قبل الكتابة
  • Rate limiting على كل endpoint حسّاس
  • 2FA للإجراءات المالية/الإدارية

5. Security Misconfiguration

الإعدادات الخاطئة = باب خلفي:

  • DEBUG=true في الإنتاج
  • تفاصيل أخطاء تُعرَض للمستخدم (stack traces)
  • خدمات غير مستخدمة مفتوحة (manage/, .git/)
  • شهادات SSL منتهية

الحلّ

js
// أخطاء مخفية في الإنتاج
app.use((err, req, res, next) => {
  console.error(err); // سجّل داخلياً
  if (process.env.NODE_ENV === "production") {
    return res.status(500).json({ error: "خطأ داخلي" });
  }
  res.status(500).json({ error: err.message, stack: err.stack });
});

6. Vulnerable Components

استخدام مكتبة قديمة بها ثغرات معروفة.

الحلّ

bash
# تدقيق مباشر
npm audit

# إصلاح تلقائي
npm audit fix

# قبل النشر
npm audit --production --audit-level=high

أضف Dependabot على GitHub لتنبيهات تلقائية.

7. Authentication Failures

  • كلمات سر ضعيفة مسموح بها
  • جلسات لا تنتهي أبداً
  • عدم حماية من brute force

الحلّ

js
import rateLimit from "express-rate-limit";

const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 دقيقة
  max: 5, // 5 محاولات
  message: "محاولات كثيرة — حاول لاحقاً",
});

app.post("/login", loginLimiter, loginHandler);

8. Software and Data Integrity Failures

  • تنزيل مكتبات بدون التحقّق من التوقيع
  • CI/CD يدفع كوداً غير مراجَع للإنتاج
  • تحديث تلقائي من مصدر مشبوه

الحلّ

  • package-lock.json داخل Git
  • توقيع commits: git commit -S
  • مراجعة PRs إلزامياً

9. Logging and Monitoring Failures

بدون سجلات، الهجوم يُكتشف بعد شهور.

الحلّ

سجّل:

  • محاولات تسجيل دخول فاشلة
  • تغييرات الصلاحيات
  • الوصول لموارد حسّاسة
  • أي 500 error
js
logger.warn("login failed", {
  email: req.body.email,
  ip: req.ip,
  ua: req.headers["user-agent"],
});

10. Server-Side Request Forgery (SSRF)

الخادم يُرسل طلباً لعنوان يُحدّده المستخدم:

js
// ❌ خطر
app.post("/fetch-url", async (req, res) => {
  const response = await fetch(req.body.url);
  res.send(await response.text());
});

هاكر يُدخل http://169.254.169.254/metadata → يحصل على أسرار AWS.

الحلّ

  • قائمة بيضاء (whitelist) للدومينات المسموح بها
  • حظر IPs الداخلية (10.x، 192.168.x، 169.254.x)
  • استخدام مكتبة مثل ssrf-filter

Checklist عملي قبل الإطلاق

  • [ ] كلمات السر بـ bcrypt (cost ≥ 12)
  • [ ] HTTPS فقط (HSTS header)
  • [ ] جميع الاستعلامات parameterized
  • [ ] Rate limiting على /login و /register
  • [ ] Input validation بـ Zod/Joi
  • [ ] Errors في الإنتاج لا تكشف stack
  • [ ] npm audit ينظّف
  • [ ] CSP header إلى حدّ ما صارم
  • [ ] CORS محدّد (ليس *)
  • [ ] Cookies: httpOnly, secure, sameSite
  • [ ] 2FA متاح للمستخدمين

الأسئلة الشائعة

هل OWASP كافٍ للأمن؟

لا — هي نقطة البداية. للتطبيقات الحرجة تحتاج pentest دوري من شركات متخصّصة.

ما الفرق بين Authentication و Authorization؟

  • Authentication: من أنت؟ (تسجيل دخول)
  • Authorization: ماذا تستطيع؟ (صلاحيات)

هل استخدام ORM يحميني تماماً؟

يحميك من SQL Injection، لكن ليس من بقية الثغرات. الأمن طبقات متعدّدة.

اقرأ أيضاً

مقالات ذات صلة