PHP에서 직렬화는 PHP 개체를 문자열로 변환하는 방법입니다. 이 문자열은 데이터베이스에 저장하거나 다른 함수에 전달하는 등 다양한 방법으로 사용될 수 있습니다. PHP 문서에서는 이것이 유형과 구조를 잃지 않고 PHP 값을 전달할 때 유용하다고 말합니다. 그러나 나는 이전에 그런 문제를 겪어본 적이 없습니다. 어쩌면 제가 못 볼 수도 있겠네요.
<?php $test = new User(); $test->name = "Denzyl"; echo serialize($test); /// Output: O:4:"User":1:{s:4:"name";s:6:"Denzyl";}
그럼 문자열을 소화해 볼까요? o는 Object를 의미하며, 다음 숫자는 해당 객체의 이름 길이입니다. 두 글자 s는 문자열과 문자열 이름의 길이를 나타냅니다.
문자열을 다시 PHP로 변환해야 하는 경우 unserialize 함수를 호출하고 문자열을 매개변수로 전달하세요.
객체를 직렬화할 때 두 가지 메소드가 자동으로 호출됩니다. __serialize() & __sleep(). 이렇게 하면 클래스 작성자가 개체를 문자열로 변환하기 전에 작업을 수행할 수 있습니다.
바로 그 점입니다. 하지만 지금은 문자열을 직렬화 해제하는 데 중점을 두겠습니다. 이는 문자열을 나중에 PHP 코드에서 런타임에 사용할 수 있는 실제 PHP 개체로 변환하는 것을 의미합니다.
<?php $string = 'O:8:"User":1:{s:4:"name";s:6:"Denzyl";}'; echo unserialize($string)->name; /// Output: Denzyl
비직렬화에도 동일한 기능이 적용됩니다. 하지만 이번에는 __unserialize()와 __wakeup() 두 가지 메서드를 사용합니다.
알지 못한 채 unserialize를 사용하면 원격 코드가 실행될 수 있습니다. 그래서 그들은 입력을 절대 믿지 말라고 말합니다.
당신이 게으르고 임의의 입력을 신뢰하고 직렬화된 객체에 연결하여
객체 내부의 값을 변경합니다. 붐, 해킹당할 수 있어요.
<?php $username = $_GET['username']; $serialized = 'O:8:"User":1:{s:4:"name";s:6:"' . $username . '";}';
이런 것에 대한 익스플로잇 작성 방법은 설명하지 않겠습니다. 일부 도구는 자동으로 페이로드를 생성할 수 있으며, 스스로를 스크립트 키디라고 부를 수 있습니다(우리는 모두 어딘가에서 시작합니다). 제가 아는 것은 PHPGGC입니다.
익스플로잇을 이해하려면 OWASP 기사를 읽어보세요.
이전에 이 사실을 몰랐다면 취약점에 관한 나머지 OWASP 기사도 읽어보세요
익스플로잇 작성 방법을 설명하지 않은 것으로 알고 있습니다. 인터넷 기사보다 더 잘할 수는 없을 것 같아요. 하지만 이제는 이 사실을 알고 연구를 수행할 수 있습니다.
왜 이것을 사용하고 싶나요? 모르겠어요; 나는 직렬화/역직렬화를 사용하여 문제를 해결할 기회를 가질 만큼 오랫동안(~15년) 프로그래밍을 해오지 않았습니다.
내 해결책은 너무 과격하다. 간단한 대답은 다음과 같습니다. 제 PHP 프로젝트에서는 사용하지 마세요.
이 기사는 몇 분/초 안에 대규모 프로젝트를 스캔할 수 있는 PHP용 정적 분석 도구를 작성하는 과정에 관한 일련의 기사 중 일부입니다. 그리고 규칙을 찾아보세요
개발자가 자신의 프로젝트에 갖고 싶어하는 것입니다. 이 글을 쓰는 시점에는 중지를 원칙으로 하고 있습니다
사람들이 unserialize를 사용하는 것을 방지하고 다음 릴리스에 대비해야 합니다.
알림을 받을 수 있도록 프로젝트를 팔로우하세요.
나는 더 많은 규칙을 작성하기로 결정했습니다.
위 내용은 PHP에서 객체를 직렬화 해제하는 것이 왜 나쁜 생각인가요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!