현재 위치: > 최신 기사 목록> xml_set_external_entity_ref_handler와 libxml_disable_entity_loader 간 호환성 문제를 해결하는 방법?

xml_set_external_entity_ref_handler와 libxml_disable_entity_loader 간 호환성 문제를 해결하는 방법?

M66 2025-07-26

PHP에서 XML 파일을 처리 할 때 XML_SET_EXTERNAL_ENTITY_ERF_HANDLERLIBXML_DISABLE_ENTITY_LOADER는 외부 엔티티를 처리하고 외부 엔티티로드를 비활성화하는 데 각각 사용되는 두 가지 일반적으로 사용되는 기능입니다. 그러나 두 가지를 사용하면 특히 외부 DTD (문서 유형 정의) 및 엔티티와 관련된 XML을 다룰 때 일부 호환성 문제가 발생할 수 있습니다. 이 기사는 이러한 문제의 근본 원인을 탐색하고 해결책을 제공합니다.

배경

xml_set_external_entity_ref_handler

XML_SET_EXTERNAL_ENTITY_REF_HANDLER는 XML 문서의 외부 엔티티에 대한 참조를 처리하기 위해 사용자 정의 콜백 함수를 지정할 수있는 PHP 기능입니다. 외부 엔티티는 종종 DTD 파일, 기타 XML 파일 또는 텍스트 파일과 같은 XML 문서에 외부 리소스를 도입하는 데 사용됩니다.

외부 엔티티 참조로 XML 문서를 구문 분석 할 때 XML_SET_EXTERNAL_ENTITY_REF_HANDLER는 정의하는 콜백 기능을 호출하여 엔티티 구문 분석 전에 처리 로직을 사용자 정의 할 수 있습니다.

libxml_disable_entity_loader

libxml_disable_entity_loader는 외부 엔티티를로드하기 위해 XML 파서를 비활성화하는 또 다른 PHP 기능입니다. 이 기능은 일반적으로 XML 외부 엔티티 주입 공격 (XXE 공격)을 방지하는 데 사용됩니다. 외부 엔티티의로드를 비활성화하면 XML 파서가 실수로 외부 리소스에서 민감한 정보를로드하지 않도록 할 수 있습니다.

문제의 근원

이 두 기능의 기능은 관련이없는 것처럼 보이지만 충돌 할 수 있습니다. XML_SET_EXTERNAL_ENTITY_REF_HANDLER는 외부 엔티티의로드를 처리 할 수있을 것으로 기대하는 반면, libxml_disable_entity_loader는 외부 엔티티의로드를 비활성화합니다. 엔티티로드가 비활성화되면 XML 파서가 외부 엔티티를로드하려고 시도하지 않기 때문에 XML_SET_EXTERNAL_ENTITY_REF_HANDLER 의 콜백 기능을 트리거 할 수 없습니다.

이것은 둘 사이의 호환성 문제로 이어집니다. 엔티티로드를 비활성화 한 후 XML_SET_EXTERNAL_ENTITY_ERF_HANDLER를 사용하려면 외부 엔티티 참조를 처리하려면 특별한 조치를 취해야합니다.

해결책

xml_set_external_entity_ref_handler가 libxml_disable_entity_loader 와 호환되는지 확인하려면 다음 방법을 사용할 수 있습니다.

1. libxml_disable_entity_loader 로 외부 엔티티로드를 비활성화하지만 여전히 엔티티 참조를 처리합니다.

가장 일반적인 관행은 XXE 공격을 방지하기 위해 외부 엔티티로드를 비활성화하고 XML_SET_EXTERNAL_ENTITY_REF_HANDLER를 사용하여 특정 외부 엔티티 참조를 처리하는 것입니다. 이를 달성하려면 다음 코드를 사용할 수 있습니다.

 <span><span><span class="hljs-comment">// 외부 엔티티 로딩을 비활성화합니다</span></span><span>
</span><span><span class="hljs-title function_ invoke__">libxml_disable_entity_loader</span></span><span>(</span><span><span class="hljs-literal">true</span></span><span>);

</span><span><span class="hljs-comment">// 외부 엔티티 참조 처리 기능 설정</span></span><span>
</span><span><span class="hljs-title function_ invoke__">xml_set_external_entity_ref_handler</span></span><span>(function (</span><span><span class="hljs-variable">$entity</span></span><span>, </span><span><span class="hljs-variable">$system</span></span><span>, </span><span><span class="hljs-variable">$public</span></span><span>) {
    </span><span><span class="hljs-comment">// 외부 엔티티 참조를 처리합니다</span></span><span>
    </span><span><span class="hljs-comment">// 예를 들어 로컬 파일 또는 데이터베이스에서 엔티티를로드합니다</span></span><span>
    </span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-string">'/path/to/your/local/entity'</span></span><span>;
});

</span><span><span class="hljs-comment">// 분석 XML</span></span><span>
</span><span><span class="hljs-variable">$xml</span></span><span> = </span><span><span class="hljs-title function_ invoke__">simplexml_load_file</span></span><span>(</span><span><span class="hljs-string">'yourfile.xml'</span></span><span>);
</span></span>

이런 식으로 Libxml_disable_entity_loader는 모든 외부 엔티티의로드를 비활성화하는 반면 XML_SET_EXTERNAL_ENTITY_ERF_HANDLER는 특정 외부 엔티티가 발생할 때 처리를 사용자 정의하는 데 사용할 수 있습니다.

2. 필요할 때 외부 엔티티 로딩을 일시적으로 활성화합니다

특정 상황에서 외부 엔티티를로드 할 수 있도록 해야하는 경우 특정 처리 단계에서 엔티티 로딩을 일시적으로 활성화 할 수 있습니다. XML을 구문 분석하기 전후에 엔터티로드를 명시 적으로 활성화 또는 비활성화 할 수 있습니다.

 <span><span><span class="hljs-comment">// 외부 엔티티 로딩을 비활성화합니다</span></span><span>
</span><span><span class="hljs-title function_ invoke__">libxml_disable_entity_loader</span></span><span>(</span><span><span class="hljs-literal">true</span></span><span>);

</span><span><span class="hljs-comment">// 분석 XML</span></span><span>
</span><span><span class="hljs-variable">$xml</span></span><span> = </span><span><span class="hljs-title function_ invoke__">simplexml_load_file</span></span><span>(</span><span><span class="hljs-string">'yourfile.xml'</span></span><span>);

</span><span><span class="hljs-comment">// 외부 엔티티가 특정 순간에로드하도록 허용합니다</span></span><span>
</span><span><span class="hljs-title function_ invoke__">libxml_disable_entity_loader</span></span><span>(</span><span><span class="hljs-literal">false</span></span><span>);

</span><span><span class="hljs-comment">// 다른 작업을 계속하십시오</span></span><span>
</span></span>

이 접근법은 외부 엔티티가로드 될 때보다 세분화 된 제어를 가능하게하여 보안 문제를 피하면서 유연한 XML 파싱을 허용합니다.

3. 외부 엔티티 처리 로직 사용자 정의

외부 엔티티로드를 비활성화하지 않으려면 보안 문제를 피하려면 XML_SET_EXTERNAL_ENTITY_ENTITY_ERF_HANDLER 콜백 기능 내에서 보안 검사를 구현할 수 있습니다. 예를 들어, 외부 엔티티의 URI가 신뢰할 수 있는지 또는 로컬 파일을로드 할 수 있는지 확인할 수 있습니다.

 <span><span><span class="hljs-comment">// 외부 엔티티 참조 처리 기능 설정</span></span><span>
</span><span><span class="hljs-title function_ invoke__">xml_set_external_entity_ref_handler</span></span><span>(function (</span><span><span class="hljs-variable">$entity</span></span><span>, </span><span><span class="hljs-variable">$system</span></span><span>, </span><span><span class="hljs-variable">$public</span></span><span>) {
    </span><span><span class="hljs-comment">// 안전 검사를 수행하십시오,신뢰할 수없는 엔티티가로드되지 않았는지 확인하십시오</span></span><span>
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">strpos</span></span><span>(</span><span><span class="hljs-variable">$system</span></span><span>, </span><span><span class="hljs-string">'trusted-path'</span></span><span>) === </span><span><span class="hljs-literal">false</span></span><span>) {
        </span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-string">''</span></span><span>;  </span><span><span class="hljs-comment">// Entity가로드되지 않았 음을 나타 내기 위해 빈 문자열을 반환합니다.</span></span><span>
    }

    </span><span><span class="hljs-comment">// 신뢰할 수있는 외부 엔티티를 처리하십시오</span></span><span>
    </span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-string">'/path/to/your/trusted/entity'</span></span><span>;
});

</span><span><span class="hljs-comment">// 분석 XML</span></span><span>
</span><span><span class="hljs-variable">$xml</span></span><span> = </span><span><span class="hljs-title function_ invoke__">simplexml_load_file</span></span><span>(</span><span><span class="hljs-string">'yourfile.xml'</span></span><span>);
</span></span>

이 접근법을 사용하면 외부 엔티티가로드 할 수 있도록하는 동시에 어떤 엔티티를로드 할 수 있는지 제어 할 수 있으므로 잠재적 인 보안 위험을 피할 수 있습니다.

결론적으로

PHP에서는 두 가지 함수 XML_SET_EXTERNAL_ENTITY_ENTITY_REF_HANDLERLIBXML_DISABLE_ENTITY_LOADER 의 목적이 다르지만 이들 사이에는 충돌이있을 수 있습니다. 합리적인 구성 및 코드 조정을 통해이 두 기능이 호환 될 수 있고 외부 엔티티 참조 처리의 요구를 충족하며 외부 엔티티로드가 가져올 보안 위험을 피할 수 있습니다. 올바른 솔루션을 선택하는 것은 특정 요구 사항 및 보안 요구 사항에 따라 다릅니다.