QueryPie Community Edition is live ๐ŸŽ‰ Get it now for free Download today!

๋ฌด๋ฃŒ๋กœ ์‹œ์ž‘ํ•˜๊ธฐ
๋ฐฑ์„œ

๊ฐœ๋ฐœ ์†๋„์™€ ์•ˆ์ •์„ฑ ํ–ฅ์ƒ์ด ๊ฒ€์ฆ๋œ QueryPie์˜ DevSecOps ํŒŒ์ดํ”„๋ผ์ธ

๊ฐœ๋ฐœ ์ดˆ๊ธฐ๋ถ€ํ„ฐ ์šด์˜ ๋‹จ๊ณ„๊นŒ์ง€ ๋ณด์•ˆ์„ ์ž๋™ํ™”ํ•˜๊ณ  ํ‘œ์ค€ํ™”๋œ ๋ฐฉ์‹์œผ๋กœ ๊ตฌ์ถ• ์šด์˜ํ•˜๊ณ  ์žˆ๋Š” QueryPie์˜ ํŒŒ์ดํ”„๋ผ์ธ์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.

Jake Im

Jake Im

Security Team Lead

์ œ์ดํฌ๋Š” 16๋…„ ์ด์ƒ์˜ ๊ฒฝ๋ ฅ์„ ๊ฐ€์ง„ ๋ณด์•ˆ ์ „๋ฌธ๊ฐ€๋กœ, ๊ธˆ์œต ๋ฐ ๊ตฐ์‚ฌ ๋ถ„์•ผ๋ฅผ ํฌํ•จํ•œ ๋งค์šฐ ๊นŒ๋‹ค๋กœ์šด ํ™˜๊ฒฝ์˜ ๋ณด์•ˆ ์šด์˜์„ ์„ ๋„ํ•ด์™”์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฝ๋ ฅ์€ ๊ณ ๊ธ‰ ์œ„ํ˜‘ ๋ถ„์„, ๋ฆฌ์Šคํฌ ๊ด€๋ฆฌ, ๋ณด์•ˆ ์•„ํ‚คํ…์ณ ์„ค๊ณ„์™€ ๊ฐ™์€ ์˜์—ญ์—์„œ ๋‘๊ฐ์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ, ๋ณต์žกํ•œ ๋ณด์•ˆ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ๋น„์ฆˆ๋‹ˆ์Šค์˜ ํ•ต์‹ฌ ์ž์‚ฐ์„ ๋ณดํ˜ธํ•˜๋Š” ๋ฐ ์ค‘์ถ”์ ์ธ ์—ญํ• ์„ ํ•ด์™”์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ QueryPie์˜ ๋ณด์•ˆํŒ€ ๋ฆฌ๋”๋กœ์„œ ๋Š์ž„์—†์ด ์ง„ํ™”ํ•˜๋Š” ์‚ฌ์ด๋ฒ„ ์œ„ํ˜‘์— ๋Œ€์‘ํ•˜๋Š” ํ˜์‹ ์  ๋ณด์•ˆ ์ „๋žต์„ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Ravi Kang

Ravi Kang

Security Engineer

๋ผ๋น„๋Š” QueryPie์˜ ๋ณด์•ˆ ์—”์ง€๋‹ˆ์–ด์ด์ž ์นจํˆฌ ํ…Œ์ŠคํŠธ ์ „๋ฌธ๊ฐ€๋กœ, ๊ธฐ์—…์— ๋ณด์•ˆ ๋ชจ๋ฒ” ์‚ฌ๋ก€๋ฅผ ์ œ๊ณตํ•˜๊ณ  ๋‹ค์–‘ํ•œ ์กฐ์ง์— ๋Œ€ํ•œ ์‹ฌ์ธต์ ์ธ ๋ณด์•ˆ ์ปจ์„คํŒ…์„ ์ง„ํ–‰ํ•ด ์˜จ ๊ฒฝ๋ ฅ์ด ํ’๋ถ€ํ•œ ์ „๋ฌธ๊ฐ€์ž…๋‹ˆ๋‹ค. ์ทจ์•ฝ์  ์‹๋ณ„๊ณผ ๊ฐ•๋ ฅํ•œ ๋ณด์•ˆ ์กฐ์น˜ ๊ตฌํ˜„์— ํƒ์›”ํ•œ ๋Šฅ๋ ฅ์„ ๋ฐœํœ˜ํ•˜๋ฉฐ, ๋ณต์žกํ•œ ๋ณด์•ˆ ํ™˜๊ฒฝ์—์„œ๋„ ๋ฐ์ดํ„ฐ์™€ ์‹œ์Šคํ…œ์˜ ์•ˆ์ „์„ฑ์„ ๋ณด์žฅํ•˜๋Š” ๋ฐ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ์˜ ์ „๋ฌธ์„ฑ์€ ๋ณด์•ˆ ๋ฐ ๋ฐ์ดํ„ฐ ๊ฑฐ๋ฒ„๋„Œ์Šค๋ฅผ ๊ฐ•ํ™”ํ•˜๋Š” ํ•ต์‹ฌ์ ์ธ ๊ธฐ์—ฌ๋กœ ์ด์–ด์ง€๊ณ  ์žˆ์œผ๋ฉฐ, ์กฐ์ง์˜ ์ „๋ฐ˜์ ์ธ ๋ณด์•ˆ ํƒœ์„ธ๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ๋ฐ ํ•„์ˆ˜์ ์ธ ์—ญํ• ์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Noah Kim

Noah Kim

Security Engineer

๋…ธ์•„๋Š” ์นจํˆฌ ํ…Œ์ŠคํŠธ ์ปจ์„คํ„ดํŠธ์ด์ž ์‚ฌ๋‚ด ์นจํˆฌ ํ…Œ์ŠคํŠธ ์ „๋ฌธ๊ฐ€๋กœ, ๋‹ค์–‘ํ•œ ์ทจ์•ฝ์„ฑ ํ‰๊ฐ€๋ฅผ ํ†ตํ•ด ์กฐ์ง์˜ ์‹œ์Šคํ…œ๊ณผ ์ œํ’ˆ์˜ ์•ˆ์ •์„ฑ ๋ฐ ๋ณด์•ˆ์„ ์ฒ ์ €ํžˆ ๋ณด์žฅํ•˜๋Š” ์ „๋ฌธ๊ฐ€์ž…๋‹ˆ๋‹ค. SAST(์†Œ์Šค ์ฝ”๋“œ ๋ถ„์„) ๋ฐ DAST(๋™์  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ณด์•ˆ ํ…Œ์ŠคํŠธ)์™€ ๊ฐ™์€ ๊ณ ๊ธ‰ ๋ณด์•ˆ ์†”๋ฃจ์…˜์„ CI/CD ํŒŒ์ดํ”„๋ผ์ธ์— ํ†ตํ•ฉํ•˜์—ฌ, ๊ฐœ๋ฐœ ๋ฐ ๋ฐฐํฌ ๊ณผ์ • ์ „๋ฐ˜์—์„œ ๋ณด์•ˆ์„ ๊ฐ•ํ™”ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, ํšŒ์‚ฌ์˜ ์ œํ’ˆ์— ๋Œ€ํ•œ ์ทจ์•ฝ์  ๊ด€๋ฆฌ๋ฅผ ์ฒด๊ณ„์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜์—ฌ, ์ž ์žฌ์ ์ธ ๋ณด์•ˆ ๋ฆฌ์Šคํฌ๋ฅผ ๋ฏธ๋ฆฌ ์‹๋ณ„ํ•˜๊ณ  ํ•ด๊ฒฐํ•˜๋Š” ์ค‘์š”ํ•œ ์—ญํ• ์„ ๋งก๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

2024๋…„ 11์›” 22์ผ

๊ฐœ๋ฐœ ์†๋„์™€ ์•ˆ์ •์„ฑ ํ–ฅ์ƒ์ด ๊ฒ€์ฆ๋œ QueryPie์˜ DevSecOps ํŒŒ์ดํ”„๋ผ์ธ

๊ฐœ์š”

๋ณด์•ˆ์„ ํ†ตํ•ฉํ•œ QueryPie์˜ ํŒŒ์ดํ”„๋ผ์ธ

QueryPie๊ฐ€ ์ค‘์š”ํ•˜๊ฒŒ ์ƒ๊ฐํ•˜๋Š” ๋ถ€๋ถ„, ๋น ๋ฅธ ๊ฐœ๋ฐœ ์†๋„์™€ ์•ˆ์ •์„ฑ์ž…๋‹ˆ๋‹ค. QueryPie ํŒ€์€ ๋น ๋ฅธ ์„ฑ์žฅ์„ ์›ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ณ€ํ™”์— ๋ฏผ์ฒฉํ•˜๊ฒŒ ๋Œ€์‘ํ•˜๊ธธ ์›ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฐ„๊ณผํ•˜๋ฉด ์•ˆ๋˜๋Š” ๋ถ€๋ถ„์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ฐœ๋ฐœ ์†๋„๋ฅผ ๋†’์ด๋‹ค ๋ณด๋ฉด ๋ณด์•ˆ ๊ฒ€ํ† ๊ฐ€ ๋’ค๋กœ ๋ฐ€๋ฆฌ๊ฑฐ๋‚˜ ๊ฐ„๊ณผ๋˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์ดˆ๊ธฐ์— ๋งŽ์ด ๊ฒฝํ—˜ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•˜์—ฌ ์ถœ์‹œ ํ›„ ๋ณด์•ˆ ์ทจ์•ฝ์ ์ด ๋ฐœ๊ฒฌ๋˜๋ฉด ๊ธด๊ธ‰ ํŒจ์น˜, ๋†’์€ ๋น„์šฉ, ๊ทธ๋ฆฌ๊ณ  ๋ธŒ๋žœ๋“œ ์‹ ๋ขฐ๋„ ์†์‹ค๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค๋Š” ์œ„ํ—˜์„ ์ถฉ๋ถ„ํžˆ ์ธ์ง€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

DevSecOps๋Š” ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ๊ทผ๋ณธ์ ์œผ๋กœ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ(Dev)๊ณผ ์šด์˜(Ops) ๊ณผ์ •์— ๋ณด์•ˆ(Security)์„ ํ†ตํ•ฉํ•˜์—ฌ, ๊ฐœ๋ฐœ ์ดˆ๊ธฐ๋ถ€ํ„ฐ ์šด์˜ ๋‹จ๊ณ„๊นŒ์ง€ ๋ณด์•ˆ์„ ์ž๋™ํ™”ํ•˜๊ณ  ํ‘œ์ค€ํ™”๋œ ๋ฐฉ์‹์œผ๋กœ QueryPie๋Š” ํŒŒ์ดํ”„๋ผ์ธ์„ ๊ตฌ์ถ• ์šด์˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

QueryPie์˜ ๊ฐœ๋ฐœ ๋ผ์ดํ”„์‚ฌ์ดํด ์ „ ๋‹จ๊ณ„ ๋ณด์•ˆ์„ฑ ๊ฒ€ํ†  ํ”„๋กœ์„ธ์Šค

QueryPie๋Š” Privileged Access Management(PAM) ์†”๋ฃจ์…˜์œผ๋กœ์„œ, Database Access Control(DAC), System Access Control(SAC), Kubernetes Access Control(KAC) ๋“ฑ ์ค‘์š”ํ•œ ์ž์‚ฐ๊ณผ ์ •๋ณด๋ฅผ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•ด ๊ณ ๋„์˜ ๋ณด์•ˆ์„ ์š”๊ตฌํ•˜๋Š” ์ œํ’ˆ์ž…๋‹ˆ๋‹ค. ์ด์— ๋”ฐ๋ผ ๋”์šฑ๋” ์ฒ ์ €ํ•œ ๋ณด์•ˆ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•˜์—ฌ QueryPie๋Š” ๊ฐœ๋ฐœ ๋ผ์ดํ”„์‚ฌ์ดํด ์ „๋ฐ˜์— ๊ฑธ์ณ ์ผ๊ด€๋œ ๋ณด์•ˆ ๊ฒ€ํ†  ๋ฐ ์ ๊ฒ€์ด ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ ์ดˆ๊ธฐ ๋‹จ๊ณ„์˜ ์š”๊ตฌ์‚ฌํ•ญ ์ˆ˜๋ฆฝ๋ถ€ํ„ฐ, ์„ค๊ณ„, ๊ตฌํ˜„, ํ…Œ์ŠคํŠธ, ๋ฐฐํฌ, ์šด์˜์— ์ด๋ฅด๊ธฐ๊นŒ์ง€ ๊ฐ ๋‹จ๊ณ„์—์„œ ๋‹ค์ธต์ ์ธ ๋ณด์•ˆ ๊ฒ€ํ†  ํ”„๋กœ์„ธ์Šค๋ฅผ ์ ์šฉํ•˜์—ฌ ์ž ์žฌ์ ์ธ ๋ณด์•ˆ ์œ„ํ˜‘์„ ์‚ฌ์ „์— ๋ฐฉ์ง€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ €ํฌ๋Š” DevSecOps ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ฑ„ํƒํ•˜์—ฌ ๊ฐœ๋ฐœ๊ณผ ๋ณด์•ˆ์„ ํ†ตํ•ฉํ•˜์—ฌ ๊ธด๋ฐ€ํžˆ ์—ฐ๊ณ„ํ•˜๊ณ  ์ž๋™ํ™”๋œ ๋ณด์•ˆ ๊ฒ€์‚ฌ์™€ ์ง€์†์ ์ธ ๋ชจ๋‹ˆํ„ฐ๋ง์œผ๋กœ ์ทจ์•ฝ์ ์„ ์‹ ์†ํ•˜๊ฒŒ ์‹๋ณ„ํ•˜๊ณ  ๋Œ€์‘ํ•จ์œผ๋กœ์จ, ์ œํ’ˆ์˜ ์•ˆ์ •์„ฑ๊ณผ ์‹ ๋ขฐ์„ฑ์„ ๋”์šฑ ๊ฐ•ํ™”ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ฒ˜๋Ÿผ, ์šฐ๋ฆฌ์—๊ฒŒ ๋ณด์•ˆ์€ ๋‹จ์ˆœํ•œ ๊ธฐ๋Šฅ์„ ๋„˜์–ด ์ œํ’ˆ์˜ ํ•ต์‹ฌ ์š”์†Œ๋กœ ์ž๋ฆฌ ์žก๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


QueryPie CI/CD Pipeline
QueryPie CI/CD ํŒŒ์ดํ”„๋ผ์ธ

DevSecOps์˜ ํ•„์š”์„ฑ๊ณผ ํด๋ผ์šฐ๋“œ ํ™˜๊ฒฝ์—์„œ์˜ ๋ณด์•ˆ ๊ณผ์ œ

๊ธฐ์กด์˜ ๋ณด์•ˆ ์ ‘๊ทผ๋ฒ•์€ ๋ณด์•ˆ์— ๋Œ€ํ•œ ๊ฒ€ํ† ๋ฅผ ๊ฐœ๋ฐœ ์™„๋ฃŒ ํ›„์— ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์•„, ๋ฌธ์ œ ๋ฐœ์ƒ ์‹œ ์ˆ˜์ •์— ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๊ณ  ๋น„์šฉ์ด ๋†’์•„์ง€๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋Œ€๋ถ€๋ถ„ ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ฝ”๋“œ๊ฐ€ ์™„์„ฑ๋œ ํ›„ ๋ฐœ๊ฒฌ๋œ ๋ณด์•ˆ ์ทจ์•ฝ์ ์„ ์ˆ˜์ •ํ•˜๋ ค๋ฉด ์ด๋ฏธ ์ž‘์„ฑ๋œ ์ฝ”๋“œ๋‚˜ ์‹œ์Šคํ…œ ์•„ํ‚คํ…์ฒ˜๋ฅผ ๋‹ค์‹œ ๋ถ„์„ํ•˜๊ณ  ๋ณ€๊ฒฝํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ดˆ๊ธฐ ๋‹จ๊ณ„์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ๊ฒฌ๋  ๋•Œ๋ณด๋‹ค ํ›จ์”ฌ ๋” ๋ณต์žกํ•˜๊ณ  ๋” ๋งŽ์ด ๋น„์šฉ์˜ ๋ฐœ์ƒ์„ ์ดˆ๋ž˜ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ DevSecOps๋Š” ๋ณด์•ˆ์„ ๊ฐœ๋ฐœ ์ดˆ๊ธฐ์— ํ†ตํ•ฉํ•จ์œผ๋กœ์จ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž๋™ํ™”๋œ ๋ณด์•ˆ ๊ฒ€ํ† ์™€ ์ฃผ๊ธฐ์ ์ด๊ณ  ์ง€์†์ ์ธ ๋ณด์•ˆ ์ ๊ฒ€์„ ํ†ตํ•ด QueryPie๋Š” ๊ฐœ๋ฐœ ํšจ์œจ์„ฑ์„ ์œ ์ง€ํ•˜๋ฉด์„œ๋„ ์•ˆ์ „ํ•œ ํด๋ผ์šฐ๋“œ ํ™˜๊ฒฝ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ํด๋ผ์šฐ๋“œ ํ™˜๊ฒฝ์—์„œ๋Š” ๋‹ค์ˆ˜์˜ ์ธํ”„๋ผ ๊ตฌ์„ฑ๊ณผ ๊ด€๋ฆฌ๊ฐ€ ์ž๋™ํ™”๋˜๋ฏ€๋กœ, ๋ณด์•ˆ ์ทจ์•ฝ์ ์ด ๋น ๋ฅด๊ฒŒ ๋…ธ์ถœ๋  ์œ„ํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ QueryPie์˜ DevSecOps ํŒŒ์ดํ”„๋ผ์ธ์€ ํด๋ผ์šฐ๋“œ ํ™˜๊ฒฝ์ด ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์—ฌ๋Ÿฌ ๋ณด์•ˆ ๊ณผ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ , ์•ˆ์ „ํ•œ ์ œํ’ˆ ์šด์˜์„ ์ง€์†ํ•˜๊ธฐ ์œ„ํ•ด ๋Š์ž„์—†์ด ๊ฐœ์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

QueryPie์˜ DevSecOps ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์ถ•์„ ํ†ตํ•œ ์‹ ๋ขฐ์„ฑ ํ™•๋ณด

QueryPie๋Š” DevSecOps ํŒŒ์ดํ”„๋ผ์ธ์„ ํ†ตํ•ด ๋ณด์•ˆ์„ ์ž๋™ํ™”ํ•˜๊ณ  ํด๋ผ์šฐ๋“œ ํ™˜๊ฒฝ์˜ ๋ณด์•ˆ ๊ณผ์ œ๋ฅผ ์ ๊ทน์ ์œผ๋กœ ํ•ด๊ฒฐํ•˜๋ฉฐ, ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” PAM ์†”๋ฃจ์…˜์œผ๋กœ ์ž๋ฆฌ๋งค๊น€ํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. ๋ณธ ๋ฐฑ์„œ์—์„œ๋Š” QueryPie์˜ ๊ฐœ๋ฐœ ๋ผ์ดํ”„์‚ฌ์ดํด ์ „ ๋‹จ๊ณ„์—์„œ ์ด๋ฃจ์–ด์ง€๋Š” ๋ณด์•ˆ์„ฑ ๊ฒ€ํ† ์™€ DevSecOps ํŒŒ์ดํ”„๋ผ์ธ์˜ ๊ตฌ์ถ• ๊ณผ์ •์„ ํ†ตํ•ด ๋ณด์•ˆ์ด ์–ด๋–ป๊ฒŒ ์ œํ’ˆ ์‹ ๋ขฐ์„ฑ์— ๊ธฐ์—ฌํ•˜๋Š”์ง€๋ฅผ ์ž์„ธํžˆ ์„ค๋ช…ํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

CI/CD ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์ถ•๊ณผ ์ž๋™ํ™”

QueryPie์—์„œ๋Š” Github Action์„ ํ†ตํ•ด CI/CD ํŒŒ์ดํ”„๋ผ์ธ์ด ๊ตฌ์ถ•๋˜์–ด ์žˆ์œผ๋ฉฐ, ์•„๋ž˜ ๊ฐ ๋‹จ๊ณ„๋ณ„๋กœ ๋ณด์•ˆ ์ฒดํฌํฌ์ธํŠธ๋ฅผ ๋ฐฐ์น˜ํ•˜์—ฌ ์ž๋™์œผ๋กœ ๋ณด์•ˆ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹จ๊ณ„๋ณ„ ์ทจ์•ฝ์  ์ง„๋‹จ์„ ํ†ตํ•ด Medium ์ด์ƒ์˜ ์ทจ์•ฝ์  ๋ฐœ๊ฒฌ๋œ ๊ฒฝ์šฐ, ์ทจ์•ฝ์  ์กฐ์น˜๊ฐ€ ๋œ ์ดํ›„์— ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ์ง„ํ–‰๋  ์ˆ˜ ์žˆ๋„๋ก ์ œ์–ดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ด€๋ฆฌ๋˜๋Š” ์ทจ์•ฝ์  ์œ ํ˜•์€ ์•„๋ž˜ ์ด๋ฏธ์ง€์™€ ๊ฐ™์ด CI/CD ํŒŒ์ดํ”„๋ผ์ธ ์ „ ๋‹จ๊ณ„์—์„œ ๋‹ค์–‘ํ•œ ์œ ํ˜•์˜ ์ทจ์•ฝ์ ์„ ์ ๊ฒ€ ๋ฐ ์‹๋ณ„ํ•˜๊ณ  ์ œ๊ฑฐํ•˜๋Š” ๊ด€๋ฆฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ตฌ์ถ•ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


Types of vulnerabilities to be checked in the CI/CD pipeline
CI/CD ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ์ ๊ฒ€๋˜์–ด์•ผ ํ•˜๋Š” ์ทจ์•ฝ์  ์œ ํ˜•

QueryPie DecSecOps ๋‹จ๊ณ„

STEP 0) ๋ฐฐํฌ๋ฅผ ์œ„ํ•œ ์ด๋ฏธ์ง€๋ฅผ ์ทจ์•ฝ์  ์—†๋Š” ๊นจ๋—ํ•œ ๊ณจ๋“  ์ด๋ฏธ์ง€๋กœ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. STEP 1) SCA, SAST ์ ๊ฒ€์„ ํ†ตํ•ด ์†Œ์Šค์ฝ”๋“œ ์ทจ์•ฝ์  ๋ฐ ์˜คํ”ˆ์†Œ์Šค Dependency๋ฅผ ์ ๊ฒ€ํ•ฉ๋‹ˆ๋‹ค. STEP 2) ๋ฐฐํฌ๋˜๋Š” ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€์— ๋Œ€ํ•œ ์ทจ์•ฝ์ ์„ ์Šค์บ”ํ•ฉ๋‹ˆ๋‹ค. STEP 3) DAST์™€ ๋ชจ์˜ํ•ดํ‚น์„ ๋ณ‘ํ–‰ํ•˜์—ฌ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ทจ์•ฝ์ ์„ ์ ๊ฒ€ํ•ฉ๋‹ˆ๋‹ค.


Vulnerability Scanning Tools in the CI/CD Pipeline
CI/CD ํŒŒ์ดํ”„๋ผ์ธ์˜ ์ทจ์•ฝ์  ์ ๊ฒ€ ๋„๊ตฌ

Report of Vulnerability Scanning in the CI/CD Pipeline
CI/CD ํŒŒ์ดํ”„๋ผ์ธ์˜ ์ทจ์•ฝ์  ์ ๊ฒ€ ํ˜„ํ™ฉ

Golden Image ๊ด€๋ฆฌ

QueryPie์—์„œ๋Š” ๊ณ ๊ฐ ๋ฐฐํฌ์šฉ ์ด๋ฏธ์ง€์™€ ๋‚ด๋ถ€ ํ…Œ์ŠคํŠธ์šฉ ์ด๋ฏธ์ง€๋ฅผ ๋ถ„๋ฆฌํ•ด์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ ์ด๋ฏธ์ง€๋Š” CIS Benchmark Level 1 ๋ฐ CVE ์ทจ์•ฝ์ ์„ ์ œ๊ฑฐํ•œ Golden Image๋กœ ์ƒ์„ฑํ•˜์—ฌ ๊ด€๋ฆฌ์ค‘์ด๋ฉฐ, ์ด์™ธ ๋ณ„๋„์˜ ์ด๋ฏธ์ง€๋Š” ์‚ฌ์šฉ์ด ๋ถˆ๊ฐ€ํ•˜๋„๋ก ํ†ต์ œํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฏธ์ง€ ํ•˜๋“œ๋‹์€ ๋ณด์•ˆํŒ€์—์„œ ์ž์ฒด ์ œ์ž‘ํ•œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ†ตํ•ด CIS Benchmark Level 1 ๋ฐ CVE ์ทจ์•ฝ์ ์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์€ OS Image Hardening ์„ ์œ„ํ•œ CIS Benchmark ์ ๊ฒ€ ํ•ญ๋ชฉ ์ž…๋‹ˆ๋‹ค.


์นดํ…Œ๊ณ ๋ฆฌ์„ธ๋ถ€ ์ ๊ฒ€ ํ•ญ๋ชฉ
1. Initial Setup1.1 Filesystem 1.2 Configure Software and Patch Management 1.3 Configure Secure Boot Settings 1.4 Configure Additional Process Hardening 1.5 Mandatory Access Control 1.6 Configure Command Line Warning Banners
2. Services2.1 Configure Time Synchronization 2.2 Configure Special Purpose Services 2.3 Configure Service Clients
3. Network Configuration3.1 Configure Network Devices 3.2 Configure Network Kernel Modules 3.3 Configure Network Kernel Parameters 3.4 Configure Host Based Firewall
4. Access, Authentication, and Authorization4.1 Configure Job Schedulers 4.2 Configure SSH Server 4.3 Configure Privilege Escalation 4.4 Configure Pluggable Authentication Modules 4.5 User Accounts and Environment
5. Logging and Auditing5.1 Configure Logging 5.2 Configure System Accounting (auditd) 5.3 Configure Integrity Checking
6. System Maintenance6.1 System File Permissions 6.2 Local User and Group Settings

์œ„ ์ ๊ฒ€ ํ•ญ๋ชฉ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์•„๋ž˜์™€ ๊ฐ™์ด Remediation Script ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์ž๋™์œผ๋กœ Configuration ์„ ์กฐ์ • ํ•ฉ๋‹ˆ๋‹ค.


CIS Benchmark Level 1 - Hardening Process
CIS Benchmark Level 1 - Hardening Process

์ฝ”๋“œ ๋ณด์•ˆ ๊ฒ€์‚ฌ ๋ฐ ์ข…์†์„ฑ ๊ด€๋ฆฌ

๊ฐœ๋ฐœ ์†Œ์Šค์ฝ”๋“œ์˜ ๋ณด์•ˆ ์ทจ์•ฝ์ ์„ ์‹๋ณ„ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” SAST ๋„๊ตฌ๋Š” ๋ฒค๋”์‚ฌ๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋ณธ ํƒ์ง€ ๋ฃฐ๋งŒ์œผ๋กœ๋Š” ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ๊ฐ€ ์ข…์ข… ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” ์ทจ์•ฝ์ ์ด ํฌํ•จ๋œ ๊ณต๊ฐœ ์ƒ˜ํ”Œ ์ฝ”๋“œ๋ฅผ ๋Œ€์ƒ์œผ๋กœ ๊ธฐ๋ณธ ํƒ์ง€ ๋ฃฐ์„ ํ™œ์šฉํ•œ ์ทจ์•ฝ์  ํƒ์ง€ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

package ai.qwiet.springbootkotlinwebgoat

import org.springframework.http.HttpHeaders
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import java.io.InputStreamReader
import java.io.BufferedReader
import java.io.File
import mu.KotlinLogging
import org.apache.logging.log4j.LogManager

@RestController
class HelloController {
    val logger = KotlinLogging.logger {}
    val secondaryLogger = LogManager.getLogger()

    @GetMapping("/")
    fun index(): String {
        return "Greetings from Spring Boot!"
    }

    @GetMapping("/greet")
    fun greet(@RequestParam("username") username: String): String {
        logger.info { "Got request for `/greet`" }
        // vulnerability: Sensitive Data Leak
        secondaryLogger.debug("Params for `/greet `: $username")
        // vulnerability: XSS
        return "Greetings ${username}!"
    }

    fun parseParams(name: String, msg: String): Map<String, String?> {
        val checkedName = name.takeUnless { it contains '\\' }?.ifBlank { "default_name" }
        val checkedMsg = msg.ifBlank { "default_msg" }
        return mapOf("parsed_name" to checkedName, "parsed_msg" to checkedMsg)
    }

    @GetMapping("/exec")
    fun exec(@RequestParam("cmd") cmd: String): ResponseEntity<String> {
        logger.info { "Got request for `/exec`!" }
        secondaryLogger.debug("Params for `/exec`: $cmd")

        var out = "NOP"
        if (cmd != "nop") {
            // vulnerability: Remote Code Execution
            val proc = Runtime.getRuntime().exec(cmd)
            val lineReader = BufferedReader(InputStreamReader(proc.getInputStream()))
            val output = StringBuilder()
            lineReader.lines().forEach { line ->
                output.append(line + "\n")
            }
            out = "Did execute command `$cmd`, got stdout: $output"
        }
        return ResponseEntity(out, HttpStatus.OK)
    }

    @GetMapping("/touch_file")
    fun touchFile(@RequestParam("name") name: String, @RequestParam("msg") msg: String): ResponseEntity<String> {
        logger.info { "Got request for `/touch_file`!" }
        secondaryLogger.debug("Params for `/touch_file`: $name | $msg")
        if (name.length < 3) {
            logger.warn { "The provided name is very short!" }
        }

        if (name == null || msg == null) {
            return ResponseEntity("The `name` & `msg` parameters have to be set.", HttpStatus.OK)
        } else {
            val parsedParams = parseParams(name, msg)
            val fullPath = "/tmp/http4kexample/" + parsedParams["parsed_name"]
            val finalMsg = "MESSAGE: " + parsedParams["parsed_msg"]
            // vulnerability: Directory Traversal
            File(fullPath).writeText(finalMsg)
            return ResponseEntity("Did write message `$finalMsg` to file at `$fullPath`", HttpStatus.OK)
        }
    }

    @GetMapping("/debug")
    fun debug(@RequestParam("url") url: String): ResponseEntity<String> {
        logger.info { "Got request for `/debug`!" }
        secondaryLogger.debug("Params for `/debug`: $url")

        val headers = HttpHeaders()
        headers.add("Location", url)
        // vulnerability: Open Redirect
        return ResponseEntity(headers, HttpStatus.FOUND)
    }

    @GetMapping("/render_html")
    fun renderHtml(@RequestParam("name") name: String): ResponseEntity<String> {
        logger.info { "Got request for `/render_html`!" }
        secondaryLogger.debug("Params for `/render_html`: $name")

        // vulnerability: XSS
        val out = StringBuilder().append("<h1>Hello there, ").append("$name").append("!</h1>").toString()
        return ResponseEntity(out, HttpStatus.OK)
    }

    @GetMapping("/add")
    fun add(@RequestParam("x") x: String, @RequestParam("y") y: String): ResponseEntity<String> {
        logger.info { "Got request for `/add`!" }
        secondaryLogger.debug("Params for `/add`: $x | $y")

        val xi = x.toInt()
        val xy = y.toInt()
        val out = (xi + xy).toString()
        return ResponseEntity(out, HttpStatus.OK)
    }
}

Vulnerability detection results using Snyk's default detection rules
Vulnerability detection results using Snyk's default detection rules

Vulnerability detection results using GitHub's default detection rules
Vulnerability detection results using GitHub's default detection rules

Vulnerability TypeSnykGitHub
XSSNot DetectedDetected
Command InjectionDetectedDetected
Directory TraversalNot DetectedNot Detected
Open RedirectNot DetectedNot Detected

์ด๋Ÿฌํ•œ ์ด์Šˆ์— ๋Œ€์‘ํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ๋‹ค์–‘ํ•œ SAST ์ œํ’ˆ์—์„œ ์ปค์Šคํ…€ ํƒ์ง€ ๋ฃฐ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ง€๋งŒ, ๊ด€๋ จ ์—…๋ฌด ๊ฒฝํ—˜์ด ๋ถ€์กฑํ•œ ๊ฒฝ์šฐ ์ด๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ํ™œ์šฉํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. QueryPie๋Š” ์ œํ’ˆ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ๊ณผ ๋ณ€ํ™”ํ•˜๋Š” ์‹ ๊ทœ ์ทจ์•ฝ์ ์— ๋Œ€์‘ํ•˜๊ธฐ ์œ„ํ•ด ์ปค์Šคํ…€ ํƒ์ง€ ํŒจํ„ด์„ ์ง์ ‘ ๊ตฌ์„ฑํ•˜์—ฌ SAST ํƒ์ง€ ํŒจํ„ด์„ ํ•ญ์ƒ ์ตœ์‹  ์ƒํƒœ๋กœ ์œ ์ง€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ดํ›„์— ์ œํ’ˆ์˜ ์†Œ์Šค์ฝ”๋“œ ์ €์žฅ์†Œ์— PR(Pull Request)์ด ์ƒ์„ฑ๋˜๋ฉด, GitHub Actions๊ฐ€ ์‹คํ–‰๋˜์–ด SAST ๋„๊ตฌ์— ํ•ด๋‹น ์†Œ์Šค์ฝ”๋“œ์˜ ์ทจ์•ฝ์  ์ง„๋‹จ์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ทจ์•ฝ์ ์ด ๋ฐœ๊ฒฌ๋˜๋ฉด, ์ด๊ด€ ์ œ์–ด ๊ธฐ๋Šฅ์„ ํ†ตํ•ด ์ทจ์•ฝ์ ์ด ํ•ด๊ฒฐ๋  ๋•Œ๊นŒ์ง€ ์†Œ์Šค์ฝ”๋“œ์˜ ๋ณ‘ํ•ฉ์„ ์ฐจ๋‹จํ•˜์—ฌ ์ œํ’ˆ์˜ ๋ฌด๊ฒฐ์„ฑ๊ณผ ๋ณด์•ˆ์„ฑ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.


CI/CD Pipeline Migration Control Process
CI/CD ํŒŒ์ดํ”„๋ผ์ธ ์ด๊ด€ ์ œ์–ด ํ”„๋กœ์„ธ์Šค

์ด๋ฏธ์ง€ ๋ณด์•ˆ ๊ฒ€์ฆ ๋ฐ SBOM ๊ด€๋ฆฌ

์ด๋ฏธ์ง€ ๋ณด์•ˆ ๊ฒ€์ฆ

GitHub Actions๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ด๋ฏธ์ง€๋ฅผ ์ž๋™์œผ๋กœ ๋นŒ๋“œํ•˜๊ณ , ๋นŒ๋“œ๋œ ์ด๋ฏธ์ง€๋ฅผ Harbor์— ์—…๋กœ๋“œํ•˜๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ตฌ์ถ•๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ Trivy๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€ ์ทจ์•ฝ์ ์„ ์Šค์บ”ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฏธ์ง€์— ์ทจ์•ฝ์ ์ด ๋ฐœ๊ฒฌ๋˜๋ฉด, ํ•ด๋‹น ๊ฒฝ๊ณ ๋Š” PR์—์„œ ์ฆ‰์‹œ ์•Œ๋ฆผ์œผ๋กœ ์ œ๊ณต๋˜์–ด ๊ฐœ๋ฐœ์ž๊ฐ€ ์‹ ์†ํ•˜๊ฒŒ ์ทจ์•ฝ์ ์„ ์ธ์ง€ํ•˜๊ณ  ์กฐ์น˜๋ฅผ ์ทจํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ, ์ทจ์•ฝ์ ์ด Medium ์ด์ƒ์œผ๋กœ ๋ถ„๋ฅ˜๋  ๊ฒฝ์šฐ, ํ•ด๋‹น ์ด๋ฏธ์ง€๋Š” ์กฐ์น˜ ๋Œ€์ƒ์ด ๋ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ, Trivy์— ์˜ํ•œ ์Šค์บ๋‹ ์™ธ์—๋„ AWS Elastic Container Registry(ECR)์— ์ด๋ฏธ์ง€๋ฅผ ์—…๋กœ๋“œํ•˜์—ฌ AWS Inspector๋ฅผ ํ†ตํ•ด ์ถ”๊ฐ€ ์ ๊ฒ€์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด Trivy๊ฐ€ ๋†“์น  ์ˆ˜ ์žˆ๋Š” ์ทจ์•ฝ์ ์„ ์‹๋ณ„ํ•˜๊ณ , ์ด๋ฏธ์ง€๋ฅผ ๋”์šฑ ์ฒ ์ €ํ•˜๊ฒŒ ๋ถ„์„ํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํ”„๋กœ์„ธ์Šค๋ฅผ ํ†ตํ•ด ์‹ ๋ขฐ์„ฑ์ด ๋†’์€ ์ด๋ฏธ์ง€๋ฅผ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

SBOM ๊ด€๋ฆฌ

QueryPie๋Š” ๋งค ๋ฆด๋ฆฌ์ฆˆ๋งˆ๋‹ค CycloneDX ํฌ๋งท์˜ ์†Œํ”„ํŠธ์›จ์–ด ์ž์žฌ ๋ชฉ๋ก(SBOM)์„ ์ƒ์„ฑํ•˜์—ฌ ์•„๋ž˜ ๊ด€๋ฆฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  • SBOM ํŒŒ์ผ์„ ์Šค์บ”ํ•˜์—ฌ ์ทจ์•ฝ์ ์ด ์กด์žฌํ•˜๋Š” ์˜คํ”ˆ์†Œ์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‹๋ณ„ํ•˜๊ณ  ์กฐ์น˜ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ผ์ด์„ผ์Šค ์ค€์ˆ˜ ์—ฌ๋ถ€๋ฅผ ํŒŒ์•…ํ•˜๊ณ , ์ €์ž‘๊ถŒ ๋˜๋Š” ๊ทœ์ œ ์š”๊ตฌ์‚ฌํ•ญ์„ ์œ„๋ฐ˜ํ•˜์ง€ ์•Š๋„๋ก ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

ํด๋ผ์šฐ๋“œ ํ™˜๊ฒฝ์˜ IaC ๋ณด์•ˆ ๊ด€๋ฆฌ

IaC๋ฅผ ํ†ตํ•œ ๋ฆฌ์†Œ์Šค ๋ฐฐํฌ ๋ฐ ๊ด€๋ฆฌ

IaC (Infrastructure as Code)๋ž€ ์ธํ”„๋ผ๋ฅผ ์ฝ”๋“œ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ์ž๋™ํ™”ํ•˜์—ฌ ํ”„๋กœ๋น„์ €๋‹ํ•˜๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œํ˜• ์ธํ”„๋ผ๋ฅผ ํ†ตํ•ด ์ˆ˜๋™ ์„ค์ •์˜ ๋ฒˆ๊ฑฐ๋กœ์›€์„ ์—†์• ๊ณ , ์ž๋™ํ™”๋œ ๋ฐฐํฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ํ†ตํ•ด ๋”์šฑ ๋” ์œ ์—ฐํ•œ ์ธํ”„๋ผ ๊ด€๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ํ™˜๊ฒฝ์—์„œ ์ผ๊ด€๋œ ์„ค์ •์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ณ , ํ•„์š”์— ๋”ฐ๋ผ ์ˆ˜์ • ๋ฐ ์—…๋ฐ์ดํŠธ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด์—๋Š” ์ˆ˜๋™์œผ๋กœ ์„ค์ •ํ•ด์•ผ ํ–ˆ๋˜ ์„œ๋ฒ„, ๋„คํŠธ์›Œํฌ, ์Šคํ† ๋ฆฌ์ง€์™€ ๊ฐ™์€ ์ž์›์„ ์ฝ”๋“œํ™”ํ•˜์—ฌ ๊ฐ„๋‹จํžˆ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ฐฐํฌ ์‹œ๊ฐ„์ด ๋‹จ์ถ•๋˜๊ณ  ์˜ค๋ฅ˜ ๊ฐ€๋Šฅ์„ฑ๋„ ์ค„์–ด๋“ญ๋‹ˆ๋‹ค. ๋˜ํ•œ, Github์™€ ๊ฐ™์€ VCS(Version Control System)์™€ ์—ฐ๊ณ„ํ•˜์—ฌ ์ธํ”„๋ผ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ถ”์ ํ•  ์ˆ˜ ์žˆ์–ด, ์‹ ์†ํ•œ ๋Œ€์‘๊ณผ ์•ˆ์ •์ ์ธ ํ™˜๊ฒฝ ๊ด€๋ฆฌ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

IaC ์Šค์บ๋‹์„ ํ†ตํ•œ ๋ณด์•ˆ ์ทจ์•ฝ์  ๊ฒ€ํ†  ๋ฐ ๊ฐœ์„ 

IaC ์Šค์บ๋‹์„ ํ†ตํ•œ ๋ณด์•ˆ ์ทจ์•ฝ์  ๊ฒ€ํ† ๋Š” ๋ฐฐํฌ ์ „์— ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ณด์•ˆ ๋ฌธ์ œ์— ๋Œ€ํ•ด IaC layer์—์„œ ์ง์ ‘ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์ธํ”„๋ผ ๊ตฌ์„ฑ์— ํ•„์š”ํ•œ ๋‹ค์–‘ํ•œ ์„ค์ •๋“ค์„ ์ฝ”๋“œํ™” ํ•˜๋ฉด์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ณด์•ˆ์ƒ์˜ risk๋ฅผ ์ดˆ๊ธฐ์— ์ฐจ๋‹จํ•˜๊ณ , ์ฝ”๋“œ ์ž‘์„ฑ ๋‹จ๊ณ„์—์„œ ์ทจ์•ฝ์ ์„ ๊ฐœ์„ ํ•˜์—ฌ ๋ณด์•ˆ์„ ๊ฐ•ํ™”ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋น ๋ฅด๊ณ  ์ผ๊ด€๋œ ๋ฐฐํฌ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” IaC์˜ ๊ฐ•์ ์€, ๋™์‹œ์— ์ž‘์€ ์„ค์ • ์˜ค๋ฅ˜ ํ•˜๋‚˜๊ฐ€ ์‹ฌ๊ฐํ•œ ๋ณด์•ˆ ์ทจ์•ฝ์ ์œผ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ๋Š” ์œ„ํ—˜์„ ๋‚ดํฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ์ธํ”„๋ผ ์ „๋ฐ˜์— ๊ฑธ์ณ ๋ถˆํ•„์š”ํ•œ ๊ถŒํ•œ์„ค์ •, ์ž˜๋ชป๋œ ์ด๋ฏธ์ง€ ์†Œ์Šค ์‚ฌ์šฉ, ์ ‘๊ทผ ๊ด€๋ฆฌ ๋ฏธํก, Secret ๋…ธ์ถœ ๋“ฑ์˜ ๋ฌธ์ œ๊ฐ€ ์ฝ”๋“œ์— ๋‚จ์•„์žˆ๋‹ค๋ฉด, ์ดํ›„ ๋ฐฐํฌ์—์„œ ๋งค๋ฒˆ ๊ฐ™์€ ๋ณด์•ˆ ๋ฌธ์ œ๋ฅผ ํฌํ•จํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. IaC ์Šค์บ๋‹์„ ํ†ตํ•ด ์ด์™€ ๊ฐ™์€ ์œ„ํ—˜์„ ์‚ฌ์ „์— ๋ฐฉ์ง€ํ•˜๊ณ , ์ ๊ฒ€ ์ ˆ์ฐจ๋ฅผ CI/CD ํŒŒ์ดํ”„๋ผ์ธ์— ํ†ตํ•ฉํ•˜์—ฌ ์ž๋™ํ™”๋œ ๋ณด์•ˆ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


IaC Scan
IaC ์Šค์บ๋‹

Open Policy Agent(OPA)๋ฅผ ํ†ตํ•œ ์ •์ฑ… ๊ฒ€์ฆ ๋ฐ ์ ์šฉ

OPA๋Š” ์ •์ฑ…์„ ์ฝ”๋“œ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์—ฌ, ๋ฆฌ์†Œ์Šค๊ฐ€ ๋ฐฐํฌ๋˜๊ธฐ ์ „์— ์ •์ฑ…์„ ์‚ฌ์ „ ๊ฒ€ํ† ํ•˜๊ณ  ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Terraform, Ansible๊ณผ ๊ฐ™์€ IaC ๋„๊ตฌ์™€ OPA๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ์ธํ”„๋ผ ๋ฐฐํฌ ์ „์— ์‚ฌ์ „์— ์ •์˜๋œ ์ •์ฑ…์„ ์ž๋™์œผ๋กœ ์‹คํ–‰ํ•˜๊ณ  ์ ์šฉํ•จ์œผ๋กœ์จ, ์ผ๊ด€๋œ ๋ณด์•ˆ ํ‘œ์ค€ ์ค€์ˆ˜๋ฅผ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ฐœ๋ฐœ, ์ธํ”„๋ผํŒ€์ด ๊ฐœ๋ณ„์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฐํฌ์—๋„ ์ผ๊ด€๋œ ์ •์ฑ…์ด ์ ์šฉ๋˜์–ด ๋ณด์•ˆ์˜ ์•ˆ์ •์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํด๋ผ์šฐ๋“œ ํ™˜๊ฒฝ์—์„œ๋Š” ๋ฆฌ์†Œ์Šค๊ฐ€ ๋‹ค์–‘ํ•œ ๊ฒฝ๋กœ๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์ƒ์„ฑ๋œ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ช…ํ™•ํžˆ ํŒŒ์•…ํ•˜๊ณ  ๊ด€๋ฆฌ ๋ฒ”์œ„์— ํฌํ•จํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ๋ณด์•ˆํŒ€์—์„œ๋Š” OPA๋ฅผ ํ†ตํ•ด AWS Native Architecture์—์„œ ๋ถˆํ•„์š”ํ•œ ์„œ๋น„์Šค๋‚˜ ๋ฆฌ์†Œ์Šค๊ฐ€ ๋ฐฐํฌ๋˜์ง€ ์•Š๋„๋ก ์ œ์–ดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํด๋ผ์šฐ๋“œ ์ธํ”„๋ผ์˜ ๊ฐ€์‹œ์„ฑ์„ ํ™•๋ณดํ•˜๊ณ , ๋ชจ๋“  ๋ฆฌ์†Œ์Šค๊ฐ€ ์ฒด๊ณ„์ ์œผ๋กœ ๊ด€๋ฆฌ๋  ์ˆ˜ ์žˆ๋„๋กํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์‚ฌ์ „์— ์ ์šฉ๋œ ์ •์ฑ…์— ๋”ฐ๋ผ ๋ณด์•ˆ ๊ธฐ์ค€์— ๋งž์ง€ ์•Š๋Š” ๋ฆฌ์†Œ์Šค๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š๋„๋ก ์ฐจ๋‹จํ•จ์œผ๋กœ์จ, ํšจ์œจ์ ์ด๊ณ  ์•ˆ์ „ํ•œ ํด๋ผ์šฐ๋“œ ๊ด€๋ฆฌ๊ฐ€ ์ด๋ฃจ์–ด์งˆ ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ, ํƒœ๊ทธ๋Š” ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ๊ถŒํ•œ ๊ด€๋ฆฌ์™€ ๋น„์šฉ ํ†ต์ œ์— ์ค‘์š”ํ•œ ์š”์†Œ๋กœ, ํŠน์ • ํƒœ๊ทธ๊ฐ€ ๋ˆ„๋ฝ๋œ ๋ฆฌ์†Œ์Šค๋Š” ์šด์˜ ๊ด€๋ฆฌ์™€ ๋น„์šฉ ์ถ”์ ์— ์–ด๋ ค์›€์„ ์ดˆ๋ž˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณด์•ˆํŒ€์—์„œ๋Š” OPA๋ฅผ ํ†ตํ•ด RiskOwner, Owner ๋“ฑ ํ•„์ˆ˜ ํƒœ๊ทธ๊ฐ€ ์ง€์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ํ•ด๋‹น ๋ฆฌ์†Œ์Šค์˜ ์ƒ์„ฑ ๋˜๋Š” ์‹คํ–‰์„ ์ œํ•œํ•˜๋Š” ์ •์ฑ…์„ ์ ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํƒœ๊ทธ ๊ด€๋ฆฌ ๋ˆ„๋ฝ์„ ์‚ฌ์ „์— ๋ฐฉ์ง€ํ•˜๊ณ , ์ž๋™ํ™”๋œ ์ •์ฑ… ์ ์šฉ์„ ํ†ตํ•ด ์ผ๊ด€๋œ ํƒœ๊ทธ ๊ด€๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ ‘๊ทผ์€ ํด๋ผ์šฐ๋“œ ํ™˜๊ฒฝ์—์„œ ์ฒด๊ณ„์ ์ธ ์ž์› ๊ด€๋ฆฌ์™€ ๋ณด์•ˆ ์ •์ฑ… ์ค€์ˆ˜๋ฅผ ์ง€์›ํ•˜๋ฉฐ, ์ธํ”„๋ผ์˜ ์•ˆ์ •์„ฑ๊ณผ ๊ฐ€์‹œ์„ฑ์„ ๊ฐ•ํ™”ํ•˜๋Š” ๋ฐ ๊ธฐ์—ฌํ•ฉ๋‹ˆ๋‹ค.

์ง€์†์  ์ปดํ”Œ๋ผ์ด์–ธ์Šค์™€ ๊ฑฐ๋ฒ„๋„Œ์Šค๋ฅผ ์œ„ํ•œ IaC ๊ด€๋ฆฌ

ISO 27001๊ณผ ๊ฐ™์€ ๋ณด์•ˆ ํ‘œ์ค€์€ ์ธํ”„๋ผ์˜ ๊ธฐ๋ฐ€์„ฑ, ๋ฌด๊ฒฐ์„ฑ, ๊ฐ€์šฉ์„ฑ์„ ๋ณด์žฅํ•˜๋Š” ๋ณด์•ˆ ๊ด€๋ฆฌ ์ฒด๊ณ„์˜ ๊ตฌ์ถ•์„ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํด๋ผ์šฐ๋“œ ์ธํ”„๋ผ์™€ ๊ฐ™์€ ํ™˜๊ฒฝ์—์„œ๋Š” ์ธํ”„๋ผ ๋ณ€๊ฒฝ์ด ๋นˆ๋ฒˆํ•˜๊ณ , ๊ทœ๋ชจ๊ฐ€ ๋ฐฉ๋Œ€ํ•ด์ง€๋ฉด์„œ ๋ชจ๋“  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ˆ˜๋™์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅ์— ๊ฐ€๊น์Šต๋‹ˆ๋‹ค. IaC๋Š” ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ธํ”„๋ผ ๊ตฌ์„ฑ์„ ์ฝ”๋“œํ™”ํ•˜์—ฌ ์ž๋™ํ™”๋œ ๋ฐฉ์‹์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ , ํ•„์š”ํ•œ ์ •์ฑ…์„ ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•˜์—ฌ ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•˜๊ณ  ์ผ๊ด€๋œ ๋ณด์•ˆ ๊ตฌ์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

๋™์  ์ทจ์•ฝ์  ์ ๊ฒ€ (DAST)

๋ฐฐํฌ ๋‹จ๊ณ„์—์„œ์˜ ์ทจ์•ฝ์  ์ง„๋‹จ ํ”„๋กœ์„ธ์Šค

๋ฐฐํฌ ๋‹จ๊ณ„์—์„œ๋Š” OWASP ZAP์„ ํ™œ์šฉํ•œ ๋™์  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ณด์•ˆ ํ…Œ์ŠคํŠธ(DAST)์™€ ํ•จ๊ป˜ ๋ชจ์˜ํ•ดํ‚น์„ ๋ณ‘ํ–‰ํ•˜์—ฌ ์ข…ํ•ฉ์ ์ธ ์ทจ์•ฝ์  ์ง„๋‹จ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. DAST ์ˆ˜ํ–‰ ๊ณผ์ •๋„ ๋‹จ์ˆœํžˆ ๊ธฐ๋ณธ Active Scan์œผ๋กœ ๋๋‚˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ๋ณด์•ˆํŒ€์ด ์ž์ฒด ์ œ์ž‘ํ•œ ์ปค์Šคํ…€ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž ํ† ํฐ์œผ๋กœ ์ ‘๊ทผ ๋ถˆ๊ฐ€ํ•œ ํŽ˜์ด์ง€์— ๋Œ€ํ•œ ๊ถŒํ•œ์„ ๊ฒ€์ฆํ•˜๊ฑฐ๋‚˜, ์ธ์ฝ”๋”ฉ ๋˜๋Š” ์•”ํ˜ธํ™”๋˜์–ด ์ „์†ก๋˜๋Š” ํŒจํ‚ท์— ๋Œ€ํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ ๋ณ€์กฐ ํ…Œ์ŠคํŠธ ๋“ฑ์„ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.


DAST - Using Custom Scripts
DAST - ์ž์ฒด์ œ์ž‘ ์Šคํฌ๋ฆฝํŠธ ํ™œ์šฉ

DAST์™€ ๋ชจ์˜ํ•ดํ‚น ๊ณผ์ •์—์„œ Medium ์ด์ƒ์˜ ์ทจ์•ฝ์ ์ด ๋ฐœ๊ฒฌ๋œ ๊ฒฝ์šฐ, ํ•ด๋‹น ์ทจ์•ฝ์ ์„ ์กฐ์น˜ํ•œ ํ›„์—์•ผ ๋ฐฐํฌ๊ฐ€ ์™„๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์•ˆ์ „ํ•œ ๋ฐฐํฌ๋ฅผ ๋ณด์žฅํ•˜๊ณ , ์‹œ์Šคํ…œ์˜ ๋ณด์•ˆ์„ฑ์„ ๊ฐ•ํ™”ํ•˜๋Š” ๋ฐ ๊ธฐ์—ฌํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

์ง€์† ๊ฐ€๋Šฅํ•œ ๋ณด์•ˆ ์†”๋ฃจ์…˜์„ ์œ„ํ•œ ํ˜์‹ ๊ณผ ์‹ ๋ขฐ ๊ตฌ์ถ•

QueryPie๋Š” ๋ณด์•ˆ์„ ๋‹จ์ˆœํ•œ ๋‹จ๊ธฐ ๊ณผ์ œ๊ฐ€ ์•„๋‹Œ, ๊ณ ๊ฐ๊ณผ์˜ ์žฅ๊ธฐ์ ์ธ ์•ฝ์†์œผ๋กœ ์ธ์‹ํ•˜๋ฉฐ ์ด๋ฅผ ์ตœ์šฐ์„  ๊ณผ์ œ๋กœ ์‚ผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€์†์ ์ธ ๋ณด์•ˆ ๊ฐ•ํ™”๋ฅผ ํ†ตํ•ด ์—…๊ณ„์˜ ์ฃผ์š” ๋ณด์•ˆ ์ •์ฑ…๊ณผ ์ปดํ”Œ๋ผ์ด์–ธ์Šค๋ฅผ ์ฒ ์ €ํžˆ ์ค€์ˆ˜ํ•˜๋ฉฐ, ๊ณ ๊ฐ์ด ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ์•ˆ์ „ํ•œ ํ™˜๊ฒฝ์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์ตœ์„ ์„ ๋‹คํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. CI/CD ํŒŒ์ดํ”„๋ผ์ธ์— ๋‹ค์–‘ํ•œ ๋ณด์•ˆ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ฉํ•˜์—ฌ ๊ฐœ๋ฐœ ์ฃผ๊ธฐ ์ „๋ฐ˜์— ๊ฑธ์ณ ์ทจ์•ฝ์ ์„ ์ฒ ์ €ํžˆ ์ ๊ฒ€ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ์ตœ๊ทผ์—๋Š” ํผ์ง•(Fuzzing) ํ…Œ์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์„œ๋น„์Šค ๊ฑฐ๋ถ€ ๊ณต๊ฒฉ(DOS)๊ณผ ๊ฐ™์€ ์œ„ํ˜‘์„ ์กฐ๊ธฐ์— ๋ฐœ๊ฒฌํ•˜๊ณ ์ž ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


Enhancing the Fuzzing Process in the CI/CD Pipeline
CI/CD ํŒŒ์ดํ”„๋ผ์ธ Fuzzing Process ๊ณ ๋„ํ™”

์ด๋Ÿฌํ•œ ๋…ธ๋ ฅ์€ ๊ณ ๊ฐ์ด ์•ˆ์ „ํ•˜๊ฒŒ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ณด์žฅํ•˜๋ฉฐ, QueryPie๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์„œ๋น„์Šค์˜ ์‹ ๋ขฐ์„ฑ์„ ๋”์šฑ ๊ฐ•ํ™”ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์•ž์œผ๋กœ๋„ ๊ณ ๊ฐ๊ณผ์˜ ์‹ ๋ขฐ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ, ์ง€์† ๊ฐ€๋Šฅํ•œ ๋ณด์•ˆ ์†”๋ฃจ์…˜์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ๋Š์ž„์—†์ด ๋ฐœ์ „ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ ์†๋„์™€ ์•ˆ์ •์„ฑ ํ–ฅ์ƒ์ด ๊ฒ€์ฆ๋œ QueryPie์˜ DevSecOps ํŒŒ์ดํ”„๋ผ์ธ | QueryPie