Item 85. Alternatives Serialization

์ž๋ฐ” ์ง๋ ฌํ™”์˜ ๋Œ€์•ˆ์„ ์ฐพ์œผ๋ผ

์ง๋ ฌํ™”๋Š” ๋ถ„์‚ฐ ๊ฐ์ฒด๋ฅผ ์†์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ์ง€๋งŒ, ์‹ฌ๊ฐํ•œ ๋ณด์•ˆ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค. ์ง๋ ฌํ™”์˜ ๊ทผ๋ณธ์ ์ธ ๋ฌธ์ œ๋Š” ๊ณต๊ฒฉ ๋ฒ”์œ„๊ฐ€ ๋„ˆ๋ฌด ๋„“๊ณ  ์ง€์†์ ์œผ๋กœ ๋„“์–ด์ ธ ๋ฐฉ์–ดํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋Š” ์ ์ธ๋ฐ, ๊ทธ ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. ObjectInputStream์˜ readObject ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ์—ญ์ง๋ ฌํ™” ์ˆ˜ํ–‰

  2. ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ์„ ์—ญ์ง๋ ฌํ™”ํ•˜๋Š” ๊ณผ์ •์—์„œ ํƒ€์ž…๋“ค ์•ˆ์˜ ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋จ

    • ์›๋ž˜ ๊ฐ์ฒด์˜ ํด๋ž˜์Šค ํƒ€์ž…์„ ์œ ์ง€ํ•˜๋ฉด์„œ ๋ณต์›๋˜๋ฉฐ, ๊ทธ ๊ณผ์ •์—์„œ ํ•ด๋‹น ํด๋ž˜์Šค์˜ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰

  3. ๊ทธ ํƒ€์ž…๋“ค์˜ ์ฝ”๋“œ ์ „์ฒด๊ฐ€ ๊ณต๊ฒฉ ๋ฒ”์œ„์— ํฌํ•จํ•˜๊ฒŒ ๋˜์–ด, ๊ทธ ํƒ€์ž…๋“ค์˜ ์ฝ”๋“œ๊ฐ€ ์•…์˜์ ์ธ ์ฝ”๋“œ๋กœ ๋Œ€์ฒด๋  ์ˆ˜ ์žˆ์Œ

๋˜ํ•œ, ์—ญ์ง๋ ฌํ™”๊ฐ€ ๋๋‚˜์ง€ ์•Š๊ฒŒ ํ•˜๋Š” ์—ญ์ง๋ ฌํ™” ํญํƒ„(deserialization bomb)์ด๋ผ๋Š” ๊ณต๊ฒฉ์—๋„ ๋…ธ์ถœ๋  ์ˆ˜ ์žˆ๋‹ค.

class Test {

    static byte[] bomb() {
        Set<Object> root = new HashSet<>(); // ๊ฐ์ฒด ๊ทธ๋ž˜ํ”„ ๋ฃจํŠธ
        Set<Object> s1 = root; // ๋ฃจํŠธ์— ๋Œ€ํ•œ ์ฒซ ๋ฒˆ์งธ ์ฐธ์กฐ
        Set<Object> s2 = new HashSet<>(); // ๋ฃจํŠธ์™€ ๋…๋ฆฝ์ ์ธ ์ƒˆ๋กœ์šด ์ง‘ํ•ฉ
        for (int i = 0; i < 100; i++) {
            // HashSet ๊ฐ์ฒด ์ƒ์„ฑ
            Set<Object> t1 = new HashSet<>();
            Set<Object> t2 = new HashSet<>();
            t1.add("foo");

            // s1์— t1, t2 ์ถ”๊ฐ€
            s1.add(t1);
            s1.add(t2);
            // s2์— t1, t2 ์ถ”๊ฐ€
            s2.add(t1);
            s2.add(t2);

            // s1, s2๋ฅผ ๊ฐ๊ฐ t1, t2๋กœ ๊ฐฑ์‹ 
            s1 = t1;
            s2 = t2;
        }
        return serialize(root);
    }
}

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

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„  ์—ญ์ง๋ ฌํ™” ์ž์ฒด๋ฅผ ํ”ผํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹๊ณ , ํ•„์š”ํ•˜๋‹ค๋ฉด ์ง๋ ฌํ™” ๋Œ€์‹  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ๋ฒ•์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

  • ์ž„์˜ ๊ฐ์ฒด ๊ทธ๋ž˜ํ”„๋ฅผ ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™” ํ•˜๋Š” ๋Œ€์‹ , ์†์„ฑ-๊ฐ’ ์Œ์˜ ์ง‘ํ•ฉ์œผ๋กœ ๊ตฌ์„ฑ๋œ ๊ฐ„๋‹จํ•˜๊ณ  ๊ตฌ์กฐํ™”๋œ JSON ๊ณผ ๊ฐ™์€ ๋ฐ์ดํ„ฐ ํ‘œํ˜„์„ ์‚ฌ์šฉ

  • ๋งŒ์•ฝ ๋ ˆ๊ฑฐ์‹œ ์‹œ์Šคํ…œ์œผ๋กœ ์ง๋ ฌํ™”๋ฅผ ๋ฐฐ์ œํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ, ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ๋ฐ์ดํ„ฐ๋Š” ์ ˆ๋Œ€ ์—ญ์ง๋ ฌํ™”ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์œผ๋กœ ํ•œ์ •

  • ์—ญ์ง๋ ฌํ™” ํ•„ํ„ฐ๋ง(ObjectInputFilter)์„ ์‚ฌ์šฉํ•  ๋• ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ ๋Œ€์‹  ํ™”์ดํŠธ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„ํ„ฐ๋ง

Last updated

Was this helpful?