병합정렬(Merge Sort)

나누는 부분인 mergesort()와
나눈 부분을 정렬을 하면서 합치는 merge()로 구분할 수 있다.
중간 중간 정렬된 원소들이 들어갈 임시 배열 sorted를 선언해줘야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
int arr[10];
int sorted[10];

mergesort(int arr[], int left, int right){
// left가 right보다 작으면 계속 반씩 나눠준다. 크다면 아무런 동작도 하지 않고 빠져 나와 재귀함수의 merge부분으로 들어간다.
if(left < right) {
int mid = (left+right)/2;

mergesort(arr, left, mid);
mergesort(arr, mid+1, right);
merge(arr, left, mid, right); // 반씩 나눈 부분을 합친다.
}
}

merge(int arr[], int left, int mid, int right){
int i = left, j = mid+1, k = left;
// 나눈 부분을 합친다
while(i <= mid && j <= right) {
if(arr[i] < arr[j]) {
sorted[k] = arr[i];
i++;
} else {
sorted[k] = arr[j];
j++;
}
k++;
}
// 왼쪽 부분이 먼저 끝날수도, 오른쪽 부분이 먼저 끝날수도 있기 때문에 남아있는 원소를 넣어준다.
if(i > mid) {
for(; j <= right; j++) {
sorted[k] = arr[j];
k++;
}
} else {
for(; i <= mid; i++) {
sorted[k] = arr[i];
k++;
}
}
// 최종적으로 sorted배열에 있는 원소를 실제 배열인 arr로 옮겨준다
for(int m = left; m <= right; m++) {
arr[m] = sorted[m];
}
}

시간복잡도는 평균적인 경우나 최악의 경우에도 O(NlogN)을 보장한다.
왜냐면 원소들의 순서가 어떻든, 퀵소트처럼 이미 정렬이 됬든 안됬든, 무조건 낱개가 될때까지 반씩 나눈 다음에
낱개가 된 원소들끼리 합치면서 정렬을 하기 때문이다.
이미 공부를 했던 정렬인데 영상을 참고하면서 따라했다.
언제나 개념은 알고있지만 실제로 코드로 옮기는 부분에 있어서 문제가 많다.
Keep Going

Comment and share

리뷰라기 보다는 책을 읽고 내용이 머릿속에 잘 안 남는 것 같아 이렇게라도 따로 내용정리를 해둘려고 한다.
책의 내용을 그대로 쓴 것이 대부분이고 중간중간 나의 생각을 짧게 곁들일 것이다.
개발자라는 직업을 선택한 이상 또한 이 시대를 살아가는 현대인인 이상
매일 매일 새로운 것들을 배워야 하고 그 배움의 과정을 보다 효율적으로 할 수 없을까라는 궁금증을 풀어줄 수 있었다
배워야 한다는 사실에 스트레스 받지 않고 배움 자체를 즐기다보면 어느 순간 꼭대기에 올라가 있지 않을까

실용주의 사고와 학습

  • 바람직한 어려움: 학습할 때 오히려 어려운 것들이 학생에게 더 이득이 되는 경우가 많다
  • 학생들의 수업 만족도가 높은(잘 배웠다고 생각이 드는) 수업이 오히려 학생에게 해가 되는 경우가 있다
  • 앞으로 의사소통 기술, 배우고 생각하는 기술이 중요
  • 우리는 교사와 학생의 관계를 착각하는 경우가 많다. 학습은 교사가 가르치는게 아니라 학생이 배우는 것이다
  • 삶에 있어서 고정불변인 것은 아무것도 없다. 오직 죽은 물고기만이 흐름을 따라간다
  • 인간의 사고(인지)에는 내재된 편견이 있다
    _ 지금 내가 떠오르는 생각이 정답이 아닐 수 있다
    _ 인간의 생각은 단순한 사실 하나에도 영향을 받는다. 신입사원 면접을 보는 층으로 올라가기 위해 엘리베이터 안에서 마시는 커피가 아이스냐 핫이냐에 따라 그 면접관의 편향은 달라지는 것처럼..

드라이퍼스 모델

  • 초보자는 규칙을 활용하고 전문가는 직관을 활용하라
  • 초보자에서 전문가로 가는 과정에 동반되는 것
    _ 규칙에 의지 -> 직관에 의존
    _ 관찰자 -> 시스템의 일부(시스템적 사고)
  • 사려 깊은 연습(말콤 글래드웰이 아웃라이어에서 말한 10년의 법칙, 칙센트미하이가 말한 ‘FLOW’ 상태에도 들어갈 수 있는 작업이니 이 얼마나 좋은 것인가..)
    _ 작업은 적당히 어려워야된다. 도전적이지만 할 수 있는 수준
    _ 피드백을 적극적으로 받을 수 있는 환경
    _ 반복하면서 잘못을 교정할 기회
  • 근무 환경에 모범이 될 만한 사람에게 배우기 -> 학교든 회사든 나만의 멘토를 정해 마음 속으로 정해서 따라해야겠다!

두 개의 CPU 모드

  • 우리의 뇌는 두 개의 모드로 구성(L모드, R모드)
  • L모드: 선형적, 논리적, 언어처리
  • R모드: 직관, 문제해결, 창조성
  • 두 가지 모두 필요
  • R모드는 예측할 수 없기 때문에 늘 R모드가 주는 해답이나 통찰력을 대비해야 한다
    _ 어떤 아이디어가 떠오르면 바로 잡을 수 있도록 24시간 준비되있어야 한다
    _ 좋은 아이디어는 누구나 갖고 있으나 아주 일부만이 그 아이디어를 기록하는 수고를 한다
    _ 그 중에 아주 일부만이 아이디어를 실천한다
    _ 그 중에 아주 일부만이 아이디어를 성공시킨다
    _ 최소한 기록이라도 해둬야지 윗 단계의 가능성이 열리므로 아이폰의 메모장을 잘 활용해서 늘 기록하자!
  • 컴퓨터는 쓸모없다. 컴퓨터는 오로지 답을 줄 뿐이다 - 파블로 피카소

  • 질문이 더 중요하다는 얘기(R모드의 중요성)
  • 상품화란 심미성을 겨루는 것이다. 좋은 디자인을 위해 노력하자 (ex: 마이크로소프트가 아이폰을 만든다면? 포장박스부터 덕지덕지 문구..)
  • 연구 결과: 매력적인 사용자가 인터페이스가 못 생긴 인터페이스보다 더 사용하기 쉽다
  • 뇌의 가소성: 가능성을 믿는한 뇌의 상한은 존재하지 않는다
    _ Impossible is nothing
    _ 생각하는 대로 된다
    _ 용불용설
    _ 외국어를 배우고 싶다? 늘 그언어로 말하고 생각
    • 코딩을 잘하고 싶다? 코딩을 더해라..
  • 지각력 있는 뇌의 R모드에 접근하려면 언어적이고 분석적인 L모드를 꺼버릴 만한 일을 주어야 한다 (음악 듣기, 그림 그리기, 명상, 조깅 등등)
    _ 요즘 공부를 하면서 재즈를 들으면서 하고 있는데 이게 생각 외로 큰 도움이 되는 것 같다
    _ 뒤늦게 공부를 시작한 나로선 공부에 대한 압박감이 있는데 공부라는 것이 L모드와 R모드가 조합이 되어야 한다면 무조건적으로 시간을 많이 투자해 앉아서 책읽기같은 전통적인 공부 방법에 치중해서는 안된다
    _ 때로는 공부/코딩 이외의 활동을 하면서 일부로 공부와 전혀 상관없는 활동을 해야된다는 말이고 넓게 보면 모든 일은 한번씩 해봄으로써 새로운 경험이 될 것이다
    _ 나에겐 웨이트를 꾸준히 하는 것이 그 예
    _ 어려운 문제를 풀려면 키보드에서 떨어져라
  • 변화는 좋은 것이다
    _ 깊이 물든 습관은 뇌에 좋지 않음
    _ 뇌는 적응해야하는 것이 없다면 축 늘어지게 됨
    _ 일상적으로 하는 작은 행동에도 변화를 줘보자(양치를 할 때 왼손으로 하기 등)

당신의 마음을 디버그하라

  • 상관 관계 VS 인과 관계
    _ 단순한 상관 관계를 원인과 결과로 오해하기 쉽다
    _ 두 변수가 연관되어 있다는 것이 꼭 어느 한 쪽이 다른 쪽의 원인이라는 것은 아니다
  • 기억보다 글로 쓴 것을 신뢰하라. 기억은 모두 읽기와 쓰기가 함께 일어난다
  • 여러분이 무엇인가를 엄청나게 확실하고 있을 때 자신에게 왜냐고 물어보자
    _ 어떻게 알았는가?
    _ 누가 말한 것인가?
    _ 구체적으로 어떠한가?
    _ 내가 하고 있는 일이 당신에게는 어떤 영향을 주는가?
    _ 무엇이랑 비교하면? 혹은 누구랑 비교하면?
    _ 항상 일어나는가? 예외는 없는가?
    _ 당신이 했다면 어땠겠는가?
    _ 무엇때문에 못하는가?
    _ 언론들도 왜곡 보도를 하고 가짜 뉴스가 판 치는 세상에서 인터넷에서 단순히 어떤 사실을 봤다고 믿지 말자. 진정한 정보를 가려내는 능력을 길러야 한다

의도적으로 배우라

  • 현재의 기술과 문화에서 배우는 능력은 성공에 있어 가장 중요한 요소
  • 교육(education)이란 단어는 라틴어 educare에서 온 단어인데 ‘끄집어낸다’라는 의미.
  • 학습은 누군가가 여러분에게 해주는 것이 아니다. 여러분이 하는 것이다.
  • 지식을 경험없이 그 자체로만 습득하는 것은 효과적이지 않다 -> 목적없이 책읽기?
  • 목표와 피드백 없이 무작위로 접근하게 되면 무작위적인 결과를 낳는다
  • SMART한 목표 설정
    _ Specific(구체적인)
    _ Measurable(측정 가능한)
    _ Achievable(달성 가능한)
    _ Relavant(의미 있는)
    _ Time-Boxed(시간 제한이 있는)
  • 계획하기는 계획 그 자체보다 중요하다 - 아이젠하워

  • 독서할 때의 의식적인 SQ3R 학습법
    _ Survey(훑어보기): 목차를 보면서 훑어보며 전체적인 개요 파악
    _ Question(질문): 생각나는 질문들을 적어놓기
    _ Read(읽기)
    _ Recite(낭송): 요약하고 메모하고 스스로 표현해보기
    _ Review(복습): 다시 읽고 메모를 확장하고 동료와 토론
  • 마인드맵
  • 타이핑보다는 손글씨
  • 가르치며 배우기 -> 러버덕디버깅

경험 축적

  • 배우기 위해 놀기 -> 그 언어를 공부하고 그 라이브러리를 공부하기 전에 일단 그 언어로 뭐라도 만들어보자. Learning by Coding
  • 압박은 인지를 죽인다
    _ 촉박한 마감이 닥쳐야 가장 효과적인 것은 L모드에 일정 부분 유효하지만 R모드에서는 그렇지 않다
    • 시간 압박은 후유증까지 남긴다. 벼락치기는 이틀 정도는 축 처지게 됨
  • 뇌는 입력의 원천이 뭔지에 대해 속기 쉽기 때문에 성공을 상상하는 것은 그것을 달성하는데 확실히 효과적이다 -> 이미 한 것처럼 연기하기 / 이미지 트레이닝
  • 우리는 모방자다 -> 나보다 뛰어난 사람들 속에 있기

초점 관리하기

  • 정보가 넘쳐나는 시대에서 정보 과잉은 지식과 주의의 결핍을 만들었다
    _ 어쩌면 미래는 이러한 노이즈에 집중하지 않고 자신의 것을 묵묵히 꾸준히 하는 사람에 있지 않을까?
  • 명상의 이득: 명상을 할 때나 의식적으로 주의를 기울일 때뿐만 아니라 하루 종일 효과가 있다 -> 명상앱은 오늘부터 깔아서 자기 전에 10분이라도 해봐야겠다라는 생각을 했는데 앉아서 해야된다네..
  • 멀티태스킹을 하지 말자. 우리의 뇌는 컴퓨터와 달라서 Context Switching시 20분의 시간이 든다.
    _ 대마초를 피우는 것보다 계속 메일을 확인 하는 것이 우리의 아이큐를 더 떨어뜨린다고 한다
    _ 윈도우나 맥에서 알트탭, 커맨드탭으로 화면전환하는 것조차 단기기억과 에너지를 필요로 한다
    _ 더블 모니터를 쓰기만 해도 생산성이 30퍼센트 올라감

Comment and share

  1. 임계영역(Critical Section)
  • 다수의 프로세스가 접근 가능한 영역이면서 한 순간에 하나의 프로세스만 사용할 수 있는 영역
  • 어떤 프로세스가 임계영역에 들어가면 다른 프로세스는 임계영역으로의 진입이 금지되어야 한다
  • 프로세스/스레드 동기화를 함으로써 임계구역 문제를 해결하고 프로세스 실행 순서를 제어할 수 있다

  • 임계영역 문제 해결책

  • 상호배제(Mutual Exclusion): 한 프로세스가 임계영역에서 작업시 다른 프로세스는 접근 불가능
  • 진행(Progress): 임계영역에서 작업하는 프로세스가 없을 때 여러 프로세스가 임계영역에 진입하고자 한다면 알고리즘에 따라 프로세스 선정, 프로세스 선택을 무한정 미룰 수 없다
  • 제한된 대기(Bounded Waiting): 한 프로세스가 임계영역 진입을 요청한 후 수락되기 전까지 다른 프로세스가 진입할 수 있는 횟수를 제한
  • 동기화 도구: 세마포어, 모니터
  1. 세마포어(Semaphore)
  • 다익스트라가 제안
  • 구조: 정수형 변수 + 두 개의 동작(P, V)
  • 세마포어란 음이 아닌 정수값을 가지는 플래그 변수
  • 임계영역에 들어가기전에 P: acquire() 하고
  • 임계영역으로부터 나올 때 V: release() 한다
  • P와 V를 다음과 같이 정의한다
    1
    2
    3
    - P(S): while S <= 0 do no-op; // 세마포어 변수 S가 0이면 임계구역 진입 불가
    S = S - 1; // 세마포어 변수 S가 1이면 진입하여 0으로 만든 후 다른 프로세스 진입 못 하게 블락
    - V(S): S = S + 1; // 작업을 완료하고 나올 때 1을 더해줘 다른 프로세스가 진입 가능하게 만듬
  1. 모니터(Monitor)
  • 세마포어보다 고수준의 개념
  • 구조: 공유자원 + 공유자원 접근 함수
  • 2개의 queues: 배타동기 + 조건동기
  1. 교착상태(Deadlock)
  • 교착상태의 필요조건: 상호배타(Mutual Exclusion), 보유 및 대기(Hold and Wait), 비선점(No Preemption), 환형대기(Circular Wait)
  • 교착상태의 처리: 방지, 회피, 검출 및 복구, 무시
  • 실제 상황에서 교착상태는 잘 일어나지 않는다

Comment and share

3장. 프로세스, 스레드

  1. 프로세스
  • 프로세스: 메모리에 적재되서 현재 실행 중인 프로그램
  • 각 프로세스마다 코드, 데이터, BSS, 힙, 스택 등의 메모리 구조를 가짐
  • 프로세스는 운영체제 내에서 프로세스 제어 블록(PCB: Process Control Block)으로 표현됨
  • PCB에는 프로세스 식별자, 프로세스 상태, 프로그램 카운터, 레지스터 등이 저장된다
  • 문맥교환(Context Switching): 프로세스끼리 제어 상태 변화가 일어났을 때 발생 -> 오버헤드(Overhead) 발생
  • OS의 스케쥴링에 의해 프로세스 실행 순서 결정
  • 각각의 프로세스는 독립적이므로 한 프로세스가 비정상적으로 종료되도 다른 프로세스에 영향이 없다
  1. 스레드
  • 스레드: 하나의 프로세스 내에서 실행되는 여러 흐름의 단위
  • 각 스레드는 스택만 할당받고 코드, 데이터, 힙 등은 프로세스 내에서 공유한다
  • OS의 스케쥴러는 스레드를 최소 단위로 작업
  • 각각의 스레드는 프로세스와 달리 비정상적으로 종료되면 다른 스레드들도 종료된
  1. 기타
  • 일반적으로 새로운 프로세스가 생성되면 프로세스를 위한 스레드도 함께 생성된다
  • 프로세스의 생성/종료보다 스레드의 생성/종료의 오버헤드가 훨씬 적다
  • 트랩(Trap): 부적절한 파일접근이나 오류, 예외 상황때문에 발생 -> 소프트웨어적인 흐름의 변화 (인터럽트: 하드웨어적인 흐름의 변)

Comment and share

학교에 가기전 전공과목에 대해서 공부하고 있다. 중요한 과목들은 다 파악이 됬고
훑어보는 목적으로 각 과목에 대해서 알아보고자 한다. 강의는 경성대 양희재 교수님의 강의로 주로 공부를 하며
도서관에서 빌린 <운영체제 : 그림으로 배우는 원리와 구조>라는 책을 읽고 모자란 설명을 채울 생각이다.

1장과 2장은 서론같은 느낌이라서 한 포스트에 요약하겠다.

1장. 컴퓨터 시스템 소개

  1. 컴퓨터 시스템 구성요소

1) 프로세서

  • 중앙처리장치(CPU) : 레지스터, 산술논리연산장치(ALU), 제어장치

2) 버스

3) 레지스터

  • 프로그램 카운터(PC: Program Counter): 프로그램 수행을 제어하는 명령어 실행 순서 보관(다음에 실행할 명령어 주소 저장)
  • 명령어 레지스터(IR: Instrument Register): 현재 수행하는 명령어를 저장, 명령어의 연산자 부분만 저장한다.
  • 프로그램 상태 레지스터(PSR: Program Status Register): 플래그 같은 상태 정보 저장
  • 메모리 주소 레지스터(MAR: Memory Address Register): 접근하려는 메모리의 주소 저장
  • 메모리 버퍼 레지스터(MBR: Memory Buffer Register): 메모리에서 정보를 읽거나 저장할 때 사용

4) 메모리

  • 메모리의 지역성: 실행 중인 프로세서가 실행기간 동안 메모리 정보를 균일하게 접근하지 않고 일부만 집중적을 참조
  • 메모리 속도: 메모리 사이클 시간 & 메모리 접근 시간
  • 가상 메모리(Virtual Memory): 보조기억장치에 저장했다가 주기억장치에 필요할 때 실행
  • 메모리의 논리적 주소 -> 물리적 주소 : Memory Mapping (메모리 관리 장치 MMU: Memory Management Unit이 해줌)
  • 캐시(Cache): 처리 속도가 빠른 프로세서와 상대적으로 느린 주기억장치 사이에서 데이터를 저장하여 속도 차이를 줄여줌. 주기억장치
    에서 일정 블록의 데이터를 가져와 워드(Word) 단위로 프로세서에 전달
  • 프로세서는 주기억장치 접근이 필요하면 먼저 캐시를 조사
  • 캐시 태그와 원하는 메모리 주소 태그가 일치하면 캐시 적중(Cache Hit)라 한다 <-> 캐시 실패(Cache Miss)

5) 주변장치

  • 키보드, 마우스 등
  1. 컴퓨터 시스템의 동작

1) 명령어 구성

  • 실행할 연산을 나타내는 연산 코드(Operation Code) & 처리할 데이터가 저장된 주소를 나타내는 오퍼랜드(Operand)로 이루어짐
  • 직접 주소와 간접 주소

2) 인터럽트

  • 인터럽트를 받은 프로그램은 실행을 멈추고 다른 프로그램을 실행한다
  • 입출력장치가 새로운 입출력 연산을 수행하려고 하면 프로세서는 폴링(Polling)을 통해 각 장치의 상태 비트 검사 (폴링 방식)
  • 인터럽트가 발생했을 때 프로세서에게 알려줌. 버스 중 인터럽트 요청 회선(IRQ: Interrupt Request Line)이 이런 용도로 쓰임(인터럽트 방식)

2장. 운영체제 소개

  1. 운영체제의 기능
  • 버퍼링과 스풀링 모두 입출력장치의 느린 속도를 보완하기 위해 이용하고 프로세서와 입출력장치를 항상 분주하게, 유휴 시간이 없게 만듬
  • 버퍼링(Buffering): 주기억장치(보통 캐시메모리)를 버퍼로 사용
  • 스풀링(Spooling): 보조기억장치(하드디스크)를 버퍼로 사용

Comment and share

CSRF란 무엇인가?

1
2
CSRF(Cross Stie Request Forgery) : 사이트간 요청 위조
웹 애플리케이션 취약점 중 하나로 사용자가 자신의 의지와 무관하게 공격자가 의도한 행동을 하여 특정 웹페이지를 보안에 취약하게 한다거나 수정, 삭제 등의 작업을 하게 만드는 공격방법을 의미한다 - 나무위키

정의만 보면 앞서 알아봤던 XSSSQL injection과 비슷하다.
XSS가 사용자가 특정 사이트를 신뢰한다는 점을 공격하는거라면, CSRF는 특정 사이트가 사용자의 브라우저를 신뢰한다는 점을 공격하는 것이 다르다.

간단하게 정리하자면, 악성코드가
XSS: 클라이언트에서 발생 / CSRF: 서버에서 발생
이라고 할 수 있다.

2008년도에 있었던 옥션 해킹 사고도 CSRF로 공격을 했다고 한다. (해커가 옥션 운영자에게 CSRF 코드가 포함된 이메일을 보내서 관리자 권한을 얻어냈다)

공격 과정

1
2
3
...
<img src="http://auction.com/changeUserAcoount?id=admin&password=admin" width="0" height="0">
...

위 옥션 사건을 예로 들어보자.

  1. 옥션 관리자 중 한명이 관리 권한을 가지고 회사내에서 작업을 하던 중 메일을 조회한다. (로그인이 이미 되어있다고 가정하면 관리자로서의 유효한 쿠키를 갖고있음)
  2. 해커는 위와 같이 태그가 들어간 코드가 담긴 이메일을 보낸다. 관리자는 이미지 크기가 0이므로 전혀 알지 못한다.
  3. 피해자가 이메일을 열어볼 때, 이미지 파일을 받아오기 위해 URL이 열린다.
  4. 해커가 원하는 대로 관리자의 계정이 id와 pw 모두 admin인 계정으로 변경된다.

방어 방법

1. Referrer 검증

request header에 있는 요청을 한 페이지의 정보가 담긴 referrer 속성을 검증하여 차단.
일반적으로 이 방법만으로도 대부분 방어가 가능할 수 있다.
옥션이 아닌 개인 이메일에서 요청이 들어오는 것처럼,
같은 도메인 상에서 요청이 들어오지 않는다면 차단하도록 하는 것이다.

2. CSRF Token 사용

랜덤한 수를 사용자의 세션에 저장하여 사용자의 모든 요청(Request)에 대하여 서버단에서 검증하는 방법.

1
2
3
4
5
// 로그인시, 또는 작업화면 요청시 CSRF 토큰을 생성하여 세션에 저장한다. 
session.setAttribute("CSRF_TOKEN",UUID.randomUUID().toString());

// 요청 페이지에 CSRF 토큰을 셋팅하여 전송한다
<input type="hidden" name="_csrf" value="${CSRF_TOKEN}" />

3. CAPTCHA 사용

요즘은 거의 모든 웹사이트에서 캡차를 이용하는 것 같은데 캡차이미지상의 숫자/문자가 아니라면 해당 요청을 거부하는 것이다.

이 외에도 form 태그를 입력할 시 GET방식을 지양하고 POST방식을 쓰도록 하는 것은 기본이라고 할 수 있다.


출처 : 나무위키, 위키피디아,
http://blog.ilkyu.kr/entry/CSRF-Crosssite-Request-Forgery-%EC%82%AC%EC%9D%B4%ED%8A%B8-%EA%B0%84-%EC%9A%94%EC%B2%AD-%EC%9C%84%EC%A1%B0,
http://itstory.tk/entry/CSRF-공격이란-그리고-CSRF-방어-방법

Comment and share

XSS와 더불어 가장 흔한 보안 공격 기술인 SQL injection에 대해서 알아보았다.

SQL injection 이란?

1
SQL 인젝션은 코드 인젝션의 한 기법으로 클라이언트의 입력값을 조작하여 서버의 데이터베이스를 공격할 수 있는 공격방식을 말한다. - 나무위키

데이터베이스 조작언어인 SQL 입력값에 정상적인 값이 아닌 SQL문을 삽입해 데이터베이스에 해를 가하는 공격이라고 할 수 있다.

예를 들어, 로그인을 하는 코드가 있다고 하자.

1
SELECT user FROM user_table WHERE id='입력한 아이디' AND password='입력한 비밀번호';

위와 같이 SQL문을 짜서 데이터베이스에 존재하는 user_table 테이블에서 입력한 id와 입력한 password와 동일한 값을 찾아 반환해주는 코드이다.

일반적인 유저라면

id = 홍길동
password = 1234

이런식으로 입력을 하겠지만

SQl injection을 할 유저는

id = 홍길동
password = 1234’; DROP table user_table–

이런식으로 입력을 하게 된다.

그렇게 되면 전체 SQL 구문은 이렇게 되어버린다.

1
2
SELECT user FROM user_table 
WHERE id='홍길동' AND password='1234'; DROP TABLE user_table--';

SQL에서 ;(세미콜론)은 한 구문의 끝을 나타내므로 위 구문은

1
SELECT user FROM user_table WHERE id='홍길동' AND password='1234'
1
DROP TABLE user_table--'

이렇게 2개의 구문으로 나눠져 실행되게 된다.

–(하이픈 2개) 다음으로 오는 문장은 주석 처리가 되므로,
결국 DROP 명령어에 의해 해당 table은 DB에서 지워지게 된다.

이 외에도 로그인을 무조건 성공하게 하는
‘ OR ‘1’ = ‘1 (1은 1과 같으니 WHERE절은 무조건 참이 되어 아이디 또는 비밀번호가 무엇이든 로그인 성공)
등 수많은 케이스가 있다.


방어 방법

1. 입력값 검증

다음과 같은 특수문자 혹은 SQL 명렁문이 입력값에 포함되있는지 검증한 후 차단한다.

1
2
3
*, –, ‘, “, ?, #, (, ), ;, @, =, *, +, union, select, drop, update, from, 
where, join, substr, user_tables, user_table_columns,
information_schema, sysobject, table_schema, declare, dual,…

유저가 클라이언트단에서 자바스크립트를 끌 수 있으니
클라이언트 단에서도 차단 및 서버 단에서도 차단하여 이중장치를 마련하자.
대부분의 경우, 입력값 검증만 해도 막을 수 있다.

2. SQL 오류 발생시 오류 메세지 클라이언트 표시 금지

SQL 오류 메세지를 통하여 유저가 해당 DB의 구조를 알 수 있다.

3. HASH 사용

DB에 데이터 저장시 민감한 정보는 HASH를 이용해 저장한다.
특히 패스워드는 반드시 SHA-256 이상으로 해싱 후 저장! (하지 않을시 개인정보보호법 29조 위반이라고 한다..)


출처 : 나무위키, http://blog.plura.io/?p=6056, https://docs.microsoft.com/ko-kr/sql/relational-databases/security/sql-injection?view=sql-server-2017, http://asfirstalways.tistory.com/360, http://brownbears.tistory.com/59

Comment and share

웹 개발자로서 기본적으로 알아야할 지식에 대해서 포스팅을 하려고 한다.
그 중 기초적인 보안 기술 중 XSS에 대해서 알아보자.

XSS(Cross Site Scripting)이란?

SQL injection과 함께 웹 상에서 가장 기초적인 취약점 공격 방법의 일종으로,
악의적인 사용자가 공격하려는 사이트에 스크립트를 넣는 기법을 말한다.
공격에 성공하면 사이트에 접속한 사용자는 삽입된 코드를 실행하게 되며,
보통 의도치 않은 행동을 수행시키거나 쿠키나 세션 토큰 등의 민감한 정보를 탈취한다. - 나무위키

웹페이지 내에 악의적인 자바스크립트 코드를 심어넣는 방법으로 공격한다.
예전부터 쓰이는 간단하고 전통적인 공격 방법이지만 많은 사이트들이 이 간단한 공격에 대비를 하지 않아 공격을 받는 경우가 많다.

공격/방어방식 라는 면에서 XSS(자바스크립트 이용해 공격)와 SQL Injection(쿼리를 통해 공격)은 서로 비슷하다고 볼 수 있다.

공격의 방법

  1. 스크립트 태그 안에 심기

    1
    <script>alert(document.cookie)</script>
  2. 서버 응답 결과에 심기

    1
    htt://www.server.com/search/?q=<script>(document.cookie)</script>&xyz
  3. 링크 또는 이미지에 심기

피해 종류

  1. 쿠키 정보/세션 ID 획득
  2. 시스템 관리자 권한 획득
  3. 악성코드 다운로드

예방 방법

1. 태그 문자 무효화

기본적으로 HTML 태그 안에 심어놓는걸 방지.(‘<’. ‘>’) 등의 태그를
서버에서 브라우저로 전송시 다음과 같은 문자로 인코딩해 전송한다.

2. 라이브러리 이용

일일이 개발자가 위와 같이 인코딩하는 것은 무리가 있다.
유명한 라이브러리를 이용하면 손쉽게 처리가 가능하다.
다음과 같은 라이브러리들이 있다.

  • AntiXSS(MS에서 개발)
  • OWASP ESAPI(validator:입력값 필터링, encoder:출력값 인코딩/디코딩)
  • NAVER Lucy XSS filter

3. 쿠키 보안 옵션 이용

쿠키 생성시
‘보안 쿠키’ 파라미터 지정시 TLS 상에서만 사용하게 할 수 있다.
‘HTTP ONLY’ 파라미터 지정시 웹브라우저상에서만 사용하게 할 수 있다.
완전히 방어 가능한 건 아니라고 한다.


출처: 나무위키, 한국인터넷진흥원

Comment and share

클래스의 static method는 정적 메소드라고 불리는데 이는 클래스의 인스턴스가 필요없이 호출이 가능한 메소드를 말한다.

예를 들어,

class Foo {
    bar() {...}

    static baz() {...}
}

라는 코드가 있을때 bar()는

const f = new Foo()
f.bar() 

위 예시처럼 f라는 Foo의 인스턴스를 선언을 하고 그 인스턴스에서 호출을 해야하지만

baz()는

Foo.baz()

위 예시처럼 클래스 Foo에서 바로 호출이 가능하다.
Foo의 인스턴스를 선언하지 않고도 메소드를 호출이 가능하다는 것이다.

용어의 반대 관계는 아래와 같다.

static method != instance method

Comment and share

개발자로서의 첫 걸음에 앞서 블로그를 시작한다.

이 블로그는 주로 내가 학습한 개발과 관련된 내용들이 주를 이룰 것이지만

비단 개발 분야만이 아니라 좀 더 멋진 미래를 위해 하루하루 발전해나가는 내 모습을 기록할 것이다.

평소 뭔가 기록을 남겨서 머릿속에 있는 생각이든, 공부한 내용이든 정리할 필요성을 느끼고 있었고

특히나 개발자로서 블로그 운영의 중요성을 보면서

당장 시작해야겠다는 생각이 들었다. 군생활도 얼마 안남은 김에 어제밤에 Hexo로 정적 사이트 생성기로 만들어봤다.

이거 하나 만드는 데에도 굉장히 시간이 많이 걸렸는데 만드면서도 그 뭔가 모를 재미를 느꼈었다.

아마 이 감정(Craftmanship라나 뭐라더나) 때문에 수 많은 개발자들이 개발을 시작했고 또 즐기는 이유일 것이다.

블로그 제목(Jinco the Snorkel)은 요즘 하고 있는 것 중 동기들과 하고있는 스노클이라는 조직에서 내가 많은 영향을 받았고

인생의 전환기에서 “항상 스노클의 정체성을 기억하자” 라는 의미를 담았다.

나를 본격적으로 개발자의 길로 이끌었던 마르코님을 보면서

자기만의 브랜드가 중요한 시대라고 느꼈다. 아마 15년 말부터 마르코님의 브런치 글을 읽기 시작했는데

초기부터 글을 읽어온 독자로서 3년 동안 마르코님은 엄청나게 성장하신 것 같다.

아마 그 이유는 여러가지가 있었겠지만 개발이든 사업구상이든 독서든 브런치 글 발행이든

무엇인가를 꾸준하게 하는 것에 있을 것이다.

이제 마르코라는 이름은 <비전공 문과 출신 개발자>라는 분야에서 어느 정도 브랜드화 되지 않았나싶다.

마르코님은 날 모르시겠지만 개인적으로도 나의 롤모델이라고 생각하고 있다.

이 블로그를 통해 비록 지금은 내세울 것 하나 없는 사람이지만 마르코님처럼 나만의 브랜드를 쌓아나갈 것이다.

또, 개인적으로 논리력이 많이 부족하다고 생각하는데 글을 쓰면서 논리력과 타인에게 나를 표현할 수 있는 자기표현력도 많이 향상되었으면 좋겠다.

Comment and share

  • page 1 of 1
Author's picture

Jin Seon

Aspiring developer who’s dreaming about freedom


Developer


Seoul