XML, DTD e entidades
Um XML pode declarar apelidos (entidades) num bloco DTD, e o parser os troca pelo valor quando lê.
O XML guarda dados em etiquetas: <invoice><id>7781</id></invoice>. Quase todo sistema que troca faturas, configurações ou documentos já leu XML em algum momento.
No começo do arquivo pode vir um bloco DTD (definição de tipo de documento), aberto com <!DOCTYPE ... [ ... ]>. Dentro dele o documento pode declarar entidades, que são apelidos. Uma entidade simples é assim:
<!DOCTYPE invoice [
<!ENTITY empresa "Estancia Santa Fe">
]>
<invoice><customer>&empresa;</customer></invoice>
Quando o parser lê &empresa;, ele troca pelo valor declarado, e o campo vira Estancia Santa Fe. Repare: o texto não estava no corpo do documento, ele foi colado pelo parser a partir da entidade. Em Python o equivalente seria um dicionário {"empresa": "Estancia Santa Fe"} e um .replace("&empresa;", d["empresa"]) feito pela biblioteca.
Isso só é perigoso quando o parser está configurado para aceitar o DTD e resolver as entidades, e aceita o XML que o usuário manda. Aí o apelido pode apontar para fora do documento, e é esse o começo do XXE.