ЁЯУж рдзрдбрд╛ 13 тАФ Dependencies: рддреБрдордЪреНрдпрд╛ app рдордзрд▓рд╛ рдЗрддрд░рд╛рдВрдЪрд╛ code
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 16 рдкреИрдХреА рдзрдбрд╛ 13 ┬╖ рдорд╛рдЧреАрд▓: lesson-12-admission ┬╖ рдкреБрдвреАрд▓: lesson-14-artifacts
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ12, рдЖрдгрд┐ supply chain рдЪреА рдкрд╣рд┐рд▓реА рдЦрд┐рдбрдХреА: dependencies. рдЖрдзреБрдирд┐рдХ app рдордзрд▓рд╛ рдмрд╣реБрддреЗрдХ code рджреБрд╕рд▒реНрдпрд╛ рдХреЛрдгреАрддрд░реА рд▓рд┐рд╣рд┐рд▓реЗрд▓рд╛ рдЕрд╕рддреЛ тАФ libraries, рдЖрдгрд┐ рддреНрдпрд╛рдВрдЪреНрдпрд╛ libraries. рддреБрдореНрд╣реА software composition analysis (SCA: versions рдирд╛ advisories рд╢реА рдЬреБрд│рд╡рдгреЗ), hashes рд╕рд╣ lockfiles, рдЖрдкреЛрдЖрдк рдпреЗрдгрд╛рд░реЗ update PRs, рдЖрдгрд┐ supply chain рдордзрд▓реНрдпрд╛ рджреЛрди рдпреБрдХреНрддреНрдпрд╛ тАФ typosquatting рдЖрдгрд┐ dependency confusion тАФ рдЖрдгрд┐ рддреНрдпрд╛ рдХрд╢рд╛ рдерд╛рдВрдмрд╡рд╛рдпрдЪреНрдпрд╛ рд╣реЗ рд╢рд┐рдХрддрд╛.
- sec/supply.py тАФ рдЫреЛрдЯреНрдпрд╛
ADVISORIESрдпрд╛рджреАрд╡рд┐рд░реБрджреНрдзvulnerable(installed), рдЖрдгрд┐POPULARрд╡рд┐рд░реБрджреНрдзtyposquat(name) - sec/demo.py тАФ
python3 sec/demo.py dependencies - sec/test_sec.py тАФ check
L13
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рд╢рд╛рд│реЗрдЪреНрдпрд╛ рдЬрддреНрд░реЗрд╕рд╛рдареА рд╕реНрд╡рдпрдВрдкрд╛рдХрдШрд░ рд╕рдЧрд│реЗ рдХрд╛рд╣реА рд╕реНрд╡рддрдГ рдмрдирд╡рдд рдирд╛рд╣реА. рддреЗ рдмреНрд░реЗрдб, рдЬреЕрдо рдЖрдгрд┐ рд░рд╕ рдмрд╛рд╣реЗрд░реВрди рд╡рд┐рдХрдд рдШреЗрддреЗ. рд╡рд┐рддрд░рдг рдЦрд┐рдбрдХреАрд╕рд╛рдареА рджреАрдкрд┐рдХрд╛рдЪреЗ рдирд┐рдпрдо:
- ЁЯУЛ рдкрд░рдд рдорд╛рдЧрд╡рд▓реЗрд▓реНрдпрд╛ рдорд╛рд▓рд╛рдЪреА рдпрд╛рджреА. рд░реЛрдЬ рд╕рдХрд╛рд│реА рдмрд╛рддрдореНрдпрд╛ рддрдкрд╛рд╕рд╛: "batch 5.3 рдордзрд▓рд╛ рдЬреЕрдо рдЦрд░рд╛рдм рдЖрд╣реЗ тАФ 5.4 рдХрд┐рдВрд╡рд╛ рдирд╡рд╛ рд╡рд╛рдкрд░рд╛." рдЖрдкрд▓рд╛ рдЬреЕрдо batch 5.3 рдЪрд╛ рдЕрд╕реЗрд▓, рддрд░ рддреЛ рдлреЗрдХреВрди рджреНрдпрд╛ рдЖрдгрд┐ рдирд╡рд╛ рдЖрдгрд╛. рд╣реЗрдЪ advisories рддрдкрд╛рд╕рдгреЗ.
- ЁЯз╛ рдиреЗрдордХреА order. рдкреНрд░рддреНрдпреЗрдХ рдмрд░рдгреАрдЪрд╛ рдиреЗрдордХрд╛ brand, batch рдЖрдгрд┐ рд╕реАрд▓ рдХреНрд░рдорд╛рдВрдХ рд▓рд┐рд╣реВрди рдареЗрд╡рд╛. рдорд╛рд▓ рдЖрд▓реНрдпрд╛рд╡рд░ рдкреНрд░рддреНрдпреЗрдХ рд╕реАрд▓ рддрдкрд╛рд╕рд╛. рд╡реЗрдЧрд│рд╛ рд╕реАрд▓ рдЕрд╕рд▓реЗрд▓реА рдмрд░рдгреА рдкрд░рдд рдЬрд╛рддреЗ тАФ label рдмрд░реЛрдмрд░ рджрд┐рд╕рдд рдЕрд╕рд▓реЗ рддрд░реА. рд╣реАрдЪ hashes рд╕рд╣ lockfile.
- ЁЯСА рд╕рд╛рд░рдЦреЗ рджрд┐рд╕рдгрд╛рд░реЗ brands. "Nestel" рдореНрд╣рдгрдЬреЗ "Nestl├й" рдирд╛рд╣реА. "Reqeusts" рдореНрд╣рдгрдЬреЗ "Requests" рдирд╛рд╣реА. рдШрд╛рдИрддрд▓реНрдпрд╛ рд╕реНрд╡рдпрдВрдкрд╛рдХреНрдпрд╛рд▓рд╛ рдлрд╕рд╡рдгреНрдпрд╛рд╕рд╛рдареА рдХреЛрдгреАрддрд░реА рд╕рд╛рд░рдЦреЗ рджрд┐рд╕рдгрд╛рд░реЗ рдмрдирд╡рд▓реЗ рдЖрд╣реЗ. рд╣реЗрдЪ typosquatting.
- ЁЯПл рдЖрдкрд▓реНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ рдкрд╛рдХрдХреГрддреА. рд╢рд╛рд│реЗрдЪреА рд╕реНрд╡рддрдГрдЪреА рдЬреЕрдордЪреА рдкрд╛рдХрдХреГрддреА рдЖрд╣реЗ, рддрд┐рдЪреЗ рдирд╛рд╡ "school-jam". рдЬрд░ рдПрдЦрд╛рджреНрдпрд╛ рдЕрдиреЛрд│рдЦреА рдорд╛рдгрд╕рд╛рдиреЗ public рджреБрдХрд╛рдирд╛рдд рдЬрд╛рд╕реНрдд batch рдХреНрд░рдорд╛рдВрдХрд╛рд╕рд╣ "school-jam" рдпрд╛рдЪ рдирд╛рд╡рд╛рдЪреА рдмрд░рдгреА рд╡рд┐рдХрд▓реА, рддрд░ рдирд┐рд╖реНрдХрд╛рд│рдЬреА рд╕реНрд╡рдпрдВрдкрд╛рдХреА рддреНрдпрд╛рдЪреА рдмрд░рдгреА рдШреЗрдК рд╢рдХрддреЛ. рдореНрд╣рдгреВрди рд╕реНрд╡рдпрдВрдкрд╛рдХрдШрд░ "school-jam" рдлрдХреНрдд рд╢рд╛рд│реЗрдЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ рдХрдкрд╛рдЯрд╛рддреВрдирдЪ рдШреЗрддреЗ. рд╣реЗрдЪ dependency confusion рдерд╛рдВрдмрд╡рдгреЗ.
- ЁЯФБ рджрд░ рдЖрдард╡рдбреНрдпрд╛рд▓рд╛ рдорд╛рд▓ рднрд░рдгреЗ. рдЖрдард╡рдбреНрдпрд╛рддреВрди рдПрдХрджрд╛ рдПрдХ рдорджрддрдиреАрд╕ рдирд╡реНрдпрд╛ batches рдЪреА рдпрд╛рджреА рдЖрдгрддреЗ, рдЖрдгрд┐ рд╕реНрд╡рдпрдВрдкрд╛рдХреА рд╕реНрд╡реАрдХрд╛рд░рдгреНрдпрд╛рдЖрдзреА рдЪрд╡ рдШреЗрддреЛ (рдЖрдкреЛрдЖрдк update PRs, CI рдордзреНрдпреЗ tested).
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
req["ЁЯУД requirements / package.json"] --> lock["ЁЯз╛ lockfile<br/>exact versions + sha256 hashes"]
lock --> audit{"ЁЯУЛ audit vs advisories<br/>pip-audit ┬╖ npm audit ┬╖ Dependabot"}
audit -->|"requests 2.28.1 тЖТ тЙе 2.31.0<br/>pyyaml 5.3.1 тЖТ тЙе 5.4"| fix["ЁЯФБ update PR + tests"]
name{"ЁЯСА new package name"} -->|"reqeusts тЙИ requests"| stop["тЫФ typosquat: review"]
idx["ЁЯПл one index / proxy<br/>internal names from internal only"] --> lock
ЁЯЧ║я╕П рдХрд╛рдврд▓реЗрд▓реА рдЖрдХреГрддреА + рдПрдХ lab: https://school-edh.pages.dev/security/lesson-diagrams.html#l13
тЭУ рдХрд╛рдп
- Direct рдЖрдгрд┐ transitive dependencies тАФ рддреБрдореНрд╣реА рдпрд╛рджреАрдд рд▓рд┐рд╣рд┐рд▓реЗрд▓реА packages, рдЖрдгрд┐ рддреНрдпрд╛рдВрдирд╛ рд▓рд╛рдЧрдгрд╛рд░реА packages. рдЫреЛрдЯреНрдпрд╛ web app рдордзреНрдпреЗ рдЕрдиреЗрдХрджрд╛ рдХрд╛рд╣реА direct dependencies рдЖрдгрд┐ рддреНрдпрд╛рд╣реВрди рдХрд┐рддреАрддрд░реА рдЬрд╛рд╕реНрдд transitive рдЕрд╕рддрд╛рдд. рддреНрдпрд╛рдВрдкреИрдХреА рдХреЛрдгрддреНрдпрд╛рд╣реА рдПрдХрд╛рддрд▓реА рд╕рдорд╕реНрдпрд╛ рдореНрд╣рдгрдЬреЗ рддреБрдордЪреНрдпрд╛ app рдордзрд▓реА рд╕рдорд╕реНрдпрд╛.
- Advisory тАФ рдПрдЦрд╛рджреНрдпрд╛ package рдЪреНрдпрд╛ versions рдордзреНрдпреЗ рдЬреНрдЮрд╛рдд vulnerability рдЖрд╣реЗ, рдЖрдгрд┐ рддреА рдХреЛрдгрддреНрдпрд╛ version рдкрд╛рд╕реВрди рджреБрд░реБрд╕реНрдд рдЭрд╛рд▓реА рдпрд╛рдЪреА public рд╕реВрдЪрдирд╛ (CVE рдЖрдгрд┐ GHSA ids; OSV database рддреНрдпрд╛ рд╡реЗрдЧрд╡реЗрдЧрд│реНрдпрд╛ ecosystems рдордзреВрди рдЧреЛрд│рд╛ рдХрд░рддреЛ).
- SCA (software composition analysis) тАФ рддреБрдордЪреНрдпрд╛ dependencies рдЪреА рдпрд╛рджреА рдХрд░реВрди рддреНрдпрд╛рдВрдирд╛
advisories рд╢реА рдЬреБрд│рд╡рдгрд╛рд░реА tools:
pip-audit,npm audit, Dependabot / GitHub dependency review, OSV-Scanner, Trivy, Grype, Snyk. - Lockfile тАФ direct рдЖрдгрд┐ transitive рдЕрд╢рд╛ рдкреНрд░рддреНрдпреЗрдХ dependency рдЪреЗ рдиреЗрдордХреЗ version:
package-lock.json,poetry.lock,uv.lock, рдХрд┐рдВрд╡рд╛ pinned versions рд╕рд╣ compile рдХреЗрд▓реЗрд▓реАrequirements.txt. Hashes рдЕрд╕рддреАрд▓ рддрд░ installer рд╣реЗ рд╕реБрджреНрдзрд╛ рддрдкрд╛рд╕рддреЛ рдХреА download рдЭрд╛рд▓реЗрд▓реА рдкреНрд░рддреНрдпреЗрдХ file рддреБрдореНрд╣реА рддрдкрд╛рд╕рд▓реЗрд▓реАрдЪ рдиреЗрдордХреА file рдЖрд╣реЗ (pip install --require-hashes,npm ci). - рдЖрдкреЛрдЖрдк updates тАФ рдирд╡реЗ version рдХрд┐рдВрд╡рд╛ fix рдЖрд▓реЗ рдХреА рдПрдХ bot (Dependabot, Renovate) pull request рдЙрдШрдбрддреЛ. CI tests рдЪрд╛рд▓рд╡рддреЗ; рдПрдХ рд╡реНрдпрдХреНрддреА merge рдХрд░рддреЗ.
- Typosquatting тАФ рд▓реЛрдХрдкреНрд░рд┐рдп package рдЪреНрдпрд╛ рдирд╛рд╡рд╛рдд рдЫреЛрдЯреА typo рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рдирд╛рд╡рд╛рдиреЗ malicious package
publish рдХрд░рдгреЗ (
reqeusts,numpyy), рдЖрдгрд┐ рдХреЛрдгреА рдЪреБрдХреАрдЪреЗ рдЯрд╛рдЗрдк рдХрд░реЗрдкрд░реНрдпрдВрдд рд╡рд╛рдЯ рдкрд╛рд╣рдгреЗ. - Dependency confusion тАФ рддреБрдордЪреА company рдПрдХ internal package рд╡рд╛рдкрд░рддреЗ,
school-utils. рдПрдХ attacker public index рд╡рд░ рдЬрд╛рд╕реНрдд version рд╕рд╣school-utilspublish рдХрд░рддреЛ. рджреЛрдиреНрд╣реА indexes рдкрд╛рд╣рдгрд╛рд░рд╛ build public package рдирд┐рд╡рдбреВ рд╢рдХрддреЛ. рддреЗ рдПрдХрд╛рдЪ index рдиреЗ рдерд╛рдВрдмрд╡рд╛ (AWS CodeArtifact рдХрд┐рдВрд╡рд╛ Artifactory рд╕рд╛рд░рдЦрд╛ proxy рдЬреЛ internal рдЖрдгрд┐ public packages рджреЗрддреЛ, рдЖрдгрд┐ internal рдирд╛рд╡рд╛рдВрдирд╛ рдкреНрд░рд╛рдзрд╛рдиреНрдп рджреЗрддреЛ), scoped рдирд╛рд╡реЗ (npm рдордзреНрдпреЗ@school/utils, scope рддреБрдордЪреНрдпрд╛ registry рд╢реА рдЬреЛрдбрд▓реЗрд▓рд╛), рдЖрдгрд┐ рддреБрдордЪреА рдирд╛рд╡реЗ public рдордзреНрдпреЗ рд░рд╛рдЦреВрди рдареЗрд╡рдгреЗ. - Install scripts тАФ рдХрд╛рд╣реА ecosystems package install рд╣реЛрдд рдЕрд╕рддрд╛рдирд╛рдЪ code рдЪрд╛рд▓рд╡рддрд╛рдд (npm
postinstall, Python source builds). Malicious package рддреНрдпрд╛рдЪ рд╡реЗрд│реА рдЖрдкрд▓реЗ рдХрд╛рдо рдХрд░рддреЗ тАФ рддреБрдордЪреЗ app рд╕реБрд░реВ рд╣реЛрдгреНрдпрд╛рдЖрдзреАрдЪ.
ЁЯдФ рдХрд╛
рдХрд╛рд░рдг рддреБрдореНрд╣реА рддреБрдордЪреНрдпрд╛ dependencies рдЪреА рдкреНрд░рддреНрдпреЗрдХ рдУрд│ рддреБрдордЪреНрдпрд╛ app рдЪреНрдпрд╛ permissions рдЖрдгрд┐ рддреБрдордЪреНрдпрд╛ users рдЪреНрдпрд╛ data рд╕рд╣ production рдордзреНрдпреЗ рдкрд╛рдард╡рддрд╛. Library рдордзрд▓реА рдЬреНрдЮрд╛рдд, рдЖрдзреАрдЪ рджреБрд░реБрд╕реНрдд рдЭрд╛рд▓реЗрд▓реА vulnerability рд╣рд╛ рдЖрдд рд╢рд┐рд░рдгреНрдпрд╛рдЪрд╛ рд╕рд░реНрд╡рд╛рдд рдиреЗрд╣рдореАрдЪрд╛ рдорд╛рд░реНрдЧ рдЖрд╣реЗ тАФ fix рдЖрдзреАрдЪ рдЙрдкрд▓рдмреНрдз рдЖрд╣реЗ, рдЖрдгрд┐ attackers рдЬреБрдиреЗ version рд╢реЛрдзрдд scan рдХрд░рддрд╛рдд. рдЖрдгрд┐ malicious packages рджреБрд░реНрдореАрд│ рдирд╛рд╣реАрдд: рд╕рд╛рд░рдЦреА рджрд┐рд╕рдгрд╛рд░реА рдирд╛рд╡реЗ рдЖрдгрд┐ рддрд╛рдмреНрдпрд╛рдд рдШреЗрддрд▓реЗрд▓реА maintainer accounts public registries рдордзреНрдпреЗ рджрд░ рдЖрдард╡рдбреНрдпрд╛рд▓рд╛ рджрд┐рд╕рддрд╛рдд. рдмрдЪрд╛рд╡ рдореНрд╣рдгрдЬреЗ "libraries рдХрдзреАрдЪ рд╡рд╛рдкрд░реВ рдирдХрд╛" рдЕрд╕рд╛ рдирд╛рд╣реА. рддреЛ рдореНрд╣рдгрдЬреЗ рддреБрдореНрд╣реА рдиреЗрдордХреЗ рдХрд╛рдп рд╡рд╛рдкрд░рддрд╛ рддреЗ рдорд╛рд╣реАрдд рдЕрд╕рдгреЗ, рддреЗ рдЕрджреНрдпрдпрд╛рд╡рдд рдареЗрд╡рдгреЗ, рдЖрдгрд┐ рдирд╡реЗ рдирд╛рд╡ рди рдкрд╛рд╣рддрд╛ рдЖрдд рдпреЗрдК рди рджреЗрдгреЗ.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
sec/supply.py рдордзреНрдпреЗ:
vulnerable(installed)рдкреНрд░рддреНрдпреЗрдХ installed version рдЪреА рддреБрд▓рдирд╛ADVISORIESрд╢реА рдХрд░рддреЗ (requests,jinja2рдЖрдгрд┐pyyamlрд╕рд╛рдареА рддреАрди рдирдореБрдирд╛ рдиреЛрдВрджреА, рдкреНрд░рддреНрдпреЗрдХ рдПрдХрд╛ version рдордзреНрдпреЗ "fixed") рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ рд╕рд╛рдкрдбрд▓реЗрд▓реНрдпрд╛рд╕рд╛рдареА(name, version, "upgrade to тЙе fixed", what)рдкрд░рдд рдХрд░рддреЗ. Versions рдЪреА рддреБрд▓рдирд╛ text рдореНрд╣рдгреВрди рдирд╛рд╣реА, рддрд░ рд╕рдВрдЦреНрдпрд╛ рдореНрд╣рдгреВрди рд╣реЛрддреЗ (2.30.0 < 2.31.0).typosquat(name)POPULARрдордзрд▓реА рдЕрд╢реА рдирд╛рд╡реЗ рдкрд░рдд рдХрд░рддреЗ рдЬреА 1 рдХрд┐рдВрд╡рд╛ 2 рдмрджрд▓рд╛рдВрдЪреНрдпрд╛ рдЕрдВрддрд░рд╛рд╡рд░ рдЖрд╣реЗрдд (Levenshtein distance). рдиреЗрдордХреЗ рддреЗрдЪ рдирд╛рд╡ (distance 0) flag рд╣реЛрдд рдирд╛рд╣реА.
sec/demo.py рдордзрд▓реЗ dependencies() рдЪрд╛рд░ installed packages рдЪрд╛ audit рдХрд░рддреЗ рдЖрдгрд┐
рдЪрд╛рд░ рдирд╛рд╡реЗ рддрдкрд╛рд╕рддреЗ.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 sec/demo.py dependencies
python3 - <<'EOF'
import sys; sys.path.insert(0, "sec"); from supply import vulnerable, typosquat
for installed in ({"requests": "2.30.0"}, {"requests": "2.31.0"}, {"jinja2": "3.1.2", "pyyaml": "6.0.1"}, {"flask": "3.0.0"}):
print(f"{str(installed):<38} тЖТ {vulnerable(installed) or 'no known advisory'}")
for name in ("request", "reqests", "pandsa", "djnago", "numpy", "boto3", "leftpad"):
print(f"typosquat check {name:<8} тЖТ {typosquat(name) or 'no close popular name'}")
EOF
python3 sec/test_sec.py
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
dependencies рд╣реЗ рдЫрд╛рдкрддреЗ:
тХРтХРтХР dependencies тХРтХРтХР
тФАтФА audit of {'requests': '2.28.1', 'jinja2': '3.1.4', 'pyyaml': '5.3.1', 'flask': '3.0.0'}
requests 2.28.1: leaks Proxy-Authorization on redirect тЖТ upgrade to тЙе 2.31.0
pyyaml 5.3.1: arbitrary code via full_load тЖТ upgrade to тЙе 5.4
typosquat check reqeusts тЖТ ['requests']
typosquat check numpyy тЖТ ['numpy']
typosquat check flask тЖТ no close popular name
typosquat check boto4 тЖТ ['boto3']
lockfiles with hashes ┬╖ automated updates ┬╖ an allow-list for new packages ┬╖ audit in CI
тЬЕ done тАФ every door checked
рддреБрдордЪрд╛ snippet рд╣реЗ рдЫрд╛рдкрддреЛ:
{'requests': '2.30.0'} тЖТ [('requests', '2.30.0', 'upgrade to тЙе 2.31.0', 'leaks Proxy-Authorization on redirect')]
{'requests': '2.31.0'} тЖТ no known advisory
{'jinja2': '3.1.2', 'pyyaml': '6.0.1'} тЖТ [('jinja2', '3.1.2', 'upgrade to тЙе 3.1.3', 'XSS via xmlattr filter')]
{'flask': '3.0.0'} тЖТ no known advisory
typosquat check request тЖТ ['requests']
typosquat check reqests тЖТ ['requests']
typosquat check pandsa тЖТ ['pandas']
typosquat check djnago тЖТ ['django']
typosquat check numpy тЖТ no close popular name
typosquat check boto3 тЖТ no close popular name
typosquat check leftpad тЖТ no close popular name
Tests рдордзреНрдпреЗ тЬЕ L13 advisories and typosquats are caught рдЖрд╣реЗ рдЖрдгрд┐ рд╢реЗрд╡рдЯ 16/16 passed рдиреЗ рд╣реЛрддреЛ.
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
рджреБрд░реБрд╕реНрдд version (2.31.0) рдкрд╛рд╕ рд╣реЛрддреЗ рдЖрдгрд┐ рддреНрдпрд╛рдЪреНрдпрд╛ рдЕрдЧрджреА рдЖрдзреАрдЪреЗ (2.30.0) рд╣реЛрдд рдирд╛рд╣реА тАФ рд░реЗрд╖рд╛
рдиреЗрдордХреА рдЖрд╣реЗ. Demo рдордзреНрдпреЗ jinja2 3.1.4 рдкрд╛рд╕ рдЭрд╛рд▓реЗ, рдкрдг 3.1.2 fail рд╣реЛрддреЗ: package рдЪреЗ рдирд╛рд╡ рдирд╛рд╣реА, рддрд░ рддреБрдордЪреЗ
version рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ рдЖрд╣реЗ. рдПрдХ рдЕрдХреНрд╖рд░ рдХрдореА, рдЬреЛрдбреА рдЕрджрд▓рд╛рдмрджрд▓ рдХрд┐рдВрд╡рд╛ рдПрдХ рдЕрдХреНрд╖рд░ рдЬрд╛рд╕реНрдд тАФ рд╣реЗ рд╕рдЧрд│реЗ
"рд▓реЛрдХрдкреНрд░рд┐рдп рдирд╛рд╡рд╛рдЪреНрдпрд╛ рдЬрд╡рд│" рдореНрд╣рдгреВрди рджрд┐рд╕рддрд╛рдд. рдЖрдгрд┐ leftpad рдкрд╛рд╕ рд╣реЛрддреЗ тАФ рддреЗ рд╕реБрд░рдХреНрд╖рд┐рдд рдЖрд╣реЗ рдореНрд╣рдгреВрди рдирд╛рд╣реА, рддрд░
рддреЗ рдпрд╛ рдпрд╛рджреАрддрд▓реНрдпрд╛ рдирд╛рд╡рд╛рдВрдЪреНрдпрд╛ рдЬрд╡рд│ рдирд╛рд╣реА рдореНрд╣рдгреВрди. рдирд╛рд╡рд╛рдВрдЪреА рддрдкрд╛рд╕рдгреА рд╕рд╛рд░рдЦреА рджрд┐рд╕рдгрд╛рд░реА рдирд╛рд╡реЗ рдкрдХрдбрддреЗ; package рдЪрд╛рдВрдЧрд▓реЗ рдЖрд╣реЗ рд╣реЗ рддреА
рд╕рд┐рджреНрдз рдХрд░рдд рдирд╛рд╣реА. рддреНрдпрд╛рд╕рд╛рдареА рдЕрдЬреВрдирд╣реА рдПрдХ рд╡реНрдпрдХреНрддреА, рдПрдХ allow-list рдЖрдгрд┐ рдПрдХ lockfile рд▓рд╛рдЧрддреЗ.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- lockfile рдирд╛рд╣реА, рдХрд┐рдВрд╡рд╛ CI рди рд╡рд╛рдкрд░рдд рдЕрд╕рд▓реЗрд▓реА lockfile (
npm ciрдРрд╡рдЬреАnpm install) - рд╕рдЧрд│реАрдХрдбреЗ
>=рдЕрд╕рд▓реЗрд▓реЗpip install -r requirements.txtтАФ рдкреНрд░рддреНрдпреЗрдХ build рдХрд╛рд╣реАрддрд░реА рдирд╡реЗ рдЖрдгреВ рд╢рдХрддреЛ - audit рдЪрд╛рд▓рд╡рдгреЗ, 40 warnings рдкрд╛рд╣рдгреЗ, рдЖрдгрд┐ audit рдмрдВрдж рдХрд░рдгреЗ
- tests рд╢рд┐рд╡рд╛рдп рдкреНрд░рддреНрдпреЗрдХ update PR рдЖрдкреЛрдЖрдк merge рдХрд░рдгреЗ тАФ malicious рдХрд┐рдВрд╡рд╛ рдмрд┐рдШрдбрд▓реЗрд▓реЗ version рдереЗрдЯ production рдордзреНрдпреЗ рдЬрд╛рддреЗ
- internal index рдХрдбреЗ рдирд┐рд░реНрджреЗрд╢ рдХрд░рдгрд╛рд░реЗ
--extra-index-urlтАФ pip рддреНрдпрд╛рдЪ рдирд╛рд╡рд╛рдЪреЗ public package рдирд┐рд╡рдбреВ рд╢рдХрддреЛ - package рдЪреЗ рдирд╛рд╡ рди рд╡рд╛рдЪрддрд╛ blog рд╡рд░реВрди install command copy рдХрд░рдгреЗ
- container рдЪреА base image рд╡рд┐рд╕рд░рдгреЗ тАФ рддрд┐рдЪреЗ OS packages рд╕реБрджреНрдзрд╛ dependencies рдЪ рдЖрд╣реЗрдд
- рдХрд╛рдпрдордЪреЗ pin рдХрд░рдгреЗ: рдХреЛрдгреА update рди рдХрд░рдгрд╛рд░реА lockfile рдЬреБрдиреЗ bugs pin рдХрд░реВрди рдареЗрд╡рддреЗ
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд
рдЦрд▒реНрдпрд╛ account рд╡рд░ тАФ pinned versions рдЖрдгрд┐ hashes рд╕рд╣ Python (pip-tools), рдЕрд╢рд╛ рдкреНрд░рдХрд╛рд░реЗ install рдХреЗрд▓реЗрд▓реЗ рдХреА рдЗрддрд░ рдХреЛрдгрддреАрд╣реА file рдирд╛рдХрд╛рд░рд▓реА рдЬрд╛рддреЗ, рдордЧ audit:
pip install pip-tools pip-audit
pip-compile --generate-hashes --output-file requirements.txt requirements.in
pip install --require-hashes -r requirements.txt
pip-audit -r requirements.txt --strict
рддрдпрд╛рд░ рдЭрд╛рд▓реЗрд▓реНрдпрд╛ requirements.txt рдЪреА рдПрдХ рдУрд│ рдЕрд╢реА рджрд┐рд╕рддреЗ (hash рд╣рд╛ рдЦрд▒реНрдпрд╛ file рдЪрд╛
SHA-256 рдЖрд╣реЗ):
requests==2.32.4 \
--hash=sha256:<sha256 of the requests-2.32.4 wheel>
Node.js тАФ npm ci рдиреЗрдордХреА lockfile install рдХрд░рддреЗ рдЖрдгрд┐ package.json рд╡ lock рдЬреБрд│рдд рдирд╕рддреАрд▓ рддрд░
fail рд╣реЛрддреЗ; high-severity issues рдЕрд╕рддреАрд▓ рддрд░ audit build fail рдХрд░рддреЛ:
npm ci --ignore-scripts # add scripts back only for packages that need them
npm audit --audit-level=high
Dependabot тАФ Python, npm, Docker base images рдЖрдгрд┐ GitHub Actions рд╕рд╛рдареА рджрд░ рдЖрдард╡рдбреНрдпрд╛рдЪреЗ update PRs
(.github/dependabot.yml):
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule: { interval: "weekly" }
groups:
minor-and-patch: { update-types: ["minor", "patch"] }
- package-ecosystem: "npm"
directory: "/web"
schedule: { interval: "weekly" }
- package-ecosystem: "docker"
directory: "/"
schedule: { interval: "weekly" }
- package-ecosystem: "github-actions"
directory: "/"
schedule: { interval: "weekly" }
рдкреНрд░рддреНрдпреЗрдХ pull request рд╡рд░ Dependency review тАФ vulnerable package рдЬреЛрдбрдгрд╛рд░рд╛ PR block рдХрд░рд╛:
name: dependency-review
on: pull_request
permissions: { contents: read }
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/dependency-review-action@v4
with: { fail-on-severity: high }
Dependency confusion рдерд╛рдВрдмрд╡рд╛ тАФ рд╕рдЧрд│реНрдпрд╛рд╕рд╛рдареА рдПрдХрдЪ index (рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде public index рдХрдбреЗ upstream рдЕрд╕рд▓реЗрд▓реЗ
AWS CodeArtifact), рдЖрдгрд┐ npm рдордзреНрдпреЗ рддреБрдордЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ registry рд╢реА рдЬреЛрдбрд▓реЗрд▓рд╛ scope
(.npmrc):
@school:registry=https://school-111122223333.d.codeartifact.ap-south-1.amazonaws.com/npm/internal/
aws codeartifact login --tool pip --domain school --domain-owner 111122223333 --repository internal
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: main branch рд╡рд░ audit рд╣рд╛ required check рдХрд░рд╛, рдЖрдгрд┐ рдЕрдкрд╡рд╛рджрд╛рдВрд╕рд╛рдареА рд▓рд┐рдЦрд┐рдд рдирд┐рдпрдо рдареЗрд╡рд╛ (finding рдХреЛрдг рд╕реНрд╡реАрдХрд╛рд░реВ рд╢рдХрддреЛ, рдЖрдгрд┐ рдХрдзреАрдкрд░реНрдпрдВрдд). рдХреЛрдгреАрд╣реА рд╡рдЧрд│реВ рд╢рдХреЗрд▓ рдЕрд╕рд╛ audit рдореНрд╣рдгрдЬреЗ рдлрдХреНрдд рдПрдХ рд╕реВрдЪрдирд╛.
тПня╕П рдкреБрдвреЗ
рд╕рд╛рд╣рд┐рддреНрдп рддрдкрд╛рд╕рд▓реЗ рдЧреЗрд▓реЗ. рдкрдг рддрдпрд╛рд░ рдбрдмрд╛ рд╡рд░реНрдЧрд╛рдд рдкреЛрд╣реЛрдЪрд▓реНрдпрд╛рд╡рд░, рддреЛ рдЖрдкрд▓реНрдпрд╛рдЪ рд╕реНрд╡рдпрдВрдкрд╛рдХрдШрд░рд╛рдиреЗ рдмрдирд╡рд▓реЗрд▓рд╛ рдЖрд╣реЗ рдЖрдгрд┐ рддреНрдпрд╛рдд рдХрд╛рдп рдЖрд╣реЗ рд╣реЗ рд╢рд┐рдХреНрд╖рд┐рдХреЗрд▓рд╛ рдХрд╕реЗ рдХрд│рддреЗ? рдкреБрдвреЗ: signatures, SBOMs рдЖрдгрд┐ provenance.
git checkout lesson-14-artifacts