본문 바로가기

보안/이론

JAVA, PHP PreparedStatement 사용법

  • JAVA에서 PreparedStatement 예제
//JAVA에서 PreparedStatement을 사용한 SQL Injection 공격 방지

PreparedStatement stmt = connection.prepareStatement("
SELECT * FROM users WHERE idx = ? AND userid = ? AND password = ?");

stmt.setInt(1,user_idx); 	// 1번째 ? 에 user_idx 바인딩
stmt.setString(2, user_id); 	// 2번째 ? 에 user_id 바인딩
stmt.setString(3, user_password);  	// 3번째 ? 에 user_password 바인딩

ResultSet rs = stmt.executeQuery(); // 쿼리 실행 결과를 가져옴

 

  • PHP에서 PreparedStatement 예제
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";

// 데이터베이스와 연결 생성
$conn = new mysqli($servername, $username, $password, $dbname);

// 연결 확인
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// prepare and bind 
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname, $email);
//sss라는 인수는 매개 변수가 있는 데이터 유형을 나열

// 매개 변수 설정 및 실행
$firstname = "John";
$lastname = "Doe";
$email = "john@example.com";
$stmt->execute();

$firstname = "Mary";
$lastname = "Moe";
$email = "mary@example.com";
$stmt->execute()


$stmt->close();
$conn->close();
?>
  • bind_param에서 데이터 유형
    • i - integer
    • d - double
    • s - string
    • b - BLOB(Binary Large Object, 이미지, 사운드, 비디오 등)

 

 

  • 내가 작성한 PHP MVC 모델에서 모델에 해당하는 부분
  public function delete_from_temp_user_table($nonce)
    {
        $sql = "DELETE FROM Temp_user where auth_code = ?";
        $sth = $this->db->prepare($sql);
        $sth->execute(array($nonce));
        $results = $sth->rowCount();
        return $results;
    }

    public function duplicate_check_by_email_from_user_table($user)
    {
        $sql = "SELECT USN from User where e_mail = ?";
        $sth = $this->db->prepare($sql);
        $sth->execute(array($user['e_mail']));
        $results = $sth->fetchAll();
        return $results;
    }
    
        public function select_USN_PW_from_User_table($user)
    {
        $sql = "SELECT USN,hashed_pwd from User where e_mail = ?";
        $sth = $this->db->prepare($sql);
        $sth->execute(array($user['e_mail']));
        $results = $sth->fetch();
        return $results;
    }

예제와 마찬가지로 db의 커넥터의 prepare 함수를 이용하여 SQL 구문을 전 처리한다. 

다른 점은 bind_param 함수를 통해 바인딩을 하지 않고 execute 함수를 이용하여 바로 파라미터로 받은 인자의 값에 대해 바인딩 처리를 하였다.

 

추가적으로

함수명 설명
fetchAll()   query의 모든 결과 (1개 이상의 레코드)를 가져온다
fetch()  여러 결과 중 1개의 결과를 가져온다. 
rowCount() 

함수는 영향을 받은 행수를 반환하는 함수이다.

데이터베이스에서 원하는 row 가 지워졌는지, 아닌지 확인할 수 있다.