웹 보안 기본기와 방어 레이어
SQL Injection, XSS, CSRF, MITM, DDoS, 패스워드 해싱, 공급망 공격을 원인과 방어 관점에서 정리한다. 핵심은 사용자 입력과 자동 첨부 권한, 해석 컨텍스트, 무결성 검증을 여러 레이어에서 함께 다루는 것이다.
Script Companion
오디오와 함께 스크립트 보기
- 01
웹 보안은 나중에 붙이는 부가 기능이 아니라, API 서버를 처음 설계하고 코드를 작성할 때부터 들어가야 하는 전제다. BackOps 엔지니어가 직접 만든 서버에서 SQL Injection 한 줄로 DB 전체가 노출되거나, 사용자의 세션이 탈취되는 상황은 실제로 일어난다. 문서는 2025년 OWASP 보고서에서 기업 API의 31%가 여전히 Injection 취약점을 포함한다고 말한다. 그래서 이 에피소드에서는 문서가 다룬 주요 공격을 각각 외우기보다, 왜 생기고 어디에서 막아야 하는지 중심으로 살펴본다.
- 02
SQL Injection의 핵심 원인은 사용자 입력을 SQL 쿼리 문자열에 직접 이어 붙이는 데 있다. 공격자가 입력 필드에 SQL 문법을 넣으면, 서버는 원래 의도한 데이터 조회가 아니라 공격자가 만든 다른 쿼리를 실행할 수 있다. TypeORM createQueryBuilder에서 파라미터 바인딩을 쓴다고 생각해도, 템플릿 리터럴로 where 조건을 직접 만들면 바인딩이 무력화된다. 해결은 Named Parameter 방식으로 바꾸거나, 가능한 경우 findOne의 where 조건처럼 ORM이 제공하는 안전한 API를 쓰는 것이다. Raw 쿼리가 꼭 필요할 때도 두 번째 배열 인자로 값을 분리해야 한다.
- 03
이 원리는 SQL에만 갇혀 있지 않다. 문서는 NoSQL Injection, OS Command Injection, LDAP, XPath, Template Injection, LLM Prompt Injection까지 같은 가족으로 묶는다. 공통점은 사용자 입력이 데이터가 아니라 명령어로 해석되는 순간 신뢰 경계가 무너진다는 것이다. MongoDB에서는 객체 페이로드가 조건식을 바꿀 수 있고, Node.js의 exec는 문자열을 셸 명령으로 파싱할 수 있다. GraphQL, gRPC, MCP tool call 같은 새 인터페이스를 도입할 때도 질문은 같다. 이 인터프리터에는 사용자 입력이 코드로 해석될 경로가 있는가를 먼저 봐야 한다.
- 04
XSS, Cross-Site Scripting은 사용자 입력이 HTML이나 JavaScript로 해석될 때 발생한다. Stored XSS는 악성 스크립트가 DB에 저장되어 다른 사용자가 볼 때 실행되고, Reflected XSS는 URL 파라미터를 통해 일회성으로 실행되며, DOM-based XSS는 클라이언트 JavaScript가 DOM을 직접 조작하는 과정에서 생긴다. React의 dangerouslySetInnerHTML, 바닐라 JS의 innerHTML, eval, 문자열을 받는 setTimeout은 모두 자동 이스케이프나 안전한 데이터 처리를 우회할 수 있다. 사용자 입력을 화면에 넣을 때는 textContent를 쓰거나 DOMPurify 같은 sanitize 라이브러리를 거쳐야 한다.
- 05
CSP, Content Security Policy는 브라우저에게 이 페이지에서 실행 가능한 스크립트 출처를 알려주는 HTTP 헤더다. script-src 'self'처럼 설정하면 외부 스크립트 주입을 브라우저가 거부할 수 있다. 다만 경계 조건이 중요하다. script-src 'unsafe-inline'은 인라인 script를 허용해 XSS 방어를 크게 약화시키고, 'unsafe-eval'은 eval과 문자열 setTimeout 경로를 열어 둔다. reportOnly: true는 배포 전 테스트용이며, 프로덕션에서 그대로 두면 실제 차단이 일어나지 않는다. helmet을 적용한 뒤 화면이 하얗게 뜬다면, CDN이나 빌드 산출물의 스크립트가 CSP에 막힌 것인지 콘솔 오류를 확인해야 한다.
- 06
CSRF, Cross-Site Request Forgery는 쿠키가 자동으로 전송된다는 성질을 공격한다. 사용자가 로그인한 상태에서 악성 사이트의 폼이나 리소스 요청이 서버로 향하면, 서버는 쿠키가 붙어 있으므로 정상 요청처럼 볼 수 있다. SameSite 쿠키는 이 자동 첨부를 줄이는 방어선이다. None은 방어가 없고, Lax는 외부 사이트 POST를 막는 일반 서비스 기본값이며, Strict는 외부 GET과 POST를 모두 막아 금융이나 보안 서비스에 적합하다. CSRF 토큰은 서버가 발급한 랜덤 토큰을 헤더에 담게 해 외부 사이트가 위조 요청을 만들기 어렵게 한다. 모던 SPA에서 JWT를 Authorization 헤더로 보내면 쿠키 자동 전송이 아니므로 CSRF 공격 자체가 성립하지 않는다.
- 07
MITM은 클라이언트와 서버 사이에 공격자가 끼어들어 트래픽을 도청하거나 변조하는 공격이다. 공공 Wi-Fi, ARP 스푸핑, DNS 스푸핑 같은 수법이 여기에 속하고, 평문 HTTP 통신은 중간에서 읽히고 바뀔 수 있다. 방어의 중심은 HTTPS, TLS, HSTS로 통신 경로를 암호화하고 강제하는 것이다. DDoS는 서버 자원을 가짜 요청으로 고갈시키는 공격이다. L3는 IP 레벨 대용량 트래픽, L4는 SYN Flood나 UDP Flood처럼 연결 자원을 노리고, L7은 HTTP Flood나 Slowloris처럼 정상 HTTP 요청처럼 보여 차단이 어렵다. AWS Shield와 WAF Rate Limiting은 이 계층별 방어의 일부다.
- 08
DDoS 방어에서 임계값은 감으로 정하지 않는다. 문서는 AWS WAF rate-based 기준으로 전체 경로에는 5분 기준 500 requests, 로그인이나 회원가입 같은 경로에는 100 requests 또는 더 낮은 값을 제시한다. BackOps 운영 사례에서는 로그인 평균 50 RPM, p99 100 RPM을 측정한 뒤 글로벌 blanket은 500 req/5min IP당, 로그인 경로는 30 req/5min IP당으로 잡았다. 다만 기업 NAT처럼 여러 사용자가 하나의 IP를 공유하면 정상 사용자도 429 Too Many Requests를 받을 수 있다. 이때는 IP 단독이 아니라 IP와 User-Agent 조합, 또는 로그인 사용자의 JWT 기반 계산을 함께 고려해야 한다.
- 09
패스워드 보안에서 중요한 구분은 빠른 해시와 느린 패스워드 해싱이다. SHA-256은 데이터 무결성 검증이나 JWT 서명에는 맞지만, GPU로 매우 빠르게 대입할 수 있어 패스워드 저장에는 쓰면 안 된다. BCrypt는 salt를 내장하고 비용 인수로 속도를 조절해 brute force 비용을 높인다. 하지만 bcrypt에는 입력을 72바이트에서 조용히 잘라내는 truncation 함정이 있다. 2025년 권장 사항으로는 Argon2id가 BCrypt보다 우수한 선택이며, 새 프로젝트는 Argon2id를 쓰고 기존 bcrypt 프로젝트는 cost factor 12 이상을 유지한 뒤 마이그레이션을 검토하는 흐름이 제시된다.
- 10
공급망 공격은 내가 작성한 코드가 아니라 의존성이나 배포 경로가 오염되는 문제다. OWASP 2025에서는 A03: Software Supply Chain Failures가 신규 항목으로 추가되었고, 문서는 event-stream, xz-utils, polyfill.io 사례를 언급한다. package-lock.json 없이 npm install을 하면 package.json의 범위 버전에 맞춰 더 최신 버전을 받을 수 있고, 그 버전이 오염되어 있으면 다음 설치에서 악성 코드가 들어올 수 있다. lock 파일은 정확한 버전과 해시를 기준으로 설치하게 해 이 위험을 줄인다. 그래서 의존성 보안은 npm audit이나 Snyk 같은 사후 탐지만이 아니라, 설치 재현성과 무결성 관리에서 시작된다.
- 11
정리하면 이 문서의 공격들은 서로 달라 보여도 다섯 질문으로 다시 묶인다. 데이터가 어디에서 어디로 흘렀는가, 입력이 데이터였는가 명령어였는가, 쿠키나 토큰 같은 자격이 자동 첨부되었는가, 공격자 비용보다 방어자 비용이 크게 늘어나는가, 사용한 코드와 인증서와 해시의 무결성은 무엇이 보증하는가를 묻는 것이다. SQL Injection과 XSS는 해석 컨텍스트, CSRF는 자동 첨부 자격, DDoS와 brute force는 비대칭 비용, 공급망 공격은 무결성과 출처 문제로 볼 수 있다. 마지막 핵심은 입력 검증, ORM 사용, 보안 헤더, 쿠키 설정, 인프라 방어를 여러 레이어로 함께 적용하는 것이다.
같은 레이어