1. XSS(Cross Site Scripting)
악의적인 사용자가 공격하려는 사이트에 스크립트를 넣는 기법. 주로 다른 웹사이트와 정보를 교환하는 식으로 작동하므로 사이트 간 스크립팅이라고 명칭함.
- 웹 애플리케이션이 사용자로부터 입력받은 값을 제대로 검사하지 않고 사용할 경우 나타남
- 공격에 성공하면 사이트에 접속한 사용자가 삽입된 코드를 실행시키게 되고, 보통 의도치 않은 행동을 수정시키거나, 쿠키나 세션 토큰 등을 탈취한다.
- 자바스크립트를 이용한 공격이 주로 많음
- 공격방법에 따라 Stored XSS와 Reflected XSS로 나뉜다.
Stored XSS
사이트 게시판이나 댓글, 닉네임 등의 형태로 삽입된 스크립트가 데이터베이스에 저장되는 방식
- 저장된 악성스크립트가 있는 게시글 등을 열람한 사용자들은 악성스크립트가 작동하면서 쿠키를 탈취당하던가, 다른 사이트로 리다이렉션되는 공격을 받게 됨
- 한번에 공격으로 악성 스크립트를 삽입하여 수많은 피해를 입힘
- 사용자가 입력한 값이 데이터베이스에 저장되고, 저장된 값이 그대로 프론트엔드 단에 보여주는 곳에 공격이 성공할 가능성이 큼
Reflected XSS
URL 파라미터(특히 GET 방식)에 스크립트를 넣어 서버에 저장하지 않고 그 즉시 스크립트를 만드는 방식
- 사용자에게 입력 받은 값을 서버에서 되돌려 주는 곳에서 발생.
- 사용자에게 입력 받은 검색어를 그대로 보여주는 곳이나 사용자가 입력한 값을 에러 메세지에 포함하여 보여주는 곳에 악성스크립트가 삽입되면, 서버가 사용자의 입력 값을 포함해 응답해줄 때 스크립트가 실행됨
- 악의적인 스크립트와 함께 URL을 사용자에게 누르도록 유도하여 공격
XSS 방지 대책
- 쿠키에 중요한 정보를 담지 않고 서버에 중요 정보를 저장
- 정보를 암호화
- httponly 속성 on (자바스크립트의 document.cookie를 이용해 쿠키에 접속하는 것을 막는 옵션)
- Secure coding(str_replace, htmlspecialchars 등 보안과 관련된 함수 사용)
2. CSRF(Cross Site Request Forgery)
사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제 등)를 특정 웹 사이트에 요청하는 공격 기법.
- 해당 세션, 쿠키를 가진 사용자들만 사용할 수 있는 기능을 요청 가능하게 된다.
- 사용자가 웹사이트에 로그인한 상태에서 사이트간 요청 위조 공격 코드가 삽입된 페이지를 열면, 공격 대상이 되는 웹사이트는 위조된 공격 명령이 믿을 수 있는 사용자로부터 발송된 것으로 판단하게 되어 공격에 노출됨
- csrf 공격이 이뤄지기 위한 조건
- 위조 요청을 전송하는 서비스에 희생자가 로그인된 상태여야 함
- 희생자가 해커가 만든 피싱 사이트에 접속
CSRF 방지 대책
- Referrer 검증 (Back-end 단에서 request의 referrer를 확인하여 domain이 일치하는지 검증)
- HTTP Referrer(리퍼러) : 웹 브라우저로 월드 와이드 웹을 서핑할 때, 하이퍼링크를 통해서 각각의 사이트로 방문시 남는 흔적
- Security Token 사용
- 사용자 세션에 임의의 난수 값을 저장하고, 요청마다 해당 난수 값을 포함시켜 전송.
- back-end 단에서 요청을 받을 때마다 세션에 저장된 토큰 값과 요청 파라미터에 전달되는 토큰 값이 일치하는지 검증
- Referrer 검증이 불가능한 환경에서 사용
3. SQL Injection
악의적인 사용자가 보안상의 취약점을 이용하여 임의의 SQL문을 전송하여 데이터베이스가 비정상적인 동작을 하도록 조작하는 행위
Error based SQL Injection(논리적 에러를 이용한 SQL Injection)
SELECT * FROM Users WHERE id = 'abcd' AND password = '1234'
↓ ' or '1'='1
SELECT * FROM Users WHERE id = 'abcd' AND password = ' or '1'='1
' or '1'=1를 넣어서 1=1이라는 참인 값을 하나라도 참이면 참이되는 or 연산과 함께 넣어 로그인을 성공시켜버린다.
Union based SQL Injection(Union 명령어를 이용한 SQL Injection)
Union 키워드는 두 개의 쿼리문에 대한 결과를 통합해서 하나의 테이블로 보여주는 키워드다. 정상적인 쿼리문에 Union 키워드를 사용하여 인젝션에 성공하면, 원하는 쿼리문을 실행할 수 있게 된다.
Union Injection을 성공하기 위해서는 두 가지 조건
- Union하는 두 테이블의 컬럼 수 가 같아야 함
- 데이터 형이 같아야 함
SELECT * FROM Users WHERE id = 'abcd' AND password = '1234'
↓ abcd' UNION SELECT 1, 1 --
SELECT * FROM Users WHERE id = 'abcd' UNION SELECT 1, 1 -- AND password = 'anything'
password를 모르더라도 id가 abcd인 유저의 비밀번호를 알아낼 수 있게 된다.
Blind SQL Injection - Boolean based Blind SQL Injection
데이터베이스로부터 특정한 값이나 데이터를 전달받지 않고, 단순히 참과 거짓의 정보만 알 수 있을 때 사용. 로그인 폼에 sql injection이 가능하다고 가정했을 때, 서버가 응답하는 로그인 성공과 로그인 실패 메시지를 이용하여, db 테이블 정보 등을 추출해 낼 수 있음
- 테이블 이름을 ascii 값으로 변환하고 한글자씩 숫자 값과 비교하여 찾아낼 수 있음.
Blind SQL Injection - Time based SQL Injection
어떤 경우에는 응답의 결과가 항상 동일하여 해당 결과만으로 참과 거짓을 판별할 수 없는 경우가 있다. 이런 경우 시간을 지연시키는 쿼리를 주입하여 응답 시간의 차이로 참과 거짓 여부를 판별할 수 있다.
- and sleep(2) 을 추가하여 앞의 값이 참이면 sleep()이 동작하고, 거짓이면 동작하지 않도록 하여 값을 찾아낼 수 있음