허가 범위와 증거 기준
90분 안팎
학습 목표
대상·허용 행위·중단 조건을 문서로 정합니다.
개념
점검 전에 정하는 경계
보안 담당자의 첫 결과물은 발견한 결함보다 점검의 경계입니다. 주소를 알고 있거나 접속이 된다는 사실은 점검 허가가 아닙니다. 신입에게는 요청을 보내기 전에 누가 소유한 무엇을 어떤 방식으로 다루는지 설명하도록 합니다. 이번 프로젝트는 합성 메모를 생성하고 조회하는 개인 자료 보관 앱입니다. 대상은 본인이 관리하는 로컬 앱 한 개이고, 외부 서비스와 다른 사람의 장비는 범위에 넣지 않습니다.
이 모듈에서는 Python 3, Node.js 18 이상, bash를 사용합니다. 브라우저 실습은 표준 입력을 읽어 결과 문자열을 출력하고 로컬 실습은 ZIP을 새 폴더에 풀어 그 루트에서 명령을 실행합니다. 외부 패키지 설치와 클라우드 계정은 필요하지 않습니다. 실제 계정, 개인정보, 운영 로그, 비밀값은 가져오지 않습니다. 다운로드한 starter와 solution은 비교 대상이므로 서로 다른 폴더에 둡니다. 후속 모듈은 이번 미션 solution의 앱과 보고서를 이어받습니다.
범위 문서의 필수 정보
범위 문서는 소유자, 대상, 허용 행위, 중단 조건, 기간, 데이터 기준을 묶은 약속입니다. 소유자는 허가를 확인할 상대를 뜻하며 별명이 빈칸인 문서는 누가 책임지는지 알 수 없습니다. 본인 환경에서는 본인을 소유자로 적고 합성 식별자를 써도 됩니다. 팀 환경이라면 담당자와 승인 근거를 별도 기록합니다. 기술적인 검사는 승인 문서의 진위나 승인자의 권한까지 증명하지 못합니다.
대상은 이번 실습에서 정확히 http://127.0.0.1:8765 한 개로 정합니다. 호스트, 포트, 스킴을 함께 적으면 같은 컴퓨터의 다른 서비스를 잘못 건드리는 일을 줄일 수 있습니다. localhost, 다른 포트, 0.0.0.0을 같은 대상이라고 자동 승인하지 않습니다. 이것은 로컬 주소 전체를 판정하는 일반 도구가 아니라 이 프로젝트의 허용 목록 계약입니다. 주소가 바뀌면 문서를 고쳐 다시 확인한 후 진행합니다.
허용 행위는 create와 read 두 가지입니다. 합성 메모 생성과 생성한 메모 조회를 뜻합니다. 점검이라는 넓은 단어만 적으면 삭제, 대량 요청, 파일 접근 같은 행위가 어디까지 가능한지 판단할 수 없습니다. 현재 실습에는 스캔, 부하 시험, 다른 계정 자료 탐색을 포함하지 않습니다. 나중에 새로운 동작을 시험하려면 대상뿐 아니라 행위도 확장된 허가를 받아야 합니다.
기간은 시작 시각을 포함하고 종료 시각은 포함하지 않는 구간으로 표현합니다. UTC의 Z 표기를 사용하면 팀원마다 다른 지역 시각으로 해석할 가능성을 줄입니다. 시작보다 이른 요청과 종료 시각에 도달한 요청은 멈춥니다. 날짜를 파싱할 수 없는 경우도 허용하지 않습니다. 문서에 기간을 적었다고 앱이 자동 종료되는 것은 아니므로 점검자는 실행 전에 시각을 대조해야 합니다.
중단 조건을 행동으로 바꾸기
중단 조건 unexpected_real_data는 실제 사람의 자료처럼 보이는 값이 나타났을 때입니다. 더 읽어 확인하려 하지 않고 요청을 멈추고, 불필요한 복사를 줄이며 소유자에게 범위를 재확인합니다. target_changed는 요청 대상이나 연결 환경이 바뀐 경우입니다. unexpected_error는 예상하지 못한 실패가 발생한 경우입니다. 오류를 더 강한 요청으로 덮지 않고 현재 요청과 최소한의 오류 정보를 기록합니다.
중단 조건에는 발생 상황뿐 아니라 다음 행동이 있어야 합니다. 동의서에 “문제가 생기면 조심”만 적으면 멈추는 기준을 공유하기 어렵습니다. 예를 들어 “실자료가 나타나면 생성·조회 요청을 중지하고 소유자 확인 전에는 재개하지 않습니다”라고 적습니다. 실습에서는 소유자가 본인이므로 데이터 출처와 실행 폴더를 다시 확인하는 것으로 시작합니다. 타인의 비밀을 증거라는 이름으로 계속 보관하는 선택은 하지 않습니다.
scope.json 작성하기
미션 ZIP의 scope.json에는 id, owner, target, actions, stopConditions, startsAt, expiresAt, dataPolicy가 있습니다. id는 scope-001로 두어 보고서와 증거가 같은 범위를 참조하게 합니다. dataPolicy는 synthetic-only입니다. JSON 문자열은 큰따옴표로 감싸고 마지막 원소 뒤에 쉼표를 붙이지 않습니다. 문서의 이름을 바꾸면 테스트와 보고서의 참조도 함께 검토해야 합니다.
미션의 날짜는 2026-10-09부터 다음 날까지인 고정 예시입니다. 자동 테스트는 그 안의 고정 시각을 전달하므로 다음 주에 실행해도 계약 검증 결과가 같습니다. 그것을 오늘의 허가 확인으로 해석하지 않습니다. 실제 실행 전에 소유자가 현재 유효한 기간을 정하고 동의서에 남깁니다. 범위 단위 테스트와 실제 작업 승인은 서로 다른 근거라는 문장을 보고서에 적습니다.
따라하기는 문서에서 값을 읽고 대상 일치와 시간 경계를 확인하는 짧은 예시입니다. 네트워크 요청을 보내지 않습니다. “허용” 출력은 코드에 적은 조건이 참이라는 의미이며 소유권을 검사한 결과가 아닙니다. 이후 미션의 validateScope 함수는 더 많은 필드를 함께 확인합니다. 한 조건의 성공을 전체 허가로 확대하지 않는 습관을 여기서부터 들입니다.
잘못된 입력과 실패 읽기
JSONDecodeError가 나오면 먼저 오류의 줄과 열을 읽습니다. 큰따옴표, 쉼표, 대괄호의 짝을 확인하고 Python 문법의 작은따옴표 객체를 JSON 파일에 붙여 넣지 않았는지 살핍니다. 파일이 없다는 오류는 허가 실패가 아니라 실행 위치나 파일 경로 문제입니다. 값을 전부 허용하도록 검사를 지우는 대신 문법 오류와 정책 거절을 구분해 수정합니다.
주소 앞부분만 비교하는 방식은 실수하기 쉽습니다. 허용 주소 문자열 뒤에 문자가 더 붙어도 접두사는 같을 수 있기 때문입니다. 이번 계약에서는 전체 문자열이 정확히 같은지 비교합니다. “127로 시작하면 로컬” 같은 느슨한 판단은 이 실습에 필요하지 않습니다. 실제 주소 정규화와 네트워크 경계의 자세한 내용은 이후 통신 모듈에서 다루며 여기서는 요청 대상을 늘리지 않습니다.
제출 전에 설명할 수 있어야 할 것
동의서를 읽는 사람이 대상과 행위, 시작·종료 시각, 멈출 조건을 다시 말할 수 있는지 확인합니다. 보고서에는 이 문서를 참조하고, 허가된 작업도 합성 자료만 사용한다는 제한을 적습니다. 프로그램이 허용한다고 말한 근거와 사람이 승인한 근거를 별도로 남기면 자동 검사 실패와 범위 변경을 혼동하지 않습니다. 이는 문서 장식을 위한 절차가 아니라 실수한 요청을 재현하고 책임 범위를 설명하기 위한 준비입니다.
신입 리뷰에서는 외부 대상을 막았다는 한 줄보다 누락 필드와 만료된 기간을 어떻게 처리하는지 질문합니다. 빈 소유자도 통과한다면 범위 문서의 핵심이 빠진 것입니다. 반대로 계약에 없는 로컬 주소가 거절되어도 앱 고장이라고 판단하지 않습니다. 먼저 문서에 그 주소가 승인되어 있는지 확인합니다. 보안 점검의 출발은 많은 대상을 빨리 확인하는 능력이 아니라 지금 확인할 수 있는 대상을 명확히 제한하는 능력입니다.
따라하기
범위 필드 읽기
import json
scope = json.loads('{"owner":"local-learner","target":"http://127.0.0.1:8765","actions":["create","read"]}')
print(scope["owner"])
print(",".join(scope["actions"]))실행 결과
local-learner create,read
전체 대상 일치 검사
allowed = "http://127.0.0.1:8765"
for target in [allowed, allowed + ".evil", "http://localhost:8765"]:
print(target, target == allowed)실행 결과
http://127.0.0.1:8765 True http://127.0.0.1:8765.evil False http://localhost:8765 False
기간 경계 비교
from datetime import datetime
start = datetime.fromisoformat("2026-10-09T00:00:00+00:00")
end = datetime.fromisoformat("2026-10-10T00:00:00+00:00")
for value in ["2026-10-09T12:00:00+00:00", "2026-10-10T00:00:00+00:00"]:
now = datetime.fromisoformat(value)
print(start <= now < end)실행 결과
True False
동의서 검토
미션 starter의 scope.json을 읽고 소유자·정확한 대상·생성/조회·시작/종료·세 중단 조건을 동의서에 풀어 씁니다. 소유자 서명 또는 본인 확인 근거를 붙이고 오늘 기간을 별도로 확인합니다. 이 단계는 문서 리뷰이므로 실행 출력은 없습니다.
확인 문제
실습
scope.json과 점검 동의서를 제출합니다. 소유자, 정확한 URL, create/read, 합성 자료 제한, UTC 시작·종료, 세 중단 조건과 재개 확인 방법을 담습니다. 빈 소유자·외부 주소·기간 밖을 거절하는 이유를 각각 한 문장으로 씁니다. 고정 fixture 기간과 오늘의 허가를 구분합니다. 사람이 대상과 행위를 동일하게 설명할 수 있으면 완료입니다.
더 읽기
면접 질문
- 보안 점검의 허가 범위를 확인하는 절차를 설명합니다.