Dependency Confusion

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ

Basic Information

Dependency Confusion (๋˜๋Š” ๋Œ€์ฒด ๊ณต๊ฒฉ)์€ ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž๊ฐ€ ์˜๋„ํ•˜์ง€ ์•Š์€, ๋œ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ/์†Œ์Šค(๋ณดํ†ต ๊ณต๊ฐœ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ)์—์„œ ์˜์กด์„ฑ ์ด๋ฆ„์„ ํ•ด๊ฒฐํ•  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๊ณต๊ฒฉ์ž๊ฐ€ ์ œ์–ดํ•˜๋Š” ํŒจํ‚ค์ง€๊ฐ€ ์„ค์น˜๋˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์ดˆ๋ž˜ํ•ฉ๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์ธ ๊ทผ๋ณธ ์›์ธ:

  • ํƒ€์ดํฌ์Šค์ฟผํŒ…/์˜คํƒ€: reqests๋ฅผ ๋Œ€์‹ ํ•˜์—ฌ requests๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ(๊ณต๊ฐœ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์—์„œ ํ•ด๊ฒฐ๋จ).
  • ์กด์žฌํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ๋ฐฉ์น˜๋œ ๋‚ด๋ถ€ ํŒจํ‚ค์ง€: ๋” ์ด์ƒ ๋‚ด๋ถ€์— ์กด์žฌํ•˜์ง€ ์•Š๋Š” company-logging์„ ๊ฐ€์ ธ์˜ค๋ฉด, ํ•ด๊ฒฐ์ž๊ฐ€ ๊ณต๊ฐœ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์—์„œ ๊ฒ€์ƒ‰ํ•˜์—ฌ ๊ณต๊ฒฉ์ž์˜ ํŒจํ‚ค์ง€๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.
  • ์—ฌ๋Ÿฌ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๊ฐ„์˜ ๋ฒ„์ „ ์„ ํ˜ธ: ๋‚ด๋ถ€ company-requests๋ฅผ ๊ฐ€์ ธ์˜ค๋ฉด์„œ ํ•ด๊ฒฐ์ž๊ฐ€ ๊ณต๊ฐœ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋„ ์ฟผ๋ฆฌํ•  ์ˆ˜ ์žˆ๊ณ  ๊ณต๊ฒฉ์ž๊ฐ€ ๊ณต๊ฐœ์ ์œผ๋กœ ๊ฒŒ์‹œํ•œ โ€œ์ตœ๊ณ ์˜โ€/๋” ์ตœ์‹  ๋ฒ„์ „์„ ์„ ํ˜ธํ•˜๋Š” ๊ฒฝ์šฐ.

ํ•ต์‹ฌ ์•„์ด๋””์–ด: ํ•ด๊ฒฐ์ž๊ฐ€ ๋™์ผํ•œ ํŒจํ‚ค์ง€ ์ด๋ฆ„์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๊ณ  โ€œ์ตœ๊ณ โ€ ํ›„๋ณด๋ฅผ ์ „ ์„ธ๊ณ„์ ์œผ๋กœ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, ํ•ด๊ฒฐ์„ ์ œํ•œํ•˜์ง€ ์•Š๋Š” ํ•œ ์ทจ์•ฝํ•ฉ๋‹ˆ๋‹ค.

Exploitation

Warning

๋ชจ๋“  ๊ฒฝ์šฐ์— ๊ณต๊ฒฉ์ž๋Š” ๊ณต๊ฐœ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์—์„œ ๋นŒ๋“œ๊ฐ€ ํ•ด๊ฒฐํ•˜๋Š” ์˜์กด์„ฑ๊ณผ ๋™์ผํ•œ ์ด๋ฆ„์˜ ์•…์„ฑ ํŒจํ‚ค์ง€๋งŒ ๊ฒŒ์‹œํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์„ค์น˜ ์‹œ ํ›„ํฌ(์˜ˆ: npm ์Šคํฌ๋ฆฝํŠธ) ๋˜๋Š” ๊ฐ€์ ธ์˜ค๊ธฐ ์‹œ ์ฝ”๋“œ ๊ฒฝ๋กœ๋Š” ์ข…์ข… ์ฝ”๋“œ ์‹คํ–‰์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

Misspelled & Inexistent

ํ”„๋กœ์ ํŠธ๊ฐ€ ๊ฐœ์ธ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ๋„๊ตฌ๊ฐ€ ๊ณต๊ฐœ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋กœ ๋˜๋Œ์•„๊ฐ€๋ฉด, ๊ณต๊ฒฉ์ž๋Š” ๊ณต๊ฐœ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ํ•ด๋‹น ์ด๋ฆ„์˜ ์•…์„ฑ ํŒจํ‚ค์ง€๋ฅผ ์‹ฌ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ ๋Ÿฌ๋„ˆ/CI/๊ฐœ๋ฐœ ๋จธ์‹ ์€ ์ด๋ฅผ ๊ฐ€์ ธ์™€ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

Unspecified Version / โ€œBest-versionโ€ selection across indexes

๊ฐœ๋ฐœ์ž๋Š” ์ข…์ข… ๋ฒ„์ „์„ ๊ณ ์ •ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ๋„“์€ ๋ฒ”์œ„๋ฅผ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ•ด๊ฒฐ์ž๊ฐ€ ๋‚ด๋ถ€ ๋ฐ ๊ณต๊ฐœ ์ธ๋ฑ์Šค ๋ชจ๋‘๋กœ ๊ตฌ์„ฑ๋œ ๊ฒฝ์šฐ, ์ถœ์ฒ˜์— ๊ด€๊ณ„์—†์ด ์ตœ์‹  ๋ฒ„์ „์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด๋ถ€ ์ด๋ฆ„์ธ requests-company์˜ ๊ฒฝ์šฐ, ๋‚ด๋ถ€ ์ธ๋ฑ์Šค์— 1.0.1์ด ์žˆ์ง€๋งŒ ๊ณต๊ฒฉ์ž๊ฐ€ ๊ณต๊ฐœ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— 1.0.2๋ฅผ ๊ฒŒ์‹œํ•˜๊ณ  ํ•ด๊ฒฐ์ž๊ฐ€ ๋‘˜ ๋‹ค ๊ณ ๋ คํ•˜๋ฉด, ๊ณต๊ฐœ ํŒจํ‚ค์ง€๊ฐ€ ์šฐ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

AWS Fix

์ด ์ทจ์•ฝ์ ์€ AWS CodeArtifact์—์„œ ๋ฐœ๊ฒฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค(์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ด ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค). AWS๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ƒ์œ„ ๊ณต๊ฐœ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์—์„œ โ€œ๋‚ด๋ถ€โ€ ์ด๋ฆ„์„ ๊ฐ€์ ธ์˜ค์ง€ ์•Š๋„๋ก ์˜์กด์„ฑ/ํ”ผ๋“œ๋ฅผ ๋‚ด๋ถ€์™€ ์™ธ๋ถ€๋กœ ํ‘œ์‹œํ•˜๋Š” ์ œ์–ด๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

Finding Vulnerable Libraries

์˜์กด์„ฑ ํ˜ผ๋ž€์— ๋Œ€ํ•œ ์›๋ž˜ ๊ฒŒ์‹œ๋ฌผ์—์„œ ์ €์ž๋Š” ์ˆ˜์ฒœ ๊ฐœ์˜ ๋…ธ์ถœ๋œ ๋งค๋‹ˆํŽ˜์ŠคํŠธ(์˜ˆ: package.json, requirements.txt, lockfiles)๋ฅผ ์ฐพ์•„ ๋‚ด๋ถ€ ํŒจํ‚ค์ง€ ์ด๋ฆ„์„ ์œ ์ถ”ํ•œ ๋‹ค์Œ, ๋” ๋†’์€ ๋ฒ„์ „์˜ ํŒจํ‚ค์ง€๋ฅผ ๊ณต๊ฐœ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ๊ฒŒ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค.

Practical Attacker Playbook (for red teams in authorized tests)

  • ์ด๋ฆ„ ์—ด๊ฑฐ:
  • ๋งค๋‹ˆํŽ˜์ŠคํŠธ/๋ฝ ํŒŒ์ผ ๋ฐ ๋‚ด๋ถ€ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ๋Œ€ํ•œ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ๋ฐ CI ๊ตฌ์„ฑ grep.
  • ์กฐ์ง ํŠน์ • ์ ‘๋‘์‚ฌ ์ฐพ๊ธฐ(์˜ˆ: @company/*, company-*, ๋‚ด๋ถ€ groupIds, NuGet ID ํŒจํ„ด, Go์˜ ๊ฐœ์ธ ๋ชจ๋“ˆ ๊ฒฝ๋กœ ๋“ฑ).
  • ๊ณต๊ฐœ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์—์„œ ๊ฐ€์šฉ์„ฑ ํ™•์ธ:
  • ์ด๋ฆ„์ด ๊ณต๊ฐœ์ ์œผ๋กœ ๋“ฑ๋ก๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ, ๋“ฑ๋กํ•˜์‹ญ์‹œ์˜ค; ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ, ๋‚ด๋ถ€ ์ „์ด ์ด๋ฆ„์„ ๋Œ€์ƒ์œผ๋กœ ํ•˜์—ฌ ํ•˜์œ„ ์˜์กด์„ฑ ํƒˆ์ทจ๋ฅผ ์‹œ๋„ํ•˜์‹ญ์‹œ์˜ค.
  • ์šฐ์„  ์ˆœ์œ„๋กœ ๊ฒŒ์‹œ:
  • โ€œ์ด๊ธฐ๋Š”โ€ ์„ธ๋ฉ˜ํ‹ฑ ๋ฒ„์ „ ์„ ํƒ(์˜ˆ: ๋งค์šฐ ๋†’์€ ๋ฒ„์ „) ๋˜๋Š” ํ•ด๊ฒฐ์ž ๊ทœ์น™์— ๋งž์ถ”๊ธฐ.
  • ์ ์šฉ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ ์ตœ์†Œ ์„ค์น˜ ์‹œ๊ฐ„ ์‹คํ–‰ ํฌํ•จ(์˜ˆ: npm preinstall/install/postinstall ์Šคํฌ๋ฆฝํŠธ). Python์˜ ๊ฒฝ์šฐ, ํœ ์ด ์ผ๋ฐ˜์ ์œผ๋กœ ์„ค์น˜ ์‹œ ์ž„์˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๊ฐ€์ ธ์˜ค๊ธฐ ์‹œ๊ฐ„ ์‹คํ–‰ ๊ฒฝ๋กœ๋ฅผ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.
  • ์ œ์–ด ์œ ์ถœ:
  • CI์—์„œ ๊ท€ํ•˜์˜ ์ œ์–ด๋œ ์—”๋“œํฌ์ธํŠธ๋กœ์˜ ์•„์›ƒ๋ฐ”์šด๋“œ๊ฐ€ ํ—ˆ์šฉ๋˜๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค; ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด DNS ์ฟผ๋ฆฌ ๋˜๋Š” ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ์‚ฌ์ด๋“œ ์ฑ„๋„๋กœ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ ์‹คํ–‰์„ ์ฆ๋ช…ํ•˜์‹ญ์‹œ์˜ค.

Caution

ํ•ญ์ƒ ์„œ๋ฉด ์Šน์ธ์„ ๋ฐ›๊ณ , ์ฐธ์—ฌ๋ฅผ ์œ„ํ•ด ๊ณ ์œ ํ•œ ํŒจํ‚ค์ง€ ์ด๋ฆ„/๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋ฉฐ, ํ…Œ์ŠคํŠธ๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด ์ฆ‰์‹œ ๊ฒŒ์‹œ ์ทจ์†Œํ•˜๊ฑฐ๋‚˜ ์ •๋ฆฌ๋ฅผ ์กฐ์ •ํ•˜์‹ญ์‹œ์˜ค.

Defender Playbook (what actually prevents confusion)

์ƒํƒœ๊ณ„ ์ „๋ฐ˜์— ๊ฑธ์ณ ์ž‘๋™ํ•˜๋Š” ๊ณ ๊ธ‰ ์ „๋žต:

  • ๊ณ ์œ ํ•œ ๋‚ด๋ถ€ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์ด๋ฅผ ๋‹จ์ผ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ๋ฐ”์ธ๋”ฉํ•ฉ๋‹ˆ๋‹ค.
  • ํ•ด๊ฒฐ ์‹œ๊ฐ„์— ์‹ ๋ขฐ ์ˆ˜์ค€ ํ˜ผํ•ฉ์„ ํ”ผํ•˜์‹ญ์‹œ์˜ค. ์Šน์ธ๋œ ๊ณต๊ฐœ ํŒจํ‚ค์ง€๋ฅผ ํ”„๋ก์‹œํ•˜๋Š” ๋‹จ์ผ ๋‚ด๋ถ€ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋ฅผ ์„ ํ˜ธํ•˜๊ณ  ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž์—๊ฒŒ ๋‚ด๋ถ€ ๋ฐ ๊ณต๊ฐœ ์—”๋“œํฌ์ธํŠธ๋ฅผ ๋ชจ๋‘ ์ œ๊ณตํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค.
  • ์ง€์›ํ•˜๋Š” ๊ด€๋ฆฌ์ž์— ๋Œ€ํ•ด ํŒจํ‚ค์ง€๋ฅผ ํŠน์ • ์†Œ์Šค์— ๋งคํ•‘ํ•˜์‹ญ์‹œ์˜ค(๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๊ฐ„์˜ ์ „์—ญ โ€œ์ตœ๊ณ  ๋ฒ„์ „โ€ ์—†์Œ).
  • ๊ณ ์ • ๋ฐ ์ž ๊ธˆ:
  • ํ•ด๊ฒฐ๋œ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ URL์„ ๊ธฐ๋กํ•˜๋Š” ๋ฝํŒŒ์ผ(npm/yarn/pnpm)์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ํ•ด์‹œ/์ฆ๋ช… ๊ณ ์ •์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค(pip --require-hashes, Gradle ์˜์กด์„ฑ ๊ฒ€์ฆ).
  • ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ/๋„คํŠธ์›Œํฌ ๊ณ„์ธต์—์„œ ๋‚ด๋ถ€ ์ด๋ฆ„์— ๋Œ€ํ•œ ๊ณต๊ฐœ ๋Œ€์ฒด๋ฅผ ์ฐจ๋‹จํ•˜์‹ญ์‹œ์˜ค.
  • ๊ฐ€๋Šฅํ•  ๊ฒฝ์šฐ ๊ณต๊ฐœ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์—์„œ ๋‚ด๋ถ€ ์ด๋ฆ„์„ ์˜ˆ์•ฝํ•˜์—ฌ ํ–ฅํ›„ ์Šค์ฟผํŠธ๋ฅผ ๋ฐฉ์ง€ํ•˜์‹ญ์‹œ์˜ค.

Ecosystem Notes and Secure Config Snippets

๋‹ค์Œ์€ ์˜์กด์„ฑ ํ˜ผ๋ž€์„ ์ค„์ด๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•œ ์‹ค์šฉ์ ์ด๊ณ  ์ตœ์†Œํ•œ์˜ ๊ตฌ์„ฑ์ž…๋‹ˆ๋‹ค. CI ๋ฐ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ ์ด๋ฅผ ์‹œํ–‰ํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.

JavaScript/TypeScript (npm, Yarn, pnpm)

  • ๋ชจ๋“  ๋‚ด๋ถ€ ์ฝ”๋“œ์— ๋Œ€ํ•ด ๋ฒ”์œ„๊ฐ€ ์ง€์ •๋œ ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋ฒ”์œ„๋ฅผ ๊ฐœ์ธ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ๊ณ ์ •ํ•ฉ๋‹ˆ๋‹ค.
  • CI์—์„œ ์„ค์น˜๋ฅผ ๋ถˆ๋ณ€์œผ๋กœ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค(npm lockfile, yarn install --immutable).

.npmrc (ํ”„๋กœ์ ํŠธ ์ˆ˜์ค€)

# Bind internal scope to private registry; do not allow public fallback for @company/*
@company:registry=https://registry.corp.example/npm/
# Always authenticate to the private registry
//registry.corp.example/npm/:_authToken=${NPM_TOKEN}
strict-ssl=true

package.json (๋‚ด๋ถ€ ํŒจํ‚ค์ง€์šฉ)

{
"name": "@company/api-client",
"version": "1.2.3",
"private": false,
"publishConfig": {
"registry": "https://registry.corp.example/npm/",
"access": "restricted"
}
}

Yarn Berry (.yarnrc.yml)

npmScopes:
company:
npmRegistryServer: "https://registry.corp.example/npm/"
npmAlwaysAuth: true
# CI should fail if lockfile would change
enableImmutableInstalls: true

์šด์˜ ํŒ:

  • @company ๋ฒ”์œ„ ๋‚ด์—์„œ๋งŒ ๋‚ด๋ถ€ ํŒจํ‚ค์ง€๋ฅผ ๊ฒŒ์‹œํ•˜์„ธ์š”.
  • ์„œ๋“œํŒŒํ‹ฐ ํŒจํ‚ค์ง€์˜ ๊ฒฝ์šฐ, ํด๋ผ์ด์–ธํŠธ์—์„œ ์ง์ ‘๊ฐ€ ์•„๋‹Œ ๊ฐœ์ธ ํ”„๋ก์‹œ/๋ฏธ๋Ÿฌ๋ฅผ ํ†ตํ•ด ๊ณต๊ฐœ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋ฅผ ํ—ˆ์šฉํ•˜์„ธ์š”.
  • ๊ฒŒ์‹œํ•˜๋Š” ๊ณต๊ฐœ ํŒจํ‚ค์ง€์— ๋Œ€ํ•ด npm ํŒจํ‚ค์ง€ ์ถœ์ฒ˜๋ฅผ ํ™œ์„ฑํ™”ํ•˜์—ฌ ์ถ”์  ๊ฐ€๋Šฅ์„ฑ์„ ๋†’์ด๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•˜์„ธ์š” (ํ˜ผ๋ž€์„ ๋ฐฉ์ง€ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค).

Python (pip / Poetry)

ํ•ต์‹ฌ ๊ทœ์น™: ์‹ ๋ขฐ ์ˆ˜์ค€์„ ํ˜ผํ•ฉํ•˜๊ธฐ ์œ„ํ•ด --extra-index-url์„ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์„ธ์š”. ๋‹ค์Œ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•˜์„ธ์š”:

  • ์Šน์ธ๋œ PyPI ํŒจํ‚ค์ง€๋ฅผ ํ”„๋ก์‹œํ•˜๊ณ  ์บ์‹œํ•˜๋Š” ๋‹จ์ผ ๋‚ด๋ถ€ ์ธ๋ฑ์Šค๋ฅผ ๋…ธ์ถœํ•˜๊ฑฐ๋‚˜,
  • ๋ช…์‹œ์  ์ธ๋ฑ์Šค ์„ ํƒ ๋ฐ ํ•ด์‹œ ๊ณ ์ •์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

pip.conf

[global]
index-url = https://pypi.corp.example/simple
# Disallow source distributions when possible
only-binary = :all:
# Lock with hashes generated via pip-tools
require-hashes = true

pip-tools๋กœ ํ•ด์‹œ๋œ ์š”๊ตฌ ์‚ฌํ•ญ ์ƒ์„ฑํ•˜๊ธฐ:

# From pyproject.toml or requirements.in
pip-compile --generate-hashes -o requirements.txt
pip install --require-hashes -r requirements.txt

๊ณต์‹ PyPI์— ์ ‘๊ทผํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ, ๋‚ด๋ถ€ ํ”„๋ก์‹œ๋ฅผ ํ†ตํ•ด ์ ‘๊ทผํ•˜๊ณ  ๋ช…์‹œ์ ์ธ ํ—ˆ์šฉ ๋ชฉ๋ก์„ ์œ ์ง€ํ•˜์‹ญ์‹œ์˜ค. CI์—์„œ --extra-index-url ์‚ฌ์šฉ์„ ํ”ผํ•˜์‹ญ์‹œ์˜ค.

.NET (NuGet)

ํŒจํ‚ค์ง€ ID ํŒจํ„ด์„ ๋ช…์‹œ์ ์ธ ์†Œ์Šค์— ์—ฐ๊ฒฐํ•˜๊ณ  ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ํ”ผ๋“œ์—์„œ์˜ ํ•ด์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ํŒจํ‚ค์ง€ ์†Œ์Šค ๋งคํ•‘์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

nuget.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="corp" value="https://nuget.corp.example/v3/index.json" />
</packageSources>
<packageSourceMapping>
<packageSource key="nuget.org">
<package pattern="*" />
</packageSource>
<packageSource key="corp">
<package pattern="Company.*" />
<package pattern="Internal.Utilities" />
</packageSource>
</packageSourceMapping>
</configuration>

Java (Maven/Gradle)

Maven settings.xml (๋ชจ๋“  ๊ฒƒ์„ ๋‚ด๋ถ€๋กœ ๋ฏธ๋Ÿฌ๋ง; Enforcer๋ฅผ ํ†ตํ•ด POM์—์„œ ์ž„์‹œ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ํ—ˆ์šฉ ๊ธˆ์ง€):

<settings>
<mirrors>
<mirror>
<id>internal-mirror</id>
<mirrorOf>*</mirrorOf>
<url>https://maven.corp.example/repository/group</url>
</mirror>
</mirrors>
</settings>

Enforcer๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ POM์— ์„ ์–ธ๋œ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์ฐจ๋‹จํ•˜๊ณ  ๋ฏธ๋Ÿฌ ์‚ฌ์šฉ์„ ๊ฐ•์ œํ•ฉ๋‹ˆ๋‹ค:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.6.1</version>
<executions>
<execution>
<id>enforce-no-repositories</id>
<goals><goal>enforce</goal></goals>
<configuration>
<rules>
<requireNoRepositories />
</rules>
</configuration>
</execution>
</executions>
</plugin>

Gradle: ์˜์กด์„ฑ์„ ์ค‘์•™ ์ง‘์ค‘ํ™”ํ•˜๊ณ  ์ž ๊ธˆ.

  • settings.gradle(.kts)์—์„œ๋งŒ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ๊ฐ•์ œ ์ ์šฉ:
dependencyResolutionManagement {
repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS
repositories {
maven { url = uri("https://maven.corp.example/repository/group") }
}
}
  • ์ข…์†์„ฑ ๊ฒ€์ฆ(์ฒดํฌ์„ฌ/์„œ๋ช…)์„ ํ™œ์„ฑํ™”ํ•˜๊ณ  gradle/verification-metadata.xml์„ ์ปค๋ฐ‹ํ•ฉ๋‹ˆ๋‹ค.

Go Modules

๊ณต์šฉ ํ”„๋ก์‹œ์™€ ์ฒดํฌ์„ฌ DB๊ฐ€ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋„๋ก ๊ฐœ์ธ ๋ชจ๋“ˆ์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

# Use corporate proxy first, then public proxy as fallback
export GOPROXY=https://goproxy.corp.example,https://proxy.golang.org
# Mark private paths to skip proxy and checksum db
export GOPRIVATE=*.corp.example.com,github.com/your-org/*
export GONOSUMDB=*.corp.example.com,github.com/your-org/*

Rust (Cargo)

์Šน์ธ๋œ ๋‚ด๋ถ€ ๋ฏธ๋Ÿฌ ๋˜๋Š” ๊ณต๊ธ‰์—…์ฒด ๋””๋ ‰ํ† ๋ฆฌ๋กœ crates.io๋ฅผ ๊ต์ฒดํ•˜์—ฌ ๋นŒ๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ณ , ์ž„์˜์˜ ๊ณต๊ฐœ ๋Œ€์ฒด๋ฅผ ํ—ˆ์šฉํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

.cargo/config.toml

[source.crates-io]
replace-with = "corp-mirror"

[source.corp-mirror]
registry = "https://crates-mirror.corp.example/index"

๊ฒŒ์‹œ๋ฅผ ์œ„ํ•ด --registry๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์ž๊ฒฉ ์ฆ๋ช…์„ ๋Œ€์ƒ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋กœ ์ œํ•œํ•˜์‹ญ์‹œ์˜ค.

Ruby (Bundler)

์†Œ์Šค ๋ธ”๋ก์„ ์‚ฌ์šฉํ•˜๊ณ  ๋‹ค์ค‘ ์†Œ์Šค Gemfile์„ ๋น„ํ™œ์„ฑํ™”ํ•˜์—ฌ gem์ด ์˜๋„๋œ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์—์„œ๋งŒ ์˜ค๋„๋ก ํ•˜์‹ญ์‹œ์˜ค.

Gemfile

source "https://gems.corp.example"

source "https://rubygems.org" do
gem "rails"
gem "pg"
end

source "https://gems.corp.example" do
gem "company-logging"
end

๊ตฌ์„ฑ ์ˆ˜์ค€์—์„œ ์‹œํ–‰:

bundle config set disable_multisource true

CI/CD ๋ฐ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ์ œ์–ด

  • ๋‹จ์ผ ์ง„์ž…์ ์œผ๋กœ์„œ์˜ ๊ฐœ์ธ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ:
  • ๊ฐœ๋ฐœ์ž/CI๊ฐ€ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ์—”๋“œํฌ์ธํŠธ๋กœ Artifactory/Nexus/CodeArtifact/GitHub Packages/Azure Artifacts๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ๋‚ด๋ถ€ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๊ฐ€ ํ•ญ์ƒ ์—…์ŠคํŠธ๋ฆผ ๊ณต๊ฐœ ์†Œ์Šค์—์„œ ํ•ด๊ฒฐ๋˜์ง€ ์•Š๋„๋ก ์ฐจ๋‹จ/ํ—ˆ์šฉ ๊ทœ์น™์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
  • CI์—์„œ ์ž ๊ธˆ ํŒŒ์ผ์€ ๋ถˆ๋ณ€์ž…๋‹ˆ๋‹ค:
  • npm: package-lock.json์„ ์ปค๋ฐ‹ํ•˜๊ณ , npm ci๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • Yarn: yarn.lock์„ ์ปค๋ฐ‹ํ•˜๊ณ , yarn install --immutable์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • Python: ํ•ด์‹œ๋œ requirements.txt๋ฅผ ์ปค๋ฐ‹ํ•˜๊ณ , --require-hashes๋ฅผ ๊ฐ•์ œํ•ฉ๋‹ˆ๋‹ค.
  • Gradle: verification-metadata.xml์„ ์ปค๋ฐ‹ํ•˜๊ณ , ์•Œ ์ˆ˜ ์—†๋Š” ์•„ํ‹ฐํŒฉํŠธ์—์„œ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.
  • ์•„์›ƒ๋ฐ”์šด๋“œ ์ด๊ทธ๋ ˆ์Šค ์ œ์–ด: ์Šน์ธ๋œ ํ”„๋ก์‹œ๋ฅผ ํ†ตํ•ด์„œ๋งŒ CI์—์„œ ๊ณต๊ฐœ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ์ง์ ‘ ์ ‘๊ทผ์„ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค.
  • ์ด๋ฆ„ ์˜ˆ์•ฝ: ์ง€์›๋˜๋Š” ๊ณต๊ฐœ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์—์„œ ๋‚ด๋ถ€ ์ด๋ฆ„/๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์‚ฌ์ „ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.
  • ํŒจํ‚ค์ง€ ์ถœ์ฒ˜/์ฆ๋ช…: ๊ณต๊ฐœ ํŒจํ‚ค์ง€๋ฅผ ๊ฒŒ์‹œํ•  ๋•Œ, ๋ณ€์กฐ๋ฅผ ๋” ์‰ฝ๊ฒŒ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ถœ์ฒ˜/์ฆ๋ช…์„ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋ฌธํ—Œ

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ