플러그인 없이 1회차 · Claude Code · Opus 5.5 · 생각 깊이 중간 · 클로드가 쓴 review.md 원문 · 목록

shop.py 코드 리뷰

결론: 이대로 머지하면 안 됩니다.

실제 결제와 재고를 다루는 코드인데 보안 취약점 4건과 돈이나 재고가 틀어지는 로직 버그 여러 건이 있습니다. 아래의 🔴 Critical 항목은 모두 고친 다음 다시 리뷰하는 것을 권합니다.

심각도 건수 요약
🔴 Critical 6 시크릿 하드코딩, SQL 인젝션, 남의 주문 조회(IDOR), 경로 탈출(Path Traversal), 음수 수량으로 돈 생성, 재고 동시성
🟠 Major 4 페이지네이션 오류, 쿠폰 예외 삼킴, 잔액 검증 없음, 상품 없음 크래시
🟡 Minor 4 커넥션 누수, N+1 쿼리, 타이밍 공격, 응답 필드 누락

🔴 Critical

1. 운영 관리자 토큰이 소스에 하드코딩되어 있음 (shop.py:7)

ADMIN_TOKEN = "sk_live_9f8e7d6c5b4a3210shopadmin"

2. SQL 인젝션 (shop.py:19)

sql = f"SELECT ... WHERE name LIKE '%{keyword}%'"

3. 남의 주문을 조회할 수 있음, IDOR (shop.py:40-43)

def get_order(order_id, current_user_id):
    row = db.execute("SELECT * FROM orders WHERE id = ?", (order_id,)).fetchone()

4. 경로 탈출로 서버의 임의 파일을 읽을 수 있음, Path Traversal (shop.py:77-80)

path = os.path.join(INVOICE_DIR, filename)

5. 음수 수량으로 주문하면 돈과 재고가 생겨남 (shop.py:46-66)

6. 재고 확인과 차감 사이의 경쟁 상태로 초과 판매가 일어남 (shop.py:48-55)


🟠 Major

7. 페이지네이션이 첫 페이지를 건너뜀 (shop.py:25)

8. 쿠폰 처리에서 예외를 삼키고 None을 반환함 (shop.py:69-74)

9. 잔액 검증이 없음 (shop.py:61-64)

10. 없는 상품으로 주문하면 500 에러가 남 (shop.py:51)


🟡 Minor

  1. DB 커넥션 누수 (shop.py:11-14, 모든 함수): 함수를 호출할 때마다 커넥션을 열고 닫지 않습니다. 트래픽이 몰리면 파일 핸들이 고갈되거나 database is locked 오류가 납니다. 컨텍스트 매니저를 쓰거나 요청 단위로 커넥션을 관리하세요.
  2. N+1 쿼리 (shop.py:31-36): 주문 20건을 조회하면 쿼리가 21번 나갑니다. WHERE order_id IN (...)이나 JOIN으로 한 번에 가져오세요.
  3. 토큰 비교 시 타이밍 공격 가능 (shop.py:84): == 대신 hmac.compare_digest(token, ADMIN_TOKEN)을 쓰세요.
  4. created_at을 조회만 하고 버림 (shop.py:27, 36): 쿼리로 가져오지만 응답에는 넣지 않습니다. 의도한 것인지 확인해 보세요.

그 밖에 확인이 필요한 점

머지 전 체크리스트