CompTIA SY0-701: 애플리케이션 및 웹 보안 — 학습 가이드
다음의 일부입니다: CompTIA Security+ SY0-701 — 학습 가이드. 검증된 답안으로 연습하기: CompTIA 시험 허브, 또는 다음에서 시간 제한 모의고사 풀기: ExamRoll.io.
현대 애플리케이션은 비즈니스 로직, 민감한 데이터, 신뢰할 수 없는 사용자 입력이 교차하는 지점에 있습니다. 웹 및 모바일 프런트엔드는 전체 인터넷에 노출되어 있기 때문에, 모든 기업에서 가장 크고 지속적으로 악용되는 공격 표면 중 하나입니다. 이를 방어하려면 코드 작성 방식에서부터 런타임 보호, 무결성 검증, 지속적인 테스트에 이르기까지 확장되는 계층화된 제어가 필요합니다.
인젝션 공격(Injection Attacks)
인젝션은 전형적인 웹 취약점으로 남아있습니다. 이는 애플리케이션이 코드와 데이터를 제대로 분리하지 않고 신뢰할 수 없는 입력을 SQL 쿼리, 셸 명령어, LDAP 필터, XML 파서, 템플릿 엔진과 같은 인터프리터에 연결할 때 발생합니다. SQL 인젝션(SQLi)에서 공격자는 쿼리를 조작하여 데이터베이스가 공격자가 제어하는 로직을 실행하도록 만듭니다. PHP의 전형적인 취약한 패턴은 다음과 같습니다.
$query = "SELECT * FROM users WHERE username = '" . $_GET['user'] . "'";
admin' OR '1'='1을 제출하면 쿼리가 모든 행을 반환하는 항진 명제로 변환됩니다. 더 발전된 변형으로는 union 기반 추출(' UNION SELECT credit_card FROM payments--), 블라인드 불리언 또는 시간 기반 추론(' AND SLEEP(5)--), DNS 콜백을 통한 대역 외(out-of-band) 유출 등이 있습니다. 확실한 해결책은 파라미터화된 쿼리 또는 준비된 구문(prepared statements)을 사용하는 것이며, 이는 쿼리 템플릿과 파라미터를 별도의 구조로 데이터베이스에 보냅니다.
cursor.execute("SELECT * FROM users WHERE username = %s", (user_input,))
명령어 인젝션(Command injection)은 동일한 패턴을 따르지만 운영 체제 셸을 대상으로 합니다. os.system("ping " + host)와 같은 코드는 공격자가 8.8.8.8; cat /etc/passwd를 제출하여 임의의 명령어를 실행할 수 있게 합니다. 해결하려면 셸 호출을 완전히 피하고, 인수 배열을 받는 API(subprocess.run(["ping", host], shell=False))를 사용하며, 셸에 도달해야 하는 모든 값에 대해 엄격한 허용 목록(allow-list) 유효성 검사를 적용해야 합니다.
크로스 사이트 스크립팅(XSS)과 CSRF
크로스 사이트 스크립팅(XSS)은 신뢰할 수 있는 애플리케이션이 렌더링하는 페이지에 악성 스크립트를 주입하여, 피해자의 브라우저가 해당 사이트의 오리진(origin) 내에서 공격자의 코드를 실행하게 만드는 공격입니다. 반사형(Reflected) XSS는 취약한 파라미터를 통해 페이로드를 반사시키고, 저장형(Stored) XSS는 페이로드를 데이터베이스에 저장하여 모든 방문자에게 전달하며, DOM 기반 XSS는 신뢰할 수 없는 데이터를 innerHTML, document.write 또는 유사한 싱크(sink)에 쓰는 클라이언트 측 JavaScript에서 전적으로 발생합니다. 그 결과는 세션 하이재킹, 키로깅부터 강제적인 작업을 통한 계정 완전 탈취에 이르기까지 다양합니다.
크로스 사이트 요청 위조(CSRF)는 별개이지만 상호 보완적인 공격입니다. 이는 브라우저가 자동으로 쿠키를 포함하는 점을 악용하여 인증된 사용자를 속여 원치 않는 요청(예: 악성 사이트의 숨겨진 폼이 bank.com/transfer로 POST 요청을 보내는 것)을 제출하게 만듭니다. 방어책으로는 동기화 토큰(synchronizer token, 폼에 내장되어 서버 측에서 검증되는 세션별 임의 값), SameSite=Lax 또는 SameSite=Strict 쿠키 속성, 민감한 작업에 대한 재인증 요구 등이 있습니다. XSS와 CSRF는 종종 혼동되지만, XSS는 피해자의 브라우저에서 코드를 실행하는 반면 CSRF는 단순히 브라우저가 요청을 보내도록 유도합니다. 특히, 성공적인 XSS 공격은 대부분의 CSRF 방어책을 무력화할 수 있습니다.
안전한 코딩: 입력 유효성 검사 vs. 출력 인코딩
자주 혼동되는 두 가지 제어 방법이 있지만, 이들은 서로 다른 문제를 해결합니다. **입력 유효성 검사(Input validation)**는 데이터가 애플리케이션에서 처리되기 전에 예상된 구조(길이, 타입, 문자 집합, 범위, 형식 등)를 따르는지 확인합니다. 이는 서버 측에서 수행되어야 하며, 가능하면 허용 목록(allow-list)을 사용해야 합니다(예: 사용자 이름에 ^[A-Za-z0-9_]{3,20}$ 적용). JavaScript를 사용한 클라이언트 측 유효성 검사는 단지 사용성(usability)을 위한 기능일 뿐입니다. 어떤 HTTP 프록시로도 우회할 수 있으므로 절대 보안 경계선이 되어서는 안 됩니다.
**출력 인코딩(Output encoding)**은 데이터가 흘러 들어가는 모든 컨텍스트에서 안전하게 렌더링되도록 보장합니다. 완벽하게 유효한 입력 문자열이라도 어디에 위치하느냐에 따라 다른 처리가 필요할 수 있습니다. HTML 본문 컨텍스트에서는 HTML 엔티티 인코딩(< → <)이, 속성 컨텍스트에서는 따옴표로 묶인 속성 인코딩이, JavaScript 컨텍스트에서는 \xHH 이스케이핑이, URL에서는 퍼센트 인코딩이 필요합니다. O'Brien과 같은 사용자 이름은 합법적인 입력이지만 HTML에 배치될 때는 O'Brien으로 인코딩되어야 합니다. 입력 유효성 검사는 출력 인코딩을 대체할 수 없으며, 인코딩 또한 유효성 검사를 대체할 수 없습니다. 이 둘은 데이터 수명 주기의 다른 지점에서 다른 문제를 해결합니다.
추가적인 강화 조치에는 스크립트 소스를 제한하는 콘텐츠 보안 정책(Content Security Policy, CSP) 헤더, 세션 쿠키의 HttpOnly 및 Secure 플래그, 모든 신뢰 경계에서의 파라미터화된 API 사용 등이 포함됩니다.
WAF와 파일 업로드 보호
웹 애플리케이션 방화벽(WAF)은 HTTP 트래픽을 검사하고 알려진 악성 패턴(SQLi 시그니처, XSS 페이로드, 경로 탐색 시퀀스, 프로토콜 이상 등)과 일치하는 요청을 차단합니다. 리버스 프록시(ModSecurity와 OWASP Core Rule Set, AWS WAF, Cloudflare, F5)로 배포되며, 코드를 수정하기 전에 취약점이 발견되었을 때 유용한 가상 패치(virtual patching)를 제공합니다. 하지만 WAF는 보완적인 제어 수단일 뿐, 안전한 코딩을 대체할 수는 없습니다. 정교한 공격자들은 인코딩 기법, HTTP 파라미터 오염, 페이로드 분할 등을 통해 WAF를 일상적으로 우회합니다.
파일 업로드는 신뢰할 수 없는 콘텐츠를 서버 측 저장소와 결합하고, 종종 실행까지 이어지기 때문에 특별한 주의가 필요합니다. 보호 조치에는 확장자나 Content-Type 헤더를 신뢰하는 대신 매직 바이트(magic bytes)를 검사하여 파일 유형을 확인하고, 업로드된 파일을 웹 루트 외부에 저장하며, 조작된 파일 이름을 통한 디렉터리 탐색(directory traversal)을 방지하기 위해 파일을 서버 생성 식별자로 이름을 바꾸고, 저장하기 전에 안티바이러스로 스캔하며, 동일 출처(same-origin) 스크립트 실행을 방지하기 위해 사용자 업로드 콘텐츠를 별도의 도메인에서 제공하는 것 등이 포함됩니다.
실무 시나리오: SQL 인젝션으로 인한 전체 데이터베이스 탈취
한 리테일 기업의 제품 검색 엔드포인트는 category 파라미터를 받아 새니타이제이션(sanitization) 과정 없이 SQL 쿼리에 직접 연결했습니다. 한 보안 연구원이 ' UNION SELECT table_name,null,null FROM information_schema.tables--를 제출하자 응답으로 모든 데이터베이스 테이블 목록이 반환되는 것을 발견했습니다. 후속 요청을 통해 customers 테이블을 추출하여 이름, 이메일 주소, bcrypt로 해시된 비밀번호를 포함한 120만 개의 레코드를 얻었습니다. 공격자는 또한 SQL 인젝션을 통해 호출하여 웹 루트에 파일을 쓸 수 있는 저장 프로시저를 발견했고, 이를 통해 웹셸(webshell)을 배포하여 서버를 완전히 탈취할 수 있었습니다. 이 취약점은 3년 동안 존재해 왔으며, 테스터들이 검색 엔드포인트가 아닌 로그인 폼만 테스트했기 때문에 이전 두 차례의 모의 침투 테스트에서 발견되지 못했습니다. 여기서 얻을 수 있는 교훈은 인젝션 테스트는 명백한 인증 경로뿐만 아니라 모든 엔드포인트의 모든 파라미터를 대상으로 해야 한다는 것입니다.
이 문제 연습하기 → · ExamRoll.io에서 시간 제한 연습 →
Pass the whole exam — not just this question
You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.
시험 합격하기 →