You are currently viewing API Keys في GitHub وثغرة BOLA — أخطاء تدمر المشاريع وكيف تتجنبها

API Keys في GitHub وثغرة BOLA — أخطاء تدمر المشاريع وكيف تتجنبها

OWASP · API Security · 2026

ثغرات الـ API التي يقع فيها كل مطور
OWASP Top 10 بأمثلة كود حقيقية وحلول فورية

BOLA، Broken Auth، تسريب API Keys في GitHub — مشاكل تقنية حقيقية دمّرت شركات كاملة. تعلّم كيف تكتشفها في كودك وتصلحها قبل أن يستغلها أحد.

⏱ وقت القراءة: 18 دقيقة 📅 أبريل 2026 🛡 CyberTeech 👨‍💻 للمطورين والمتخصصين
السياق

📡 لماذا الـ API هي الهدف الأول للمهاجمين في 2026؟

الـ API لم تعد مجرد واجهة تقنية — أصبحت شريان الحياة الرقمي للشركات. كل طلب دفع، كل تسجيل دخول، كل تكامل بين خدمتين — يمر عبر API. وبالتالي أصبحت الهدف الأول لأي مهاجم يبحث عن بيانات أو صلاحيات.

17%
من كل الثغرات المنشورة عالمياً في 2025 كانت في الـ APIs
Wallarm 2026
43%
من الثغرات المستغلة في قائمة CISA KEV كانت API-related
CISA 2025
23.5%
من حوادث الاختراق سببها ثغرة BOLA وحدها
42Crunch 2026
$4.88M
متوسط تكلفة اختراق API واحد على المؤسسات
IBM Cost of Breach 2025
30K+
Postman workspace تحتوي API keys حية مكشوفة للعموم
CybelAngel 2025
92%
من المؤسسات تستخدم AI coding assistants — والكود المولّد هو النقطة العمياء الأولى
Cycode 2026
🎯

المشكلة الأساسية: المطورون يبنون APIs بسرعة كبيرة — خصوصاً مع مساعدات الـ AI مثل Copilot وCursor — لكن الكود المُولَّد غالباً لا يتبع best practices الأمنية. النتيجة: ثغرات تُنشر مع أول deployment.

API1 — الثغرة الأولى

🔓 BOLA — Broken Object Level Authorization

🔓
Broken Object Level Authorization (BOLA / IDOR)
API1:2023 OWASP — الأكثر انتشاراً والأكثر استغلالاً
🔴 Critical

BOLA تحدث حين يتحقق الـ API من أن المستخدم مُسجّل الدخول فقط، لكنه لا يتحقق من أنه يملك صلاحية الوصول لهذا المورد بالذات. المهاجم ببساطة يُغيّر رقم الـ ID في الـ request ويصل لبيانات مستخدمين آخرين.

اختُرقت بسببها شركات كبرى: Uber 2016، Facebook 2018، Trello 2024 — جميعها كشفت بيانات ملايين المستخدمين.

❌ الكود المعطوب — هل لديك هذا في مشروعك؟

Python — Flask API ❌ ثغرة BOLA
# ❌ خطأ شائع — لا يوجد تحقق من الملكية
@app.route('/api/orders/<int:order_id>', methods=['GET'])
@login_required
def get_order(order_id):
    # ⚠️ يجلب الطلب بالـ ID مباشرة بدون أي تحقق
    order = Order.query.get(order_id)
    
    if not order:
        return jsonify({'error': 'Not found'}), 404
    
    # ⚠️ لم يتحقق هل هذا الطلب يخص المستخدم الحالي!
    return jsonify(order.to_dict())

# المهاجم يرسل: GET /api/orders/1337 ويقرأ طلبات أي مستخدم

✅ الحل الصحيح — أضف هذا الكود

Python — Flask API ✅ محمي من BOLA
# ✅ صح — التحقق من ملكية المورد قبل إرجاعه
@app.route('/api/orders/<int:order_id>', methods=['GET'])
@login_required
def get_order(order_id):
    # ✅ اجلب هوية المستخدم من الـ JWT token
    current_user_id = get_jwt_identity()
    
    # ✅ تحقق من الملكية في نفس الـ query
    order = Order.query.filter_by(
        id=order_id,
        user_id=current_user_id  # ← هذا هو المفتاح
    ).first()
    
    if not order:
        # ✅ 404 وليس 403 — لا تكشف وجود المورد
        return jsonify({'error': 'Not found'}), 404
    
    return jsonify(order.to_dict())

# المهاجم الآن يحصل على 404 حتى لو كان الطلب موجوداً

🔍 كيف تختبر BOLA في API الخاص بك؟

cURL — اختبار يدوي 🔍 اختبار
# 1. سجّل دخول بحساب User A واحصل على token
TOKEN_A="eyJhbGci..."

# 2. اجلب موردك الخاص
curl -X GET https://api.example.com/orders/100 \
  -H "Authorization: Bearer $TOKEN_A"
# ✅ يجب أن يرجع 200

# 3. حاول تغيير الـ ID لمورد مستخدم آخر
curl -X GET https://api.example.com/orders/101 \
  -H "Authorization: Bearer $TOKEN_A"
# ✅ يجب أن يرجع 404 — إذا رجع 200 فلديك ثغرة BOLA!

القاعدة الذهبية: دائماً استخدم UUIDs بدلاً من sequential integers كـ IDs. UUID مثل f47ac10b-58cc-4372-a567-0e02b2c3d479 يصعب تخمينه — لكنه لا يُغني عن التحقق من الصلاحيات!

API2 — الثغرة الثانية

🔑 Broken Authentication — المصادقة المكسورة

🔑
Broken Authentication
API2:2023 OWASP — سبب اختراق Twitter بـ 5.4 مليون حساب
🔴 Critical

تشمل كل خلل في آلية التحقق من هوية المستخدم: JWT tokens ضعيفة أو منتهية الصلاحية لا تُرفض، API keys مكشوفة، refresh tokens لا تُلغى بعد تسجيل الخروج، وغياب الحماية من Brute-Force.

❌ أخطاء JWT الأكثر شيوعاً

JavaScript — Node.js ❌ JWT معطوب
// ❌ خطأ 1: السماح بخوارزمية "none"
const decoded = jwt.verify(token, secret, {
  algorithms: ['HS256', 'none'] // ⚠️ خطر جداً!
});

// ❌ خطأ 2: JWT بدون انتهاء صلاحية
const token = jwt.sign(
  { userId: user.id },
  process.env.JWT_SECRET
  // ⚠️ لا يوجد expiresIn — يصلح للأبد!
);

// ❌ خطأ 3: secret ضعيف
const JWT_SECRET = "secret"; // ⚠️ قابل للتخمين
JavaScript — Node.js ✅ JWT آمن
// ✅ صح — JWT محكم وآمن
const token = jwt.sign(
  {
    userId: user.id,
    role: user.role,
    jti: uuidv4() // ✅ معرف فريد للـ token
  },
  process.env.JWT_SECRET, // ✅ من متغيرات البيئة
  {
    algorithm: 'HS256',     // ✅ خوارزمية صريحة
    expiresIn: '15m',      // ✅ 15 دقيقة فقط
    issuer: 'api.myapp.com'  // ✅ مصدر محدد
  }
);

// ✅ التحقق مع تحديد الخوارزمية فقط
const decoded = jwt.verify(token, process.env.JWT_SECRET, {
  algorithms: ['HS256'],  // ✅ لا "none" أبداً
  issuer: 'api.myapp.com'
});

✅ حماية Rate Limiting من Brute-Force

JavaScript — Express.js ✅ Rate Limiting
const rateLimit = require('express-rate-limit');
const RedisStore = require('rate-limit-redis');

// ✅ حماية endpoint تسجيل الدخول
const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,  // 15 دقيقة
  max: 5,                     // ✅ 5 محاولات فقط
  message: {
    error: 'Too many attempts, try again later'
  },
  store: new RedisStore({ ... }), // ✅ Redis لـ distributed systems
  standardHeaders: true,
  legacyHeaders: false,
  // ✅ Block بالـ IP + username معاً
  keyGenerator: (req) => `${req.ip}:${req.body.email}`
});

app.post('/api/auth/login', loginLimiter, authController.login);
📌 حادثة حقيقية

T-Mobile 2023 — 37 مليون مستخدم بسبب API مكشوف

اكتشف أحد الباحثين API endpoint في T-Mobile لا يتطلب مصادقة على الإطلاق. بمجرد معرفة رقم الهاتف يمكن جلب بيانات الحساب الكاملة. المهاجم جمع بيانات 37 مليون مستخدم قبل الاكتشاف. الدرس: كل endpoint يحتاج authentication — بدون استثناء.

API3 — الثغرة الثالثة

📤 Broken Object Property Level Authorization — تسريب البيانات الزائدة

📤
Excessive Data Exposure + Mass Assignment
API3:2023 OWASP — ترجع أكثر مما يجب
🟠 High

يحدث حين يُرجع الـ API كل حقول الـ object من قاعدة البيانات مباشرة، بدلاً من إرجاع الحقول المسموح بها فقط. مشكلة Mass Assignment تحدث حين يقبل الـ API تحديث حقول حساسة كـ isAdmin أو role من المستخدم مباشرة.

Python — FastAPI ❌ يكشف كل الحقول
# ❌ خطأ — إرجاع كل بيانات المستخدم بدون فلترة
@app.get("/users/{user_id}")
async def get_user(user_id: int):
    user = await db.get_user(user_id)
    return user.__dict__  # ⚠️ يرجع password_hash, role, internal_notes...

# ❌ Mass Assignment — يقبل تحديث أي حقل
@app.put("/users/{user_id}")
async def update_user(user_id: int, data: dict):
    await db.update_user(user_id, **data)  # ⚠️ يقبل {isAdmin: true}!
Python — FastAPI + Pydantic ✅ مع Data Filtering
from pydantic import BaseModel
from typing import Optional

# ✅ Response schema — يحدد ما يُرجع فقط
class UserPublicResponse(BaseModel):
    id: int
    username: str
    email: str
    created_at: str
    # ✅ لا password_hash، لا role، لا internal_notes

# ✅ Update schema — يحدد ما يمكن تعديله فقط
class UserUpdateRequest(BaseModel):
    username: Optional[str] = None
    bio: Optional[str] = None
    # ✅ لا isAdmin، لا role، لا permissions

@app.get("/users/{user_id}", response_model=UserPublicResponse)
async def get_user(user_id: int):
    user = await db.get_user(user_id)
    return user  # ✅ Pydantic يفلتر تلقائياً

@app.put("/users/{user_id}")
async def update_user(user_id: int, data: UserUpdateRequest):
    await db.update_user(user_id, **data.dict(exclude_unset=True))
API4 — الثغرة الرابعة

Unrestricted Resource Consumption — بدون Rate Limiting

Unrestricted Resource Consumption
API4:2023 OWASP — DDoS + استنزاف موارد السيرفر
🟠 High

API بدون rate limiting يمكن استخدامه لـ: استنزاف موارد السيرفر حتى يتوقف، scraping البيانات بشكل آلي، أو إرسال آلاف رسائل SMS/Email على حسابك. المهاجم يُشغّل loop بسيط ويُكلّفك الآلاف.

Python — Django REST Framework ✅ Rate Limiting متقدم
# settings.py
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle',
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '100/hour',    # ✅ زوار غير مسجلين
        'user': '1000/hour',   # ✅ مستخدمين مسجلين
        'login': '5/minute',   # ✅ تسجيل الدخول
        'otp': '3/hour',       # ✅ رموز OTP
        'sms': '10/day',       # ✅ إرسال SMS
    }
}

# views.py
class SendOTPView(APIView):
    # ✅ throttle_classes خاص لهذا الـ endpoint
    throttle_classes = [ScopedRateThrottle]
    throttle_scope = 'otp'
    
    def post(self, request):
        # إرسال OTP بأمان
        ...
⚠️

لا تنسَ: Rate limiting يجب أن يكون على مستوى الـ IP والـ User معاً. المهاجم يمكنه استخدام حسابات مختلفة لتجاوز حد مستخدم واحد.

المشكلة الأخطر

🗝️ تسريب API Keys في GitHub — المشكلة التي تدمر الشركات

في 2025، وجد باحثو CybelAngel أكثر من 30,000 Postman workspace تحتوي API keys ورموز وصول حية مكشوفة للعموم. وفي GitHub، يُرفع آلاف الـ secrets كل يوم عن طريق الخطأ. هذه المشكلة تحدث لمطورين محترفين في شركات كبرى.

📌 حادثة حقيقية — 2025

مطور رفع .env file على GitHub العام — خسر $47,000 في ساعات

رفع مطور مشروعه على GitHub ونسي حذف ملف .env الذي يحتوي AWS credentials. خلال ساعة واحدة، اكتشفها bot يُمسح GitHub باستمرار. أنشأ المهاجم 200 EC2 instance لتعدين العملات الرقمية. الفاتورة: $47,000 في أقل من 24 ساعة.

❌ الأخطاء الأكثر شيوعاً في التعامل مع الـ Secrets

Python ❌ Hardcoded Secrets
# ❌ أسوأ ما يمكن فعله
AWS_ACCESS_KEY = "AKIAIOSFODNN7EXAMPLE"  # ⚠️ مباشرة في الكود
DB_PASSWORD = "mypassword123"            # ⚠️ مرئي في Git history
STRIPE_SECRET = "sk_live_abcdefghijk"    # ⚠️ حتى لو حذفته لاحقاً

# ❌ في ملف config.js
const config = {
  apiKey: "AIzaSyD-9tSrke72...",       // ⚠️ سيظهر في GitHub
  databaseURL: "https://..."
};
Python + Bash ✅ Environment Variables
# ✅ ملف .env (مُدرج في .gitignore)
AWS_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE
DB_PASSWORD=mypassword123
STRIPE_SECRET=sk_live_abcdefghijk

# ✅ في الكود — اقرأ من البيئة فقط
import os
from dotenv import load_dotenv

load_dotenv()

AWS_ACCESS_KEY = os.getenv('AWS_ACCESS_KEY')
DB_PASSWORD = os.getenv('DB_PASSWORD')

# ✅ تحقق من وجود الـ secrets عند البدء
required_secrets = ['AWS_ACCESS_KEY', 'DB_PASSWORD', 'STRIPE_SECRET']
for secret in required_secrets:
    if not os.getenv(secret):
        raise ValueError(f"Missing required secret: {secret}")

✅ إعداد .gitignore الصحيح من اليوم الأول

.gitignore ✅ ضروري في كل مشروع
# Secrets & Credentials
.env
.env.local
.env.production
.env.*.local
*.pem
*.key
*_rsa
*_dsa
secrets.json
credentials.json
service-account.json

# AWS
.aws/
aws-credentials

# IDE
.idea/
.vscode/settings.json

# Logs
*.log
logs/

🔍 افحص إذا رفعت secrets بالخطأ سابقاً

Bash — أدوات الفحص 🔍 فحص فوري
# ✅ أداة trufflehog — تفحص الـ Git history كاملاً
pip install trufflehog
trufflehog git file://./  --only-verified

# ✅ أداة gitleaks — أسرع وأشمل
brew install gitleaks
gitleaks detect --source . -v

# ✅ إذا وجدت secret في الـ history، أزله بالكامل
# (لا يكفي حذفه في commit جديد — الـ history لا يزال موجوداً)
git filter-repo --path .env --invert-paths
# ثم أعد رفع الـ repo وأبطل كل الـ secrets القديمة
🚨

مهم جداً: حذف الـ secret في commit جديد لا يكفي — الـ Git history لا يزال يحتوي القيمة القديمة. الحل الوحيد: أبطل الـ secret فوراً وأصدر واحداً جديداً، بغض النظر عن أي شيء آخر.

الأدوات

🧰 أدوات فحص أمان الـ API

هذه الأدوات يستخدمها مختبرو الاختراق وفرق الأمن يومياً. معظمها مجاني ومفتوح المصدر.

🕷️

OWASP ZAP

فحص تلقائي شامل لثغرات OWASP Top 10. مثالي للبدء

مجاني
🔫

Burp Suite

المعيار الصناعي لاختبار الاختراق. نسخة Community مجانية

Community مجاني

Nuclei

فحص سريع بـ templates جاهزة. آلاف القوالب من المجتمع

مجاني
🐶

Trufflehog

فحص الـ Git history عن secrets مسرّبة بدقة عالية

مجاني
🔍

Gitleaks

اكتشاف secrets في الـ repos قبل النشر. يندمج مع CI/CD

مجاني
📡

42Crunch

تحليل ثابت لملفات OpenAPI/Swagger لاكتشاف الثغرات

Bash — تشغيل Nuclei 🔍 فحص سريع
# تثبيت Nuclei
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest

# ✅ فحص الـ API بقوالب متخصصة
nuclei -u https://api.example.com \
  -t api/ \
  -severity critical,high \
  -o results.txt

# ✅ فحص ملف OpenAPI spec
nuclei -t exposures/apis/ \
  -u https://api.example.com/swagger.json
Checklist

Checklist أمان الـ API قبل كل Deployment

احفظ هذا الـ checklist وطبّقه قبل كل نشر. كل نقطة تمنع ثغرة حقيقية.

🔐 المصادقة والصلاحيات
كل endpoint يتطلب مصادقة إلا ما هو مُصرّح بأنه عام صراحةً
JWT tokens لها صلاحية زمنية (15 دقيقة للـ access، 7 أيام للـ refresh)
خوارزمية JWT محددة صراحةً — بدون “none”
تحقق من ملكية كل object قبل إرجاعه (BOLA check)
RBAC مُطبّق على كل endpoint حساس
📤 البيانات والإدخال
Response schemas محددة — لا تُرجع حقولاً زائدة أبداً
Whitelist للحقول القابلة للتحديث — بدون Mass Assignment
Input validation على كل الحقول المُدخلة
Parameterized queries — بدون string concatenation في SQL
Content-Type validation — رفض الطلبات غير المتوقعة
⚡ الحماية من الاستغلال
Rate limiting على كل endpoint — خاصة Login وOTP وSMS
HTTPS فقط — بدون HTTP
CORS مُضبوط على domains محددة فقط
Security headers: HSTS, X-Frame-Options, CSP
Secrets في Environment variables — بدون hardcoding
📋 المراقبة والتسجيل
كل طلب مصادقة فاشل مُسجّل مع الـ IP
تنبيهات فورية على أنماط هجوم معروفة
لا تُسجّل passwords أو tokens في الـ logs
API inventory محدّث — لا shadow APIs منسية

🎯 الخلاصة للمطور

الـ API الآمن ليس ترفاً — إنه المسؤولية الأساسية. كل سطر كود تكتبه اليوم هو إما سور حماية أو ثغرة مفتوحة. طبّق هذا الـ checklist، أضف الأدوات لـ CI/CD pipeline، واجعل الأمن جزءاً من الكود وليس فكرة لاحقة.

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

الأسئلة الأكثر بحثاً

ما الفرق بين BOLA وIDOR؟

BOLA (Broken Object Level Authorization) هو المصطلح الرسمي في OWASP لما يُعرف سابقاً بـ IDOR (Insecure Direct Object Reference). هما نفس الثغرة — الوصول لمورد لا تملكه بتغيير الـ ID. OWASP اعتمد مصطلح BOLA لأنه أكثر دقة ويشمل حالات أوسع من مجرد تغيير رقم في الـ URL.

هل UUID يحمي من BOLA؟

UUID يُصعّب التخمين لكنه لا يُحمّي من BOLA. المشكلة الأساسية هي غياب تحقق الصلاحيات — إذا حصل المهاجم على UUID بأي طريقة (من response آخر مثلاً) سيستطيع الوصول للمورد. UUID هو طبقة دفاع إضافية، وليس الحل الكامل. دائماً أضف user_id = current_user_id في الـ query.

ما أفضل مكتبة لإدارة JWT في Node.js؟

مكتبة jsonwebtoken هي الأكثر استخداماً وموثوقية. تأكد دائماً من تحديد الخوارزمية صراحةً algorithms: ['HS256']، وتعيين وقت انتهاء الصلاحية expiresIn، وتحديد الـ issuer. لمشاريع أكبر، فكّر في jose كبديل أكثر أماناً.

كيف أحمي API Keys في CI/CD pipeline؟

استخدم خدمات Secret Management المدمجة مع منصتك: GitHub Actions Secrets، GitLab CI Variables، أو AWS Secrets Manager. لا تضع الـ secrets في ملفات الـ config أو متغيرات بيئة pipeline مرئية. أضف أداة مثل gitleaks كـ pre-commit hook وكـ CI/CD step.

هل GraphQL APIs لها نفس ثغرات REST؟

نعم وأكثر. GraphQL يضيف مخاطر إضافية: Introspection في الـ Production يكشف كل الـ schema للمهاجم — أوقفها دائماً. Query Depth Attacks — قيّد عمق الاستعلام. N+1 Queries التي تستنزف قاعدة البيانات. تحقق من BOLA بتغيير الـ IDs في الـ GraphQL queries مثلما تفعل مع REST.

ما أسرع طريقة لفحص API الخاص بي الآن؟

ابدأ بـ 3 خطوات فورية: أولاً شغّل gitleaks detect --source . -v في مشروعك للتأكد من عدم وجود secrets. ثانياً جرّب تغيير الـ IDs في طلباتك يدوياً وتحقق من الردود. ثالثاً ثبّت OWASP ZAP وشغّله على بيئة الـ staging قبل أي deployment. هذه الخطوات الثلاث تكشف 80% من المشاكل الشائعة.

📊 ملخص الثغرات والحلول

الثغرةOWASPالخطورةالحل الأساسيوقت التطبيق
BOLA / IDOR API1 Critical تحقق من ملكية الـ object في كل query ساعة
Broken Auth API2 Critical JWT صحيح + Rate Limiting + MFA يوم
Excessive Data API3 High Response schemas + Whitelist للحقول ساعات
No Rate Limiting API4 High Rate limiting على كل endpoint ساعة
API Key Leak Critical Environment variables + .gitignore 30 دقيقة