ما هي OWASP؟
OWASP (Open Worldwide Application Security Project) منظّمة غير ربحية تُصدر قائمة دورية لأخطر ثغرات التطبيقات الويب. القائمة تُحدَّث كل 3-4 سنوات وتُعتبر المرجع الأول للمطوّرين.
كل مطوّر يجب أن يعرف هذه القائمة — ليس لحفظها، بل لفهم كيف يُهاجَم الكود وكيف يحمي نفسه.
1. Broken Access Control
المشكلة الأولى — مستخدم يصل لبيانات غير مسموح له بها.
مثال
// ❌ لا يتحقّق من ملكية البيانات
app.get("/api/users/:id", async (req, res) => {
const user = await db.users.findById(req.params.id);
res.json(user);
});أيّ مسجّل دخول يستطيع رؤية بيانات أيّ مستخدم.
الحلّ
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 مجاني)
- مفاتيح تشفير في متغيّرات بيئة، ليس في الكود
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
// ❌ كارثة أمنية
const sql = `SELECT * FROM users WHERE email = '${email}'`;
db.query(sql);هاكر يُدخل: ' OR '1'='1 → يحصل على كل المستخدمين.
الحلّ: Parameterized Queries
// ✅ آمن
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 منتهية
الحلّ
// أخطاء مخفية في الإنتاج
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
استخدام مكتبة قديمة بها ثغرات معروفة.
الحلّ
# تدقيق مباشر
npm audit
# إصلاح تلقائي
npm audit fix
# قبل النشر
npm audit --production --audit-level=highأضف Dependabot على GitHub لتنبيهات تلقائية.
7. Authentication Failures
- كلمات سر ضعيفة مسموح بها
- جلسات لا تنتهي أبداً
- عدم حماية من brute force
الحلّ
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
logger.warn("login failed", {
email: req.body.email,
ip: req.ip,
ua: req.headers["user-agent"],
});10. Server-Side Request Forgery (SSRF)
الخادم يُرسل طلباً لعنوان يُحدّده المستخدم:
// ❌ خطر
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، لكن ليس من بقية الثغرات. الأمن طبقات متعدّدة.