[Security-02] Web Security Pt.1

유영석·2022년 9월 8일
1

Security

목록 보기
2/12
post-thumbnail

보안에 대한 여러 토픽 중에서 우리에게 가장 친숙한 개념이 Web(웹)과 관련된 보안에 대해서 이야기 해보겠습니다. 이번 글은 먼저 웹을 이해하기 위해 웹이 사용하는 프로토콜인 HTTP에 대해서 알아보도록 하겠습니다.

HTTP

HTTP(HyperText Transfer Protocol)은 웹이 사용하는 언어라고 볼 수 있습니다. 조금 더 정확하게 얘기하자면 웹 서버가 클라이언트, 즉 브라우저와 대화하는 데 쓰는 프로토콜인 것입니다. TCP/UDP의 포트 번호 80번에서 돌아갑니다. 요즘은 보안에 취약한 HTTP에 보안 프로토콜인 TLS를 결합한 HTTPS가 권장되고 있는데 이는 포트 번호 443번을 사용하고 있습니다. 웹 브라우저의 주소창 가장 왼쪽에 보면 자물쇠가 있는데, 걸려있다면 HTTPS 프로토콜을 사용 중이라는 뜻이지요.

HTTP는 기본적으로 create(생성), read(조회), update(수정), delete(삭제)의 기본적인 CRUD 연산들을 각각 POST, GET, PUT, DELETE 메서드로 제공하고 있습니다. HTTP의 가장 큰 특징이자 기억해야 할 것은 바로 HTTP가 Stateless 프로토콜이라는 점입니다. 상태를 보존하지 않는다....간단하게 얘기하면 메서드의 요청만 들어준다면 끝이라는 뜻입니다. 해당 요청에 대한 그 어떤 정보도 기억/기록하지 않고 까먹는다는 것이지요. 그럴 수 밖에 없는 게, 예를 들어 전세계에서 가장 많이 이용하는 웹사이트인 구글에 지금 이 시간에도 도대체 얼마나 많은 요청들이 들어올까요? 도무지 상상이 되지 않죠? 그것들을 기억한다는 것은 말이 되지 않습니다.🤮

그런데, 현재 우리가 이용하고 있는 웹사이트를 볼까요? 예를 들어, 많이 사용하는 Youtube에서 우리는 로그인을 하고 동영상을 추천 받습니다. 이를 위해서는 서버에 우리의 정보, 즉 State(상태)가 저장되어 있어야 할 것입니다. 그런데 웹서버는 Stateless잖아요? 그래서 웹서버 뒷단에 따로 상태를 저장 및 관리하는 StatefulApplication Server 를 운영합니다. 여기서 이 웹서버 영역을 FrontEnd(프론트엔드), 어플리케이션 서버 영역을 BackEnd(백엔드)라고 부르는 것입니다.

URL

URL(Uniform Resource Locator)은 네트워크 영역에서 어떤 웹사이트에 접속하기 위한 주소를 포함한 일련의 문자를 의미합니다. 다른 의미로는 어떤 네트워크 document의 전역적인 식별자라고 표현할 수도 있습니다.

URL은 위의 그림과 같은 형태를 집니다. 먼저 처음에는 프로토콜이 명시가 됩니다. 만약 HTTPS 프로토콜일 경우에는 https로 시작할 것입니다. 구분자로 ://가 명시된 뒤에는 해당 웹사이트의 도메인 네임이 명시가 됩니다. 우리가 아는 naver.com 등이 해당합니다. 구분자로 :가 명시된 뒤에 포트 번호가 오고 여기까지가 stateless한 웹서버에서 사용하는 영역입니다. 이후에는 어플리케이션 서버에서 사용하는 영역인데요. / 뒤에 어떤 어플리케이션에 해당하는 지에 대한 경로가 명시됩니다. ?에는 해당 데이터베이스에 요청할 쿼리가 담기게 됩니다. 여기까지를 뒤로 #의 구분자가 보이실텐데요. 이는 Fragment라 해서 서버로 날라가지는 않는 부분입니다 로컬 영역에서 페이지의 위치를 명시하는 데 사용됩니다.

HTML

HTML(HyperText Markup Language)는 웹 브라우저에서 보여지는 웹 페이지, 즉 document를 디자인하기 위한 언어입니다. .html 파일 안에 명시되지요. HTML에는 여러 element(요소)들이 있는데, 이들은 <tagename>...contents...</tagname>와 같이 시작 태그와 마침 태그 사이에 내용이 들어가있는 구조로 이루어져 있습니다. 그리고 이 모든 HTML element들은 Attribute를 가지는 데, 이 attributes는 요소에 대한 추가적인 정보를 담고 있으며 항상 시작 태그 안에 명시되어야 합니다. 예를 들어 <a>라는 태그 안에 링크라는 요소를 추가하고 싶다면 <a href="https://www.w3schools.com">This is a link</a>라고 쓸 수 있는 것이죠. 추가적으로 이미지 삽입을 위해서 <img>라는 태그를 사용하며, 이미지의 source 명시하기 위해 요소를 추가하여 <img src="img_girl.jpg">와 같이 사용합니다.

만약 웹 페이지 안에 또 다른 웹 페이지를 보이고 싶을 때는 어떻게 할까요? 바로 Frame(프레임)을 이용하면 됩니다. 프레임은 하나의 웹 페이지 화면을 여러 페이지, 즉 window들로 나누어 줍니다. 여러 구역들로 나누어주는 강력한 장점을 제공하는 셈이죠. 프레임의 특징적인 부분은 프레임의 컨텐츠가 꼭 지금 현재의 도메인 것이 아니어도 상관없다는 점입니다. 네이버 글에서 유튜브 영상처럼 우린 어떤 웹사이트 안 어떤 구역에 다른 웹사이트의 화면이 내장되어 있는 모습을 종종 보곤합니다. 다른 서비스의 프레임을 사용하는 것이지요. 하지만 이는 곧 보안의 취약점을 나타내기도 합니다.

위와 같이 프레임을 디자인 할 수 있습니다. 오른쪽은 index.html의 코드 내용입니다. index.html에서 3대 7로 프레임으로 나누어 각각 title.html과 main.html을 적용한 것을 볼 수있습니다. 프레임은 어떤 구역은 고정하고 어떤 구역의 컨텐츠는 변경하고 싶을 때 주로 사용됩니다. title.html의 내용은 고정적으로 하고 main.html의 내용을 동적으로 한다면, 직관적이고 확실하게 상단 영역을 고정할 수 있겠죠? 물론, 브라우저 상단 바에 표시되는 이 페이지의 주소에는 title.html도 main.html도 아닌, 가장 상단의 index.html이 명시됩니다.

JavaScript

그런데 실제로 우리가 방문하는 웹사이트들은 신문을 보는 것과는 다릅니다. 클릭을 함에 따라 화면이 바뀌고, 스크롤에 따라 애니메이션이 펼치기도 합니다. 정적인 웹 페이지가 이렇게 동적으로 상호 작용을 하기 위해 고안된 Scripting 언어가 바로 JavaScript(자바스크립트) 입니다. 웹 브라우저에서 HTML 페이지에 동적인 텍스트를 넣어주고, 이벤트를 만들어주며, 쿠키를 다루기도, 심지어 서버와 통신하기 까지 정말 많은 일들을 할 수 있도록 해주는 고마운 존재이지요. 백엔드 영역에서는 C, Python, Perl, GO 등 정말 다양한 프로그래밍 언어들을 사용해도 무방하지만 이 프론트엔드 영역만큼은 아직까지도 대부분의 브라우저들이 자바스크립트만을 지원하기 때문에 필수 불가결한 존재가 되었습니다. TMI를 덧붙이자면, 자바스크립트만을 사용하는 프론트엔드 개발자들이 백엔드 개발을 용이하게 하기 위해 고안된 프로그래밍 언어가 바로 NodeJS인 것입니다.

클라이언트 영역에서 자바스크립트를 사용하기 위해서는 <script>태그를 사용합니다. 외부의 자바스크립트를 로드하기 위해서는 <script src="FILE.JS"></script>와 같이 사용하는 데요. 여기서 특이한 점은 꼭 내 도메인에서가 아니라 <script src="https://www.example.com/FILE.JS"></script>와 같이 외부 도메인의 자바스크립트를 불러와서 실행시킬 수도 있다는 점입니다. 그러나 악의를 가진 적이 악성 코드가 담긴 자신의 자바스크립트를 남들이 실행하도록 할 수 있기 때문에 보안에 위험이 생길 수 있으며, 이와 같은 공격을 Injection이라 합니다. 물론 굳이 파일을 불러오는 게 아니라 내부에서 직접 <script>DO SOMETHING</script>와 같이 HTML에 자바스크립트 코드를 적어서 실행시킬 수도 있습니다.

Document Object Model(DOM)

이 자바스크립트도 실제 우리가 보는 이 HTML을 변경하기 위해서는 어떤 API들이 필요할 것입니다. 아니면 새로이 HTML을 생성할 수도 있고, 동적으로 새로운 스타일을 적용해볼 수도 있죠. 심지어 서버에서 새로운 데이터를 fetch해서 웹 페이지의 일부를 업데이트할 수도 있을 겁니다. 이 때 필요한 Web API들을 우리는 Document Object Model(DOM)이라고 합니다.

웹 페이지에 필요한 API인 DOM은 또한, HTML의 계층적 구조를 나타내는 개념이기도 합니다. 어떤 웹 페이지가 로드될 때, 우리의 웹 브라우저는 해당 페이지에 대한 하나의 DOM을 생성합니다. 그리고 그 최상단, 즉 html의 상위 개념이 바로 document입니다. DOM과 자바스크립트를 이용해 우리는 html document의 모든 속성들을 조작하여 컨텐츠들을 동적으로 바꿀 수 있는 것이죠. 그림에는 나오지 않았지만, DOM의 최상단의 개념은 해당 웹 페이지의 창을 의미하는 window입니다. DOM은 하나의 페이지에 대한 모든 인터페이스를 아우리는 가장 큰 총체적인 모델인 것이죠.

오른쪽의 코드는 DOM을 사용한 예시입니다. 어떤 <p> 요소의 id를 demo라고 하였는데요. 이후에 보면 document.domain 코드를 통해 이 페이지의 도메인을 가져오며 이후에 document.getElementById("demo").innerHTML 코드를 통해 demo라는 요소의 HTML을 변경하기도 합니다. 그리고 보시면 알겠지만, 이 myFunction()이라는 함수는 위에서 버튼을 클릭하면 호출되도록 이벤트를 달아 놓았지요. 그래서 이렇듯 우리는 document.(function name)을 통해 DOM을 사용하는 것을 확인할 수 있습니다.

DOM의 구조를 더 확인해볼가요? HTML document로 어떤 웹 페이지를 디자인한 예시입니다. 가장 큰 window라는 개념 아래, document가 있을 수 있습니다. 또한 여러 document를 포함하고 있는 여러 frame들로 나누어질수도 있는 거지요.

이제 다시, HTTP로 돌아오자면 HTTP는 Client에서 HTTP request, 즉 어떤 요청을 보내면 Server에서 그에 대해 HTTP response를 보내는 간단한 형식으로 이루어집니다.

그림의 위는 HTTP request에서 GET 메서드의 사용 예시를 나타내며, 아래는 이에 대한 HTTP response의 header(헤더)를 나타낸 것입니다. 각각의 필드가 무엇을 의미하는 지는 생략하겠습니다. 다만, 알아야 할 것은 헤더와 실제 데이터는 의외로 간단하게 두 번의 개행으로 구분된다는 점입니다.

profile
백엔드 개발자

0개의 댓글