웹 동작 기본 구조
브라우저(요청) → 서버(처리) → DB(확인) → 서버(응답) → 브라우저
핵심 문제는 사용자 입력값을 서버가 검증 없이 그대로 처리한다는 것. 대부분 취약점의 근본 원인이 여기서 나옴.
OWASP Top 10: OWASP는 웹 보안 비영리 단체로, 실제 침해사고 데이터를 기반으로 2~4년마다 가장 흔하고 위험한 취약점 10개 발표
2021 버전 10개 항목
1. 접근 제어 실패 — 권한 없는 사용자가 남의 데이터에 접근
2. 암호화 실패 — 평문 저장, 약한 암호화 방식
3. 인젝션 — SQLi 등, 오늘 다룰 주제
4. 안전하지 않은 설계 — 설계 단계부터 보안 미고려
5. 보안 설정 오류 — 기본 비밀번호 방치 등
6. 취약·오래된 컴포넌트 — 구버전 라이브러리 사용
7. 인증 실패 — 약한 비밀번호 정책, 세션 관리 부실
8. 무결성 실패 — 검증 없이 외부 코드/데이터 신뢰
9. 로깅·모니터링 실패 — 침해당해도 못 알아챔
10. SSRF — 서버가 공격자 대신 내부 자원 요청
SQL Injection (SQLi)
입력값 검증이 미흡할 때 공격자가 SQL 쿼리 자체를 조작하는 취약점. 질문지에 답 대신 질문 자체를 바꾸는 문장을 써넣는 것과 비슷함.
예시: 로그인 우회
정상 쿼리: SELECT * FROM users WHERE id=‘입력값’ AND pw=‘입력값’
아이디 칸에 ’ OR ‘1’=‘1 입력
변형된 쿼리: SELECT * FROM users WHERE id=’’ OR ‘1’=‘1’ AND pw=’…’
‘1’=‘1’은 항상 참이라서 비밀번호 확인 없이 로그인 성공
방어
Prepared Statement(파라미터 바인딩)가 가장 기본이고 확실한 방법. 그 외 입력값 화이트리스트 검증, DB 계정 권한 최소화, WAF 적용.
XSS (Cross-Site Scripting)
악성 스크립트를 심어서 다른 사용자 브라우저에서 실행되게 만드는 취약점. SQLi는 DB를 노리는 데 반해 XSS는 다른 사용자 브라우저를 노림.
예시: 댓글 저장형
댓글창에 <script>alert(‘해킹’)</script> 입력. 서버가 그대로 저장하면 다른 사용자가 게시글을 볼 때마다 스크립트가 실행됨. 실제 공격은 alert 대신 세션 쿠키를 공격자 서버로 전송하는 코드를 심는 식.
유형
Stored는 DB에 저장돼서 조회하는 모든 사용자에게 실행되는 방식으로 피해 범위가 가장 큼. Reflected는 URL 파라미터에 담아서 링크를 클릭해야 실행됨. DOM based는 서버를 안 거치고 브라우저 내 JS 처리 과정에서 발생.
피해
세션 쿠키 탈취로 세션 하이재킹, 가짜 로그인창으로 피싱, 사용자 권한으로 원치 않는 행동 유발.
방어
출력 시 HTML 이스케이프(< 를 <로 변환 등), CSP 설정, 쿠키에 HttpOnly 속성 적용해서 JS로 쿠키 접근 자체를 막음.
CSRF (Cross-Site Request Forgery)
로그인된 사용자의 권한을 도용해서 원치 않는 요청을 대신 실행시키는 취약점. XSS는 스크립트 실행 자체가 목적이지만 CSRF는 이미 인증된 세션을 빌려 쓰는 게 목적이라는 점에서 다름.
예시: 송금 도용
사용자가 은행 사이트에 로그인한 상태를 유지 중일 때, 악성 사이트에 <img src="은행사이트.com/transfer?to=공격자&amount=100000"> 같은 코드가 숨어있으면 브라우저가 이미지를 불러오면서 은행 사이트에 자동으로 요청을 보냄. 은행 서버는 이걸 로그인된 사용자의 정상 요청으로 착각하고 처리함.
방어
CSRF 토큰으로 요청마다 예측 불가능한 값을 발급하고 검증. SameSite 쿠키 속성으로 타 사이트발 요청엔 쿠키가 자동으로 안 실리게 설정. Referer/Origin 헤더 검증.
세 취약점 비교
SQLi는 대상이 DB, 목적은 데이터 탈취·조작, 원인은 입력값이 SQL 쿼리에 그대로 삽입되는 것.
XSS는 대상이 다른 사용자 브라우저, 목적은 악성 스크립트 실행, 원인은 입력값이 HTML/JS로 그대로 출력되는 것.
CSRF는 대상이 서버의 요청 처리, 목적은 인증된 권한 도용, 원인은 요청 출처를 검증하지 않는 것