학습
PHP 기본 보안 개념
PHP 기본 보안 개념 — 초급
PHP 기본 보안 개념
1. 도입 (왜 배워야 하는가)
웹 애플리케이션은 사용자의 데이터와 정보를 다루기 때문에 보안이 매우 중요합니다. 보안이 취약한 애플리케이션은 해커의 공격에 노출되어 데이터 유출, 서비스 중단, 금전적 손실 등의 심각한 문제를 일으킬 수 있습니다. 예를 들어, 쇼핑몰 웹사이트에서 고객의 결제 정보가 유출된다면, 고객 신뢰도는 크게 하락하고 법적 문제까지 발생할 수 있습니다.
따라서 PHP 개발자로서 기본적인 보안 개념을 이해하고 적용하는 것은 필수적입니다. 이를 통해 사용자의 정보를 안전하게 보호하고, 애플리케이션의 신뢰성을 높일 수 있습니다.
2. 핵심 개념 설명
- SQL 인젝션 (SQL Injection): 악의적인 사용자가 SQL 쿼리를 조작하여 데이터베이스에 접근하거나 데이터를 변조하는 공격입니다.
- 크로스사이트 스크립팅 (XSS): 사용자의 브라우저에서 악성 스크립트를 실행시키는 공격입니다.
- 비밀번호 해싱 (Password Hashing): 사용자의 비밀번호를 안전하게 저장하기 위해 해시 함수를 사용하는 것입니다.
- 데이터베이스에 연결합니다.
- 사용자 입력을 받아옵니다.
- SQL 쿼리를 문자열로 직접 생성합니다. (여기서 취약점이 발생)
- 쿼리를 실행합니다.
- 데이터베이스에 연결합니다.
- 사용자 입력을 받아옵니다.
- 준비된 문장을 사용하여 SQL 쿼리를 작성합니다.
- 사용자 입력을 바인딩하여 쿼리를 실행합니다.
- SQL 쿼리 직접 삽입
- 사용자 입력 검증 소홀
- PHP에서 보안은 웹 애플리케이션의 핵심입니다.
- SQL 인젝션과 XSS 공격을 예방하기 위해 준비된 문장과 사용자 입력 필터링이 중요합니다.
- 비밀번호는 해싱하여 안전하게 저장해야 합니다.
- HTTPS와 SSL/TLS의 중요성
- 세션 관리와 CSRF (Cross-Site Request Forgery) 방지
- 파일 업로드 보안 및 데이터 암호화
- 비유: 집의 문을 잠그지 않고, 친구가 아닌 사람에게 열쇠를 주는 것과 같습니다. 누군가 열쇠를 악용할 수 있습니다.
- 비유: 누군가의 집에 몰래 들어가서 그 집 주인의 이메일을 빼내는 것과 같습니다.
- 비유: 비밀번호를 자물쇠로 잠그는 것과 같습니다. 원본 비밀번호는 보이지 않게 보호됩니다.
| 용어 | 정의 |
|---|---|
| SQL 인젝션 | SQL 쿼리의 취약점을 이용한 공격 |
| XSS | 웹 페이지에 악성 스크립트를 삽입하는 공격 |
| 비밀번호 해싱 | 비밀번호를 안전하게 저장하기 위한 방법 |
3. 기본 코드 예제
SQL 인젝션 방지
// 데이터베이스 연결
$conn = new mysqli('localhost', 'username', 'password', 'database');
// 사용자 입력
$user_id = $_POST['user_id'];
$password = $_POST['password'];
// SQL 쿼리 생성 (취약점)
$sql = "SELECT * FROM users WHERE user_id = '$user_id' AND password = '$password'";
// 실행
$result = $conn->query($sql);
// 이 코드는 SQL 인젝션에 취약합니다.
// 예를 들어, user_id에 ' OR '1'='1' 입력하면 모든 유저의 정보가 노출될 수 있습니다.
안전한 SQL 쿼리
// 데이터베이스 연결
$conn = new mysqli('localhost', 'username', 'password', 'database');
// 사용자 입력
$user_id = $_POST['user_id'];
$password = $_POST['password'];
// 준비된 문장 사용
$stmt = $conn->prepare("SELECT * FROM users WHERE user_id = ? AND password = ?");
$stmt->bind_param("ss", $user_id, $password);
$stmt->execute();
$result = $stmt->get_result();
// 이 코드는 SQL 인젝션에 안전합니다.
// 입력값을 바인딩하여 SQL 쿼리를 실행하므로, 악의적인 입력을 차단합니다.
4. 실전 활용 예제
예제 1: 로그인 기능 구현
쇼핑몰에서 사용자가 로그인 시 SQL 인젝션 공격을 예방하기 위해 준비된 문장을 사용하여 로그인 기능을 구현합니다.
// 로그인 기능
function login($user_id, $password) {
global $conn; // 전역적으로 DB 연결 사용
$stmt = $conn->prepare("SELECT * FROM users WHERE user_id = ? AND password = ?");
$stmt->bind_param("ss", $user_id, $password);
$stmt->execute();
return $stmt->get_result()->fetch_assoc();
}
예제 2: 사용자 입력 필터링
크로스사이트 스크립팅(XSS) 공격을 예방하기 위해 사용자 입력을 필터링합니다.
// 사용자 입력
$user_input = $_POST['comment'];
// XSS 방지
$safe_input = htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
// 안전한 입력을 사용하여 DB에 저장
이 코드는 사용자의 댓글을 필터링하여 HTML 특수 문자를 변환합니다.
5. 흔한 실수와 주의사항
- 잘못된 코드:
$sql = "SELECT * FROM users WHERE user_id = '$user_id'";
- 올바른 코드:
$stmt = $conn->prepare("SELECT * FROM users WHERE user_id = ?");
- 잘못된 코드:
$user_id = $_POST['user_id'];
- 올바른 코드:
$user_id = filter_input(INPUT_POST, 'user_id', FILTER_SANITIZE_STRING);