시큐어 코딩(Secure Coding) 1. SQL injection(SQL 삽입공격)

    SQL Injection는, OWSAP에서 매번 발표했을 때, 가장 위협적이고 가장 쉬운 방법이라고 거론이 될 정도로 어찌보면 기본이며, 꼭 알아야 할 해킹 기술이다. Injection은 주입이라는 뜻으로, 즉 직독하자면 SQL 언어를 외부에서 주입하여 해킹을 하는 기법을 뜻한다.


    외부는 일반적으로 웹(Web)을 뜻하며, 아이디를 입력하는 란이라든지 뭔가 정보를 주고 받는 곳에서 예상치 못한 공격으로 사이트를 마비 시키거나, 데이터를 훔치거나 관리자 정보나 기타 유저들의 정보를 훔쳐볼 수 있다.



    SQL Injection은 OWASP에 꾸준히 1위를 유지하고 있으며, 최근 발표한 2017년 버전에도 여전히 1위를 지키고 있을 정도로 관심은 여전하다.


    - SQL Injection 외에도 허술한 인증 관리와 XSS는 늘 TOP 3를 지키고 있다.






    1. SQL Injection의 개념

    - 웹 어플리케이션에서 입력값에 대한 유효성 검증을 하지 않을 경우, 공격자가 입력 폼 및 파라미터에 쿼리문을 조작하여 정보를 열람하거나 데이터를 조작하는 해킹 기술

    - DB에서 전달되는 SQL Query를 변경시키기 위해 Web Application에서 입력 받은 파라미터를 변조 후 삽입하여 비정상적인 데이터베이스 접근을 시도하거나 재구성하여 원하는 정보를 열람하는 해킹 기법



    2. SQL Injection의 특징

    • DB에 악성코드를 대량으로 삽입
    • POST나 HTTP Header를 이용한 경우는 로그를 찾기 어려움
    • 해킹 기법이 매우 간단하여 누구나 사용 가능
    • 해킹 기법에 비해, 효과가 매우 높고 위협적임


    3. SQL  Injection의 공격 흐름도

    - 공격자는 웹페이지에서 쿼리를 입력란에 삽입하여, DB에 직접 쿼리를 조작



    4. SQL Injection에 걸리기 쉬운 소스 코드 구조 및 보안 코딩

    가. SQL Injection에 걸리기 쉬운 소스 코드 구조

    1
    2
    3
    4
    5
    6
    7
    String query = "SELECT account_balance FROM user_data WHERE user_name = "
       + request.getParameter("customerName");
     
     try {
         Statement statement = connection.createStatement( … );
         ResultSet results = statement.executeQuery( query );
     }
    cs


    위 소스에서 보다시피, 리퀘스트 값을 검증 없이 단순히 쿼리에 넣을 경우 발생함



    나. SQL Injection을 방지하기 위한 보안 코딩

    1
    2
    3
    4
    5
    6
    7
     String custname = request.getParameter("customerName"); 
     String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
     
     PreparedStatement pstmt = connection.prepareStatement( query );
     pstmt.setString( 1, custname); 
     ResultSet results = pstmt.executeQuery( );
    cs


    Statement 대신, PreparedStatement같이 안전한 구문을 사용한 보안코딩 사용.


    다. SQL Injection을 방지하기 위한 Replace 구문 사용

    1
    2
    3
    4
    5
    6
    7
    8
    String customerName = request.getParameter("customerName");
    String query = "SELECT account_balance FROM user_data WHERE user_name = "
       + customerName.replaceAll("'""");
     
     try {
         Statement statement = connection.createStatement( … );
         ResultSet results = statement.executeQuery( query );
     }
    cs


    statement구문을 사용시에는 꼭 컬럼값에 Injection을 유발할 수 있는 '(외따옴표) ;(세미콜론) 같은 DB에서 사용하는 특수문자 값을 제거하여 보안성 강화


    그외 자세한 공격에 대한 대응기법은 

    https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet 참조



    5. 그외 SQL Injection을 방지하기 위한 노력

    • 불필요한 권한은 삭제하여, Drop Table같은 공격을 미연에 방지 필요
    • Mybatis같은 프레임워크 사용시, 별도의 보안 코딩 기법 확인 필요
    • 웹페이지에서 직접 SQL Injection 공격을 시도하여, 빠진 부분이 있는지 체크 필요
    • Replace같은 경우, 자바스크립트에서만 처리하지 말고, Backend 단에서도 처리 해야 함(URL로 변조 가능)


    댓글

    Designed by JB FACTORY