jinsusong / CS-Study

CS
3 stars 5 forks source link

SQL Injection이 무엇인지 설명하고 SQL Injection을 방어 및 방지하기 위한 방법에 대해 알고 있다면 설명하세요 #81

Open jinsusong opened 1 year ago

anuu0916 commented 1 year ago

SQL Injection SQL Injection 이란 악의적인 사용자가 보안상의 취약점을 이용하여, 임의의 SQL 문을 주입하고 실행되게 하여 데이터베이스가 비정상적인 동작을 하도록 조작하는 행위 입니다.

image 위의 사진에서 보이는 쿼리문은 일반적으로 로그인 시 많이 사용되는 SQL 구문입니다. 해당 구문에서 입력값에 대한 검증이 없음을 확인하고, 악의적인 사용자가 임의의 SQL 구문을 주입하였습니다. 주입된 내용은 ‘ OR 1=1 -- 로 WHERE 절에 있는 싱글쿼터를 닫아주기 위한 싱글쿼터와 OR 1=1 라는 구문을 이용해 WHERE 절을 모두 참으로 만들고, -- 를 넣어줌으로 뒤의 구문을 모두 주석 처리 해주었습니다.

매우 간단한 구문이지만, 결론적으로 Users 테이블에 있는 모든 정보를 조회하게 됨으로 써 가장 먼저 만들어진 계정으로 로그인에 성공하게 됩니다. 보통은 관리자 계정을 맨 처음 만들기 때문에 관리자 계정에 로그인 할 수 있게 됩니다. 관리자 계정을 탈취한 악의적인 사용자는 관리자의 권한을 이용해 또 다른 2차피해를 발생 시킬 수 있게 됩니다.

출처 : https://noirstar.tistory.com/264

developer-sora commented 1 year ago

image

jungmiin commented 1 year ago

nodeJS의 경우

    db.query(`update author set name=?, profile=? where id=?`, [post.name, post.profile, post.id], function (error, result) {
            if (error) throw error;
            response.writeHead(302, { Location: `/author` });
            response.end();
        });

query문 안에 '?'표시를 두고, 그 다음 인자인 리스트에 '?'표시 각각에 대입되는 값을 나열함으로써 injection 공격을 방지한다.

anuu0916 commented 1 year ago

1) 입력값 검증 사용자의 입력이 DB Query 에 동적으로 영향을 주는 경우, 입력된 값이 개발자가 의도한 값(유효값) 인지 검증합니다.

코드 예시 (JAVA)

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/* 특수문자 공백 처리 */
final Pattern SpecialChars = Pattern.compile(“[‘\”\\-#()@;=*/+]”);
UserInput = SpecialChars.matcher(UserInput).replaceAll(“”);

final String regex = “(union|select|from|where)”;
final Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
final Matcher matcher = pattern.matcher(UserInput);

2) 저장 프로시저 사용

저장 프로시저는 사용하자고 하는 Query 에 미리 형식을 지정하는 것을 말합니다. 지정된 형식의 데이터가 아니면 Query 가 실행되지 않기 때문에 보안성을 크게 향상시킵니다.

취약 코드 예시(JAVA)

try{
  String uId = props.getProperty(“jdbc.uId”);

  String query = “SELECT * FROM tb_user WHERE uId=” + uId;
  stmt = conn.prepareStatement(query);
  ResultSet rs = stmt.executeQuery();
  while(rs.next()){
    .. …
  }
}catch(SQLException se){
  .. …
}finally{
  .. …
}

안전한 코드 예시

try{
  String uId = props.getProperty(“jdbc.uId”);

  String query = “SELECT * FROM tb_user WHERE uId= ?”

  stmt = conn.prepareStatement(query);
  stmt.setString(1, uId);

  ResultSet rs = stmt.executeQuery();
  while(rs.next()){
    .. …
  }
}catch(SQLException se){
  .. …
}finally{
  .. …
}

출처 : http://blog.plura.io/?p=6056

developer-sora commented 1 year ago

nodeJS의 경우

  db.query(`update author set name=?, profile=? where id=?`, [post.name, post.profile, post.id], function (error, result) {
            if (error) throw error;
            response.writeHead(302, { Location: `/author` });
            response.end();
        });

query문 안에 '?'표시를 두고, 그 다음 인자인 리스트에 '?'표시 각각에 대입되는 값을 나열함으로써 injection 공격을 방지한다.

이걸 prepared statement라고 한다네용