ایمن کردن خط لوله CI/CD با CodeMender

۱. قبل‌از شروع

به codelab عملی برای ایمن‌سازی خط لوله CI/CD با CodeMender خوش آمدید.

در ارائه نرم‌افزارهای مدرن، ابزارهای تحلیل ایستا (مانند CodeQL) برای شناسایی الگوهای نحوی شناخته‌شده ضروری هستند، اما اغلب آسیب‌پذیری‌های ظریف پنهان‌شده در عمق منطق کسب‌وکار را نادیده می‌گیرند و هشدارهای شلوغ و تأییدنشده تولید می‌کنند.

CodeMender (اجرایی CLI: cm) خط لوله CI/CD شما را بهبود می‌بخشد—در کنار ابزارهای SAST موجود عمل می‌کند—با استقرار عوامل استدلال امنیتی Google با پشتیبانی Gemini برای:

کشف نقص‌های پیچیده منطق کسب‌وکار: استدلال درباره بافت برنامه و جریان‌های داده معماری فراتر از قوانین الگوی ایستا و انعطاف‌ناپذیر.

کاهش چشمگیر موارد مثبت کاذب ازطریق درستی‌سنجی بهره‌برداری خودکار: اثبات پویای بهره‌برداری‌پذیری در محیط‌های جعبه امن قبل‌از هشدار دادن به توسعه‌دهندگان.

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

در این codelab، بااستفاده از GitHub Actions و Google Cloud Workload Identity Federation‏ (WIF) بدون کلید، CodeMender را در مخزن OWASP Juice Shop ادغام خواهید کرد.

پیش‌نیازها

  • توصیه‌شده: آشنایی اولیه با مفاهیم CodeMender (در ایمن‌سازی برنامه با CodeMender پوشش داده شده است)
  • درک اولیه از گردش‌های کاری GitHub Actions، راه‌اندازها، و نحو YAML
  • آشنایی اولیه با فرمان‌های Git و گردش‌های کار بازبینی درخواست pull
  • دانش پایه درباره مفاهیم Google Cloud IAM (حساب‌های خدمات، نقش‌ها، و میاناهای برنامه‌سازی کاربردی)
  • آشنایی با آسیب‌پذیری‌های رایج برنامه وب (مانند تزریق SQL و XSS)

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

  • نحوه پیکربندی اصالت‌سنجی بدون کلید با اعتماد صفر بین GitHub Actions و Google Cloud ازطریق Workload Identity Federation (WIF)
  • نحوه ساختن گردش کار اسکن خودکار آسیب‌پذیری بااستفاده از CodeMender و gemini-3.8-flash
  • نحوه انتشار گزارش‌های امنیتی قابل‌اجرا بااستفاده از OASIS SARIF v2.1.0 و خلاصه‌های کار GitHub Actions بومی
  • نحوه ساختن گردش کار اصلاح خودکار که وصله‌های کد تأییدشده با آزمایش را تولید می‌کند و «درخواست‌های واکشی» را برای بازبینی انسانی باز می‌کند
  • نحوه اعمال دروازه‌های سخت کیفیت خودکارسازی‌شده (--fail-on) و ذخیره‌سازی موقت خط لوله برای امنیت مداوم با سرعت بالا

آنچه نیاز خواهید داشت

  • پروژه Google Cloud با صورت‌حساب فعال و اجازه‌های «مالک/ ویرایشگر پروژه»
  • یک حساب GitHub با اجازه‌های ایجاد مخازن، پیکربندی Secrets، و مدیریت Actions (در مرحله ۳ بااستفاده از GitHub CLI، OWASP Juice Shop GitHub Repo را منشعب می‌کنید).

۲. آشنایی با معماری CodeMender CI/CD

در DevSecOps سازمانی مدرن، امنیت مبتنی بر هوش مصنوعی نمی‌تواند صرفاً یک ابزار دستی رایانه باشد. این ابزار باید به‌عنوان یک دروازه‌بان خودکار (مسدود کردن درخواست‌های واکشی ناامن) و یک توسعه‌دهنده مشترک خودکار (پیشنهاد وصله‌های تأییدشده مستقیماً در Git) عمل کند.

برای دستیابی به این هدف، معماری گردش کار دوگانه را که توسط Google Cloud Workload Identity Federation (WIF) و مدل‌های استدلال Gemini Enterprise پشتیبانی می‌شود پیاده‌سازی خواهید کرد.

معماری گردش کار دوگانه

CodeMender Autonomous CI/CD Pipeline Architecture

به‌جای گنجاندن تشخیص و اصلاح در یک اسکریپت یکپارچه، خط لوله امنیت را به دو گردش کار مجزا و هدفمند تقسیم می‌کند:

Workflow

راه‌انداز اصلی

مسئولیت اصلی

Quality Hard Gate

۱. اسکنر آسیب‌پذیری(codemender-scan.yml)

درخواست‌های Pull، ارسال‌های Main،‏ Cron هفتگی، ارسال دستی

• اسکن‌های AST تفاضلی سریع را روی PRها (حدود ۱۵ ثانیه)، اسکن‌های خط مبنای سریع را روی pushها (–quick)، و ممیزی‌های عمیق هم‌زمان را روی زمان‌بندی‌ها اجرا می‌کند• آمادگی را ازقبل ازطریق cm health –strict اعتبارسنجی می‌کند• «خلاصه‌های کار کنش‌های» بومی را تولید می‌کند و OASIS SARIF را در برگه «امنیت GitHub» بارگذاری می‌کند

اگر آسیب‌پذیری‌های «بالا» یا «بحرانی» جدیدی شناسایی شود، ادغام PR را مسدود می‌کند (–fail-on)

۲. Autonomous Remediator(codemender-remediate.yml)

راه‌انداز دستی (workflow_dispatch)، کرون شبانه

• وضعیت را از مصنوعات اسکن (cm report import) و state.db ازسر می‌گیرد• وصله‌ها را بااستفاده از استدلال Gemini ترکیب می‌کند• مرزهای فضای کاری تمیز را حفظ می‌کند و «درخواست‌های واکشی» آماده بازبینی را ارسال می‌کند

اطمینان از تمیز بودن تفاوت‌های تولید قبل‌از باز کردن PR

سه اصل اصلی طراحی سازمانی

همان‌طور که این گردش‌های کاری را در بخش‌های بعدی می‌سازید، این سه ستون معماری بنیادی را در ذهن داشته باشید:

🔑 اعتبارسنجی پیش‌پرواز و اصالت‌سنجی بدون کلید با اعتماد صفر:

هیچ کلید JSON حساب سرویس Google Cloud با عمر طولانی در GitHub Secrets ذخیره نشده است. اجراکننده یک توکن OIDC کوتاه‌مدت تولید می‌کند که ازطریق Google Cloud STS با یک اعتبارنامه موقت ۱ ساعته مبادله می‌شود، persist-credentials: false را در Git checkouts تنظیم می‌کند، و cm health --strict را اجرا می‌کند تا اعتبارنامه‌ها، دسترسی‌پذیری شبکه، و اجازه‌های IAM را قبل‌از مصرف سهمیه مدل تأیید کند.

⚡ مسیریابی اسکن تطبیقی و نوفه‌زدایی قدیمی:

CodeMender به‌جای اجرای ممیزی‌های کامل و کند مخزن در هر درخواست واکشی، هر رویداد CI را به حالت اسکن بهینه هدایت می‌کند: درخواست‌های واکشی باعث راه‌اندازی تحلیل AST تفاضلی (--diff="origin/$BASE_REF") روی فایل‌های اصلاح‌شده و فراخوان‌های ۱-پرشی در کمتر از ۱۵ ثانیه می‌شوند؛ ارسال‌های شاخه اصلی اسکن‌های پایه سریع تک‌جلسه‌ای (--quick) را اجرا می‌کنند؛ و برنامه‌های هفتگی ممیزی‌های عمیق هم‌زمان فایل‌به‌فایل (پیش‌فرض cm find .) را اجرا می‌کنند. آسیب‌پذیری‌های پایگاه کد ازپیش‌موجود که توسط درخواست واکشی دست‌نخورده باقی مانده‌اند، با برچسب [LEGACY / UNTOUCHED] مشخص می‌شوند؛ این آسیب‌پذیری‌ها برای رؤیت‌پذیری در گزارش‌های SARIF ظاهر می‌شوند، اما دروازه ادغام درخواست واکشی را مسدود نمی‌کنند و اصلاح خودکار را راه‌اندازی نمی‌کنند.

🛡️ مشاهده‌پذیری امنیتی غیرمسدودکننده ارتجاعی:

حتی وقتی --fail-on با کد 1 برای مسدود کردن PR ناامن خارج می‌شود، محافظت از مراحل صادر کردن گزارش و بارگذاری SARIF با steps.scan.outputs.completed == 'true' و hashFiles('results.sarif') != '' تضمین می‌کند که هشدارهای OASIS SARIF و «خلاصه‌های کار» همچنان منتشر می‌شوند—درحالی‌که اگر اجرا لغو شود یا به‌دلیل خطای راه‌اندازی یا ظرفیت متوقف شود، صادر کردن و بارگذاری به‌طور تمیز نادیده گرفته می‌شود (10–60).

۳. اصالت‌سنجی و آماده‌سازی مخزن هدف در Cloud Shell

برای ایجاد اصالت‌سنجی بدون کلید و اجرای خطوط لوله امنیتی خودکارشده، به یک مخزن GitHub هدف قابل‌دسترسی که متعلق به شما باشد نیاز دارید. در این codelab، از OWASP Juice Shop (یک برنامه وب Node.js که به‌طور عمدی آسیب‌پذیر است) به‌عنوان یک زمین بازی امنیتی آماده استفاده می‌کنید.

از GitHub CLI (gh) که ازقبل در Google Cloud Shell نصب شده است برای اصالت‌سنجی با GitHub، ضبط خودکار جزئیات کاربر، و آماده‌سازی مخزن در یک جریان ساده استفاده خواهید کرد.

مرحله ۱: باز کردن Cloud Shell و اصالت‌سنجی GitHub CLI

کنسول Google Cloud را باز کنید و Cloud Shell (نماد >_ در نوار پیمایش بالا) را فعال کنید.

برای پیکربندی مدیریت اطلاعات کاربری Git، اصالت‌سنجی GitHub CLI (gh) را انجام دهید:

gh auth login --hostname github.com --git-protocol https --web

دستورالعمل‌های روی صفحه را دنبال کنید:

کد یک‌بارمصرف ۸ نویسه‌ای چاپ‌شده در Cloud Shell (مثلاً 1234-ABCD) را کپی کنید.

کلید ورود را فشار دهید تا https://github.com/login/device در مرورگرتان باز شود.

کد را جای‌گذاری کنید و روی مجاز کردن github کلیک کنید.

مرحله ۲: صادر کردن متغیرها به‌صورت پویا و انشعاب OWASP Juice Shop

فرمان‌های زیر را در Cloud Shell اجرا کنید تا نام کاربری GitHub شما به‌طور خودکار ضبط شود و مخزن آماده شود:

# 1. Automatically capture your GitHub username (customize GITHUB_REPO if desired)
export GITHUB_ORG=$(gh api user -q .login)
export GITHUB_REPO="${GITHUB_REPO:-juice-shop}"
export GITHUB_REPOSITORY="${GITHUB_ORG:+${GITHUB_ORG}/${GITHUB_REPO}}"
echo "Authenticated as: ${GITHUB_REPOSITORY}"

# 2. Fork on GitHub server using GITHUB_REPO as the fork name
gh repo fork juice-shop/juice-shop --fork-name "${GITHUB_REPO}" --default-branch-only --clone=false 2>/dev/null || true

# 3. Shallow clone your fork (downloads only ~15 MB in 3-5 seconds, skipping heavy upstream git history)
[ -d ~/"${GITHUB_REPO}" ] || git clone --depth=1 "https://github.com/${GITHUB_REPOSITORY}.git" ~/"${GITHUB_REPO}" || \
 (sleep 2 && git clone --depth=1 "https://github.com/${GITHUB_REPOSITORY}.git" ~/"${GITHUB_REPO}")
cd ~/"${GITHUB_REPO}"

# 4. Confirm you are in the repository directory
git status

۴. پیکربندی Google Cloud Workload Identity Federation ازطریق gcloud

در این مرحله، از gcloud CLI در Google Cloud Shell برای فعال کردن میاناهای برنامه‌سازی کاربردی لازم، ایجاد «حساب خدمات» CI/CD اختصاصی، راه‌اندازی Workload Identity Pool، و ایجاد اعتماد OIDC با مخزن GitHub‏ (${GITHUB_REPOSITORY}) استفاده خواهید کرد.

مرحله ۱: تنظیم متغیرهای محیطی Google Cloud

در پایانه Cloud Shell (در فضای کاری مخزن کلون‌شده)، شناسه پروژه Google Cloud فعال خود را ضبط کنید، متغیر مخزن GitHub خود را تأیید کنید، و نام‌های منبع WIF را تعریف کنید:

# Capture active Google Cloud Project ID and verify GitHub repository
export PROJECT_ID=$(gcloud config get-value project)
export GITHUB_USER=$(gh api user -q ".login")
export GITHUB_REPO="${GITHUB_REPO:-$(git remote get-url origin 2>/dev/null | sed -E 's#^.*/##; s#\.git$##')}"
export GITHUB_REPO="${GITHUB_REPO:-juice-shop}"
export GITHUB_REPOSITORY="${GITHUB_USER:+${GITHUB_USER}/${GITHUB_REPO}}"

# Define WIF and Service Account resource names
export WORKLOAD_IDENTITY_POOL="codemender-github-pool"
export WORKLOAD_IDENTITY_PROVIDER="codemender-github-provider"
export SERVICE_ACCOUNT_NAME="codemender-ci-runner"

if [ -z "${PROJECT_ID}" ] || [ -z "${GITHUB_REPOSITORY}" ]; then
 echo "ERROR: PROJECT_ID ('${PROJECT_ID}') or GITHUB_REPOSITORY ('${GITHUB_REPOSITORY}') is empty. Check 'gcloud config get-value project' and 'gh auth status'."
else
 echo "Project ID:        ${PROJECT_ID}"
 echo "GitHub Repository: ${GITHUB_REPOSITORY}"
fi

مرحله ۲: فعال کردن Google Cloud APIهای لازم

IAM API،‏ Security Token Service API،‏ IAM Credentials API،‏ Agent Platform API، و Resource Manager API را فعال کنید:

gcloud services enable \
 iam.googleapis.com \
 iamcredentials.googleapis.com \
 sts.googleapis.com \
 aiplatform.googleapis.com \
 cloudresourcemanager.googleapis.com \
 --project=${PROJECT_ID}

مرحله ۳: ایجاد حساب سرویس CI/CD اختصاصی

یک «حساب سرویس Google Cloud» با کمترین امتیاز ایجاد کنید که به اجرای خط لوله CI/CD اختصاص داده شده باشد (اگر ازقبل وجود دارد، به‌طور ایمن از آن مجدداً استفاده کنید):

export SERVICE_ACCOUNT_EMAIL="${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"

gcloud iam service-accounts describe "${SERVICE_ACCOUNT_EMAIL}" \
 --project="${PROJECT_ID}" >/dev/null 2>&1 || \
gcloud iam service-accounts create "${SERVICE_ACCOUNT_NAME}" \
 --display-name="CodeMender CI/CD Pipeline Runner" \
 --project="${PROJECT_ID}"

echo "Service Account Email: ${SERVICE_ACCOUNT_EMAIL}"

مرحله ۴: اعطا کردن اجازه‌های IAM به Agent Platform

نقش roles/aiplatform.user (Agent Platform User) را به «حساب سرویس» اعطا کنید تا بتواند با Gemini Enterprise Agent Platform ارتباط برقرار کند:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
 --member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
 --role="roles/aiplatform.user"

مرحله ۵: ایجاد کردن استخر Workload Identity

«مجموعه هویت حجم کاری» را برای مدیریت ادعاهای هویت GitHub Actions ایجاد کنید (یا اگر ازقبل در پروژه‌تان وجود دارد، آن را به‌طور خودکار بازیابی و فعال کنید):

POOL_STATE=$(gcloud iam workload-identity-pools list \
 --location="global" \
 --show-deleted \
 --project="${PROJECT_ID}" \
 --filter="name ~ /${WORKLOAD_IDENTITY_POOL}$" \
 --format="value(state)")

if [ -z "${POOL_STATE}" ]; then
 gcloud iam workload-identity-pools create "${WORKLOAD_IDENTITY_POOL}" \
   --location="global" \
   --display-name="CodeMender GitHub Pool" \
   --project="${PROJECT_ID}"
else
 [ "${POOL_STATE}" = "DELETED" ] && gcloud iam workload-identity-pools undelete "${WORKLOAD_IDENTITY_POOL}" \
   --location="global" \
   --project="${PROJECT_ID}"
 gcloud iam workload-identity-pools update "${WORKLOAD_IDENTITY_POOL}" \
   --location="global" \
   --no-disabled \
   --project="${PROJECT_ID}"
fi

مرحله ۶: ایجاد کردن ارائه‌دهنده Workload Identity با GitHub OIDC

«ارائه‌دهنده OIDC» را در استخر ایجاد (یا به‌روزرسانی) کنید، نشانی وب صادرکننده https://token.actions.githubusercontent.com را مقید کنید، و ادعاهای رمز GitHub را به ویژگی‌های Google STS نگاشت کنید:

PROVIDER_STATE=$(gcloud iam workload-identity-pools providers list \
 --workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
 --location="global" \
 --show-deleted \
 --project="${PROJECT_ID}" \
 --filter="name ~ /${WORKLOAD_IDENTITY_PROVIDER}$" \
 --format="value(state)")

if [ -z "${GITHUB_REPOSITORY}" ]; then
 echo "ERROR: GITHUB_REPOSITORY is empty. Re-run Step 1 before configuring the OIDC provider."
elif [ -z "${PROVIDER_STATE}" ]; then
 gcloud iam workload-identity-pools providers create-oidc "${WORKLOAD_IDENTITY_PROVIDER}" \
   --workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
   --location="global" \
   --display-name="CodeMender GitHub Provider" \
   --issuer-uri="https://token.actions.githubusercontent.com" \
   --attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository,attribute.repository_owner=assertion.repository_owner" \
   --attribute-condition="assertion.repository == '${GITHUB_REPOSITORY}'" \
   --project="${PROJECT_ID}"
else
 [ "${PROVIDER_STATE}" = "DELETED" ] && gcloud iam workload-identity-pools providers undelete "${WORKLOAD_IDENTITY_PROVIDER}" \
   --workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
   --location="global" \
   --project="${PROJECT_ID}"
 gcloud iam workload-identity-pools providers update-oidc "${WORKLOAD_IDENTITY_PROVIDER}" \
   --workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
   --location="global" \
   --issuer-uri="https://token.actions.githubusercontent.com" \
   --attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository,attribute.repository_owner=assertion.repository_owner" \
   --attribute-condition="assertion.repository == '${GITHUB_REPOSITORY}'" \
   --no-disabled \
   --project="${PROJECT_ID}"
fi

مرحله ۷: به مخزن GitHub اجازه دهید تا خود را به‌جای حساب سرویس جا بزند

نقش roles/iam.workloadIdentityUser را مقید کنید تا به کدهای صادرشده از مخزن شما اجازه دهد خود را به‌جای «حساب سرویس» CI runner جا بزنند، و مقیدسازی خط‌مشی را تأیید کنید:

# Retrieve the canonical Workload Identity Pool resource ID
export POOL_ID=$(gcloud iam workload-identity-pools describe "${WORKLOAD_IDENTITY_POOL}" \
 --project="${PROJECT_ID}" \
 --location="global" \
 --format="value(name)")

if [ -z "${POOL_ID}" ] || [ -z "${GITHUB_REPOSITORY}" ]; then
 echo "ERROR: POOL_ID ('${POOL_ID}') or GITHUB_REPOSITORY ('${GITHUB_REPOSITORY}') is empty. Re-run Step 1 and Step 5."
else
 # Bind Workload Identity User role to the principalSet of your repository
 gcloud iam service-accounts add-iam-policy-binding "${SERVICE_ACCOUNT_EMAIL}" \
   --project="${PROJECT_ID}" \
   --role="roles/iam.workloadIdentityUser" \
   --member="principalSet://iam.googleapis.com/${POOL_ID}/attribute.repository/${GITHUB_REPOSITORY}"

 # Verify the principalSet binding on the Service Account
 gcloud iam service-accounts get-iam-policy "${SERVICE_ACCOUNT_EMAIL}" \
   --project="${PROJECT_ID}"
fi

مرحله ۸: بازیابی مقادیر پیکربندی برای اسرار GitHub

نام کامل منبع «ارائه‌دهنده هویت حجم کاری» خود را بازیابی کنید و آن را در یک متغیر محیطی برای ثبت خودکار در مرحله بعدی ذخیره کنید:

# Retrieve full Workload Identity Provider name
export WORKLOAD_PROVIDER_NAME=$(gcloud iam workload-identity-pools providers describe ${WORKLOAD_IDENTITY_PROVIDER} \
 --workload-identity-pool=${WORKLOAD_IDENTITY_POOL} \
 --location="global" \
 --project=${PROJECT_ID} \
 --format="value(name)")

echo "=========================================================="
echo "WIF CONFIGURATION READY:"
echo "=========================================================="
echo "GCP_WORKLOAD_IDENTITY_PROVIDER: ${WORKLOAD_PROVIDER_NAME}"
echo "GCP_SERVICE_ACCOUNT:            ${SERVICE_ACCOUNT_EMAIL}"
echo "=========================================================="

۵. پیکربندی اجازه‌های گردش کار و اسرار مخزن GitHub

اکنون که Google Cloud WIF آماده شده است، GitHub Repository Secrets را پیکربندی خواهید کرد و اجازه‌های گردش کار لازم را برای اسکن امنیتی خودکار و «درخواست‌های واکشی» اصلاح خودکار اعطا خواهید کرد.

می‌توانید این تنظیمات را مستقیماً از Cloud Shell بااستفاده از GitHub CLI (gh) پیکربندی کنید و نیاز به کپی و جای‌گذاری دستی نام‌های طولانی منابع را کاملاً ازبین ببرید.

مرحله ۱: تنظیم کردن رازهای مخزن بااستفاده از GitHub CLI

در پایانه Cloud Shell، فرمان‌های زیر را اجرا کنید تا دو رمز مخزن موردنیاز را بااستفاده از متغیرهای محیطی فعال به‌طور ایمن تنظیم کنید:

# 1. Set the Workload Identity Provider resource name
gh secret set GCP_WORKLOAD_IDENTITY_PROVIDER \
 --body "${WORKLOAD_PROVIDER_NAME}" \
 --repo "${GITHUB_REPOSITORY}"

# 2. Set the CI/CD Service Account email
gh secret set GCP_SERVICE_ACCOUNT \
 --body "${SERVICE_ACCOUNT_EMAIL}" \
 --repo "${GITHUB_REPOSITORY}"

# 3. Verify the secrets are registered
gh secret list --repo "${GITHUB_REPOSITORY}"

مرحله ۲: اعطای اجازه‌های گردش کار برای درخواست‌های ادغام خودکار

به‌طور پیش‌فرض، گردش‌های کاری GitHub Actions با اجازه‌های فقط خواندنی اجرا می‌شوند و نمی‌توانند «درخواست‌های Pull» ایجاد کنند. در مرحله ۹، CodeMender به‌طور خودکار «درخواست‌های واکشی» اصلاحی درستی‌سنجی‌شده را تولید و ارسال می‌کند.

اجازه‌های نوشتن را اعطا کنید و ایجاد درخواست واکشی را مستقیماً ازطریق GitHub API فعال کنید:

[ -d .git ] || cd ~/"${GITHUB_REPO:-juice-shop}"
export GITHUB_REPOSITORY="${GITHUB_REPOSITORY:-$(git remote get-url origin 2>/dev/null | sed -E 's#^.*github\.com[:/]##; s#\.git$##')}"

gh api \
 --method PUT \
 -H "Accept: application/vnd.github+json" \
 /repos/${GITHUB_REPOSITORY}/actions/permissions/workflow \
 -f default_workflow_permissions="write" \
 -F can_approve_pull_request_reviews=true

مرحله ۳: غیرفعال کردن گردش‌های کاری Juice Shop بالادستی موروثی

انشعاب OWASP Juice Shop بیش‌از ۱۶ گردش کار CI بالادستی (مثل PR Compliance Check،‏ CI/CD Pipeline، و CodeQL Scan) را به‌همراه الگوی PR همیار بالادستی که PRهای هدف‌یابی master را به‌طور خودکار می‌بندد منتقل می‌کند. همه گردش‌های کاری غیر CodeMender را ازطریق GitHub CLI غیرفعال کنید و فایل‌های بالادستی را به‌صورت محلی بردارید تا انشعاب شما فقط گردش‌های کاری CodeMender را اجرا کند:

[ -d .git ] || cd ~/"${GITHUB_REPO:-juice-shop}"
export GITHUB_REPOSITORY="${GITHUB_REPOSITORY:-$(git remote get-url origin 2>/dev/null | sed -E 's#^.*github\.com[:/]##; s#\.git$##')}"

# 1. Disable all inherited non-CodeMender workflows in GitHub Actions (and CodeQL default setup if active)
for WF_ID in $(gh workflow list --all --limit 100 --repo "${GITHUB_REPOSITORY}" --json id,path \
 -q '.[] | select((.path | startswith(".github/workflows/")) and (.path | test("codemender-") | not)) | .id'); do
 gh workflow disable "${WF_ID}" --repo "${GITHUB_REPOSITORY}" 2>/dev/null || true
done
gh api -X PATCH "/repos/${GITHUB_REPOSITORY}/code-scanning/default-setup" \
 -f state=not-configured >/dev/null 2>&1 || true

# 2. Remove upstream workflow files and PR template from the local workspace
for f in .github/workflows/*; do
 case "$f" in *codemender-*) ;; *) rm -f "$f" ;; esac
done
rm -f .github/PULL_REQUEST_TEMPLATE.md

‫۶. ساختن گردش کار اسکن آسیب‌پذیری خودکار با SARIF

در این مرحله، گردش کار اصلی اسکن امنیتی مداوم (.github/workflows/codemender-scan.yml) را ایجاد خواهید کرد که اسکن‌های پایه را روی ارسال‌های شاخه، دروازه‌های تفاضلی روی درخواست‌های Pull، و صادر کردن SARIF به «اسکن کد GitHub» اجرا می‌کند.

مرحله ۱: بارگیری گردش کار اسکن CodeMender

‫codemender-scan.yml را از مخزن آغازگر در .github/workflows/ بارگیری کنید:

[ -d .git ] || cd ~/"${GITHUB_REPO:-juice-shop}"
mkdir -p .github/workflows
curl -fsSL https://raw.githubusercontent.com/edwardc-gcp/codemender-github-actions/main/.github/workflows/codemender-scan.yml \
 -o .github/workflows/codemender-scan.yml

مرحله ۲: Commit،‏ Push، و راه‌اندازی اسکن CI

تغییرات گردش کار را ثبت کنید و مستقیماً به شاخه اصلی مخزن خود ارسال کنید (master برای Juice Shop، یا main):

# Stage workflow changes, commit, and push to primary branch
git add -A .github
git commit -m "ci: add CodeMender SARIF security scanning workflow"
git push origin $(git branch --show-current)

در مرورگر:

به مخزن GitHub منشعب‌شده خود بروید: https://github.com/YOUR_GITHUB_USER/juice-shop (برای نمونه، https://github.com/octocat/juice-shop).

روی برگه کنش‌ها در نوار پیمایش بالا کلیک کنید.

در نوار کناری سمت راست، در بخش گردش‌های کاری، اسکن امنیتی CodeMender و صادر کردن SARIF را انتخاب کنید.

اجرای گردش کار را راه‌اندازی یا مشاهده کنید:

راه‌انداز خودکار: اگر اجرای خودکاری که با ارسال شما راه‌اندازی شده است در فهرست وجود دارد، مستقیماً روی آن کلیک کنید تا اجرای زنده را پایش کنید.

راه‌انداز دستی درخواستی (workflow_dispatch): اگر هنوز اجرایی شروع نشده است، روی دکمه اجرای گردش کار ▾ در سمت چپ کلیک کنید، مطمئن شوید Branch: master انتخاب شده باشد (چارگوش انتخاب deep_scan را علامت نزنید تا اسکن سریع خط مبنای --quick اجرا شود)، و روی دکمه سبز اجرای گردش کار کلیک کنید.

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

درون codemender-scan.yml: مسیریابی اسکن آگاه از رویداد

درحالی‌که --quick اسکن پایه در فضای ابری اجرا می‌شود (حدود ۳ تا ۵ دقیقه)، بررسی کنید که چگونه codemender-scan.yml (خطوط ۱۱۸ تا ۱۵۵) هر رویداد GitHub را به حالت اسکن اختصاصی خود در داخل اجراکننده هدایت می‌کند:

# Excerpt from .github/workflows/codemender-scan.yml
if [ "${{ github.event_name }}" = "pull_request" ]; then
 cm find . \
   --diff="origin/${{ github.base_ref }}" \
   --diff-workers=16 \
   --fail-on="CRITICAL,HIGH" \
   --sandbox=false --yes --bypass-warning || status=$?
elif [ "${{ github.event_name }}" = "schedule" ] || [ "${{ github.event.inputs.deep_scan }}" = "true" ]; then
 cm find . \
   --deep-workers=8 \
   --sandbox=false --yes --bypass-warning || status=$?
else
 cm find . \
   --quick \
   --sandbox=false --yes --bypass-warning || status=$?
fi

راه‌اندازی Hardened Runner ( خطوط ۲۷–۱۱۷): از انشعاب خارجی غیرقابل‌اعتماد و dependabot[bot] PRها رد می‌شود، با persist-credentials: false بررسی می‌کند، ~/.local/bin/cm و ~/.codemender/state.db را ذخیره می‌کند، و cm health --strict را قبل‌از مصرف سهمیه مدل اجرا می‌کند.

مرزهای جعبه شنی بدون سر (--sandbox=false --yes --bypass-warning): جداسازی فضای نام کاربر Linux را غیرفعال می‌کند (محدودشده در داخل محفظه‌های GitHub Actions بدون امتیاز) درحالی‌که مرزهای مسیر فضای کاری (project_paths) و command_policy.yaml را اعمال می‌کند.

Exit-Code Guarded SARIF & Artifact Export ( خطوط ۱۴۷–۱۹۴): steps.scan.outputs.completed=true را دقیقاً زمانی تنظیم می‌کند که cm find با 0 (پاک) یا 1 (--fail-on آستانه برآورده‌شده) خارج می‌شود. این تضمین می‌کند که گزارش‌های SARIF (cm report -f sarif با امتیازهای شدت CVSS)، جدول‌های $GITHUB_STEP_SUMMARY (cm report -f md)، و مصنوعات codemender-findings.json همچنان وقتی --fail-on یک PR را مسدود می‌کند منتشر می‌شوند—درحالی‌که از صادر کردن درصورت وجود خطاهای راه‌اندازی یا ظرفیت (10–60) صرف‌نظر می‌شود تا فایل‌های SARIF خالی هرگز هشدارهای موجود را نبندند.

‫۷. بازرسی کردن هشدارهای «اسکن کد GitHub» و داشبورد امنیتی

پس‌از پایان گردش کار ارسال خط مبنا، GitHub فایل SARIF بارگذاری‌شده را پردازش می‌کند و هم خلاصه اجرای Actions و هم برگه «امنیت» مخزن را پر می‌کند.

مرحله ۱: بررسی خلاصه کار بومی در GitHub Actions

هر اجرای گردش کار یک جدول خلاصه Markdown‏ (cm report -f md) را مستقیماً به نمای کلی اجرای GitHub Actions اضافه می‌کند:

در مخزن GitHub، روی برگه کنش‌ها کلیک کنید.

اجرای تکمیل‌شده CodeMender Security Scan & SARIF Export را انتخاب کنید (بازرسی‌های ارسال شاخه پایه با علامت ✅ سبز پس‌از انتشار یافته‌های SARIF به‌پایان می‌رسد).

به بخش 🛡️ CodeMender Security Scan Summary پیمایش کنید تا تفکیک یافته‌ها را بررسی کنید:

🔒 گزارش امنیتی CodeMender

خلاصه

کل یافته‌ها: ۲۸

شدت

تعداد

🔴 بحرانی

6

🟠 زیاد

16

🟡 متوسط

6

وضعیت

تعداد

🔴 باز کردن

28

یافته‌ها

شناسه

شدت

اطمینان

وضعیت

رفع اشکال

فایل

عنوان

c1b96b9a

🔴 بحرانی

‎٪۱۰۰

باز کردن

—

routes/userProfile.ts

اجرای کد از راه دور ازطریق تزریق کد سمت سرور در نمایه کاربر

cd47b38a

🔴 بحرانی

‎٪۱۰۰

باز کردن

—

routes/login.ts

تزریق SQL در مسیر اصالت‌سنجی کاربر

a47a9e45

🔴 بحرانی

‎٪۱۰۰

باز کردن

—

routes/b2bOrder.ts

اجرای کد از راه دور ازطریق فرار از جعبه امن در پردازش سفارش شرکت‌به‌شرکت

مرحله ۲: کاوش داشبورد متمرکز «اسکن کد»

در نوار پیمایش بالای مخزن GitHub، روی برگه امنیت و کیفیت (یا امنیت) کلیک کنید.

در نوار کناری سمت راست، در بخش یافته‌ها، اسکن کد را انتخاب کنید.

اگر چند ابزار فعال است، ابزار را روی CodeMender (is:open branch:master tool:CodeMender) فیلتر کنید تا هشدارهای نگاشت‌شده با نشان‌های شدت CVSS بومی را بررسی کنید:

نشان شدت

عنوان آسیب‌پذیری

مکان شناسایی‌شده

Branch

🔴 بحرانی

اجرای کد از راه دور ازطریق تزریق کد سمت سرور در نمایه کاربر

routes/userProfile.ts:58

master

🔴 بحرانی

تزریق SQL در مسیر اصالت‌سنجی کاربر

routes/login.ts:34

master

🔴 بحرانی

اجرای کد از راه دور ازطریق فرار از جعبه امن در پردازش سفارش شرکت‌به‌شرکت

routes/b2bOrder.ts:21

master

روی تزریق SQL در مسیر اصالت‌سنجی کاربر (routes/login.ts:34) کلیک کنید تا جریان داده‌های آلوده و «تحلیل علت ریشه‌ای» ترکیب‌شده توسط Gemini را مرور کنید.

‫۸. مسدود کردن «درخواست Pull» ناامن با اسکن تفاضلی

اسکن خط مبنای شما ۲۸ آسیب‌پذیری ازپیش موجود را در OWASP Juice Shop آشکار کرد. با تحلیل‌گرهای ایستا سنتی، آن ۲۸ یافته قدیمی باعث می‌شدند هر «درخواست ادغام» آتی ناموفق شود تا زمانی که کل کارهای معوقه برطرف شود—و تیم‌ها مجبور می‌شدند مسدود کردن ادغام را غیرفعال کنند.

اکنون دروازه AST تفاضلی درخواست بازبینی (--diff + --fail-on="CRITICAL,HIGH") CodeMender را در عمل آزمایش خواهید کرد: باز کردن «درخواست بازبینی» که آسیب‌پذیری جدیدی را معرفی می‌کند و تماشای CodeMender که دلتا را جدا می‌کند، ادغام را در حدود ۱۵ تا ۲۵ ثانیه مسدود می‌کند، و خطوط متخلف دقیق را حاشیه‌نویسی می‌کند.

مرحله ۱: باز کردن «درخواست Pull» که نقص تزریق فرمان را معرفی می‌کند

در Cloud Shell (در فضای کاری مخزن شبیه‌سازی‌شده)، یک شاخه ویژگی ایجاد کنید، یک مسیر Express جدید حاوی آسیب‌پذیری «تزریق فرمان سیستم‌عامل» اضافه کنید، و یک «درخواست واکشی» برای انشعاب خود باز کنید:

[ -d .git ] || cd ~/"${GITHUB_REPO:-juice-shop}"
export GITHUB_REPOSITORY="${GITHUB_REPOSITORY:-$(git remote get-url origin 2>/dev/null | sed -E 's#^.*github\.com[:/]##; s#\.git$##')}"
PRIMARY_BRANCH=$(git symbolic-ref --short refs/remotes/origin/HEAD | sed 's@^origin/@@')

# Reset any previous demo PR/branch so this step can be re-run cleanly
gh pr close feat/diagnostics --repo "${GITHUB_REPOSITORY}" --delete-branch 2>/dev/null || true
git checkout "${PRIMARY_BRANCH}"
git checkout -B feat/diagnostics

# Introduce an Express endpoint vulnerable to OS Command Injection (CWE-78)
cat << 'EOF' > routes/diagnostics.ts
import { execSync } from 'node:child_process'
import { type Request, type Response } from 'express'

export function systemDiagnostics () {
 return (req: Request, res: Response) => {
   const host = String(req.query.host ?? '127.0.0.1')
   const output = execSync(`ping -c 1 ${host}`).toString()
   res.status(200).json({ status: 'ok', output })
 }
}
EOF

git add routes/diagnostics.ts
git commit -m "feat: add network diagnostics endpoint"
git push -f -u origin feat/diagnostics

gh pr create \
 --repo "${GITHUB_REPOSITORY}" \
 --base "${PRIMARY_BRANCH}" \
 --head feat/diagnostics \
 --title "feat: add network diagnostics endpoint" \
 --body "Adds a ping diagnostics handler."

مرحله ۲: درستی‌سنجی کردن دروازه ادغام تفاضلی و حاشیه‌نویسی PR درون‌خطی

«نشانی وب درخواست واکشی» را که در انتهای خروجی پایانه چاپ شده است باز کنید.

به چارگوش بررسی‌ها در پایین صفحه مکالمه «درخواست واکشی» پیمایش کنید و اسکن خودکار آسیب‌پذیری کد را تماشا کنید:

سرعت دلتا: به‌جای اسکن کردن همه بیش‌از ۶۸۰ فایل موجود در مخزن (حدود ۳ تا ۵ دقیقه)، cm find . --diff="origin/${PRIMARY_BRANCH}" تجزیه‌وتحلیل را دقیقاً به routes/diagnostics.ts (و هر تماس‌گیرنده ۱-پرشی) محدود می‌کند و اسکن را در حدود ۱۵ تا ۲۵ ثانیه تکمیل می‌کند.

جداسازی بدهی قدیمی و مسدود کردن ادغام: هیچ‌کدام از ۲۸ آسیب‌پذیری قدیمی دست‌نخورده Juice Shop در بررسی رد نمی‌شوند—فقط CRITICAL تزریق فرمان جدیداً معرفی‌شده --fail-on="CRITICAL,HIGH" را راه‌اندازی می‌کند و با کد وضعیت 1 (❌ قرمز) خارج می‌شود تا ادغام PR را مسدود کند!

روی برگه فایل‌های تغییریافته در بالای «درخواست واکشی» کلیک کنید:

چون محافظ کد خروج گردش کار (steps.scan.outputs.completed == 'true') همچنان results.sarif را صادر و بارگذاری می‌کند وقتی --fail-on با کد 1 خارج می‌شود، «اسکن کد GitHub» یک حاشیه‌نویسی امنیتی CodeMender — Critical درون‌خطی را مستقیماً زیر execSync در routes/diagnostics.ts ارائه می‌دهد!

مرحله ۳: پاک‌سازی درخواست بازبینی آزمایشی و بازگشت به شاخه اصلی

قبل‌از ادامه دادن به اصلاح خودکار، فضای کاری Cloud Shell خود را به شاخه اصلی برگردانید و «درخواست کشیدن» آزمایشی ناامن را ببندید:

[ -d .git ] || cd ~/"${GITHUB_REPO:-juice-shop}"
export GITHUB_REPOSITORY="${GITHUB_REPOSITORY:-$(git remote get-url origin 2>/dev/null | sed -E 's#^.*github\.com[:/]##; s#\.git$##')}"
PRIMARY_BRANCH=$(git symbolic-ref --short refs/remotes/origin/HEAD | sed 's@^origin/@@')
git checkout "${PRIMARY_BRANCH}"
gh pr close feat/diagnostics --repo "${GITHUB_REPOSITORY}" --delete-branch
git branch -D feat/diagnostics 2>/dev/null || true

‫۹. ساختن گردش کار اصلاح خودکار و درخواست ادغام خودکار

اکنون که دروازه «درخواست Pull» شما از ورود آسیب‌پذیری‌های جدید به پایگاه کد جلوگیری می‌کند، اصلاح خودکار (.github/workflows/codemender-remediate.yml) را برای رفع فعال آسیب‌پذیری‌های موجود و باز کردن «درخواست‌های Pull» آماده بازبینی مستقر خواهید کرد.

مرحله ۱: بارگیری فایل گردش کار اصلاح

‫CodeMender دو الگوی اصلاحی بسته به رؤیت‌پذیری مخزن ارائه می‌دهد:

مخازن عمومی / متن‌باز (codemender-remediate.yml): حالت شفاف‌سازی مسئولانه—به هشدارهای SARIF «اسکن کد GitHub» پیوند می‌دهد بدون اینکه بردارهای بهره‌برداری خام را به‌طور عمومی افشا کند.

مخازن خصوصی / سازمانی (codemender-remediate-private-repo.yml): حالت شواهد ممیزی داخلی—مصنوعات درستی‌سنجی (PLAN.md، REPORT.md، exploit.sh) را در بخش‌های جمع‌شدنی درخواست‌های ادغام جاسازی می‌کند و آن‌ها را از Git commits مستثنی می‌کند.

گردش کار اصلاحی ایمن برای عموم را در مخزن خود بارگیری کنید:

mkdir -p .github/workflows
curl -fsSL https://raw.githubusercontent.com/edwardc-gcp/codemender-github-actions/main/.github/workflows/codemender-remediate.yml \
 -o .github/workflows/codemender-remediate.yml

مرحله ۲: تأیید و راه‌اندازی گردش کار اصلاح خودکار

گردش کار اصلاح را به شاخه اصلی‌تان ارسال و اعمال کنید:

git add .github/workflows/codemender-remediate.yml
git commit -m "ci: add CodeMender autonomous remediation workflow"
git push origin $(git branch --show-current)

در مرورگر، به برگه کنش‌ها در مخزن GitHub خود بروید.

در نوار کناری سمت راست، در بخش گردش‌های کاری، CodeMender Autonomous Security Remediation & Auto-PR را انتخاب کنید.

روی منو کرکره‌ای سبز اجرای گردش کار در سمت چپ کلیک کنید:

استفاده از گردش کار از: مطمئن شوید که شاخه پیش‌فرض (master) انتخاب شده باشد.

پیشوند یا شناسه یافته خاص برای اصلاح: پیشوند ۸ نویسه‌ای routes/login.ts را که در مرحله ۷ یادداشت کردید وارد کنید (برای مثال، cd47b38a). اگر این فیلد را خالی بگذارید، اصلاح دسته‌ای برای همه یافته‌های «بحرانی» و «بالا» اجرا می‌شود (حدود ۱۰ تا ۱۵ دقیقه)؛ هدف‌یابی یک شناسه در حدود ۴۵ تا ۶۰ ثانیه تکمیل می‌شود.

روی دکمه سبز اجرای گردش کار در داخل بالاپر کلیک کنید و اجرای درحال اجرا را باز کنید.

راه‌اندازی گردش کار «اصلاح امنیتی خودکار CodeMender» ازطریق منو کرکره‌ای «اجرای گردش کار»

درون codemender-remediate.yml: ترکیب وصله خودکار

درحالی‌که CodeMender وصله را در فضای ابری ترکیب می‌کند (حدود ۳۰ تا ۴۵ ثانیه)، بررسی کنید که چگونه codemender-remediate.yml (خطوط ۱۱۱ تا ۱۸۴) اصلاح را در داخل اجراکننده سازمان‌دهی می‌کند:

Zero-Scan Resume (cm report import): مصنوع codemender-findings.json را از گردش کار اسکن بارگیری می‌کند و آن را به فضای کاری (cm report import -f codemender-findings.json) وارد می‌کند، و تنها درصورتی به cm find . --quick برمی‌گردد که مصنوع قبلی وجود نداشته باشد.

Headless Patch Synthesis (cm fix): پین‌های project_paths به $GITHUB_WORKSPACE، لوله‌های < /dev/null برای جلوگیری از توقف‌های تعاملی، و پاس‌های --no-reset درطول حلقه‌های دسته‌ای تا اصلاحات تجمعی در یافته‌ها حفظ شوند:

# Executed inside the GitHub Actions runner (codemender-remediate.yml)
cm fix "${SPECIFIC_TARGET}" --sandbox=false --yes --bypass-warning < /dev/null

Clean Production Commits ( خطوط ۱۵۵–۲۵۲): .cm_project، .exploit/، و فایل‌های موقت را ازطریق .git/info/exclude پاک‌سازی می‌کند پیش‌از اینکه peter-evans/create-pull-request@v8 شاخه (codemender/auto-remediation-${{ github.run_id }}) را باز کند، و تغییرات کد تولید را به‌طور دقیق ثبت می‌کند:

--- a/routes/login.ts
+++ b/routes/login.ts
@@ -28,8 +28,8 @@ module.exports = function login () {
-    models.sequelize.query(`SELECT * FROM Users WHERE email = '${req.body.email || ''}' AND password = '${security.hash(req.body.password || '')}' AND deletedAt IS NULL`, { model: models.User })
+    models.sequelize.query('SELECT * FROM Users WHERE email = :email AND password = :password AND deletedAt IS NULL', {
+      replacements: { email: req.body.email || '', password: security.hash(req.body.password || '') },
+      model: models.User
+    })

مرحله ۳: «درخواست واکشی» جدیداً بازشده را در GitHub مرور کنید

به برگه درخواست‌های Pull در مخزن خود بروید و «درخواست Pull» جدید (مثلاً 🛡️ [CodeMender] Fix: SQL Injection in User Authentication Route) را باز کنید.

روی فایل‌های تغییریافته کلیک کنید تا مطمئن شوید که فقط routes/login.ts اصلاح شده است و همه فراداده‌های زمان اجرای داخلی مستثنی شده‌اند.

شرح درخواست ارسال را که مستقیماً به هشدار GitHub Code Scanning (SARIF) پیوند داده شده است برای تأیید نگهدارنده مرور کنید.

‫۱۰. عیب‌یابی موارد حاشیه‌ای و مخازن خصوصی

مخازن خصوصی بدون GitHub Advanced Security (GHAS)

مخزن‌های عمومی GitHub به‌طور رایگان و نامحدود SARIF «اسکن کد GitHub» را دریافت می‌کنند. بااین‌حال، اگر این گردش کار را در مخزن خصوصی سازمانی که پروانه فعال GitHub Advanced Security (GHAS) ندارد مستقر کنید، مرحله upload-sarif با این خطا مواجه خواهد شد:

HTTP 403: Advanced Security must be enabled for this repository to use code scanning.

وضوح: بازگشت به گزارش HTML تعاملی مستقل

تولیدکننده گزارش HTML داخلی CodeMender (cm report -f html) یک داشبورد امنیتی مستقل و تعاملی ایجاد می‌کند که دارای کارت‌های سنجه شدت، تکه‌کدهای با نحو برجسته با شماره خط، و یک نمایشگر تفاوت وصله درون‌خطی بدون هیچ‌گونه وابستگی وب خارجی است.

برای پشتیبانی از مخازن خصوصی بدون پروانه GHAS، .github/workflows/codemender-scan.yml را به‌روز کنید تا به‌جای بارگذاری SARIF، یک مصنوع گزارش HTML را بایگانی کند:

تولید گزارش HTML مستقل: در مرحله Export Security Reports & Publish Job Summary، بااستفاده از cm report -f html > codemender-audit-report.html، داشبورد HTML را در کنار خلاصه Markdown صادر کنید.

بایگانی کردن گزارش به‌عنوان مصنوع گردش کار: مرحله Upload SARIF Report to GitHub Code Scanning (github/codeql-action/upload-sarif@v4) را با actions/upload-artifact@v4 پیکربندی‌شده برای بارگذاری codemender-audit-report.html (برای مثال، تحت نام مصنوع codemender-security-report) جایگزین کنید.

بازرسی محلی در هر مرورگری: codemender-security-report.zip را مستقیماً از صفحه خلاصه اجرای گردش کار GitHub Actions بارگیری کنید، آن را استخراج کنید، و codemender-audit-report.html را در هر مرورگر وبی برای تریاژ بصری باز کنید.

اصلاح خودکار مخزن خصوصی با شواهد حسابرسی جاسازی‌شده

در مخازن شرکتی خصوصی، تیم‌های مهندسی و امنیتی به رؤیت‌پذیری کامل در تحلیل علت ریشه‌ای، اثبات مفهوم بهره‌برداری، و طرح اصلاح بدون نیاز به داشبوردهای ابزار خارجی نیاز دارند. بااین‌حال، ارسال اسکریپت‌های بهره‌برداری (exploit.sh) یا فایل‌های markdown داخلی (PLAN.md، LOG.md) به شاخه مخزن، سابقه git را آلوده می‌کند و می‌تواند هشدارهای کاذب ازسوی دیگر اسکنرهای امنیتی ایجاد کند.

برای رسیدگی به این موضوع، گردش کار اصلاح مخزن خصوصی (codemender-remediate-private-repo.yml) اختصاصی را مستقر کنید:

curl -fsSL https://raw.githubusercontent.com/edwardc-gcp/codemender-github-actions/main/.github/workflows/codemender-remediate-private-repo.yml \
 -o .github/workflows/codemender-remediate.yml
git add .github/workflows/codemender-remediate.yml
git commit -m "ci: switch to private repository remediation workflow with embedded audit evidence"
git push origin $(git branch --show-current)

نحوه عملکرد اصلاح مخزن خصوصی

درستی‌سنجی اثبات مفهوم پویا (cm verify): پیش‌از تولید اصلاحیه، یک اکسپلویت فعال را ترکیب و آزمایش می‌کند تا قابلیت اکسپلویت را تأیید کند—اگر درستی‌سنجی یافته‌ای را که قابلیت اکسپلویت ندارد به‌عنوان DISMISSED علامت‌گذاری کند، به‌طور خودکار از cm fix رد می‌شود.

Embedded PR Audit Collapsibles: Extracts REPORT.md, PLAN.md, and exploit.sh into /tmp/codemender-evidence/ and formats them directly into the Pull Request description inside <details open> collapsible blocks for one-click reviewer inspection.

بایگانی کردن مصنوع: پوشه کامل شواهد را ازطریق actions/upload-artifact@v4 بایگانی می‌کند.

Pristine Git Commits: همه فراداده‌های زمان اجرا و دایرکتوری‌های .exploit را پاک می‌کند تا Pull Request git commit فقط حاوی تغییرات کد تولید باشد.

بازبینه عیب‌یابی «اتحادیه هویت حجم کاری» (WIF)

به‌طور پیش‌فرض، google-github-actions/auth@v2 درطول راه‌اندازی، فایل پیکربندی اعتبارنامه فدرال محلی را می‌نویسد و تبادل واقعی کد OAuth 2.0 زمانی رخ می‌دهد که cm health --strict یا cm find شروع شود. از بازبینه زیر برای تشخیص خطاهای اصالت‌سنجی HTTP 400 یا HTTP 403 استفاده کنید:

نشانه خطا

علت ریشه‌ای رایج

درستی‌سنجی و رفع مشکل

HTTP 403 (iam.serviceAccounts.getAccessToken رد شد)

roles/iam.workloadIdentityUser در «حساب سرویس» وجود ندارد، رمز GCP_SERVICE_ACCOUNT نادرست است، یا iamcredentials.googleapis.com فعال نیست.

تأیید کنید GCP_SERVICE_ACCOUNT با codemender-ci-runner@.iam.gserviceaccount.com مطابقت دارد و بررسی خط‌مشی IAM را در زیر اجرا کنید تا اتصال principalSet درستی‌سنجی شود.

HTTP 400 (unauthorized_client یا وضعیت مشخصه رد شده است)

نام (یا حروف بزرگ و کوچک) مخزن OIDC –attribute-condition با مخزن GitHub که گردش کار را راه‌اندازی می‌کند مطابقت ندارد، یا ارائه‌دهنده WIF غیرفعال است.

مرحله ۴ (مراحل ۱ و ۶) را دوباره اجرا کنید و مطمئن شوید که ${GITHUB_REPOSITORY} دقیقاً با حروف بزرگ و کوچک owner/repo در GitHub مطابقت دارد و –no-disabled اعمال شده است.

HTTP 400 (invalid_grant در تبادل رمز)

نگاشت –issuer-uri ناقص یا attribute.repository=assertion.repository موجود نیست در ارائه‌دهنده OIDC.

تأیید کنید که –issuer-uri دقیقاً روی https://token.actions.githubusercontent.com تنظیم شده باشد (بدون خط مورب در انتها).

خطای موقت HTTP 403 بلافاصله پس‌از راه‌اندازی

انتشار «اتحاد هویت حجم کاری» و IAM جهانی می‌تواند ۱ تا ۵ دقیقه در اتصال‌های جدیداً ایجادشده طول بکشد.

۱ تا ۲ دقیقه صبر کنید و روی اجرای مجدد کارهای ناموفق در GitHub Actions کلیک کنید.

برای بازرسی اتصال Workload Identity فعال در «حساب سرویس» CI/CD در Cloud Shell، این فرمان را اجرا کنید:

gcloud iam service-accounts get-iam-policy "${SERVICE_ACCOUNT_EMAIL}" \
 --project="${PROJECT_ID}" \
 --flatten="bindings[].members" \
 --filter="bindings.role=roles/iam.workloadIdentityUser"

تأیید کنید که برونداد roles/iam.workloadIdentityUser را به principalSet://iam.googleapis.com/<POOL_ID>/attribute.repository/<GITHUB_USER>/<GITHUB_REPO> متصل می‌کند:

---
bindings:
 members: principalSet://iam.googleapis.com/.../attribute.repository/<OWNER>/<REPO>
 role: roles/iam.workloadIdentityUser

عیب‌یابی کد خروج CLI و پیش‌پرواز CI/CD

فرمان‌های CodeMender‏ (cm health --strict،‏ cm find،‏ cm verify، و cm fix) کدهای خروج قطعی را برمی‌گردانند تا خطوط لوله CI/CD بتوانند فوراً یافته‌های امنیتی را از خطاهای راه‌اندازی یا سرویس تشخیص دهند:

خروج از حالت کد

دسته

علت ریشه‌ای رایج و اصلاح

0

موفقیت‌آمیز

بررسی‌های سلامت با موفقیت انجام شده است یا اسکن بدون یافته‌های مسدودکننده تکمیل شده است.

1

یافته‌ها / عمومی

‫–fail-on مسدود کردن آسیب‌پذیری‌های CRITICAL یا HIGH را در PR شناسایی کرد (انتظار می‌رفت دروازه ادغام ناموفق باشد).

10

credentials

تبادل کد WIF OAuth/ADC ناموفق بود (400/401). GCP_WORKLOAD_IDENTITY_PROVIDER، GCP_SERVICE_ACCOUNT، و اتصال roles/iam.workloadIdentityUser بالا را درستی‌سنجی کنید.

20

config

نحو .codemender/config.yaml یا ~/.codemender/config.yaml ناهنجار است.

30

reachability

Runner نمی‌تواند به aiplatform.googleapis.com دسترسی پیدا کند (ساناد، پراکسی، قطعی سرویس، یا کنترل‌های سرویس‌های VPC).

40

authorization

«حساب سرویس» فاقد roles/aiplatform.user در پروژه هدف است، یا cloudresourcemanager.googleapis.com / aiplatform.googleapis.com غیرفعال است.

50

timeout

بررسی پیش‌پرواز cm health از مهلت ۳۰ ثانیه‌ای فراتر رفت.

60

capacity

«نماینده» به حد تکلیف فعال هم‌زمان خود رسیده است؛ گردش کار را پس‌از تأخیری کوتاه دوباره اجرا کنید.

برای خطاهای زمان اجرای دیگر (مانند وضوح شاخه پایه Git diff‏ (fetch-depth: 0)، تأخیرهای انتشار منبع، یا اجازه‌های ایجاد درخواست GitHub Actions Pull)، به راهنمای عیب‌یابی CodeMender CI/CD رسمی مراجعه کنید.

‫۱۱. پاک‌سازی منابع

برای جلوگیری از مصرف مداوم منابع یا پاک‌سازی پیکربندی‌های آزمایشی در محیط‌های Google Cloud و GitHub، مراحل پاک‌سازی زیر را انجام دهید.

مرحله ۱: حذف کردن اطلاعات محرمانه مخزن GitHub و غیرفعال کردن گردش‌های کاری ازطریق gh CLI

از GitHub CLI (gh) برای حذف کامل اسرار Actions مخزن و غیرفعال کردن گردش‌های کاری CodeMender استفاده کنید:

# Delete the repository Actions secrets
gh secret delete GCP_WORKLOAD_IDENTITY_PROVIDER --repo "${GITHUB_REPOSITORY}" 2>/dev/null || true
gh secret delete GCP_SERVICE_ACCOUNT --repo "${GITHUB_REPOSITORY}" 2>/dev/null || true

# Disable the CodeMender workflows to prevent unwanted automatic triggers
gh workflow disable codemender-scan.yml --repo "${GITHUB_REPOSITORY}" 2>/dev/null || true
gh workflow disable codemender-remediate.yml --repo "${GITHUB_REPOSITORY}" 2>/dev/null || true

مرحله ۲: غیرفعال کردن یا حذف منابع Google Cloud Workload Identity Federation

Workload Identity Pools، «ارائه‌دهندگان»، و «حساب‌های سرویس» وقتی توکن‌ها را مبادله نمی‌کنند، هیچ هزینه بی‌کاری ندارند. حالت پاک‌سازی‌ای را که با گردش کارتان مطابقت دارد انتخاب کنید:

گزینه الف — توقف موقت دسترسی (اگر قصد دارید دوباره در این پروژه اجرا کنید، این گزینه توصیه می‌شود): تبادل توکن OIDC را فوراً غیرفعال می‌کند، بدون اینکه نگهداری حذف نرم ۳۰ روزه Google Cloud IAM یا تأخیرهای انتشار uniqueId «حساب سرویس» را فعال کند:

gcloud iam workload-identity-pools providers update-oidc "${WORKLOAD_IDENTITY_PROVIDER}" \
 --workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
 --location="global" \
 --disabled \
 --project="${PROJECT_ID}"

گزینه ب — جداسازی کامل: «ارائه‌دهنده WIF»، «مجموعه» (به‌مدت ۳۰ روز در وضعیت DELETED حفظ می‌شود)، و «حساب سرویس» اختصاصی را حذف می‌کند:

# Delete Workload Identity Provider
gcloud iam workload-identity-pools providers delete "${WORKLOAD_IDENTITY_PROVIDER}" \
 --workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
 --location="global" \
 --project="${PROJECT_ID}" \
 --quiet

# Delete Workload Identity Pool
gcloud iam workload-identity-pools delete "${WORKLOAD_IDENTITY_POOL}" \
 --location="global" \
 --project="${PROJECT_ID}" \
 --quiet

# Delete CI/CD Service Account
gcloud iam service-accounts delete "${SERVICE_ACCOUNT_EMAIL}" \
 --project="${PROJECT_ID}" \
 --quiet

‫۱۲. تبریک می‌گوییم

تبریک! ‫codelab ایمن‌سازی خط لوله CI/CD با CodeMender را تکمیل کردید!

شما با موفقیت یک خط لوله DevSecOps با اعتماد صفر و در سطح تولید را بااستفاده از Google Cloud Workload Identity Federation،‏ CodeMender، و GitHub Actions طراحی، ساخته، و خودکارسازی کرده‌اید.

آنچه پوشش داده‌اید

اصالت‌سنجی بدون کلید با اعتماد صفر: کلیدهای JSON حساب سرویس پرخطر و با عمر طولانی را با مقید کردن نشان‌های OIDC زودگذر GitHub به Google Cloud IAM ازطریق «فدراسیون هویت حجم کاری» (WIF) حذف کردیم.

اسکن AST تفاضلی PR و نوفه‌زدایی قدیمی: اسکن مداوم محدود به فایل‌های اصلاح‌شده و وابسته‌ها (--diff="origin/$BASE_REF")، جداسازی بدهی فنی قدیمی ([LEGACY / UNTOUCHED]) برای نگه داشتن حلقه‌های بازخورد توسعه‌دهنده زیر ۱۵ ثانیه.

گزارش‌دهی چندقالبی و خلاصه‌های شغلی بومی: OASIS SARIF v2.1.0 ترکیبی برای اسکن متمرکز کد GitHub با Markdown بومی (cm report -f md >> $GITHUB_STEP_SUMMARY) برای رؤیت‌پذیری اجرایی فوری مستقیماً در صفحه‌های اجرای گردش کار CI.

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

دروازه‌های سخت کیفیت خودکار: محافظت سخت‌گیرانه از شاخه و دروازه ادغام (--fail-on) را اعمال کردیم تا از رسیدن آسیب‌پذیری‌های خطرناک به مرحله تولید جلوگیری کنیم.

انتقال وضعیت مبتنی بر آرتیفکت و جداسازی فضای کاری: یافته‌ها را به‌طور یکپارچه بین کارهای CI بااستفاده از cm report import منتقل کردیم، درحالی‌که از .git/info/exclude برای حفظ سابقه Git دست‌نخورده و جلوگیری از نشت اعتبارنامه استفاده کردیم.

تغییر طرز فکر توسعه‌دهنده

روال سنتی DevSecOps

خط لوله CI/CD خودکار CodeMender

Passive Alert Dumping: اسکنرها گزارش‌های خام پایانه یا فهرست‌های خطای ایستا را چاپ می‌کنند و بار اولویت‌بندی را کاملاً به توسعه‌دهندگان منتقل می‌کنند.

توسعه‌دهنده همکار فعال: وصله‌های کد درستی‌سنجی‌شده را ترکیب می‌کند و «درخواست‌های ادغام» آماده برای ادغام را برای تأیید مهندس باز می‌کند.

مثبت کاذب بالا: روش‌های اکتشافی AST ایستا هزاران آسیب‌پذیری نظری را بدون اثبات بهره‌برداری علامت‌گذاری می‌کنند.

درستی‌سنجی بهره‌برداری ۲سطحی: تولید آزمایش جعبه شنی پویا (cm verify) آسیب‌پذیری واقعی را تأیید می‌کند و موارد مثبت کاذب را حذف می‌کند.

ذخیره‌سازی محرمانه پرخطر: کلیدهای JSON حساب سرویس با عمر طولانی که در اسرار CI ذخیره شده‌اند، خطر نشت تصادفی و پراکندگی اطلاعات اعتباری را به‌همراه دارند.

Zero-Trust WIF: اصالت‌سنجی بدون کلید ازطریق نشان‌های OIDC زودگذر که درصورت درخواست با Google Cloud STS مبادله می‌شوند.

اسکن‌های مجدد یکپارچه: هر ثبت تغییرات باعث ممیزی کامل مخزن می‌شود، که گردش‌های کاری ادغام پیوسته را به‌تأخیر می‌اندازد و کدهای گران‌قیمت را هدر می‌دهد.

مسیریابی AST آگاه از رویداد: «درخواست‌های Pull» اسکن‌های AST تفاضلی ۱۵ ثانیه‌ای (–diff) را اجرا می‌کنند، درحالی‌که cron runs ممیزی‌های عمیق انجام می‌دهد.

سابقه مخزن آلوده: گزارش‌های حمله و اسکریپت‌های بهره‌برداری موقت که مستقیماً به شاخه‌های مخزن ارسال شده‌اند.

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

مراحل بعدی

🚀 ادامه دادن سفر یادگیری CodeMender:

بخش ۱: ایمن‌سازی برنامه با CodeMender — بر کشف آسیب‌پذیری مخزن خودکار، درستی‌سنجی بهره‌برداری از اثبات مفهوم، و ترکیب وصله محلی مسلط شوید.

Shift Left Locally & Serverless Cloud Native CI/CD: پیاده‌سازی‌های مرجع راهنمای رسمی CI/CD را برای Google Cloud Build (cloudbuild.yaml) و Local Git Pre-commit Hooks (cm find . --diff --staged) کاوش کنید.

📖 کاوش اسناد و منابع:

راهنمای رسمی ادغام CodeMender CI/CD در Google Cloud

اسناد رسمی CodeMender در Google Cloud

مخزن الگوی شروع CodeMender GitHub Actions

مستندات فدراسیون هویت حجم کاری Google Cloud

💡 اعمال کردن بر مخزن‌های خودتان:

گردش کار آغازین را منشعب کنید و مخازن Python،‏ Go،‏ Java،‏ Rust، و Node.js سازمانتان را با CodeMender ایمن کنید!