PHP 시니어 보안 면접

PHP 시니어 (7년+) 보안 7문항 조회수 28 · 2026-08-22 (토) 22:12:14
1 웹 취약점 - XSS
Hard

Q. PHP 애플리케이션에서 Rich Text Editor(TinyMCE, CKEditor 등)를 통해 사용자가 HTML 콘텐츠를 입력하는 게시판을 운영할 때, XSS 공격을 방어하면서도 정상적인 HTML 태그는 허용해야 하는 상황입니다. HTML Purifier와 DOMPurify 같은 라이브러리의 동작 원리를 설명하고, Whitelist 기반 필터링과 Blacklist 기반 필터링의 차이점, 그리고 CSP(Content Security Policy) 헤더를 함께 적용하여 다층 방어를 구현하는 전략을 실무 관점에서 설명해주세요.

허용 태그 목록과 속성을 명시적으로 정의하는 방식과, CSP nonce 또는 hash 기반 인라인 스크립트 제어를 고려하세요.

A. 모범답안

HTML Purifier는 DOM 파싱을 통해 HTML을 구조적으로 분석한 후 Whitelist에 정의된 태그와 속성만 허용하는 방식으로 동작하며, 이는 알려지지 않은 공격 벡터도 차단할 수 있어 Blacklist 방식보다 안전합니다. Blacklist 방식은 알려진 위험 패턴을 차단하지만 우회 기법에 취약하므로 실무에서는 Whitelist 방식을 권장합니다. CSP 헤더는 script-src 'self' 'nonce-{random}' 형태로 설정하여 인라인 스크립트 실행을 nonce 기반으로 제한하고, unsafe-inline을 제거하여 XSS 공격 시 스크립트 실행 자체를 브라우저 레벨에서 차단합니다. 실무에서는 HTML Purifier로 저장 시점에 정화하고, 출력 시점에 htmlspecialchars()로 이중 검증하며, CSP 헤더로 최종 방어선을 구축하는 다층 전략을 사용합니다. 또한 허용 태그 설정 시 iframe, object, embed 등 위험 태그는 제외하고, a 태그의 href 속성은 javascript: 프로토콜을 차단하는 URL 검증을 추가합니다.

핵심 포인트
  • • HTML Purifier의 DOM 파싱 기반 Whitelist 필터링 원리
  • • Whitelist와 Blacklist 방식의 보안성 차이
  • • CSP nonce 기반 인라인 스크립트 제어
  • • 저장-출력-브라우저 레벨의 다층 방어 전략
답변에 넣으면 좋은 키워드
HTML Purifier Whitelist CSP nonce DOM 파싱 다층 방어
실무에서는

사용자 생성 콘텐츠(UGC)를 제공하는 커뮤니티, 블로그 플랫폼, CMS 시스템에서 필수적으로 적용됩니다.

Follow-up 질문

Rich Text 콘텐츠를 여러 플랫폼(웹, 모바일 앱, 이메일)에서 재사용할 때 각 플랫폼별로 다른 XSS 방어 전략이 필요한 이유와 구현 방법을 설명해주세요.

2 인증/인가 - JWT
Hard

Q. JWT(JSON Web Token)를 사용한 인증 시스템에서 Access Token과 Refresh Token을 분리하여 운영하는 이유와 각각의 적절한 만료 시간 설정 전략을 설명해주세요. 또한 Refresh Token이 탈취되었을 때의 위험성과 이를 방어하기 위한 Token Rotation 전략, 그리고 Refresh Token을 데이터베이스에 저장할 때 해싱 처리 여부와 Token Family 개념을 활용한 탈취 감지 메커니즘을 실무 관점에서 설명해주세요.

Access Token은 짧은 수명으로 노출 위험을 최소화하고, Refresh Token은 재발급 시 이전 토큰을 무효화하는 Rotation 패턴을 고려하세요.

A. 모범답안

Access Token은 5-15분의 짧은 만료 시간을 설정하여 탈취 시 피해 기간을 최소화하고, Refresh Token은 1-2주로 설정하여 사용자 편의성을 보장하면서도 주기적인 재인증을 유도합니다. Refresh Token이 탈취되면 공격자가 지속적으로 Access Token을 재발급받을 수 있으므로, Token Rotation 전략을 적용하여 Refresh Token 사용 시마다 새로운 Refresh Token을 발급하고 이전 토큰은 즉시 무효화합니다. 데이터베이스에는 Refresh Token을 SHA-256 해싱하여 저장하고, Token Family ID를 부여하여 동일 Family의 무효화된 토큰이 재사용되면 해당 Family 전체를 무효화하여 탈취를 감지합니다. 실무에서는 Redis에 Refresh Token 해시를 저장하고 TTL을 설정하여 자동 만료시키며, 사용자별 활성 세션 수를 제한하고 의심스러운 IP 변경 시 추가 인증을 요구하는 다층 보안을 구현합니다. 또한 httpOnly, Secure, SameSite 쿠키 속성을 설정하여 XSS와 CSRF 공격으로부터 Refresh Token을 보호합니다.

핵심 포인트
  • • Access Token과 Refresh Token의 만료 시간 차별화 전략
  • • Token Rotation을 통한 Refresh Token 재사용 방지
  • • Token Family 기반 탈취 감지 메커니즘
  • • Refresh Token 해싱 저장 및 쿠키 보안 속성 설정
답변에 넣으면 좋은 키워드
Token Rotation Token Family 해싱 httpOnly SameSite Redis TTL
실무에서는

모바일 앱, SPA 애플리케이션에서 세션 없이 인증을 구현하고, 토큰 탈취 시 피해를 최소화하는 데 사용됩니다.

Follow-up 질문

마이크로서비스 환경에서 여러 서비스가 동일한 JWT를 검증해야 할 때, 공개키 기반 서명 검증(RS256)과 대칭키 기반(HS256)의 장단점을 비교하고 키 관리 전략을 설명해주세요.

3 웹 취약점 - CSRF
Medium

Q. PHP 애플리케이션에서 CSRF(Cross-Site Request Forgery) 공격의 동작 원리를 설명하고, CSRF Token을 활용한 방어 메커니즘의 구현 방법을 설명해주세요. 또한 SameSite 쿠키 속성(Strict, Lax, None)의 차이점과 각각이 CSRF 방어에 미치는 영향, 그리고 RESTful API에서 CSRF Token 대신 사용할 수 있는 대안적인 방어 방법을 실무 관점에서 설명해주세요.

CSRF Token은 세션별로 생성하여 폼에 숨겨두고 서버에서 검증하며, SameSite 쿠키는 크로스 도메인 요청 시 쿠키 전송을 제어합니다.

A. 모범답안

CSRF 공격은 사용자가 로그인한 상태에서 공격자가 만든 악성 사이트를 방문하면, 해당 사이트의 스크립트가 사용자 브라우저의 쿠키를 이용해 정상 사이트에 요청을 보내 의도하지 않은 작업을 수행하는 공격입니다. CSRF Token 방어는 세션 시작 시 cryptographically secure한 랜덤 토큰을 생성하여 세션에 저장하고, 폼이나 AJAX 요청에 이 토큰을 포함시킨 후 서버에서 요청 토큰과 세션 토큰을 비교 검증하는 방식으로 구현합니다. SameSite=Strict는 모든 크로스 사이트 요청에서 쿠키를 차단하여 가장 강력하지만 외부 링크 클릭 시에도 로그인이 풀리고, Lax는 GET 요청에만 쿠키를 허용하여 일반적인 사용성을 유지하며, None은 명시적으로 크로스 사이트 쿠키를 허용하지만 Secure 속성이 필수입니다. RESTful API에서는 세션 쿠키 대신 Authorization 헤더에 Bearer Token을 사용하면 브라우저가 자동으로 전송하지 않아 CSRF 공격이 원천적으로 차단되며, 추가로 Origin과 Referer 헤더 검증을 통해 요청 출처를 확인합니다.

핵심 포인트
  • • CSRF 공격의 쿠키 자동 전송 메커니즘 악용 원리
  • • CSRF Token 생성-전송-검증 프로세스
  • • SameSite Strict, Lax, None의 쿠키 전송 정책 차이
  • • API에서 Bearer Token 사용 시 CSRF 면역성
답변에 넣으면 좋은 키워드
CSRF Token SameSite Origin 검증 Bearer Token 세션 쿠키
실무에서는

사용자 계정 설정 변경, 결제 처리, 관리자 권한 작업 등 중요한 상태 변경 작업에서 필수적으로 적용됩니다.

Follow-up 질문

Single Page Application에서 CSRF Token을 관리할 때 페이지 새로고침 없이 토큰을 갱신하는 방법과, AJAX 요청마다 토큰을 포함시키는 구현 패턴을 설명해주세요.

4 인증/인가 - RBAC
Hard

Q. 대규모 엔터프라이즈 애플리케이션에서 RBAC(Role-Based Access Control)와 ABAC(Attribute-Based Access Control)의 차이점을 설명하고, 각각의 장단점과 적합한 사용 사례를 비교해주세요. 또한 PHP에서 복잡한 권한 체계를 구현할 때 Role Hierarchy(역할 계층), Permission Inheritance(권한 상속), Dynamic Permission(동적 권한)을 어떻게 설계하고 데이터베이스 스키마로 구현할 수 있는지 실무 관점에서 설명해주세요.

RBAC는 역할 기반으로 정적 권한을 부여하고, ABAC는 사용자 속성, 리소스 속성, 환경 조건을 조합하여 동적으로 판단합니다.

A. 모범답안

RBAC는 사용자에게 역할을 부여하고 역할에 권한을 할당하는 방식으로, 구현이 단순하고 이해하기 쉬우나 세밀한 권한 제어가 어렵고 역할이 폭발적으로 증가할 수 있는 단점이 있습니다. ABAC는 사용자 속성(부서, 직급), 리소스 속성(소유자, 분류), 환경 조건(시간, IP)을 조합한 정책으로 권한을 판단하여 유연하지만 정책 관리가 복잡하고 성능 오버헤드가 있습니다. Role Hierarchy는 roles 테이블에 parent_role_id를 추가하여 트리 구조로 구현하고, 권한 확인 시 재귀적으로 상위 역할의 권한을 상속받도록 설계합니다. Dynamic Permission은 Policy 클래스를 활용하여 런타임에 리소스 소유권이나 조건을 검사하며, 예를 들어 '자신이 작성한 게시글만 수정' 같은 규칙을 구현합니다. 실무에서는 users-roles(다대다), roles-permissions(다대다) 테이블 구조를 기본으로 하고, 캐싱을 통해 권한 조회 성능을 최적화하며, Laravel의 Gate와 Policy, Symfony의 Voter 패턴을 활용하여 복잡한 권한 로직을 체계적으로 관리합니다.

핵심 포인트
  • • RBAC의 단순성과 ABAC의 유연성 트레이드오프
  • • Role Hierarchy를 통한 권한 상속 구조
  • • Dynamic Permission의 Policy 기반 런타임 검증
  • • 다대다 관계 테이블과 캐싱을 통한 성능 최적화
답변에 넣으면 좋은 키워드
RBAC ABAC Role Hierarchy Policy Gate Voter 권한 상속
실무에서는

ERP, CMS, SaaS 플랫폼 등 다양한 역할과 복잡한 권한 규칙이 필요한 시스템에서 필수적으로 사용됩니다.

Follow-up 질문

멀티 테넌시 SaaS 애플리케이션에서 테넌트별로 다른 권한 체계를 운영해야 할 때, 권한 데이터를 어떻게 격리하고 관리할 수 있는지 설명해주세요.

5 웹 취약점 - SQL Injection
Medium

Q. PHP에서 SQL Injection 공격의 원리와 위험성을 설명하고, PDO Prepared Statement를 사용한 방어 메커니즘의 동작 원리를 설명해주세요. 또한 동적 쿼리 생성이 필요한 경우(예: 다양한 검색 조건 조합, ORDER BY 절의 동적 컬럼명) Prepared Statement만으로 해결할 수 없는 상황에서 안전하게 쿼리를 구성하는 방법과 Query Builder의 역할을 실무 관점에서 설명해주세요.

Prepared Statement는 쿼리 구조와 데이터를 분리하여 파라미터를 문자열로만 처리하며, 동적 식별자는 Whitelist 검증이 필요합니다.

A. 모범답안

SQL Injection은 사용자 입력을 SQL 쿼리에 직접 결합할 때 악의적인 SQL 구문을 삽입하여 데이터 유출, 변조, 삭제를 수행하는 공격으로, 데이터베이스 전체를 장악당할 수 있는 심각한 취약점입니다. PDO Prepared Statement는 쿼리 구조를 먼저 데이터베이스에 전송하여 파싱하고, 이후 파라미터를 바인딩할 때 해당 값을 SQL 구문이 아닌 순수 데이터로만 처리하여 구조 변경을 원천 차단합니다. 동적 ORDER BY나 WHERE IN 절 같은 경우 컬럼명이나 연산자는 파라미터로 바인딩할 수 없으므로, 허용된 값들의 Whitelist 배열을 정의하고 사용자 입력이 이 목록에 있는지 검증한 후 쿼리에 포함시켜야 합니다. Query Builder(Eloquent, Doctrine DBAL)는 메서드 체이닝으로 쿼리를 구성하면서 내부적으로 자동으로 파라미터 바인딩을 처리하고, 동적 조건 추가 시에도 안전성을 보장하여 실수로 인한 취약점을 방지합니다. 또한 ORM을 사용하더라도 Raw Query가 필요한 경우 반드시 바인딩 파라미터를 사용하고, 절대 문자열 결합으로 쿼리를 생성하지 않아야 합니다.

핵심 포인트
  • • SQL Injection의 쿼리 구조 변조 공격 원리
  • • Prepared Statement의 쿼리-데이터 분리 메커니즘
  • • 동적 식별자의 Whitelist 기반 검증 전략
  • • Query Builder의 자동 파라미터 바인딩 안전성
답변에 넣으면 좋은 키워드
Prepared Statement PDO 파라미터 바인딩 Whitelist Query Builder ORM
실무에서는

모든 데이터베이스 연동 애플리케이션에서 가장 기본적이면서도 중요한 보안 원칙으로 적용됩니다.

Follow-up 질문

NoSQL 데이터베이스(MongoDB, Redis)를 사용할 때도 Injection 공격이 가능한지, 그리고 PHP에서 이를 방어하는 방법을 설명해주세요.

6 암호화 - 데이터 보호
Hard

Q. PHP 애플리케이션에서 민감한 개인정보(주민등록번호, 신용카드 번호)를 데이터베이스에 저장할 때 암호화 전략을 설명해주세요. 특히 대칭키 암호화(AES-256-GCM)와 비대칭키 암호화(RSA)의 차이점과 각각의 적합한 사용 사례, 암호화 키 관리 방법(Key Rotation, HSM, KMS), 그리고 검색 가능한 암호화(Searchable Encryption)가 필요한 경우의 해결 방법을 실무 관점에서 설명해주세요.

대칭키는 빠르지만 키 배포가 어렵고, 비대칭키는 안전하지만 느리며, 암호화된 데이터는 일반적으로 검색이 불가능합니다.

A. 모범답안

AES-256-GCM 같은 대칭키 암호화는 동일한 키로 암복호화를 수행하여 속도가 빠르고 대용량 데이터 처리에 적합하지만, 키 유출 시 모든 데이터가 노출되므로 키 관리가 중요합니다. RSA 같은 비대칭키 암호화는 공개키로 암호화하고 개인키로 복호화하여 키 배포 문제를 해결하지만 연산 비용이 높아 대량 데이터에는 부적합하므로, 실무에서는 RSA로 AES 키를 암호화하는 하이브리드 방식을 사용합니다. 암호화 키는 애플리케이션 코드나 환경변수에 직접 저장하지 않고, AWS KMS, HashiCorp Vault 같은 Key Management Service를 사용하거나 HSM(Hardware Security Module)에 저장하여 키 자체의 암호화와 접근 제어를 보장합니다. Key Rotation은 주기적으로 새 키를 생성하고 이전 키로 암호화된 데이터를 재암호화하는 과정으로, 키 유출 피해를 최소화하며 키 버전 관리를 통해 복호화 키를 추적합니다. 검색 가능한 암호화가 필요한 경우 일방향 해시(HMAC-SHA256)로 검색용 필드를 별도로 생성하거나, Format-Preserving Encryption(FPE)을 사용하여 암호화된 값도 인덱싱이 가능하도록 하되 보안성 트레이드오프를 고려해야 합니다.

핵심 포인트
  • • 대칭키(AES)의 성능과 비대칭키(RSA)의 안전성 트레이드오프
  • • 하이브리드 암호화를 통한 장점 결합
  • • KMS/HSM을 활용한 키 관리와 Key Rotation 전략
  • • 검색 가능 암호화의 HMAC 해시 또는 FPE 방식
답변에 넣으면 좋은 키워드
AES-256-GCM RSA KMS HSM Key Rotation HMAC FPE
실무에서는

금융, 의료, 전자상거래 등 개인정보를 다루는 모든 시스템에서 법적 요구사항과 보안 정책 준수를 위해 필수적으로 적용됩니다.

Follow-up 질문

GDPR이나 개인정보보호법에서 요구하는 '잊혀질 권리' 구현 시, 암호화된 개인정보를 완전히 복구 불가능하게 만드는 Crypto Shredding 기법을 설명해주세요.

7 웹 취약점 - 파일 업로드
Hard

Q. PHP 애플리케이션에서 사용자 파일 업로드 기능을 구현할 때 발생할 수 있는 보안 취약점(원격 코드 실행, 경로 탐색, 파일 타입 위조)을 설명하고, 각각의 방어 전략을 제시해주세요. 특히 파일 확장자 검증과 MIME 타입 검증의 한계, Magic Byte 검증의 필요성, 업로드 파일의 안전한 저장 위치와 실행 권한 제거, 그리고 이미지 파일의 경우 재인코딩을 통한 악성 코드 제거 방법을 실무 관점에서 설명해주세요.

확장자와 MIME 타입은 쉽게 위조 가능하며, 파일 내용 자체를 검증하고 웹 루트 외부에 저장하며 실행 권한을 제거해야 합니다.

A. 모범답안

파일 업로드의 가장 큰 위험은 악의적인 PHP 파일을 업로드하여 서버에서 실행시키는 원격 코드 실행 공격으로, 공격자가 시스템을 완전히 장악할 수 있습니다. 확장자 검증은 .php.jpg 같은 이중 확장자나 대소문자 우회로 쉽게 우회되고, MIME 타입은 클라이언트가 전송하는 값이므로 조작 가능하여 신뢰할 수 없습니다. 실제 파일 내용의 Magic Byte(파일 시그니처)를 finfo_file()로 검증하여 진짜 파일 타입을 확인하고, Whitelist 방식으로 허용된 타입만 수용해야 합니다. 업로드된 파일은 웹 루트 외부의 별도 디렉토리에 저장하고, 원본 파일명을 사용하지 않고 UUID나 해시값으로 재명명하며, 디렉토리에 .htaccess로 PHP 실행을 차단하거나 파일 권한을 읽기 전용(0644)으로 설정합니다. 이미지 파일의 경우 GD나 Imagick 라이브러리로 재인코딩하면 메타데이터에 숨겨진 악성 코드를 제거할 수 있으며, 파일 크기 제한과 업로드 속도 제한으로 DoS 공격도 방어합니다. 또한 사용자에게 파일을 제공할 때는 X-Content-Type-Options: nosniff 헤더와 Content-Disposition: attachment를 설정하여 브라우저가 파일을 실행하지 않고 다운로드하도록 강제합니다.

핵심 포인트
  • • 확장자와 MIME 타입 검증의 우회 가능성과 한계
  • • Magic Byte 검증을 통한 실제 파일 타입 확인
  • • 웹 루트 외부 저장, 파일명 재명명, 실행 권한 제거
  • • 이미지 재인코딩과 응답 헤더를 통한 다층 방어
답변에 넣으면 좋은 키워드
Magic Byte finfo_file 재인코딩 X-Content-Type-Options Content-Disposition 경로 탐색
실무에서는

프로필 이미지, 문서 첨부, 미디어 공유 등 사용자 파일 업로드 기능이 있는 모든 웹 애플리케이션에서 필수적으로 적용됩니다.

Follow-up 질문

클라우드 스토리지(S3, GCS)에 파일을 업로드하는 경우, Pre-signed URL을 활용한 직접 업로드 방식의 보안 장점과 구현 시 주의사항을 설명해주세요.

댓글 0

로그인 후 댓글을 작성할 수 있습니다.

아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!