SQL 인젝션 XSS 방어 기초, 준비된 문장 활용

핵심 요약
  • SQL 인젝션은 쿼리 문자열에 입력값을 이어 붙이지 않고 준비된 문장으로 값을 따로 전달해 막는다.
  • XSS는 출력하는 위치에 맞는 인코딩과 안전한 DOM 사용으로 막고, 입력 검증과 CSP는 보조 수단으로 쓴다.
  • 두 공격 모두 한 가지 기법으로 끝나지 않으므로 검증, 최소 권한, 업데이트를 겹쳐서 적용한다.

SQL 인젝션과 XSS는 웹 보안에서 가장 오래되고 흔한 취약점입니다. 둘의 뿌리는 같습니다. 사용자가 입력한 값을 데이터가 아니라 명령으로 해석하게 만드는 코드 때문에 생깁니다. SQL 인젝션은 데이터베이스가, XSS는 방문자의 브라우저가 입력값을 명령으로 받아들입니다.

이 글은 공격 방법이 아니라 방어 관점만 다룹니다. 직접 코드를 작성하거나 수정하는 운영자, 외주 개발자에게 무엇을 요구해야 하는지 알고 싶은 분을 대상으로 합니다. OWASP 문서는 2026년 10월 24일에 확인했습니다.

두 취약점이 생기는 원리

구분SQL 인젝션XSS
입력값이 해석되는 곳데이터베이스방문자 브라우저
원인쿼리에 입력값을 문자열로 이어 붙임입력값을 인코딩 없이 화면에 출력
피해데이터 열람·변조·삭제방문자 세션 탈취, 화면 변조
핵심 방어준비된 문장(파라미터 쿼리)출력 위치별 인코딩

피해를 보는 대상도 다릅니다. SQL 인젝션은 서버 데이터가, XSS는 사이트를 방문한 사람이 위험해집니다.

SQL 인젝션 방어 1 준비된 문장

OWASP가 가장 먼저 권하는 방어는 준비된 문장(prepared statement)과 파라미터 쿼리입니다. OWASP는 SQL 코드를 먼저 정의하고 각 값을 나중에 따로 전달하게 하는 방식이라고 설명합니다. 데이터베이스는 전달된 값을 항상 데이터로만 취급하므로 값의 내용이 쿼리 구조를 바꾸지 못합니다.

PHP의 PDO를 쓰는 예시입니다.

<?php
// 값을 쿼리 문자열에 이어 붙이지 않고 ?에 따로 전달한다
$stmt = $pdo->prepare('SELECT id, name FROM members WHERE email = ?');
$stmt->execute([$email]);
$row = $stmt->fetch();

반대로 "... WHERE email = '" . $email . "'" 처럼 이어 붙이는 코드는 피해야 합니다. 이 형태가 코드 안에 있는지가 외주 코드 검토의 첫 번째 확인 항목입니다.

내 사이트의 HTTPS·인증서·보안 헤더를 바로 확인할 수 있습니다.

무료 보안 검사 시작

SQL 인젝션 방어 2 검증과 최소 권한

값 자리는 준비된 문장으로 처리되지만 테이블 이름, 컬럼 이름, 정렬 방향처럼 파라미터로 보낼 수 없는 부분이 있습니다. OWASP는 이런 경우 입력을 그대로 쓰지 말고 미리 정해 둔 허용 목록에 대응시키라고 안내합니다. 예를 들어 정렬 기준은 화면에서 받은 문자열을 쓰지 않고, latest 면 created_at, popular 면 views 로 코드에서 바꿔 쓰는 식입니다.

최소 권한 원칙도 중요합니다. 웹 애플리케이션이 쓰는 데이터베이스 계정에는 필요한 테이블에 대한 필요한 권한만 주세요. 관리자 계정이나 DBA 권한을 앱에 쓰면 취약점 하나가 서버 전체 피해로 번집니다. 이 두 가지는 취약점이 남아 있을 때 피해를 줄이는 방어층입니다.

OWASP가 마지막 수단으로 분류한 입력값 이스케이프는 새로 만드는 코드에서 선택하지 않는 것이 좋습니다.

XSS 방어 1 출력 위치별 인코딩

XSS 방어의 핵심은 입력 필터링이 아니라 출력 인코딩입니다. OWASP는 데이터가 놓이는 위치에 맞는 인코딩을 쓰라고 설명합니다.

  • HTML 본문에 출력할 때는 HTML 엔티티 인코딩을 쓴다
  • URL 파라미터에 넣을 때는 퍼센트 인코딩을 쓴다
  • 자바스크립트나 속성 위치에는 검증된 라이브러리 인코더를 쓴다

직접 만든 치환 함수는 빠뜨리는 경우가 많아 권장되지 않습니다. PHP에서는 아래처럼 표준 함수를 씁니다.

<?php
// HTML 본문에 출력할 때
echo htmlspecialchars($comment, ENT_QUOTES, 'UTF-8');

최신 프레임워크의 템플릿은 기본적으로 자동 인코딩을 제공합니다. 다만 OWASP는 React의 dangerouslySetInnerHTML, Angular의 bypassSecurityTrust 계열처럼 이 보호를 우회하는 기능에 주의하라고 안내합니다. 이름에 경고가 붙은 기능은 정말 필요한 곳에서만 쓰세요.

XSS 방어 2 안전한 DOM 사용과 정화

브라우저 쪽 자바스크립트에서는 innerHTML 대신 textContent 나 value 처럼 텍스트로 다루는 속성을 쓰는 것이 안전합니다. 사용자가 HTML을 직접 작성하는 게시판 같은 기능이 꼭 필요하다면 DOMPurify 같은 유지 보수되는 정화 라이브러리를 거치고, 정화한 뒤에는 내용을 다시 수정하지 않으며, 라이브러리를 최신으로 유지해야 합니다.

입력 검증과 CSP는 보조 수단

입력 검증은 쓸모없다는 뜻이 아닙니다. 전화번호 칸에 숫자만 받는 식의 형식 검증은 오류를 줄이고 방어층을 하나 더 만들어 줍니다. 다만 OWASP는 이것이 단독 해법이 아니라 보조라고 설명합니다.

CSP(Content-Security-Policy)도 같은 위치입니다. 브라우저가 허용된 출처의 스크립트만 실행하게 해 XSS 피해를 줄이지만, OWASP는 CSP만 믿는 것을 경고합니다. 적용 순서는 Content-Security-Policy 적용 가이드에, 다른 헤더는 보안 헤더 설정 방법에 정리했습니다. 한 기법이 모든 XSS를 해결하지 못하므로 겹쳐서 쓰라는 것이 OWASP의 핵심 메시지입니다.

운영자가 점검할 목록

  • 직접 만든 코드와 외주 코드에서 쿼리를 문자열로 이어 붙이는 곳이 없는지 검토한다
  • 데이터베이스 계정 권한이 필요한 만큼인지 확인한다
  • 출력하는 모든 곳에서 인코딩 함수를 쓰는지 확인한다
  • 사용하지 않는 플러그인과 오래된 코드를 제거하고 소프트웨어를 최신으로 유지한다
  • 오류 메시지가 화면에 그대로 노출되지 않게 한다. 설정 방법은 PHP 서버 보안 설정 php.ini 글을 참고하세요
  • 구글 도움말도 열린 디렉터리 권한, XSS, SQL 인젝션 같은 흔한 취약점을 점검하라고 안내합니다

이 글은 방어 원칙만 설명하며, 외부 검사로 취약점 존재 여부를 확정할 수는 없습니다. 실제 점검은 소스 코드 검토나 허가받은 환경의 점검 도구로 하세요.

웹사이트 기본 보안 검사HTTPS·리디렉션·인증서·보안 헤더·서버 정보 노출 10개 항목을 무료로 확인할 수 있습니다.

무료 보안 검사 시작

자주 묻는 질문

입력값에서 특수문자를 지우면 SQL 인젝션이 막히나요?

안전하다고 보기 어렵습니다. OWASP는 이스케이프를 마지막 수단으로만 쓰라고 하며, 데이터베이스마다 규칙이 달라 깨지기 쉽다고 설명합니다. 준비된 문장이 기본 해법입니다.

ORM을 쓰면 SQL 인젝션 걱정이 없나요?

ORM이 기본적으로 값을 분리해 주지만 원본 쿼리를 문자열로 직접 이어 붙이는 기능을 쓰면 같은 위험이 생깁니다. 값은 항상 파라미터로 전달하고 정렬 기준 같은 부분은 허용 목록으로 제한하세요.

워드프레스는 어떻게 대비하나요?

워드프레스 코어와 플러그인을 최신으로 유지하고, 직접 코드를 짜는 경우 DB 쿼리 함수의 준비 기능과 출력 이스케이프 함수를 사용하세요. 사용하지 않는 플러그인은 삭제하는 것이 좋습니다.

외부 검사로 이 취약점이 있는지 알 수 있나요?

외부 응답만으로는 확정할 수 없습니다. 코드를 직접 검토하거나 허가된 환경에서 취약점 점검 도구를 쓰세요. 남의 사이트에 시도하는 것은 법적으로 문제가 됩니다.

확인한 자료

기술 정보는 2026-10-24에 위 자료로 확인했습니다. 소프트웨어 버전·기본값·서비스 정책은 바뀔 수 있으므로 적용 전 각 문서의 최신 내용을 확인하세요. 이 글은 일반 정보이며 특정 서비스 가입을 권하지 않습니다.

Next
웹사이트 보안

CSP 적용 가이드, Report-Only부터 시작

CSP를 안전하게 적용하는 순서를 정리했습니다. Report-Only로 시작하는 방법, default-src·script-src·frame-ancestors 등 주요 지시어, unsafe-inline 문제와 nonce, Apache·Nginx 예시를 다룹니다.

가이드 보기 →
웹사이트 보안

보안 헤더 설정 방법, Apache·Nginx 예시

HSTS, CSP, X-Content-Type-Options, Referrer-Policy, X-Frame-Options, Permissions-Policy의 역할과 권장값, Apache·Nginx 설정 예시, 적용 후 확인 방법을 정리했습니다.

가이드 보기 →
PHP 보안

PHP 서버 보안 설정 php.ini 필수 항목 정리

expose_php, display_errors, allow_url_include, disable_functions, open_basedir, 세션 쿠키 옵션 등 php.ini 보안 설정의 기본값과 권장 값, 적용 확인 방법을 정리했습니다.

가이드 보기 →
웹사이트 보안

웹사이트 악성코드 감염 대처, 초기 대응과 증거 보존

웹사이트 악성코드 감염이 의심될 때 먼저 할 일을 순서대로 정리했습니다. 격리, 증거 보존, 비밀번호 교체, 정리와 재발 방지, Search Console 검토 요청까지 다룹니다.

가이드 보기 →
웹사이트 보안

홈페이지 해킹 확인 방법, Search Console 점검

내 홈페이지가 해킹됐는지 확인하는 순서를 정리했습니다. 검색 결과 스팸, 리디렉션, Search Console 보안 문제 보고서, 파일·로그 점검과 공개 검사의 한계까지 다룹니다.

가이드 보기 →