أمان تطبيقات TypeScript: أهم 10 ثغرات أمنية للمبتدئين

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

أمان تطبيقات TypeScript: أهم 10 ثغرات أمنية للمبتدئين

\n\n

TypeScript هي طبقة فوق JavaScript تضيف الكتابة الثابتة، لكنها لا تحمي من الثغرات الأمنية الكلاسيكية للويب. غالبًا ما يعتمد المطورون المبتدئون على صرامة الأنواع، متناسين الأمان على مستوى المنطق والبيانات. في هذه المقالة، سنستعرض أكثر 10 ثغرات أمنية شيوعًا في تطبيقات TypeScript مع أمثلة على الكود وطرق الحماية.

\n\n

1. XSS (Cross-Site Scripting) عبر dangerouslySetInnerHTML

\n

واحدة من أكثر المشكلات شيوعًا هي إدراج HTML الخاص بالمستخدم دون تنقية. في TypeScript، يحدث هذا غالبًا عند العمل مع React أو Angular.

\n\n
// ❌ كود ضعيف
function UserComment({ comment }: { comment: string }) {
  return <div dangerouslySetInnerHTML={{ __html: comment }} />;
}

// ✅ الخيار الآمن
import DOMPurify from 'dompurify';

function SafeComment({ comment }: { comment: string }) {
  const sanitized = DOMPurify.sanitize(comment);
  return <div dangerouslySetInnerHTML={{ __html: sanitized }} />;
}
\n\n

2. حقن SQL عبر استعلامات نصية

\n

TypeScript لا يحمي من حقن SQL إذا كنت تستخدم نصوصًا خام. استخدم دائمًا الاستعلامات ذات المعاملات.

\n\n
// ❌ خطير
const query = `SELECT * FROM users WHERE email = '${userEmail}'`;

// ✅ آمن (مثال مع Prisma)
const user = await prisma.user.findUnique({
  where: { email: userEmail }
});
\n\n

3. تخزين غير آمن للأسرار في الكود

\n

يجب ألا تظهر مفاتيح API والرموز وكلمات المرور في الكود المصدري. يتم ترجمة TypeScript إلى JavaScript، وتبقى جميع النصوص قابلة للقراءة.

\n\n
// ❌ لا تفعل هذا أبدًا
const API_KEY = 'sk-1234567890abcdef';

// ✅ استخدم متغيرات البيئة
const API_KEY = process.env.API_KEY;
if (!API_KEY) throw new Error('API_KEY is missing');
\n\n

4. حقن NoSQL (MongoDB)

\n

عند العمل مع MongoDB عبر Mongoose أو برنامج التشغيل، يمكن أن تمرر عن طريق الخطأ كائن استعلام يتلاعب بالمنطق.

\n\n
// ❌ كود ضعيف
app.post('/login', async (req, res) => {
  const user = await User.findOne({ 
    email: req.body.email, 
    password: req.body.password 
  });
});

// ✅ الخيار الآمن
app.post('/login', async (req: Request, res: Response) => {
  const { email, password } = req.body;
  if (typeof email !== 'string' || typeof password !== 'string') {
    return res.status(400).send('Invalid input');
  }
  const user = await User.findOne({ email, password });
});
\n\n

5. CSRF (Cross-Site Request Forgery)

\n

إذا كان تطبيقك يستخدم مصادقة ملفات تعريف الارتباط، يمكن للمهاجم تنفيذ إجراءات نيابة عن المستخدم.

\n\n
// ❌ عدم وجود حماية
app.post('/transfer', (req, res) => {
  // تنفيذ التحويل دون التحقق من المصدر
});

// ✅ الحماية عبر رمز CSRF (مثال مع csurf)
import csrf from 'csurf';
const csrfProtection = csrf({ cookie: true });
app.post('/transfer', csrfProtection, (req, res) => {
  // تنفيذ آمن
});
\n\n

6. تلوث النموذج الأولي (Prototype Pollution)

\n

عند دمج الكائنات دون تحقق، يمكن استبدال خصائص النموذج الأولي، مما يؤدي إلى ثغرات أمنية.

\n\n
// ❌ خطير
function merge(target: any, source: any) {
  for (const key in source) {
    target[key] = source[key];
  }
}

// ✅ آمن
function safeMerge(target: Record<string, any>, source: Record<string, any>) {
  for (const key in source) {
    if (Object.prototype.hasOwnProperty.call(source, key)) {
      target[key] = source[key];
    }
  }
}
\n\n

7. تسرب المعلومات عبر الأخطاء

\n

يجب ألا تظهر تتبعات المكدس وتفاصيل قاعدة البيانات للمستخدم. قد يخدع TypeScript اليقظة بسبب الأنواع الصارمة.

\n\n
// ❌ سيء
app.use((err, req, res, next) => {
  res.status(500).json({ error: err.m                

المدونات

توصيات الكتب