36. 압축 해제(decompression bomb)의 크기 상한·비율 검증 부재 (C#)

난이도 상 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C#
// 시나리오: 게임 프로토콜 — 압축된 패킷 프레임의 해제(decompression)
//
// 대역폭 절약을 위해 큰 페이로드(맵 스냅샷, 인벤토리 대량 동기화 등)는 압축해서
// 보낸다. 프레임 구조는 [uint32 declaredSize][compressed bytes...] 이며,
// declaredSize 는 "해제 후 크기"를 알려주는 힌트다. 서버는 이를 받아 해제한다.
//
// 요구사항:
//  - 신뢰할 수 없는 클라이언트 입력을 파싱한다(악의적 바이트/압축 가정).
//  - 한 연결/한 프레임이 서버 메모리를 위협할 만큼 큰 데이터를 만들 수 없어야 한다.
//  - 해제 실패·비정상 크기는 안전하게 거부하고 연결을 종료한다.
//
// 아래 해제 코드를 검토하라.

using System;
using System.IO;
using System.IO.Compression;

public static class PacketCodec
{
    // 프레임에서 declaredSize 와 압축 바이트를 읽어 해제한 원본을 돌려준다.
    public static byte[] Decompress(byte[] frame)
    {
        int declaredSize = BitConverter.ToInt32(frame, 0);      // (A) 해제 후 크기 힌트
        var output = new byte[declaredSize];                     // (B) 힌트대로 버퍼 할당

        using var input = new MemoryStream(frame, 4, frame.Length - 4);
        using var deflate = new DeflateStream(input, CompressionMode.Decompress);

        int total = 0;
        int n;
        while ((n = deflate.Read(output, total, output.Length - total)) > 0) // (C)
            total += n;

        return output;
    }
}
내 리뷰 · C#
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.