OPEN HYPER STEP
← 목록으로 (화이트햇 보안)
SECURITY · 64 / 84
security
CHAPTER 64 / 84
읽기 약 2
FUNCTION

API 엔드포인트 탐색


핵심 개념

REST API의 구조를 이해하고 엔드포인트를 체계적으로 탐색하는 방법을 배운다.

본문

REST API 구조

📋 코드 (8줄)
GET    /users          → 목록 조회
POST   /users          → 생성
GET    /users/{id}     → 단일 조회
PUT    /users/{id}     → 전체 수정
PATCH  /users/{id}     → 부분 수정
DELETE /users/{id}     → 삭제

GET    /users/{id}/posts → 중첩 리소스

공개 API로 CRUD 실습

PYTHON📋 코드 (33줄)
# ⚠️ 이 코드는 허가된 환경에서만 사용하세요.
# JSONPlaceholder — 학습용 공개 API
import requests

BASE = 'https://jsonplaceholder.typicode.com'

# CREATE
r = requests.post(f'{BASE}/posts', json={
    'title': '보안 실습',
    'body': 'API 호출 테스트',
    'userId': 1,
}, timeout=5)
created = r.json()
print('생성:', created)

# READ
r = requests.get(f'{BASE}/posts/1', timeout=5)
print('조회:', r.json())

# UPDATE (PUT — 전체 교체)
r = requests.put(f'{BASE}/posts/1', json={
    'id': 1,
    'title': '수정됨',
    'body': '본문 수정',
    'userId': 1,
}, timeout=5)

# UPDATE (PATCH — 부분 수정)
r = requests.patch(f'{BASE}/posts/1', json={'title': '제목만 수정'}, timeout=5)

# DELETE
r = requests.delete(f'{BASE}/posts/1', timeout=5)
print('삭제 상태:', r.status_code)  # 200

API 인증 패턴

PYTHON📋 코드 (14줄)
# 1. Bearer 토큰 (JWT)
headers = {'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIs...'}
r = requests.get(f'{BASE}/me', headers=headers)

# 2. API 키 — 헤더
headers = {'X-API-Key': 'sk_live_abc123'}

# 3. API 키 — 쿼리 파라미터 (보안상 비추천)
r = requests.get(f'{BASE}/data', params={'api_key': 'sk_...'})

# 4. Basic Auth
r = requests.get(f'{BASE}/admin', auth=('admin', 'password'))

# 5. OAuth — requests-oauthlib 별도 패키지

API 문서 없을 때 엔드포인트 추측

PYTHON📋 코드 (35줄)
# 책임 있는 점검 — 자기 서버 또는 허가된 환경에서만!
COMMON_ENDPOINTS = [
    # 인증
    '/api/login', '/api/auth', '/api/token', '/api/refresh',
    # 사용자
    '/api/users', '/api/me', '/api/profile', '/api/admin',
    # 데이터
    '/api/posts', '/api/items', '/api/products',
    # 메타
    '/api/health', '/api/status', '/api/version',
    # 위험 — 디버그·스왜거 노출
    '/api/docs', '/api/swagger', '/api/swagger.json', '/api/openapi.json',
    '/.env', '/config.json', '/admin', '/debug',
]

def discover_endpoints(base_url: str) -> dict:
    """공개된 API 엔드포인트 탐색 (자기 서버용)."""
    found = {}
    for path in COMMON_ENDPOINTS:
        url = base_url.rstrip('/') + path
        try:
            r = requests.get(url, timeout=3, allow_redirects=False)
            if r.status_code in (200, 401, 403):
                # 200=공개, 401/403=존재하지만 인증 필요 (정보 누설)
                found[path] = {
                    'status': r.status_code,
                    'size': len(r.content),
                    'content_type': r.headers.get('Content-Type', ''),
                }
        except requests.exceptions.RequestException:
            pass
    return found

# 사용 (자기 로컬 서버)
# results = discover_endpoints('http://localhost:8000')

OpenAPI/Swagger로 자동 매핑

PYTHON📋 코드 (26줄)
# 많은 백엔드가 /openapi.json 또는 /swagger.json을 노출
def fetch_api_spec(base_url: str):
    candidates = [
        '/openapi.json',
        '/swagger.json',
        '/api-docs',
        '/v3/api-docs',
    ]
    for path in candidates:
        try:
            r = requests.get(base_url + path, timeout=5)
            if r.status_code == 200 and r.headers.get('Content-Type', '').startswith('application/json'):
                return path, r.json()
        except Exception:
            continue
    return None, None

# spec 분석
def list_endpoints(spec: dict):
    """OpenAPI 명세에서 모든 엔드포인트와 메서드를 추출."""
    endpoints = []
    for path, methods in spec.get('paths', {}).items():
        for method in methods:
            if method.lower() in ('get', 'post', 'put', 'patch', 'delete'):
                endpoints.append((method.upper(), path))
    return endpoints

⚠️ Rate Limit 존중

PYTHON📋 코드 (16줄)
import time

def respectful_scan(urls: list[str], delay: float = 0.5):
    """초당 2회 이하 — 서버에 부담 안 주기."""
    for url in urls:
        try:
            r = requests.get(url, timeout=3)
            if r.status_code == 429:
                # Retry-After 헤더 존중
                wait = int(r.headers.get('Retry-After', 60))
                time.sleep(wait)
                continue
            yield url, r.status_code
        except Exception as e:
            yield url, str(e)
        time.sleep(delay)

AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude

무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6

이 API 엔드포인트의 인증 흐름을 분석해서
Bearer 토큰·API 키 처리에서 보안 허점을
실제 공격 시나리오와 함께 알려줘.
ChatGPT

무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro

REST API 보안 점검 시 자주 쓰는 도구
(Postman/curl/httpie/requests)의
실전 사용 비교를 보여줘.
Gemini

무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro

내 백엔드의 OpenAPI 명세를 분석해서
인증 누락·과도한 권한·민감 정보 응답이 있는
엔드포인트 목록을 우선순위로 정리해줘.
Grok

무료: Grok 4.1 / SuperGrok $30/mo

2026년 API 보안 트렌드 —
GraphQL vs REST 보안 모델 차이와
OWASP API Security Top 10 변화를 솔직히 알려줘.

⭐ 이것만 기억하세요
API 엔드포인트 탐색 이 3가지만 확실히 잡으세요
1.REST API 6대 메서드(GET/POST/PUT/PATCH/DELETE/HEAD)와 5가지 인증 방식(Bearer/API Key/Basic/OAuth/Session)을 모두 다룰 수 있다
2.OpenAPI/Swagger 명세를 자동 추출하면 API 매핑 시간을 90% 단축한다
3.다음 챕터에서 BeautifulSoup으로 HTML 페이지에서 정보를 추출하는 스크래핑 기법을 배운다


공유하기
진행도 64 / 84