Mybatis 는 어떻게 SQL 주입 방 지 를 실현 합 니까?

4881 단어 자바
Mybatis 라 는 프레임 워 크 는 일상적인 개발 에 많이 사용 된다.예 를 들 어 면접 에서 자주 문제 가 있다.$#의 차이 점 은 사용#이 SQL 주입 을 방지 할 수 있다 는 것 이다.오늘 은 SQL 주입 을 어떻게 실현 하 는 지 살 펴 보 자.
SQL 주입 이란 무엇 인가
어떻게 실현 되 는 지 토론 하기 전에 먼저 SQL 주입 이 무엇 인지 알 아 보 겠 습 니 다.저 희 는 간단 한 조회 작업 이 있 습 니 다.id 에 따라 사용자 정 보 를 조회 합 니 다.그것 의 sql 문 구 는 다음 과 같 아야 한다.select * from user where id = 우 리 는 전송 조건 에 따라 id 를 입력 하여 조회 합 니 다.
만약 에 정상적으로 조작 하면 정상 적 인 id,예 를 들 어 2 가 들 어 오 면 이 문 구 는select * from user where id =2로 변 합 니 다.이 문 구 는 정상적으로 운행 할 수 있 고 우리 가 기대 하 는 것 에 부합된다.
그러나 들 어 오 는 매개 변수 가 '' or 1=1로 변 하면 이 문 구 는select * from user where id = '' or 1=1로 변 한다.이 문장의 집행 결과 가 어떻게 될 지 생각해 봅 시다.그것 은 우리 사용자 표 의 모든 데 이 터 를 조회 할 것 이다.분명히 이것 은 큰 오류 이다.이것 이 바로 SQL 주입 이다.
Mybatis 는 SQL 주입 을 어떻게 방지 합 니까?
처음에 말 했 듯 이#를 사용 하여 SQL 의 주입 을 방지 할 수 있 습 니 다.그의 쓰 기 는 다음 과 같 습 니 다.

my batis 에서 조회 하 는 또 하나의 쓰기 방법 은 사용$입 니 다.그의 쓰기 방법 은 다음 과 같 습 니 다.

우리 가 외부 에서 이 두 가지 방법 을 계속 호출 할 때 안전 한 매개 변 수 를 입력 할 때 이들 의 결 과 는 다 르 지 않다 는 것 을 발견 했다.안전 하지 않 은 매개 변 수 를 입력 할 때 첫 번 째 사용#방법 으로 결 과 를 조회 하지 못 하지만 이 매개 변 수 는 두 번 째,즉select * from user where id = '' or 1=1에서 모든 결 과 를 얻 을 수 있다.
또한 sql 을 인쇄 하면$를 추가 할 때 데이터베이스 에 실 행 된 sql 은#이 고 우리 의 매개 변수 에 따옴표 를 추가 합 니 다.select * from user where id = ' \'\' or 1=1 '를 사용 할 때 sql 은$입 니 다.
버 려 도 될까요?
우리 가 사용select * from user where id = '' or 1=1해도$의 역할 을 완성 할 수 있 고 사용#이 위험 하 다 면 우 리 는 앞으로 사용 하지 않 으 면 되 지 않 겠 습 니까?
아 닙 니 다.이것 은 우리 의 이런 장면 에서 문제 가 있 을 수 있 지만 일부 동적 조회 장면 에서 대체 할 수 없 는 역할 을 합 니 다.예 를 들 어 동적 수정 표 이름$.저 희 는 정보 가 일치 하 는 상황 에서 동적 으로 조 회 를 변경 할 수 있 습 니 다.이것 도 my batis 의 동태 가 강 한 곳 입 니 다.
어떻게 SQL 주입 을 실현 합 니까?Mybatis 없 이 어떻게 실현 합 니까?
사실 Mybatis 도 jdbc 를 통 해 데이터 베 이 스 를 연결 합 니 다.jdbc 의 사용 을 살 펴 보면 이 유 를 얻 을 수 있 습 니 다.$$을 사용 하여 예비 처 리 를 한 다음 에 set 방식 으로 자리 표시 자 를 설정 하고select * from ${table} where id = #{id}#를 통 해 직접 조회 하 며 매개 변수 가 있 을 때 직접 연결 하여 조회 한다.
그래서 우 리 는 jdbc 를 사용 하여 SQL 주입 을 실현 할 수 있다.
이 두 개의 코드 를 보 세 요.
public static void statement(Connection connection) {
  System.out.println("statement-----");
  String selectSql = "select * from user";
  //    mybatis   $,         
  String unsafeSql = "select * from user where id = '' or 1=1;";
  Statement statement = null;
  try {
    statement = connection.createStatement();
  } catch (SQLException e) {
    e.printStackTrace();
  }
  try {
    ResultSet resultSet = statement.executeQuery(selectSql);
    print(resultSet);
  } catch (SQLException e) {
    e.printStackTrace();
  }
  System.out.println("---****---");
  try {
    ResultSet resultSet = statement.executeQuery(unsafeSql);
    print(resultSet);
  } catch (SQLException e) {
    e.printStackTrace();
  }
}

public static void preparedStatement(Connection connection) {
  System.out.println("preparedStatement-----");
  String selectSql = "select * from user;";
  //   mybatis  #,      sql     ,     ,      
  String safeSql = "select * from user where id =?;";
  PreparedStatement preparedStatement = null;
  try {
    preparedStatement = connection.prepareStatement(selectSql);
    ResultSet resultSet = preparedStatement.executeQuery();
    print(resultSet);
  } catch (SQLException e) {
    e.printStackTrace();
  }
  System.out.println("---****---");
  try {
    preparedStatement = connection.prepareStatement(safeSql);
    preparedStatement.setString(1," '' or 1 = 1 ");
    ResultSet resultSet = preparedStatement.executeQuery();
    print(resultSet);
  } catch (SQLException e) {
    e.printStackTrace();
  }
}

public static void print(ResultSet resultSet) throws SQLException {
  while (resultSet.next()) {
    System.out.print(resultSet.getString(1) + ", ");
    System.out.print(resultSet.getString("name") + ", ");
    System.out.println(resultSet.getString(3));
  }
}

총결산
  • Mybatis 에서 사용PreparedStatement하면 SQL 주입 을 방지 할 수 있 습 니 다.$SQL 주입 을 방지 할 수 없습니다
  • Mybatis 가 SQL 주입 을 실현 하 는 원 리 는 jdbc 의Statement를 호출 하여 예비 처 리 를 하 는 것 이다.

  • 본문 은 블 로그 의 한 글 다발 플랫폼 이다.
    OpenWrite발표!
    블 로 거 메 일 박스:[email protected]문제 가 있 으 면 메 일 로 교류 할 수 있 습 니 다.

    좋은 웹페이지 즐겨찾기