25. TLV 옵션 리스트 역직렬화의 경계·길이 검증 부재

난이도 중 해설 보기 →

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

결함 코드 · C#
// 시나리오: 클라이언트가 캐릭터의 가변 "장식/외형 옵션"을 한 패킷에 담아 보낸다.
//   payload 는 옵션 엔트리가 0개 이상 반복되는 구조다:
//       [ type:1바이트 ][ len:2바이트 LE ][ value:len바이트 ]   (반복)
//   서버는 payload 끝까지 엔트리를 순회하며 각 옵션을 파싱해 적용한다.
//   len 과 개수는 모두 클라이언트(신뢰 불가)가 정한다.
//
// 요구사항:
//   - 잘리거나 조작된 payload(잘못된 len, 끝에서 헤더가 부족한 경우 등)가 와도
//     서버는 안전하게 거부할 뿐, 버퍼 밖을 읽거나 비정상 종료해서는 안 된다.
//   - 이 파서는 수많은 세션의 수신 패킷을 처리하는 공용 경로에서 호출된다.
//
// 과제: 신뢰 불가 입력에 대해 (A)~(C) 지점에서 무슨 일이 벌어질 수 있는지
//       진단하고, 안전하게 파싱하도록 수정하라.

using System;
using System.Collections.Generic;

public sealed class OptionParser
{
    public List<(byte Type, byte[] Value)> Parse(byte[] buf)
    {
        var result = new List<(byte, byte[])>();
        int pos = 0;

        while (pos < buf.Length)                          // 남은 엔트리 순회
        {
            byte type = buf[pos];
            int len = buf[pos + 1] | (buf[pos + 2] << 8); // (A) 길이 헤더 읽기
            pos += 3;

            var value = new byte[len];                    // (C) 선언된 len 으로 버퍼 확보
            Array.Copy(buf, pos, value, 0, len);          // (B) len 바이트 복사
            pos += len;

            result.Add((type, value));
        }
        return result;
    }
}
내 리뷰 · C#
내 답안 · 자동 저장

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