GammaCyber

כתיבת קוד — שיעור 19

Context API ו-Redux

כל 7 משימות הקוד שנשמרו מהשיעור מופיעות כאן, עם דרישות, דוגמאות וקוד פתיחה. אפשר לכתוב פתרון בעורך המקומי וללחוץ על „בדיקת AI” לקבלת ציון, רמזים והערות.

מטלה 1
הקמת תשתית השרת

כתבו קוד JavaScript בסיסי (קובץ server.js) המייבא את ספריית express, מפעיל את האפליקציה, ומגדיר את השרת להאזין על פורט 3000. כאשר השרת עולה, הדפיסו לקונסול: 'Secure HQ Server is online on port 3000'. אל תשכחו להוסיף את ה-Middleware שמאפשר קריאת נתוני JSON!

פתרון מטלה 1 ›
const express = require('express'); const app = express(); const PORT = 3000; // חובה! בלי זה req.body יהיה undefined app.use(express.json()); app.listen(PORT, () => { console.log(`Secure HQ Server is online on port ${PORT}`); });
הפתרון נשמר מקומית אוטומטית.
מטלה 2
בדיקת בריאות המערכת (Healthcheck Route)

הוסיפו לשרת נתיב GET לכתובת /api/health. כאשר פונים לנתיב זה, השרת יחזיר אובייקט JSON עם: status: 'active' ו-timestamp: Date.now().

פתרון מטלה 2 ›
app.get('/api/health', (req, res) => { res.status(200).json({ status: 'active', timestamp: Date.now() }); });
הפתרון נשמר מקומית אוטומטית.
מטלה 3
שליפה דינמית (Dynamic Params)

סוכנים צריכים לשלוף משימות. צרו נתיב GET דינמי לכתובת /api/missions/:missionId. חלצו את ה-ID מהבקשה והחזירו: { mission: '<ה-ID שהתקבל>', clearanceRequired: 'Top Secret' }.

פתרון מטלה 3 ›
app.get('/api/missions/:missionId', (req, res) => { const requestedId = req.params.missionId; // חילוץ ה-ID res.status(200).json({ mission: requestedId, clearanceRequired: 'Top Secret' }); });
💡 מיקרו-למידה — Dynamic Route Params: במקום לכתוב נתיב נפרד לכל /missions/1, /missions/2... נגדיר :missionId ונגיש ב-req.params.missionId.
הפתרון נשמר מקומית אוטומטית.
מטלה 4
קליטת מודיעין (POST Route & Body)

סוכנים שולחים מידע מהשטח. צרו נתיב POST לכתובת /api/intel שמקבל targetName ו-dangerLevel מה-Body. הדפיסו למסוף והחזירו { success: true, message: 'Intel Received' }.

פתרון מטלה 4 ›
app.post('/api/intel', (req, res) => { const { targetName, dangerLevel } = req.body; console.log(`[!] Intel received on ${targetName}, Level: ${dangerLevel}`); res.status(200).json({ success: true, message: 'Intel Received' }); });
הפתרון נשמר מקומית אוטומטית.
מטלה 5
יישום Trust Boundary — ולידציה מתקדמת

הגנו על הנתיב ממטלה 4! שנו אותו כך שיבצע ולידציה: אם חסר targetName או אם dangerLevel אינו מספר (או גדול מ-10), החזירו קוד 400 Bad Request עם הודעת שגיאה. רק מידע תקין יקבל 201 Created.

פתרון מלא כל 5 המטלות ›
// server.js — פתרון מלא משולב const express = require('express'); const app = express(); const PORT = 3000; // מטלה 1: Middleware לפענוח JSON app.use(express.json()); // מטלה 2: Healthcheck app.get('/api/health', (req, res) => { res.status(200).json({ status: 'active', timestamp: Date.now() }); }); // מטלה 3: Dynamic Params app.get('/api/missions/:missionId', (req, res) => { const requestedId = req.params.missionId; res.status(200).json({ mission: requestedId, clearanceRequired: 'Top Secret' }); }); // מטלות 4 + 5: POST עם ולידציה (Trust Boundary) app.post('/api/intel', (req, res) => { const { targetName, dangerLevel } = req.body; // מטלה 5: ולידציה — Trust Boundary if (!targetName || typeof dangerLevel !== 'number' || dangerLevel > 10) { return res.status(400).json({ error: 'Invalid intel format. Target name is required and danger must be 0-10.' }); } // מטלה 4: מידע תקין — הדפסה ואישור console.log(`[!] Intel received on ${targetName}, Level: ${dangerLevel}`); res.status(201).json({ success: true, message: 'Intel Received securely' }); }); // מטלה 1: האזנה על הפורט app.listen(PORT, () => { console.log(`Secure HQ Server is online on port ${PORT}`); });
הפתרון נשמר מקומית אוטומטית.
T2 · בסיסי300 נק'~20 דק'algorithmic
אימות טוקן חתום (HMAC)
לפני שמאבטחים endpoint צריך לאמת זהות. טוקן בפורמט "payload.signature", כאשר signature = HMAC-SHA256(secret, payload) ב-hex. ממש verify_token(token, secret) שמחזיר True רק אם החתימה תקפה. השתמשו בהשוואת זמן-קבוע (hmac.compare_digest) כדי למנוע timing attack. פורמט שגוי → False.
דוגמאות
verify_token(valid_token, secret) → True
verify_token(tampered_token, secret) → False
verify_token('noDotHere', secret) → False
פתרון-ייחוס אימות טוקן חתום (HMAC) ›
import hmac, hashlib def verify_token(token: str, secret: str) -> bool: if token.count('.') != 1: return False payload, sig = token.rsplit('.', 1) expected = hmac.new(secret.encode(), payload.encode(), hashlib.sha256).hexdigest() return hmac.compare_digest(expected, sig) # השוואה בזמן-קבוע (נגד timing attack)
הפתרון נשמר מקומית אוטומטית.
T3 · בינוני450 נק'~30 דק'build
שכבת הרשאה מלאה (Auth + Trust Boundary)
ממש את מקבל-ההחלטות של ה-endpoint המאובטח כפונקציה טהורה (שפה-אגנוסטית, לבדיקה אוטומטית). authorize(request) מקבל {method, path, headers, body}. עבור POST /api/intel: דרוש כותרת Authorization: Bearer <token> תקף (HMAC, כמו במשימה הקודמת) — אחרת (401, {error:'Unauthorized'}). לאחר מכן החל Trust Boundary: targetName מחרוזת לא-ריקה ו-dangerLevel מספר ≤10 — אחרת (400, {error:'Invalid intel'}). קלט תקין → (201, {success:True}). נתיב לא-מוכר → (404, {error:'Not found'}).
דוגמאות
POST /api/intel + Bearer תקף + body תקין → (201, {'success': True})
POST /api/intel בלי טוקן → (401, {'error': 'Unauthorized'})
POST /api/intel + טוקן תקף + dangerLevel=99 → (400, {'error': 'Invalid intel'})
פתרון-ייחוס שכבת הרשאה מלאה (Auth + Trust Boundary) ›
import hmac, hashlib SECRET = "hq-secret" def _verify(token): if token.count('.') != 1: return False p, sig = token.rsplit('.', 1) exp = hmac.new(SECRET.encode(), p.encode(), hashlib.sha256).hexdigest() return hmac.compare_digest(exp, sig) def authorize(request: dict): method, path = request.get('method'), request.get('path') headers, body = request.get('headers', {}), request.get('body', {}) if path == '/api/intel' and method == 'POST': auth = headers.get('Authorization', '') if not auth.startswith('Bearer ') or not _verify(auth[7:]): return (401, {'error': 'Unauthorized'}) # שכבת אימות tn, dl = body.get('targetName'), body.get('dangerLevel') if not isinstance(tn, str) or not tn: return (400, {'error': 'Invalid intel'}) if isinstance(dl, bool) or not isinstance(dl, (int, float)) or dl > 10: return (400, {'error': 'Invalid intel'}) # Trust Boundary return (201, {'success': True}) return (404, {'error': 'Not found'})
הפתרון נשמר מקומית אוטומטית.