🕳️ Null Pointer 역참조 시뮬레이터 KISA A-5 · Null Pointer 역참조
프로필 엔드포인트가 id로 사용자를 조회합니다. 존재하지 않는 id(또는 할당 실패)면 조회는 null/None을 반환합니다. 취약 코드는 곧바로 user.getName()을 호출 → NullPointerException, 500 응답, 손쉬운 서비스 거부로 이어집니다.
① 취약: GET /profile?id=... VULNERABLE
존재하는 id는 1, 2, 3입니다. 없는 id를 넣으면 조회가 null을 반환하지만 코드는 그대로 역참조합니다. 할당 실패도 강제할 수 있습니다. 공격자는 없는 id 하나만 보내면 요청 핸들러를 크래시시킬 수 있습니다.
mock DB: users = { 1: Alice, 2: Bob, 3: Carol }
(실행 전)
② 안전: null 검사 · Optional · 가드 절 SECURE
수정본은 사용 전에 결과를 검사합니다: 없는 사용자는 가드 절로 404를 반환하고, 할당 실패는 503으로 처리합니다 — null을 역참조하는 일이 결코 없습니다.
(실행 전)
③ 취약 vs 안전 코드
VULNERABLE
// Java — null 검사 없이 역참조
@GetMapping("/profile")
String profile(@RequestParam long id){
User user = repo.findById(id); // 없으면 null
return user.getName(); // 💥 NullPointerException
}
// C — malloc 결과를 안 본다
char *buf = malloc(n); // 실패 시 NULL
strcpy(buf, src); // 💥 NULL 역참조 → SIGSEGV
SECURE
// Java — 가드 절 / Optional
@GetMapping("/profile")
ResponseEntity<?> profile(@RequestParam long id){
User user = repo.findById(id);
if (user == null) // 가드 절
return ResponseEntity.status(404).body("not found");
return ResponseEntity.ok(user.getName());
}
// 또는: Optional.ofNullable(repo.findById(id))
// .map(User::getName)
// .orElse("(unknown)");
// C — 할당 결과 확인
char *buf = malloc(n);
if (!buf) return ERR_OOM; // null 검사
strncpy(buf, src, n - 1);
크래시 원리: 아무것도 못 찾은 조회는 null/None(Java), 널 포인터(C/C++), None(Python)을 반환합니다. 그 위에서 메서드/필드를 호출하면 NullPointerException / SIGSEGV / AttributeError가 발생해 요청이 500으로 중단됩니다 — 공격자는 존재하지 않는 id만으로 마음대로 유발(서비스 거부)할 수 있습니다. 방어: nullable 결과는 모두 nullable로 다루세요: 가드 절 null 검사 ·
Optional/Maybe · null-object 패턴 · 언어의 null 안전성(Kotlin ?., Rust Option). 역참조 대신 깔끔한 404/503을 반환하세요.
⚠️ 교육용 시뮬레이션입니다. 사용자 조회·크래시·스택 트레이스는 페이지 내부 mock이며, 실제 백엔드·메모리·프로세스와 무관합니다.