security
CHAPTER 64 / 84
읽기 약 2분
FUNCTION
API 엔드포인트 탐색
핵심 개념
REST API의 구조를 이해하고 엔드포인트를 체계적으로 탐색하는 방법을 배운다.
본문
REST API 구조
GET /users → 목록 조회
POST /users → 생성
GET /users/{id} → 단일 조회
PUT /users/{id} → 전체 수정
PATCH /users/{id} → 부분 수정
DELETE /users/{id} → 삭제
GET /users/{id}/posts → 중첩 리소스공개 API로 CRUD 실습
# ⚠️ 이 코드는 허가된 환경에서만 사용하세요.
# 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) # 200API 인증 패턴
# 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 문서 없을 때 엔드포인트 추측
# 책임 있는 점검 — 자기 서버 또는 허가된 환경에서만!
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로 자동 매핑
# 많은 백엔드가 /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 존중
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