PHP의 웹 개발에서 SQL 주입은 일반적이고 위험한 보안 위협입니다. SQL 주입을 효과적으로 방지하기 위해, 준비 된 명령문, 파라미터 바인딩 및 기타 방법을 사용하는 것 외에도 데이터베이스 연결에서 사용하는 문자 세트가 올바른지 확인하는 것도 중요한 링크입니다. 이 기사는 mysqli :: get_charset 함수의 사용과 SQL 주입을 방지하는 역할에 중점을 둘 것입니다.
mysqli :: get_charset은 PHP MySQLI Extension에서 제공하는 메소드입니다. 현재 데이터베이스 연결의 문자 세트 정보를 얻습니다. 문자 세트 이름, 인코딩 등과 같은 문자 세트 속성을 포함하는 객체를 반환합니다.
문자 세트는 데이터베이스 보안에서 중요한 역할을합니다. 캐릭터 세트가 올바르게 설정되지 않으면 공격자는 인코딩 차이를 사용하여 입력 유효성 검사를 우회하거나 특수 주입 페이로드를 구성 할 수 있기 때문입니다.
예를 들어, MySQL은 기본적으로 latin1 인코딩을 사용합니다. 클라이언트가 UTF8 데이터를 제출하지만 서버가 Latin1을 사용하여 구문 분석하면 예기치 않은 문자가 발생하여 SQL 주입이 발생할 수 있습니다.
먼저 기본 예를 살펴 보겠습니다.
<?php
$mysqli = new mysqli("localhost", "user", "password", "database");
// 연결이 성공했는지 확인하십시오
if ($mysqli->connect_errno) {
die("연결이 실패했습니다: " . $mysqli->connect_error);
}
// 문자 세트 정보를 얻으십시오
$charsetInfo = $mysqli->get_charset();
echo "현재 연결에 사용되는 문자 세트: " . $charsetInfo->charset;
?>
이 스크립트는 UTF8MB4 와 같은 현재 데이터베이스 연결의 문자 세트를 출력합니다. UTF8 은 실제로 MySQL에서 3 바이트 인코딩이며 모든 유니 코드 문자를 지원하지 않기 때문에 UTF8 대신 UTF8MB4를 사용하는 것이 좋은 습관입니다. UTF8MB4는 전체 4 바이트 UTF-8 인코딩입니다.
문자 세트는 서버가 클라이언트가 보낸 데이터를 이해하고 처리하는 방식에 영향을 미칩니다. 데이터베이스 연결에 LATIN1을 사용하지만 입력 데이터에 멀티 바이트 문자가 포함 된 경우 일부 바이트 시퀀스는 SQL 제어 문자 (예 : 단일 따옴표, 세미콜론)로 오해되어 SQL 주입을 유발할 수 있습니다.
프로그램에서 get_charset을 사용하여 연결이 안전한 문자 세트인지 확인하면 ( UTF8MB4 가 권장됨) 불일치를 인코딩하여 발생하는 공격의 위험을 크게 줄일 수 있습니다.
다음 코드는 전체 시나리오를 보여줍니다.
<?php
$mysqli = new mysqli("localhost", "user", "password", "database");
// 연결을 확인하십시오
if ($mysqli->connect_errno) {
die("연결이 실패했습니다: " . $mysqli->connect_error);
}
// 문자 세트를 확인하십시오
$charsetInfo = $mysqli->get_charset();
if ($charsetInfo->charset !== 'utf8mb4') {
// 강제 utf8mb4
if (!$mysqli->set_charset("utf8mb4")) {
die("문자 세트를 설정할 수 없습니다: " . $mysqli->error);
}
echo "문자 세트가 업데이트되었습니다 utf8mb4\n";
} else {
echo "현재 문자 세트는입니다 utf8mb4\n";
}
// 전처리 명세서를 사용한 주입 방지
$stmt = $mysqli->prepare("SELECT * FROM users WHERE email = ?");
if (!$stmt) {
die("전처리가 실패했습니다: " . $mysqli->error);
}
// 사용자 입력에서 얻은 값을 시뮬레이션합니다
$userInput = $_GET['email'] ?? '';
// 매개 변수를 바인딩하고 실행합니다
$stmt->bind_param("s", $userInput);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
echo "사용자 이름: " . htmlspecialchars($row['username']) . "\n";
}
$stmt->close();
$mysqli->close();
?>
이 예에서는 get_charset을 사용하여 문자 세트를 확인할뿐만 아니라 Set_Charset을 사용하여 연결이 안전 해지도록합니다. 다음으로, 우리는 전처리 명세서와 파라미터 결합을 사용하여 SQL 스트링을 접합하지 않아 SQL 주입을 효과적으로 방지합니다.