variant ํ๋ผ๋ฏธํฐ ํ๋๊ฐ ์๋ฒ ๊ถํ์ ๋๊ธด๋ค — Rails Active Storage ๊ฒฐํจ ๋์ ์ ๋ฆฌ
Rails๋ก ์๋น์ค๋ฅผ ๋ง๋ค์ด ๋ณธ ์ฌ๋์ด๋ผ๋ฉด Active Storage๋ฅผ ์ ์จ๋ณธ ๊ฒฝ์ฐ๊ฐ ๋๋ฌผ์. ํ๋กํ ์ฌ์ง ์ ๋ก๋, ์ฒจ๋ถํ์ผ ๋ค์ด๋ก๋, ์ธ๋ค์ผ ์๋ ์์ฑ๊น์ง ๋ช ์ค์ด๋ฉด ๋๋๋๊น ๊ธฐ๋ณธ๊ฐ์ฒ๋ผ ์ฐ๊ฒ ๋๋ ์ปดํฌ๋ํธ์. ๊ทธ๋ฐ๋ฐ ๊ทธ ํธ๋ฆฌํจ์ ๋ท๋ฉด, ์ฆ "์ด๋ฏธ์ง ๋ณํ ์ต์ ์ URL๋ก ์ ๋ฌํ๋ค"๋ ๊ตฌ์กฐ์์ ์ฌ๊ฐํ ๊ฒฐํจ์ด ๋์๊ณ , Rails ํ์ด ์ด๋ฅผ ๊ธด๊ธ ํจ์น๋ก ๋ง์์. ๋ฐฉ์ด์ ์ ์ฅ์์ ์ด ๊ฑด์ด ์ ๋ฌด์์ด์ง, ๊ทธ๋ฆฌ๊ณ ๋ฌด์์ ๋ด์ผ ํ๋์ง ์ ๋ฆฌํด ๋ด.
- Active Storage์ ์ด๋ฏธ์ง variant ์ฒ๋ฆฌ ๊ฒฝ๋ก์์ ๊ฒ์ฆ์ด ์ถฉ๋ถ์น ์์, ์กฐ์๋ ์์ฒญ์ด ์๋ฒ ์ธก ์ฝ๋ ์คํ(RCE)๊น์ง ์ด์ด์ง ์ ์๋ ๊ฒฐํจ์ด ํจ์น๋จ
- ์ํ๋๊ฐ ๋๊ฒ ํ๊ฐ๋ ์ด์ ๋ ์ธ์ฆ ์์ด ์ ๊ทผ ๊ฐ๋ฅํ ์ฒจ๋ถํ์ผ URL์ด ๊ณต๊ฒฉ ํ๋ฉด์ด ๋๊ธฐ ๋๋ฌธ์ — ๋ก๊ทธ์ธ ๋ฒฝ ๋ค๊ฐ ์๋
- ๋์์ ๋จ์ํจ: Rails·Active Storage๋ฅผ ํจ์น ๋ฒ์ ์ผ๋ก ์ฌ๋ฆฌ๊ณ , ์ด๋ฏธ์ง ์ฒ๋ฆฌ ํ๋ก์ธ์ค๋ฅผ ์ต์ ๊ถํ์ผ๋ก ๊ฒฉ๋ฆฌํ๋ฉฐ, ๋ณํ ์์ฒญ ๋ก๊ทธ์์ ๋น์ ์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฐพ์
1. ์ด ๊ฒฐํจ์ ๊ตฌ์กฐ — ์ "์ด๋ฏธ์ง"์์ ์ฝ๋ ์คํ์ด ๋์ค๋
Active Storage๋ ์๋ณธ ํ์ผ์ ๊ทธ๋๋ก ๋ด๋ ค์ฃผ๊ธฐ๋ ํ์ง๋ง, variant๋ฅผ ๋ถ์ด๋ฉด ๋ฆฌ์ฌ์ด์ฆ·ํฌ๋งท ๋ณํ ๊ฐ์ ๊ฐ๊ณต๋ณธ์ ๋ง๋ค์ด ์ค. ์ด๋ ์ค์ ๋ณํ ์์
์ Rails๊ฐ ์ง์ ํ๋ ๊ฒ ์๋๋ผ image_processing ์ ฌ์ ๊ฑฐ์ณ ImageMagick(๋๋ libvips) ๊ฐ์ ์ธ๋ถ ๋ฐ์ด๋๋ฆฌ์ ๋๊น. ์ฌ๊ธฐ๊ฐ ํต์ฌ์.
- ํด๋ผ์ด์ธํธ๊ฐ ๋ณด๋ด๋ ๊ฒ์ "์ด ์ด๋ฏธ์ง๋ฅผ ์ด๋ ๊ฒ ๋ณํํด ๋ฌ๋ผ"๋ ๋ณํ ์ง์(transformation) ๊ฐ์
- Rails๋ ๊ทธ ์ง์๋ฅผ ์๋ช (signed blob key)์ผ๋ก ๋ณดํธํ์ง๋ง, ๊ฒ์ฆ์ด ์ฐํ๋๊ฑฐ๋ ํ์ฉ ๋ชฉ๋ก์ด ๋์จํ๋ฉด ์๋ํ์ง ์์ ๋ณํ ์ต์ ์ด ์ธ๋ถ ์ด๋ฏธ์ง ์ฒ๋ฆฌ๊ธฐ๋ก ํ๋ฌ๊ฐ
- ImageMagick ๊ณ์ด์ ์ต์ ์์ฒด๊ฐ ๋งค์ฐ ๊ฐ๋ ฅํด์, ํน์ ์ต์ ์ด ํ์ผ ๊ฒฝ๋ก๋ ์ธ๋ถ ๋ฆฌ์์ค ์ฐธ์กฐ๋ก ํด์๋๋ฉด ์ฌ์ฉ์ ์ ๋ ฅ์ด ๋ช ๋ น ์คํ ๋ฌธ๋งฅ์ ๋๋ฌํ๊ฒ ๋จ
์ฆ "์ด๋ฏธ์ง ํ์ผ์ ์ ์ฑ์ผ๋ก ๋ง๋ ๋ค"๊ฐ ์๋๋ผ "์ด๋ฏธ์ง ์ฒ๋ฆฌ ์ง์๋ฅผ ์ ์ฑ์ผ๋ก ๋ง๋ ๋ค"๋ ๊ฒ ์ด ์ ํ์ ๋ณธ์ง์. ํ์ผ ํ์ฅ์ ๊ฒ์ฌ, ๋งค์ง๋ฐ์ดํธ ๊ฒ์ฌ, ์ํฐ๋ฐ์ด๋ฌ์ค ์ค์บ — ์ ํต์ ์ธ ์ ๋ก๋ ๋ฐฉ์ด๊ฐ ์ ๋ถ ๋ฌด๋ ฅํ ์ด์ ๊ฐ ์ฌ๊ธฐ ์์. ๊ฒ์ฌํ ํ์ผ ์์ฒด๊ฐ ๋ฌธ์ ๊ฐ ์๋๊ธฐ ๋๋ฌธ์.
2. ์ฐ๋ฆฌ ์๋น์ค๊ฐ ์ํฅ๊ถ์ธ์ง 30๋ถ ์์ ํ์ธํ๊ธฐ
์ฌ๊ณ ๋์์ ๋ฒ์ ํ์ ์ด ๋จผ์ ์. ์์๋๋ก ๋ณด๋ฉด ๋จ.
- ๋ฒ์ ํ์ธ:
bundle list | grep -i rails,Rails.version์ผ๋ก ํ์ฌ ๋ฒ์ ์ ๋ฝ๊ณ , ๋ฆด๋ฆฌ์ค ๋ ธํธ์ ๋ช ์๋ ํจ์น ๋ฒ์ ๊ณผ ๋์กฐํจ. Gemfile.lock์ด ์ค์ ๋ฐฐํฌ๋ณธ๊ณผ ๊ฐ์์ง๋ ๊ฐ์ด ํ์ธํด์ผ ํจ — ์คํ ์ด์ง๋ง ์ฌ๋ฆฌ๊ณ ํ๋ก๋์ ์ด ๋จ๋ ์ฌ๊ณ ๊ฐ ์๊ทผํ ๋ง์ - ์ฌ์ฉ ์ฌ๋ถ ํ์ธ:
grep -rn "variant\|has_one_attached\|has_many_attached" app/๋ก variant ํธ์ถ ์ง์ ์ ์ฐพ์. Active Storage๋ฅผ ๋ถ์ฌ๋ง ๋๊ณ variant๋ฅผ ์ ์ด๋ค๋ฉด ๋ ธ์ถ ๋ฉด์ด ํจ์ฌ ์ข์์ง - ๊ฒฝ๋ก ๋
ธ์ถ ํ์ธ:
rails routes | grep -i active_storage๋ก/rails/active_storage/representations/...๊ฐ์ ์๋ํฌ์ธํธ๊ฐ ์ธ๋ถ์ ์ด๋ ค ์๋์ง ๋ด. CDN์ด๋ ๋ฆฌ๋ฒ์ค ํ๋ก์ ์๋จ์์ ์ด ๊ฒฝ๋ก๊ฐ ๊ทธ๋๋ก ํต๊ณผ๋๋์ง๋ ํ์ธ ๋์์ - ์ฒ๋ฆฌ๊ธฐ ํ์ธ: ImageMagick์ ์ฐ๋์ง libvips๋ฅผ ์ฐ๋์ง์ ๋ฐ๋ผ ์ํ ์ฑ๊ฒฉ์ด ๋ฌ๋ผ์ง. ๊ฐ์ธ์ ์ผ๋ก๋ ์ด์ฐธ์ libvips๋ก ๋์ด๊ฐ๋ ๊ฒ์ ์ถ์ฒํจ. ์ฑ๋ฅ๋ ๋ซ๊ณ ์ต์ ํ๋ฉด์ด ํจ์ฌ ์ข์
3. ํ์ง — ๋ก๊ทธ์์ ๋ฌด์์ ์ฐพ์ ๊ฒ์ธ๊ฐ
ํจ์น๋ฅผ ์ฌ๋ ธ๋ค๊ณ ๋์ด ์๋. ํจ์น ์ด์ ์ ์ด๋ฏธ ๋ค์ด์๋์ง๋ฅผ ๋ด์ผ ํจ. ์น ์๋ฒ ์ก์ธ์ค ๋ก๊ทธ์ Rails ๋ก๊ทธ๋ฅผ ๊ฐ์ด ๋๊ณ ๋ณด๋ฉด ์ ํธ๊ฐ ์กํ.
- Active Storage ํํ(representation) ๊ฒฝ๋ก์ ๋ํ ์์ฒญ ์ค ๋น์ ์์ ์ผ๋ก ๊ธด ํ๋ผ๋ฏธํฐ๋ ์ธ์ฝ๋ฉ์ด ์ค์ฒฉ๋ ๊ฐ — ์ ์ ํธ๋ํฝ์ variant ํค๋ ๊ธธ์ด ๋ถํฌ๊ฐ ์๋นํ ์ผ์ ํจ. ์ด ๋ถํฌ์์ ๋ฒ์ด๋๋ ๊ฐ์ด 1์ฐจ ํ๋ณด์
- ๊ฐ์ blob์ ๋ํด ์งง์ ์๊ฐ์ ์์ญ~์๋ฐฑ ๋ฒ ๋ค๋ฅธ ๋ณํ ํ๋ผ๋ฏธํฐ๋ก ๋ค์ด์ค๋ ์์ฒญ — ์ ์ ์ฌ์ฉ์๋ ์ธ๋ค์ผ ์ฌ์ด์ฆ๋ฅผ ๋ช ์ข ๋ฅ๋ง ์์ฒญํจ. ํ๋ผ๋ฏธํฐ ๋ธ๋ฃจํธํฌ์ฑ์ ์ ํ์ ํจํด์
- 500 ์๋ฌ์ ๊ธ์ฆ — ์ต์คํ๋ก์ ์๋๋ ๋๊ฐ ์คํจ๋ฅผ ๋จผ์ ๋จ๊น. ์ด๋ฏธ์ง ๋ณํ ๊ด๋ จ ์์ธ(
ImageProcessing::Error,MiniMagick๊ด๋ จ ์คํํธ๋ ์ด์ค)๊ฐ ํ์๋ณด๋ค ๋์๋ค๋ฉด ๋ฐ๋์ ์ ์์ฒญ๊น์ง ์ญ์ถ์ ํด์ผ ํจ - ์น ์๋ฒ ํ๋ก์ธ์ค์์ ํ์๋ ์์ ๋ฐ ์์ ํ๋ก์ธ์ค —
convert,magick์ ์ ์์ด์ง๋ง ๊ทธ ๋ฐ์์sh,curl,wget,bash๊ฐ ๋ฌ๋ค๋ฉด ๊ทธ๊ฑด ์ฌ๊ณ ์. EDR์ด ์๋ค๋ฉด ์ด ๋ถ๋ชจ-์์ ๊ด๊ณ๋ฅผ ๋ฃฐ๋ก ๋ฐ์๋๋ ๊ฒ ๊ฐ์ฅ ํ์คํ ํ์ง ์ง์ ์ - ์ ํ๋ฆฌ์ผ์ด์ ์๋ฒ์์ ๋๊ฐ๋ ์์์น ๋ชปํ ์์๋ฐ์ด๋ ์ฐ๊ฒฐ — ์ด๋ฏธ์ง ์ฒ๋ฆฌ ์๋ฒ๊ฐ ์ธ๋ถ๋ก ๋จผ์ ๋ง์ ๊ฑธ ์ด์ ๋ ๊ฑฐ์ ์์
4. ์ํ — ํจ์น ์ธ์ ๊ฒน์ณ ๋ ๋ฐฉ์ด์ธต
ํจ์น๊ฐ 1์์์ธ ๊ฑด ๋น์ฐํ์ง๋ง, ๋ค์์ ๋ ๋น์ทํ ๊ฒฐํจ์ด ๋์๋ ๋ฒํธ ์ ์๊ฒ ๊ตฌ์กฐ๋ฅผ ๋ฐ๊ฟ ๋๋ ๊ฒ ์ง์ง ์๋์.
- ๋ณํ ์ต์ ํ์ฉ ๋ชฉ๋ก ๊ณ ์ : Rails์๋ ์ฒ๋ฆฌ ๊ฐ๋ฅํ ๋ณํ ๋ฉ์๋๋ฅผ ์ ํํ๋ ์ค์ ์ด ์์. ์๋น์ค๊ฐ ์ค์ ๋ก ์ฐ๋ ๋ฆฌ์ฌ์ด์ฆ·ํฌ๋งท ๋ณํ ๋ช ๊ฐ์ง๋ง ๋จ๊ธฐ๊ณ ๋๋จธ์ง๋ ์ ๋ถ ๋ง์ ๋๋ฉด, ๋ฏธ์ง์ ์ต์ ์ ์ฉ์ ๋๋ถ๋ถ ๋ฌธํฑ์์ ๋๊น
- ์ฌ์ ์ ์๋ variant๋ง ํ์ฉ: URL๋ก ์์ ๋ณํ์ ๋ฐ์ง ๋ง๊ณ , ์๋ฒ๊ฐ ์ ํ ํ๋ฆฌ์ (thumb, medium, large)๋ง ์ด๋ฆ์ผ๋ก ๋ฐ๊ฒ ์ค๊ณํ๋ฉด ๊ณต๊ฒฉ์๊ฐ ์กฐ์ํ ๊ฐ ์์ฒด๊ฐ ์ฌ๋ผ์ง. ๊ฐ์ธ์ ์ผ๋ก ๊ฐ์ฅ ํจ๊ณผ ์ข์ ๊ตฌ์กฐ ๋ณ๊ฒฝ์ด๋ผ๊ณ ๋ด
- ์ด๋ฏธ์ง ์ฒ๋ฆฌ ๊ฒฉ๋ฆฌ: ๋ณํ ์์ ์ ๋ณ๋ ์์ปค·๋ณ๋ ์ปจํ ์ด๋๋ก ๋นผ๊ณ , ๋คํธ์ํฌ ์์๋ฐ์ด๋๋ฅผ ์ฐจ๋จํ๊ณ , ์ฝ๊ธฐ ์ ์ฉ ํ์ผ์์คํ ์ ๋นํน๊ถ ๊ณ์ ์ผ๋ก ๋๋ฆผ. RCE๊ฐ ๋๋๋ผ๋ ์ป๋ ๊ฒ ์๋ ํ๊ฒฝ์ ๋ง๋๋ ๊ฒ์
- ImageMagick ์ ์ฑ
ํ์ผ ์๋ณด๊ธฐ:
policy.xml์์ ์ฐ์ง ์๋ ์ฝ๋(MSL, MVG, HTTPS, EPHEMERAL, URL ๋ฑ)๋ฅผ ๋ง์ ๋๋ ๊ฒ์ ์ค๋์ ๋ถํฐ ์ ์์ด์๊ณ ์ง๊ธ๋ ์ ํจํจ - WAF๋ ๋ณด์กฐ ์๋จ์ผ๋ก: Active Storage ๊ฒฝ๋ก์ ๋ํด ํ๋ผ๋ฏธํฐ ๊ธธ์ด ์ํ์ ๊ฑฐ๋ ์ ๋๋ ์๊ฐ์ ๋ฒ์ด ์ค. ๋ค๋ง ์๋ช ๊ฐ ํํ๋ฅผ ํ๋ด ๋ธ ์ฐํ๋ ์ผ๋ง๋ ์ง ๊ฐ๋ฅํ๋ WAF๋ง ๋ฏฟ๊ณ ํจ์น๋ฅผ ๋ฏธ๋ฃจ๋ ๊ฑด ๊ธ๋ฌผ์
5. ์ด ์ฌ๊ฑด์์ ๋จ๊ธธ ๊ตํ
์ ๋ก๋ ๋ณด์์ด๋ผ๊ณ ํ๋ฉด ๋๊ฐ "์ ์ฑ ํ์ผ์ ์ด๋ป๊ฒ ๊ฑธ๋ฌ๋ผ๊น"๋ถํฐ ๋ ์ฌ๋ฆฌ๊ฒ ๋๋๋ฐ, ์ค์ ๋ก ํฌ๊ฒ ํฐ์ง๋ ๊ฑด ํ์ผ์ ์ฒ๋ฆฌํ๋ ๊ณผ์ ์ธ ๊ฒฝ์ฐ๊ฐ ๋ง์. ImageMagick์ ImageTragick, ๊ฐ์ข ๋ฌธ์ ๋ณํ๊ธฐ ๊ฒฐํจ, ์ธ๋ค์ผ ์์ฑ๊ธฐ ์ทจ์ฝ์ — ๊ณ๋ณด๊ฐ ๊ฝค ๊ธบ. ๊ณตํต์ ์ ํ๋์. ์ ๋ขฐํ ์ ์๋ ์ ๋ ฅ์ด ๊ฐ๋ ฅํ ์ธ๋ถ ๋๊ตฌ์ ์ ๋ฌ๋๋ ์ง์ ์ด ์๋ค๋ ๊ฒ.
๊ทธ๋์ ์ ๊ฒ ๊ด์ ๋ ๋ฐ๊ฟ ์ก๋ ๊ฒ ์ข์. "์ฐ๋ฆฌ๊ฐ ์ด๋ค ํ์ผ์ ๋ฐ๋๊ฐ"๊ฐ ์๋๋ผ "์ฌ์ฉ์ ์ ๋ ฅ์ด ์ต์ข ์ ์ผ๋ก ์ด๋ค ํ๋ก๊ทธ๋จ์ ์ธ์๋ก ๋์ฐฉํ๋๊ฐ"๋ฅผ ๊ทธ๋ ค ๋ณด๋ ๊ฒ์. ์ด ์ง๋๋ฅผ ํ ๋ฒ ๊ทธ๋ ค ๋๋ฉด Active Storage๋ฟ ์๋๋ผ PDF ๋ณํ, ๋์์ ์ธ์ฝ๋ฉ, ์คํผ์ค ๋ฌธ์ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๊น์ง ๊ฐ์ ๋์ผ๋ก ๋ณผ ์ ์๊ฒ ๋จ. ํ๋ ์์ํฌ๊ฐ ํธ์ ๊ธฐ๋ฅ์ผ๋ก ๊ฐ์ธ ๋ ๋ถ๋ถ์ผ์๋ก ๊ทธ ์์์ ๋ฌด์จ ์ผ์ด ๋ฒ์ด์ง๋์ง ๋ชจ๋ฅด๊ณ ์ง๋๊ฐ๊ธฐ ์ฌ์ด๋ฐ, ๊ทธ๋ฐ ๊ณณ์ด ๊ฒฐ๊ตญ ์ฌ๊ณ ์ง์ ์ด ๋๋ ๊ฒ ๊ฐ์.
์ฃผ๋ง์ ์๊ฐ ๋ด์ ์ฐ๋ฆฌ ์๋น์ค์ rails routes ํ ๋ฒ ๋ฝ์ ๋ณด์๋ฉด ์ข๊ฒ ์. ์๊ฐ๋ณด๋ค ์ด๋ ค ์๋ ๊ฒฝ๋ก๊ฐ ๋ง์์ ๋๋ ์๋ ์์. ์ ๊ฒํด ๋ณด์๊ณ ์์ธ์ ๋ฐ๊ฒฌ์ด ์์๋ค๋ฉด ๋๊ธ๋ก ๊ณต์ ํด ์ฃผ์ธ์. ๊ฐ์ด ์ฑ๊ฒจ ๋ณด์์!
# ๋๊ธ