کد منبع امن

۱. مرور کلی

تکنیک‌های کد منبع امن مجموعه‌ای از شیوه‌ها هستند که می‌توانند برای بهبود امنیت کد منبع مورد استفاده قرار گیرند. این تکنیک‌ها می‌توانند به شناسایی و رفع آسیب‌پذیری‌های کد منبع، جلوگیری از دسترسی غیرمجاز به کد منبع و محافظت از کد منبع در برابر تغییر کمک کنند.

برخی از تکنیک‌های رایج امن‌سازی کد منبع عبارتند از:

  • Linting: Linting فرآیند بررسی کد منبع برای خطاها و مشکلات سبکی است. این کار با استفاده از ابزار lint انجام می‌شود، که برنامه‌ای است که کد منبع را تجزیه و تحلیل کرده و مشکلات احتمالی را شناسایی می‌کند. ابزارهای Lint می‌توانند برای بررسی انواع خطاها، از جمله خطاهای نحوی، خطاهای معنایی، خطاهای سبک و آسیب‌پذیری‌های امنیتی استفاده شوند.
  • تست امنیتی استاتیک اپلیکیشن (SAST): SAST نوعی تست امنیتی است که کد منبع، کد باینری یا کد بایت را برای شناسایی آسیب‌پذیری‌های امنیتی تجزیه و تحلیل می‌کند. ابزارهای SAST را می‌توان برای یافتن آسیب‌پذیری‌ها در زبان‌های برنامه‌نویسی متنوعی از جمله Go، Java، Python، C++ و C# استفاده کرد.
  • اسکن مجوز: اسکن مجوز فرآیند شناسایی مجوزهای اجزای نرم‌افزاری شخص ثالث مورد استفاده در یک برنامه نرم‌افزاری است. این امر مهم است زیرا به اطمینان از مطابقت برنامه با شرایط مجوزها کمک می‌کند و می‌تواند به جلوگیری از مشکلات قانونی کمک کند.

این تکنیک‌ها می‌توانند برای بهبود امنیت کد منبع در تمام مراحل چرخه عمر توسعه نرم‌افزار مورد استفاده قرار گیرند. Linting می‌تواند برای شناسایی خطاها در اوایل فرآیند توسعه استفاده شود، SAST می‌تواند برای یافتن آسیب‌پذیری‌ها قبل از کامپایل یا استقرار کد استفاده شود و اسکن مجوز می‌تواند برای اطمینان از مطابقت برنامه با شرایط مجوزها مورد استفاده قرار گیرد.

استفاده از این تکنیک‌ها می‌تواند به بهبود امنیت کد منبع و کاهش خطر نقض‌های امنیتی کمک کند.

آنچه یاد خواهید گرفت

این آزمایشگاه بر ابزارها و تکنیک‌های ایمن‌سازی کد منبع نرم‌افزار تمرکز خواهد داشت.

  • آسترکاری
  • تست امنیت برنامه‌های کاربردی استاتیک
  • اسکن مجوز

تمام ابزارها و دستورات مورد استفاده در این آزمایشگاه در Cloud Shell اجرا خواهند شد.

۲. تنظیمات و الزامات

تنظیم محیط خودتنظیم

  1. وارد کنسول گوگل کلود شوید و یک پروژه جدید ایجاد کنید یا از یک پروژه موجود دوباره استفاده کنید. اگر از قبل حساب جیمیل یا گوگل ورک اسپیس ندارید، باید یکی ایجاد کنید .

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • نام پروژه ، نام نمایشی برای شرکت‌کنندگان این پروژه است. این یک رشته کاراکتری است که توسط APIهای گوگل استفاده نمی‌شود. می‌توانید آن را در هر زمانی به‌روزرسانی کنید.
  • شناسه پروژه در تمام پروژه‌های گوگل کلود منحصر به فرد است و تغییرناپذیر است (پس از تنظیم، قابل تغییر نیست). کنسول کلود به طور خودکار یک رشته منحصر به فرد تولید می‌کند؛ معمولاً برای شما مهم نیست که چیست. در اکثر آزمایشگاه‌های کد، باید به شناسه پروژه ارجاع دهید (که معمولاً با عنوان PROJECT_ID شناخته می‌شود). اگر شناسه تولید شده را دوست ندارید، می‌توانید یک شناسه تصادفی دیگر ایجاد کنید. به عنوان یک جایگزین، می‌توانید شناسه خودتان را امتحان کنید و ببینید که آیا در دسترس است یا خیر. پس از این مرحله قابل تغییر نیست و در طول پروژه باقی خواهد ماند.
  • برای اطلاع شما، یک مقدار سوم، شماره پروژه ، وجود دارد که برخی از APIها از آن استفاده می‌کنند. برای کسب اطلاعات بیشتر در مورد هر سه این مقادیر، به مستندات مراجعه کنید.
  1. در مرحله بعد، برای استفاده از منابع/API های ابری، باید پرداخت صورتحساب را در کنسول ابری فعال کنید . اجرای این آزمایشگاه کد، اگر اصلاً هزینه‌ای نداشته باشد، هزینه زیادی نخواهد داشت. برای خاموش کردن منابع به طوری که پس از این آموزش متحمل پرداخت صورتحساب نشوید، می‌توانید منابعی را که ایجاد کرده‌اید یا کل پروژه را حذف کنید. کاربران جدید Google Cloud واجد شرایط برنامه آزمایشی رایگان ۳۰۰ دلاری هستند.

ویرایشگر Cloud Shell را شروع کنید

این آزمایشگاه برای استفاده با ویرایشگر پوسته ابری گوگل (Google Cloud Shell Editor) طراحی و آزمایش شده است. برای دسترسی به ویرایشگر،

  1. برای دسترسی به پروژه گوگل خود به آدرس https://console.cloud.google.com مراجعه کنید.
  2. در گوشه بالا سمت راست، روی آیکون ویرایشگر پوسته ابری کلیک کنید.

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)

۳. پرزگیری

Linting برای بررسی اشتباهات رایج مبتنی بر سبک یا نقص‌های مربوط به نحو استفاده می‌شود. Linting با ارائه یک الگوی نحو مشترک در بین چندین تیم، به امنیت کمک می‌کند که منجر به بررسی سریع‌تر کد، اشتراک‌گذاری دانش و وضوح کد می‌شود.

علاوه بر این، Linting اشتباهات رایج نحوی را که می‌توانند منجر به آسیب‌پذیری‌های رایجی مانند استفاده نادرست یا ناکارآمد از کتابخانه‌ها یا APIهای اصلی شوند، شناسایی می‌کند.

ابزار لینک‌دهی 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 $?

در این حالت، از آنجایی که دستور منجر به خطا شده است، وضعیت خروج ۱ یا بیشتر خواهد بود. این روشی است که می‌تواند در یک خط لوله CI/CD برای تعیین موفقیت/شکست ابزار استفاده شود.

فایل main.go را ویرایش کنید و کد را اصلاح کنید:

  • خط زیر را با اضافه کردن اسلش ( // ) در متد main() از حالت کامنت خارج کنید. LINTING - Step 1
  • دو خطی که مستقیماً زیر LINTING - Step 2 درون متد main() قرار دارند را با حذف اسلش‌های ابتدای آنها از حالت کامنت خارج کنید.

staticcheck در دایرکتوری ریشه پروژه دوباره اجرا کنید

staticcheck

دستور نباید هیچ نتیجه‌ای (یعنی یک خط خالی) برگرداند.

وضعیت خروج فرمان را بررسی کنید.

  echo $?

در این حالت، از آنجایی که دستور منجر به خطایی نشده است، وضعیت خروج صفر خواهد بود.

۴. تست امنیت برنامه‌های کاربردی استاتیک

تست امنیتی AST/استاتیک - تجزیه و تحلیل کد استاتیک را برای یافتن نقاط ضعف و آسیب‌پذیری‌های رایج ( 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

۵. اسکن مجوز

مجوزها برای امنیت مهم هستند زیرا می‌توانند از نظر قانونی شما را ملزم به افشای کد منبعی کنند که ممکن است نخواهید آن را افشا کنید. این مفهوم، مجوزهای « کپی‌لفت » نامیده می‌شود که در صورت استفاده از وابستگی‌ها با آن مجوزها، شما را ملزم به افشای کد منبع می‌کنند.

نصب 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

۶. تبریک

تبریک می‌گویم، شما codelab را تمام کردید!

آنچه آموخته‌اید

  • ابزارها و تکنیک‌هایی برای ایمن‌سازی کد منبع

آخرین به‌روزرسانی: ۲۳/۳/۲۳