mini-pms 37 b

1 minute read

37-b. 데이터 관리를 DBMS에게 맡기기 : SQL 삽입 공격과 자바 시큐어 코딩

SQL 삽입 공격

  • 사용자의 입력 값으로 SQL 문을 만들 때 가능한 공격 방법이다.
  • 값을 입력할 때 SQL 문에 영향을 끼치는 SQL 코드를 함께 삽입하는 방법이다.
  • 예)
    • SQL 문: ‘select * from uwer where username=’아이디’ and password=’암호’’
      • 아이디: ‘hongkildong’
      • 암호: ok’ or 1=1 –
    • 입력값이 포함된 최종 SQL 문
      • 입력값이 포함된 최종 SQL 문
      • ‘select * from user where username=’hongkildong’ and password=’ok’ or 1=1 –’’
        • 1=1 조건은 무조건 참이므로 username과 password가 일치하지 않더라도 상관없이 결과는 true이다.
        • –은 줄 끝까지 주석으로 취급하기 때문에 sql문의 끝에 있던 작은 따옴표를 제거하는 효과가 있다.
      • 해결 방법
        • ‘statement’ 대신에 ‘preparedStatement’를 사용하면 된다.

statement vs preparedStatement

  • SQL 삽입 공격
    • statment : 가능
    • preparedStatement : 불가능
  • 바이너리 컬럼(이진 컬럼) 값 넣기(http://www.mysqlkorea.com/sub.html?mcode=develop&scode=01&m_no=21689&cat1=11&cat2=334&cat3=347&lang=k)
    • statment : 가능
    • preparedStatement : 불가능
  • 코드의 간결함
    • statment : 가독성이 떨어진다. String.format()으로 개선할 수 있다.
    • preparedStatement : in-parameter 문법으로 SQL 문과 값을 분리하기 때문에 가독성이 좋다.
  • 실행 속도
    • statment
      • SQL을 실행할 때마다 DBMS는 매번 SQL 구문 분석 -> 최적화 -> 실행 과정을 거친다.
    • preparedStatement
      • 처음 SQL을 실행할 때 딱 한번 SQL 구문 분석 -> 최적화 -> 실행 과정을 거친다.
      • 이후에는 내부 SQL 공유 풀에 보관된 최적화된 실행 계획을 바로 실행한다.
      • 따라서 SQL을 준비한 후 반복하여 실행하는 경우에는 Statement 보다 빠르다.

SQL 싫행 과정

  • SQL 구문 분석(Parsing)
    • 문법의 유효성 검사(Syntax check)
      • 문법의 규칙을 준수하는지 검사한다.
    • SQL 문의 의미 검사(Semantic check)
      • SQL 문에서 지정하는 컬럼이나 테이블, 뷰 등이 유효한지 검사한다.
    • SQL 공유 풀 검사
      • 공유 풀은 SQL 문에 대해 생성된 실행 계획 등을 보관한다.
      • 먼저 SQL 문에 대해 해시 연산을 수행하여 SQL ID를 생성한다.
      • 공유 풀에 저장된 값 중에서 SQL ID와 일치하는 값이 있는지 조사한다.
      • 만약 있다면 즉시 해당 값을 꺼내 실행 계획에 따라 SQL 문을 실행한다.
      • 없다면 하드파싱(hard parsing) 이라는 과정을 수행한다.
        • Hard Parsing
          • SQL 최적화(Optimization)
            • SQL 문을 가장 효율적으로 실행할 수 있게 재구성한다.
            • 각 문장 별로 실행 계획이라는 명령 코드를 생성한다.
            • 여러 개의 실행 계획을 검토한 후 실행 비용을 계산하여 최적의 실행 계획을 생성한다.
          • SQL 컴파일
            • 최적화 단계에서 생성된 실행 계획을 입력으로 받는다.
            • 각 실행 단계 별로 결과 데이터(result set)를 리턴할 바이너리 명령을 생성한다.
            • 이 바이너리 명령을 row source라고 부른다.
            • 로우 소스는 테이블이나 뷰, 조인 또는 그룹 연산을 가리킨다.
            • 로우 소스 제너레이터는 실행 순서에 따라 로우 소스 트리를 생성한다.
          • SQL 실행
            • SQL 엔진은 로우 소스 트리에 따라가면서 로우 소스 바이너리 명령을 실행한다.
            • 각 로우 소스 바이너리 명령은 테이블이나 뷰, 조인 또는 그룹 연산 결과를 생성한다.
            • 최종 실행 결과는 애플리케이션에게 리턴할 결과 테이터이다.

Categories:

Updated: