أمان التطبيقات

أمان API

4 دقيقة للقراءة

واجهات برمجة التطبيقات (APIs) هي العمود الفقري للتطبيقات الحديثة. يغطي هذا الدرس أنماط المصادقة والثغرات الشائعة وأفضل ممارسات الأمان التي ستواجهها في المقابلات.

أنماط المصادقة

مفاتيح API مقابل OAuth 2.0 مقابل JWT

الطريقةحالة الاستخداممستوى الأمانالإدارة
مفاتيح APIخادم إلى خادم، تطبيقات بسيطةمنخفض (تتسرب بسهولة)تدوير يدوي
OAuth 2.0وصول الطرف الثالث، موافقة المستخدمعاليتحديث الرمز
JWTمصادقة بدون حالةمتوسط-عاليالتحقق من التوقيع

سؤال المقابلة

س: "متى تستخدم مفاتيح API مقابل OAuth 2.0؟"

الإجابة:

  • مفاتيح API: الخدمات الداخلية، معرّف تحديد المعدل، العمليات غير الحساسة
  • OAuth 2.0: تكاملات الطرف الثالث، الوصول لبيانات المستخدم، التفويض المفوض
  • JWT: تطبيقات الجوال، الخدمات المصغرة، عندما تحتاج مصادقة بدون حالة مع مطالبات

تدفقات OAuth 2.0

تدفق رمز التفويض (الأكثر أماناً)

┌─────────┐                              ┌──────────────┐
│ المستخدم│                              │ خادم المصادقة│
└────┬────┘                              └──────┬───────┘
     │                                          │
     │  1. النقر على "تسجيل الدخول بـ Google"   │
     ├────────────────────────────────────────▶│
     │                                          │
     │  2. إعادة التوجيه لخادم المصادقة         │
     │◀────────────────────────────────────────┤
     │                                          │
     │  3. المستخدم يصادق ويوافق               │
     ├────────────────────────────────────────▶│
     │                                          │
     │  4. إعادة التوجيه مع رمز المصادقة        │
     │◀────────────────────────────────────────┤
     │         │                                │
     │         │  5. استبدال الرمز بالرموز      │
     │         └───────────────────────────────▶│
     │                                          │
     │         6. إرجاع رموز الوصول والتحديث   │
     │◀────────────────────────────────────────┤

امتداد PKCE (مطلوب للعملاء العامين)

import hashlib
import base64
import secrets

# إنشاء رمز التحقق
code_verifier = secrets.token_urlsafe(32)

# إنشاء تحدي الرمز
code_challenge = base64.urlsafe_b64encode(
    hashlib.sha256(code_verifier.encode()).digest()
).decode().rstrip('=')

# الاستخدام في طلب التفويض
auth_url = f"{AUTH_ENDPOINT}?client_id={CLIENT_ID}&code_challenge={code_challenge}&code_challenge_method=S256"

OWASP API Security Top 10

الترتيبالثغرةمثال
API1تفويض مستوى الكائن المعطل/api/users/123 متاح للمستخدم 456
API2المصادقة المعطلةرموز ضعيفة، لا تحديد معدل على تسجيل الدخول
API3تفويض مستوى خاصية الكائن المعطلتعيين جماعي يسمح برفع الدور
API4استهلاك موارد غير مقيدلا حدود للصفحات، استنفاد الذاكرة
API5تفويض مستوى الوظيفة المعطلالمستخدم يصل لنقاط نهاية المشرف
API6وصول غير مقيد لتدفقات العمل الحساسةسمسرة التذاكر الآلية
API7تزوير طلب جانب الخادمجلب URLs عشوائية عبر API
API8التكوين الأمني الخاطئأخطاء مطولة، بيانات اعتماد افتراضية
API9إدارة المخزون غير السليمةإصدارات API غير موثقة/منسية
API10استهلاك غير آمن للـ APIsالوثوق باستجابات API الطرف الثالث

تفويض مستوى الكائن المعطل (BOLA)

# ثغرة - لا فحص ملكية
@app.get("/api/orders/{order_id}")
def get_order(order_id: int):
    return db.query(Order).get(order_id)

# آمن - التحقق من الملكية
@app.get("/api/orders/{order_id}")
def get_order(order_id: int, current_user: User = Depends(get_current_user)):
    order = db.query(Order).get(order_id)
    if order.user_id != current_user.id:
        raise HTTPException(status_code=403, detail="Forbidden")
    return order

تحديد المعدل

أنماط التنفيذ

from fastapi import Request, HTTPException
from datetime import datetime, timedelta
import redis

redis_client = redis.Redis()

def rate_limit(key: str, limit: int, window: int):
    """
    تحديد معدل دلو الرموز.

    Args:
        key: معرف فريد (user_id، IP، مفتاح API)
        limit: أقصى طلبات لكل نافذة
        window: نافذة الوقت بالثواني
    """
    current = redis_client.get(key)

    if current is None:
        # أول طلب
        redis_client.setex(key, window, 1)
        return True

    if int(current) >= limit:
        raise HTTPException(
            status_code=429,
            detail="Rate limit exceeded",
            headers={"Retry-After": str(window)}
        )

    redis_client.incr(key)
    return True

# الاستخدام
@app.get("/api/search")
def search(request: Request, q: str):
    rate_limit(f"search:{request.client.host}", limit=100, window=60)
    return perform_search(q)

التحقق من المدخلات

from pydantic import BaseModel, Field, validator
import re

class UserCreateRequest(BaseModel):
    username: str = Field(..., min_length=3, max_length=30)
    email: str = Field(..., max_length=255)
    password: str = Field(..., min_length=12)

    @validator('username')
    def username_alphanumeric(cls, v):
        if not re.match(r'^[a-zA-Z0-9_]+$', v):
            raise ValueError('Username must be alphanumeric')
        return v

    @validator('email')
    def email_valid(cls, v):
        if not re.match(r'^[^@]+@[^@]+\.[^@]+$', v):
            raise ValueError('Invalid email format')
        return v.lower()

    @validator('password')
    def password_strong(cls, v):
        if not re.search(r'[A-Z]', v):
            raise ValueError('Password must contain uppercase')
        if not re.search(r'[a-z]', v):
            raise ValueError('Password must contain lowercase')
        if not re.search(r'\d', v):
            raise ValueError('Password must contain digit')
        return v

رؤوس الأمان

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

# تكوين CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://trusted-domain.com"],
    allow_credentials=True,
    allow_methods=["GET", "POST"],
    allow_headers=["Authorization", "Content-Type"],
)

@app.middleware("http")
async def add_security_headers(request, call_next):
    response = await call_next(request)
    response.headers["X-Content-Type-Options"] = "nosniff"
    response.headers["X-Frame-Options"] = "DENY"
    response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains"
    response.headers["Content-Security-Policy"] = "default-src 'self'"
    return response

نصيحة المقابلة: عند مناقشة أمان API، اذكر دائماً مبدأ الدفاع في العمق: المصادقة في البوابة، التفويض في مستوى الخدمة، والتحقق من المدخلات في كل نقطة نهاية.

في الدرس التالي، سنغطي DevSecOps وأمان CI/CD. :::

مراجعة سريعة: كيف تجد هذا الدرس؟

اختبار

الوحدة 3: أمان التطبيقات

خذ الاختبار
نشرة أسبوعية مجانية

ابقَ على مسار النيرد

بريد واحد أسبوعياً — دورات، مقالات معمّقة، أدوات، وتجارب ذكاء اصطناعي.

بدون إزعاج. إلغاء الاشتراك في أي وقت.