38. UTF-8 문자열 필드의 인코딩 유효성 검증 부재 (C#)
난이도 중 해설 보기 →
결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커
(A)(B) 는 주목 위치 힌트다.
결함 코드 · C#
// 시나리오: 채팅/닉네임 등 사용자 문자열은 [uint16 byteLen][UTF-8 바이트] 형태로 전송된다.
// 서버는 이를 받아 string 으로 복원한 뒤 저장하고 다른 클라이언트에게 재전송한다.
//
// 요구사항:
// - 신뢰할 수 없는 원격지가 보낸 문자열 필드를 안전하게 복원해야 한다.
// - byteLen 은 이미 버퍼 경계 안이라고 가정한다(길이 검증은 상위 계층에서 끝났다).
// - 복원된 문자열은 저장·재전송·로그 등 여러 다운스트림으로 흘러간다.
//
// 과제: DecodeString 을 검토하고, 원격지가 이 경로로 다운스트림에 무엇을 흘려보낼 수
// 있는지, 어떤 입력에서 드러나는지, 어떻게 방어할지 설명하라. (A)(B) 를 살펴보라.
using System;
using System.Text;
public sealed class StringCodec
{
// frame[offset..offset+byteLen) 가 UTF-8 문자열 바이트라고 보고 복원한다.
public string DecodeString(ReadOnlySpan<byte> frame, int offset, int byteLen)
{
var bytes = frame.Slice(offset, byteLen); // (A) 경계는 상위에서 검증됨
string s = Encoding.UTF8.GetString(bytes); // (B) 바이트를 그대로 문자열로
return s;
}
} 결함 코드 · C++
// 시나리오: 채팅/닉네임 등 사용자 문자열은 [uint16 byteLen][UTF-8 바이트] 형태로 온다.
// 서버는 이를 std::string 으로 복원해 저장하고 다른 클라이언트에게 재전송한다.
//
// 요구사항:
// - 신뢰할 수 없는 원격지 문자열 필드를 안전하게 복원해야 한다.
// - byteLen 은 이미 버퍼 경계 안이라고 가정한다(길이 검증은 상위 계층에서 끝났다).
// - 복원된 문자열은 저장·재전송·로그 등 여러 다운스트림으로 흘러간다.
//
// 과제: decodeString 을 검토하고, 원격지가 이 경로로 다운스트림에 무엇을 흘려보낼 수
// 있는지, 어떤 입력에서 드러나는지, 어떻게 방어할지 설명하라. (A)(B) 를 살펴보라.
#include <string>
#include <cstdint>
#include <cstring>
class StringCodec {
public:
// frame[offset..offset+byteLen) 가 UTF-8 문자열 바이트라고 보고 복원한다.
std::string decodeString(const uint8_t* frame, size_t offset, size_t byteLen) {
// (A) 경계는 상위에서 검증됨 — 바이트를 그대로 std::string 에 담는다.
std::string s(reinterpret_cast<const char*>(frame + offset), byteLen); // (B)
return s; // 별도 검사 없이 저장/재전송 경로로 반환
}
}; 내 리뷰 · C#
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.
내 리뷰 · C++
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.