불순한 의도를 가진 사용자(즉 공격자)가 파일 경로를 알아내서 사이트의 중요한 정보를 알아낼 수가 있다.
그걸 방지하기 위한 방법 중에 일부를 이번에도 생활코딩 php 수업 영상으로 공부해 보겠다.
이전 포스트
php, XSS 공격 방어 (feat. htmlspecialchars와 strip_tags 함수)
생활코딩의 php 수업 영상: 보안 파일 경로 보호
영상을 보면서 참 신기하기도 하고, 대단하다는 생각도 들고(좋은 의미 아님), 내가 나중에 웹사이트를 만들었을 때 이런 공격이 들어올까봐 무섭기도 하다.
왜 저런 범죄를 저지르는 사람들이 있는 건지.. 남에게 피해를 안 주면서 살면 안 되는 건가?
basename()
basename() 함수는 파일의 전체 경로(Path) 중에서 파일 이름 부분만 쏙 골라내는 php의 내장 함수다.
웹 보안, 특히 파일 시스템을 다룰 때 아주 중요한 역할을 한다.
1. 기본 동작 방식
<?php
$path = "/var/www/html/data/hello.txt";
echo basename($path);
// 결과: hello.txt
?>
basename()은 경로 문자열에서 마지막 슬래시(/ 또는 \) 뒤에 오는 문자열을 반환한다.
2. 확장자 제거 기능
<?php
$path = "data/setting.conf";
echo basename($path, ".conf");
// 결과: setting
?>
basename()의 두 번째 인자에 확장자를 넣어주면, 그 확장자까지 떼어낸 순수 파일 이름만 얻을 수 있다.
3. 왜 보안(Security)에 필수인가?
이전에 다뤘던 파일 삭제(unlink)나 파일 이름 변경(rename) 로직을 떠올려 보자.
사용자가 입력한 id 값을 그대로 경로에 합치면 위험하다.
만약 공격자가 삭제할 id 값에 ../index.php를 입력해서 보낸다면?
코드가 unlink('data/'.$_POST['id']);였기 때문에 실제 실행은 unlink('data/../index.php');로 되어 서버의 메인 파일이 삭제되고 만다.
이것을 Directory Traversal 공격이라고 한다.
<?php
$id = "../index.php"; // 공격자의 입력
$safe_id = basename($id);
// 결과: index.php (앞의 위험한 경로가 다 날아감)
unlink('data/'.$safe_id);
// 실제 실행: unlink('data/index.php'); ➔ 상위 폴더로 이동 불가능
?>
basename()을 사용하면 공격자가 아무리 ../를 섞어 보내도 모든 경로를 다 잘라내고 마지막 파일명만 남긴다.
"클라이언트가 보내는 모든 데이터(GET, POST, Cookie 등)는 언제든 조작될 수 있다고 가정해야 한다."
이게 바로 웹 보안의 첫걸음이다.
그래서 서버(php)에서는 항상 basename()이나 이전에 다뤘던 htmlspecialchars() 같은 함수로 데이터를 한 번 걸러준 뒤 사용해야 하는 것이다.
다음 포스트
php 생활코딩 수업 영상 마지막 (feat. UI와 API)
응원이나 피드백이 담긴 댓글은 제가 계속 블로그를 해나갈 수 있는 원동력이 됩니다. 😊
지인에게 보여주고 싶은 글이었다면 URL을 복사해서 메신저나 소셜 미디어에 공유해 주세요.
0 Comments
댓글 쓰기
🔸 댓글은 블로그 운영자의 승인 후에 블로그에 표시됩니다.
🔸 비로그인 방문자 분께서는 '익명'보다 이름/URL로 댓글을 남겨주시면 감사하겠습니다. (URL은 생략 가능합니다.)
🔸 구글 로그인 방문자는 '알림 사용'에 체크를 하시면, 남겨주신 댓글에 대한 답글 알림을 메일로 받아볼 수 있습니다. 📩