OWASP API Top 10: 핵심 취약점 방어 및 보안 설계

이크로서비스 아키텍처(MSA)의 확산과 SPA(Single Page Application)의 대중화로 인해 API는 단순한 데이터 통로를 넘어 비즈니스 로직의 핵심이 되었습니다. 하지만 API 엔드포인트가 외부로 직접 노출되는 빈도가 늘어나면서 공격 표면(Attack Surface) 또한 급격히 확장되었습니다. 기존의 경계 보안(Perimeter Security) 모델이나 단순 WAF(Web Application Firewall) 설정만으로는 비즈니스 로직의 결함을 파고드는 API 특화 공격을 막아내기 어렵습니다. 본 글에서는 OWASP(Open Web Application Security Project)가 선정한 API 보안 위협 Top 10 중 엔지니어링 관점에서 가장 치명적인 취약점들을 분석하고, 이를 코드로 방어하는 구체적인 설계를 다룹니다.

1. 객체 수준 권한 부여 실패 (BOLA)

BOLA(Broken Object Level Authorization)는 과거 IDOR(Insecure Direct Object References)로 불리던 취약점으로, API 보안 사고의 가장 큰 비중을 차지합니다. 서버가 클라이언트로부터 받은 리소스 ID(예: user_id, document_id)에 대해 요청자가 해당 리소스에 접근할 권한이 있는지 검증하지 않을 때 발생합니다. 공격자는 단순히 ID 값을 순차적으로 변경(Enumeration)하는 것만으로도 타인의 민감한 데이터에 접근할 수 있습니다.

Anti-Pattern: 입력받은 ID를 신뢰하여 검증 없이 DB를 조회하는 경우

# 취약한 코드 예시 (Python/Flask)
@app.route('/api/invoices/<invoice_id>')
def get_invoice(invoice_id):
    # 요청자가 누구인지 확인하지 않고, ID만으로 데이터를 조회함
    invoice = db.session.query(Invoice).filter_by(id=invoice_id).first()
    return jsonify(invoice)

이를 방어하기 위해서는 모든 컨트롤러 레벨에서 '현재 로그인한 사용자(Current User)'와 '요청된 리소스의 소유자(Resource Owner)'가 일치하는지 확인하는 로직이 필수적입니다. 미들웨어나 데코레이터 패턴을 활용하여 권한 검증 로직을 중앙화하는 것이 유지보수 측면에서 유리합니다.


# 보안이 적용된 코드 예시
@app.route('/api/invoices/<invoice_id>')
@login_required
def get_invoice(invoice_id):
    # 1. 리소스 조회
    invoice = db.session.query(Invoice).filter_by(id=invoice_id).first()
    
    # 2. 소유권 검증 (Authorization Check)
    if invoice.user_id != current_user.id:
        abort(403, description="Access Denied")
        
    return jsonify(invoice)

2. 불완전한 인증 (Broken Authentication)

API 인증 메커니즘은 웹 세션보다 복잡하며, 주로 JWT(Json Web Token)나 OAuth 2.0이 사용됩니다. 하지만 토큰 서명 검증을 누락하거나, 만료 기한(Expiration Time)을 무제한으로 설정하는 실수가 빈번합니다. 또한, URL에 인증 토큰을 포함시키거나 강력하지 않은 서명 키(Weak Signing Key)를 사용하는 경우 토큰 탈취 및 위조 공격에 취약해집니다.

Security Note: JWT 사용 시 'None' 알고리즘 공격을 방어하기 위해 라이브러리 설정에서 명시적으로 허용된 알고리즘(HS256, RS256 등)만 사용하도록 제한해야 합니다.

인증 보안을 강화하기 위해서는 Access Token의 수명을 짧게(예: 30분) 가져가고, Refresh Token Rotation 전략을 도입해야 합니다. 아래는 토큰 검증 시 반드시 확인해야 할 체크리스트입니다.

검증 항목 설명 위험도
Signature Verification 토큰이 변조되지 않았는지 서명 키로 확인 Critical
Expiration (exp) 토큰의 만료 시간이 지났는지 확인 High
Algorithm (alg) 헤더의 알고리즘이 예상된 값인지 확인 ('None' 공격 방지) High
Issuer (iss) 신뢰할 수 있는 발급자가 발행했는지 확인 Medium

3. 대량 할당 (Mass Assignment)

대량 할당(Mass Assignment) 취약점은 클라이언트가 보낸 JSON 데이터를 그대로 내부 객체나 데이터베이스 모델에 바인딩할 때 발생합니다. 공격자는 요청 바디에 is_admin: true, balance: 1000000과 같은 승인되지 않은 필드를 추가하여 권한을 상승시키거나 데이터를 조작할 수 있습니다. 이는 최신 프레임워크의 'Auto-binding' 기능이 주는 편의성의 이면(Trade-off)입니다.

이를 방지하기 위해 입력 데이터(Request Body)와 내부 모델(Entity)을 엄격히 분리해야 합니다. DTO(Data Transfer Object) 패턴을 사용하여 클라이언트가 수정할 수 있는 필드만을 명시적으로 정의(Allow-list)하는 것이 표준입니다.


// Java Spring Boot 예시: DTO를 통한 필드 제한

// 취약한 방식: Entity를 직접 매핑
@PostMapping("/profile")
public void updateProfile(@RequestBody UserEntity user) {
    userRepository.save(user); // 'role'이나 'id' 필드까지 덮어쓸 위험 있음
}

// 안전한 방식: DTO 사용
public class UserUpdateDTO {
    private String username;
    private String email;
    // role 필드는 제외됨
}

@PostMapping("/profile")
public void updateProfile(@RequestBody UserUpdateDTO dto) {
    UserEntity user = userRepository.findById(currentUserId);
    user.setUsername(dto.getUsername());
    user.setEmail(dto.getEmail());
    userRepository.save(user);
}
Best Practice: 모든 API 엔드포인트에 대해 입력 스키마 유효성 검사(Schema Validation)를 수행하고, 필요 없는 필드는 무시하거나 에러를 반환하도록 설정하십시오.

4. 제한 없는 리소스 소비 (Unrestricted Resource Consumption)

API는 자동화된 스크립트에 의해 호출되기 쉽기 때문에 DoS(Denial of Service) 공격이나 Brute-force 공격에 취약합니다. 요청 횟수 제한(Rate Limiting)뿐만 아니라, 페이징 처리가 없는 리스트 조회, 지나치게 큰 페이로드, 복잡한 정규표현식 처리 등도 시스템 자원을 고갈시키는 원인이 됩니다.

API Gateway 레벨(Nginx, AWS API Gateway 등)이나 애플리케이션 레벨에서 속도 제한 정책을 적용해야 합니다. 또한, GraphQL과 같은 유연한 쿼리 언어를 사용할 때는 쿼리의 깊이(Depth)와 복잡도(Complexity)를 제한하여 서버 부하를 제어해야 합니다.

Configuration Check: 업로드 파일 크기 제한, 타임아웃 설정, 최대 메모리 할당량 등 컨테이너 및 웹 서버 설정을 점검하십시오.

보안은 기능이 아니라 아키텍처입니다

API 보안은 개발 마지막 단계에 수행하는 체크리스트가 아닙니다. 설계 단계부터 인증, 인가, 데이터 검증 전략을 수립하는 'Shift Left' 접근이 필요합니다. 위에서 언급한 OWASP Top 10 항목들은 대부분 코드 레벨의 단순 실수보다는 구조적인 설계 미흡에서 기인합니다. BOLA를 막기 위한 소유권 검증 로직의 표준화, DTO를 활용한 데이터 격리, 그리고 API Gateway를 통한 트래픽 제어는 현대적인 백엔드 시스템이 갖춰야 할 기본 소양입니다. 지속적인 보안 감사와 자동화된 테스트(DAST/SAST)를 CI/CD 파이프라인에 통합하여 안전한 API 생태계를 구축하십시오.

OlderNewest

Post a Comment