웹 보안
우아한테크 [10분 테코톡] 바니의 웹 보안을 보고 정리했습니다
OWASP Top 10
OWASP : Open Web Application Security Project라는 비영리 보안 프로젝트 재단
웹 어플리케이션에서 발생할 수 있는 취약점을 분석하고 연구해, 공격 가능성과 기술적 영향을 기준으로 10개의 취약점 OWASP Top 10을 공개한다
Injection
신뢰할 수 없는 데이터가 명령어나 쿼리문의 일부분으로 전달될 때 발생하며, 공격자의 악의적인 데이터로 인해 예기치 않은 명령이 실행되거나 올바른 권한 없이 데이터에 접근할 수 있다
강의의 실습환경 : bWAPP - Bee Box
OWASP Top 10 기반 취약점을 포함하여 모의해킹 테스트가 가능한 무료 오픈 소스인 취약한 웹 어플리케이션 (Buggy Web Application)
SQL Injection
SQL 삽입 또는 SQL 주입이며, 코드 인젝션의 기법 중 하나
클라이언트의 입력값 조작을 통해 서버의 데이터베이스를 공격하는 방식
SELECT * FROM member
WHERE id = '" + id + "' and " + "password = '" + password + "';
# 입력값
SELECT * FROM member
WHERE id = 'bunny' or 1=1#' and " + "password = '" + password + "';
# 최종적으로 항상 True
SELECT * FROM member
WHERE id = 'bunny' or 1=1#
Error Based SQL Injection
데이터베이스에 고의적으로 오류를 발생시켜 에러 출력을 통해 데이터베이스 구조를 파악하고 필요한 정보 습득
아래처럼 입력했을 때 에러가 발생하면 MySQL임을 알 수 있다
SELECT * FROM movie WHERE title = ‘ ‘ ‘
Union Based SQL Injection
데이터베이스의 UNION 연산자를 사용하여 쿼리 결과값의 조합을 통해 정보를 파악
(전제조건 : 컬럼의 개수와 데이터 형식이 같아야 한다)
우선 컬럼의 개수를 구하는 것부터 시작한다. 아래처럼 1, 2, 3...을 입력하다가 더이상 에러가 나지 않을 때 컬럼의 개수를 알게 되어 공격할 수 있게 된다.
union select all 1# -- 컬럼 개수가 충분하지 않다는 에러
union select all 1, 2, 3, 4, 5# -- 에러가 없다면 쿼리 컬럼 개수가 5개임을 알 수 있다
아래처럼 users 테이블까지 보게 된다면 id나 비밀번호까지 노출될 수 있다.
union select all 1, table_name, 3, 4, 5 from information_schema.tables#
대응방안
1) 에러 메시지 노출 차단 (너무 자세히 알려주지 않기)
2) 입력값 검증 (SQL문을 아예 입력 불가능하도록 하기)
- 사용 가능한 특수문자 제한
- 특수문자 필터링
3) Prepared Statements
- Statements : sql 쿼리문에 사용하는 데이터를 넣어서 쿼리문을 만들어서 그걸로 데이터베이스 조회
- Prepared Statements : sql문을 데이터베이스에 적용해놓은 다음 파라미터로 바인딩 → 바인딩된 파라미터는 쿼리로써 동작할 수 없기 때문에 SQL Injection에 대응 가능
그럼 왜 작성했던 코드에서는 에러가 발생하지 않았을까
- JdbcTemplate는 Prepared Statements 사용
- JPA는 파라미터 바인딩으로 동작
XSS (Cross Site Scripting)
악성 스크립트를 웹사이트에 주입하는 코드 인젝션 기법 중 하나
공격자가 웹 어플리케이션에 보낸 악성 코드가 다른 사용자에게 전달될 때 발생한다
Stored XSS
공격자가 취약점이 있는 Web Application에 악성 스크립트를 영구적으로 저장하여 다른 사용자에게 전달하는 방식
Reflected XSS
공격자가 사용자에게 악성 스크립트를 메일이나 웹 사이트를 통해 전달하고 사용자가 실행하도록 하는 공격 기법
대응방안
1) 입출력 값 검증 및 필터링 → 인코딩 (특수문자 등)
2) 라이브러리, 외부 솔루션 사용
그럼 왜 작성했던 코드에서는 에러가 발생하지 않았을까
입출력 값 검증 및 필터링 → 리액트는 모든 값을 렌더링하기 전에 이스케이프하기 때문에 자동으로 XSS에 대응
리액트 돔이 JSX에 삽입된 모든 값을 렌더링하기 전에 치환하여 XSS를 대응한다는 것을 처음 알았다.
강의는 단순하게 웹 보안에 대해서 설명하기만 한 것이 아니라, 진행했던 프로젝트에서 웹 보안을 덜 고려했음에도 왜 문제가 발생하지 않았는지 분석까지 해서 좋았다. 확실히 발표는 경험에 기반한 것으로 진행하는 것이 좋은 것 같다.