رمز المصدر الآمن

1. نظرة عامة

تقنيات رمز المصدر الآمن هي مجموعة من الممارسات التي يمكن استخدامها لتحسين أمان رمز المصدر. يمكن أن تساعد هذه التقنيات في تحديد الثغرات الأمنية في رمز المصدر وإصلاحها، ومنع الوصول غير المصرَّح به إلى رمز المصدر، وحماية رمز المصدر من التعديل.

تشمل بعض التقنيات الشائعة لرمز المصدر الآمن ما يلي:

  • التدقيق: التدقيق هو عملية التحقّق من رمز المصدر بحثًا عن الأخطاء والمشاكل المتعلّقة بالأسلوب. ويتم ذلك باستخدام أداة Lint، وهي برنامج يحلّل الرمز المصدر ويحدّد المشاكل المحتملة. يمكن استخدام أدوات Lint للتحقّق من مجموعة متنوعة من الأخطاء، بما في ذلك أخطاء التركيب وأخطاء المعنى وأخطاء الأسلوب والثغرات الأمنية.
  • اختبار أمان التطبيقات الثابت (SAST): هو نوع من اختبارات الأمان التي تحلّل الرمز المصدر أو الرمز الثنائي أو رمز البايت لتحديد الثغرات الأمنية. يمكن استخدام أدوات SAST للعثور على الثغرات الأمنية في مجموعة متنوعة من لغات البرمجة، بما في ذلك Go وJava وPython وC++‎ وC#.
  • فحص التراخيص: فحص التراخيص هو عملية تحديد تراخيص مكوّنات البرامج التابعة لجهات خارجية والمستخدَمة في أحد تطبيقات البرامج. هذا الإجراء مهم لأنّه يساعد في ضمان امتثال التطبيق لبنود التراخيص، ما يساعد في تجنُّب المشاكل القانونية.

يمكن استخدام هذه الأساليب لتحسين أمان الرمز المصدري في جميع مراحل دورة حياة تطوير البرامج. يمكن استخدام التحليل باستخدام أداة Lint لتحديد الأخطاء في وقت مبكر من عملية التطوير، ويمكن استخدام تحليل SAST للعثور على الثغرات الأمنية قبل تجميع الرمز البرمجي أو نشره، ويمكن استخدام فحص الترخيص للتأكّد من أنّ التطبيق يتوافق مع بنود التراخيص.

يمكن أن يساعد استخدام هذه التقنيات في تحسين أمان الرمز المصدري والحدّ من خطر اختراق الأمان.

ما ستتعلمه

سيركّز هذا الدرس التطبيقي على الأدوات والتقنيات اللازمة لتأمين الرمز المصدري للبرامج.

  • Linting
  • اختبار أمان التطبيقات غير التفاعلي
  • فحص التراخيص

سيتم تنفيذ جميع الأدوات والأوامر المستخدَمة في هذا الدرس التطبيقي في Cloud Shell.

2. الإعداد والمتطلبات

إعداد البيئة بوتيرة ذاتية

  1. سجِّل الدخول إلى Google Cloud Console وأنشِئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. إذا لم يكن لديك حساب على Gmail أو Google Workspace، عليك إنشاء حساب.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • اسم المشروع هو الاسم المعروض للمشاركين في هذا المشروع. وهي سلسلة أحرف لا تستخدمها Google APIs. ويمكنك تعديله في أي وقت.
  • رقم تعريف المشروع هو معرّف فريد في جميع مشاريع Google Cloud ولا يمكن تغييره بعد ضبطه. تنشئ Cloud Console تلقائيًا سلسلة فريدة، ولا يهمّك عادةً ما هي. في معظم دروس البرمجة، عليك الرجوع إلى رقم تعريف المشروع (يتم تحديده عادةً على أنّه PROJECT_ID). إذا لم يعجبك رقم التعريف الذي تم إنشاؤه، يمكنك إنشاء رقم تعريف عشوائي آخر. يمكنك بدلاً من ذلك تجربة اسم مستخدم من اختيارك ومعرفة ما إذا كان متاحًا. لا يمكن تغيير هذا الخيار بعد هذه الخطوة وسيظل ساريًا طوال مدة المشروع.
  • للعلم، هناك قيمة ثالثة، وهي رقم المشروع الذي تستخدمه بعض واجهات برمجة التطبيقات. يمكنك الاطّلاع على مزيد من المعلومات عن كل هذه القيم الثلاث في المستندات.
  1. بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام موارد/واجهات برمجة تطبيقات Cloud. لن تكلفك تجربة هذا الدرس البرمجي الكثير من المال، إن لم تكلفك شيئًا على الإطلاق. لإيقاف الموارد كي لا يتم تحصيل رسوم منك بعد هذا البرنامج التعليمي، يمكنك حذف الموارد التي أنشأتها أو حذف المشروع بأكمله. يمكن لمستخدمي Google Cloud الجدد الاستفادة من برنامج الفترة التجريبية المجانية بقيمة 300 دولار أمريكي.

بدء Cloud Shell Editor

تم تصميم هذا الدرس التطبيقي واختباره لاستخدامه مع "محرّر Google Cloud Shell". للوصول إلى المحرِّر، اتّبِع الخطوات التالية:

  1. يمكنك الوصول إلى مشروعك على Google من خلال https://console.cloud.google.com.
  2. في أعلى يسار الصفحة، انقر على رمز محرر Cloud Shell

8560cc8d45e8c112.png

  1. سيتم فتح لوحة جديدة في أسفل النافذة
  2. انقر على الزر "فتح المحرِّر"

9e504cb98a6a8005.png

  1. سيتم فتح المحرِّر مع مستكشف على اليسار ومحرِّر في المنطقة الوسطى
  2. يجب أن يتوفّر جزء وحدة طرفية أيضًا في أسفل الشاشة
  3. إذا لم تكن النافذة الطرفية مفتوحة، استخدِم مجموعة المفاتيح `ctrl+`` لفتح نافذة طرفية جديدة.

إعداد البيئة

اضبط GOPATH على دليل واحد لتبسيط الأوامر المستخدَمة في هذا الدرس التطبيقي.

export GOPATH=$HOME/gopath

إنشاء دليل لتخزين عملنا

mkdir -p workspace
cd workspace

استنساخ مستودع رمز المصدر

git clone https://gitlab.com/gcp-solutions-public/shift-left-security-workshop/source-code-lab.git
cd source-code-lab
export WORKDIR=$(pwd)

3- Linting

يتم استخدام Linting للتحقّق من الأخطاء الشائعة المستندة إلى الأسلوب أو العيوب المتعلّقة بالبنية. تساعد عملية التحليل باستخدام أداة Lint في تعزيز الأمان من خلال توفير بنية مشتركة بين فِرق متعددة يؤدي إلى تسريع عمليات مراجعة الرموز البرمجية ومشاركة المعرفة وتوضيح الرموز البرمجية.

بالإضافة إلى ذلك، تحدّد عملية التحليل باستخدام أداة Lint أخطاء البنية الشائعة التي يمكن أن تؤدي إلى ثغرات أمنية شائعة، مثل الاستخدام غير السليم أو الأقل فعالية للمكتبات أو واجهات برمجة التطبيقات الأساسية.

تثبيت أداة الربط staticcheck

 go get honnef.co/go/tools/cmd/staticcheck@latest

تشغيل Go Linter (staticcheck) في الدليل الجذري للمشروع

 staticcheck

مراجعة الناتج

main.go:42:29: unnecessary use of fmt.Sprintf (S1039)

يظهر لك الخطأ لأنّ http.ListenAndServe() يقبل سلسلة، ويستخدم الرمز الحالي Sprintf بدون تمرير متغيرات إلى السلسلة.

راجِع حالة إنهاء الأمر.

echo $?

في هذه الحالة، بما أنّ الأمر أدّى إلى حدوث خطأ، ستكون حالة الخروج 1 أو أكبر. هذه إحدى الطرق التي يمكن استخدامها في مسار CI/CD لتحديد نجاح الأداة أو تعذّر تنفيذها.

عدِّل ملف main.go وأصلِح الرمز البرمجي:

  • علِّق على السطر أدناه LINTING - Step 1 داخل طريقة main()، وذلك بإضافة شرطتين مائلتين في البداية(//).
  • أزِل التعليق من السطرَين أسفل LINTING - Step 2 مباشرةً داخل الدالة main()، وذلك عن طريق إزالة الشرطتَين المائلتَين في البداية.

أعِد تشغيل staticcheck في الدليل الجذر للمشروع

staticcheck

يجب ألا يعرض الأمر أي نتائج (أي سطر فارغ).

افحص حالة الخروج للأمر.

  echo $?

في هذه الحالة، بما أنّ الأمر لم يؤدِّ إلى حدوث خطأ، ستكون حالة الخروج صفر.

4. اختبار أمان التطبيقات غير التفاعلي

اختبار الأمان الثابت/تحليل الأمان الثابت: يوفّر تحليل الرمز البرمجي الثابت بحثًا عن نقاط الضعف والثغرات الشائعة ( CWE)

تثبيت أداة AST (gosec)

    export GOSEC_VERSION="2.15.0"
    curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | \
          sh -s -- -b $(go env GOPATH)/bin v${GOSEC_VERSION}

تشغيل gosec باستخدام ملف السياسة مقابل رمز المصدر

gosec -conf policies/gosec-policy.json -fmt=json ./...

يجب أن تكون النتيجة مشابهة لما يلي

{
    "Golang errors": {},
    "Issues": [
        {
            "severity": "HIGH",
            "confidence": "LOW",
            "cwe": {
                "ID": "798",
                "URL": "https://cwe.mitre.org/data/definitions/798.html"
            },
            "rule_id": "G101",
            "details": "Potential hardcoded credentials",
            "file": "/home/random-user-here/shift-left-security-workshop/labs/source-code-lab/main.go",
            "code": "31: \t// STEP 2: Change this and the reference below to something different (ie, not \"pawsword\" or \"password\")\n32: \tvar pawsword = \"im-a-cute-puppy\"\n33: \tfmt.Println(\"Something a puppy would use: \", username, pawsword)\n",
            "line": "32",
            "column": "6"
        }
    ],
    "Stats": {
        "files": 1,
        "lines": 89,
        "nosec": 0,
        "found": 1
    }
}

رصدت الأداة مشكلة محتملة: Potential hardcoded credentials

5- فحص التراخيص

تُعدّ التراخيص مهمة للأمان لأنّها قد تتطلّب منك قانونيًا الكشف عن الرمز المصدر الذي قد لا تريد الكشف عنه. يُطلق على هذا المفهوم اسم تراخيص " المشاركة مع الاحتفاظ بالحقوق" التي تتطلّب منك عرض الرمز المصدر إذا كنت تستخدم تبعيات مع هذه التراخيص.

تثبيت تطبيق "golicense"

mkdir -p /tmp/golicense
wget -O /tmp/golicense/golicense.tar.gz https://github.com/mitchellh/golicense/releases/download/v0.2.0/golicense_0.2.0_linux_x86_64.tar.gz
pushd /tmp/golicense
tar -xzf golicense.tar.gz
chmod +x golicense
mv golicense $(go env GOPATH)/bin/golicense
popd

إنشاء الملف الثنائي

go build

نفِّذ عملية التحقّق من الترخيص باستخدام ملف السياسة الحالي الذي لا يسمح بتراخيص "BSD-3-Clause"

golicense policies/license-policy.hcl hello-world

ملاحظة: من المفترض أن يتعذّر ذلك مع ظهور نتيجة مشابهة لما يلي:

 🚫 rsc.io/sampler    BSD 3-Clause "New" or "Revised" License
 🚫 rsc.io/quote      BSD 3-Clause "New" or "Revised" License
 🚫 golang.org/x/text BSD 3-Clause "New" or "Revised" License

عدِّل ملف السياسة policies/license-policy.hcl لنقل "BSD-3-Clause" من القائمة deny إلى القائمة allow.

إعادة إجراء فحص الترخيص

golicense policies/license-policy.hcl hello-world

ملاحظة: من المفترض أن تنجح هذه العملية مع ظهور نتيجة مشابهة لما يلي:

    ✅ rsc.io/quote      BSD 3-Clause "New" or "Revised" License
    ✅ rsc.io/sampler    BSD 3-Clause "New" or "Revised" License
    ✅ golang.org/x/text BSD 3-Clause "New" or "Revised" License

6. تهانينا

تهانينا، لقد أكملت درس البرمجة.

ما تعلّمته

  • أدوات وأساليب لتأمين رمز المصدر

تاريخ آخر تعديل: 23/3/2023