Pergunta

Assim, em meu projeto atual eu uso o JAXB RI com o analisador Java padrão do JRE da Sun (que eu acredito é Xerces) para XML arbitrário unmarshal.

Primeiro eu uso XJC para compilar um XSD da seguinte forma:

<?xml version="1.0" encoding="utf-8" ?> 
<xs:schema attributeFormDefault="unqualified" 
elementFormDefault="qualified" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
<xs:element name="foobar">
...
</xs:element> 
</xs:schema>

No "caso bom" tudo funciona conforme projetado. Isso quer dizer que se eu sou XML passado em conformidade com esse esquema, em seguida, JAXB unmarshals-lo corretamente em uma árvore de objetos.

O problema surge quando eu estou passou XML com um DTD referências externas, por exemplo.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foobar SYSTEM "http://blahblahblah/foobar.dtd">
<foobar></foobar>

Ao unmarshalling algo assim, as tentativas parser SAX para carregar a entidade remota ( " http: // somehost / foobar. dtd "), apesar do fato de que esse trecho claramente não está em conformidade com o esquema I compilado anteriormente com XJC.

A fim de contornar este comportamento, desde que eu sei que qualquer XML conformant (de acordo com o XSD Eu compilei) não vai exigir o carregamento de uma entidade remota, eu tenho que definir um EntityResolver personalizado que curto-circuitos do carregamento de todos os remoto entidades. Então, ao invés de fazer algo como:

MyClass foo = (MyClass) myJAXBContext.createUnmarshaller().unmarshal(myReader);

Eu sou forçado a fazer isso:

XMLReader myXMLReader = mySAXParser.getXMLReader();
myXMLReader.setEntityResolver(myCustomEntityResolver);
SAXSource mySAXSource = new SAXSource(myXMLReader, new InputSource(myReader));
MyClass foo = (MyClass) myJAXBContext.createUnmarshaller().unmarshal(mySAXSource);

Então, minha pergunta final é:

Quando unmarshalling com JAXB, deve o carregamento de entidades remotas pelo analisador SAX subjacente ser automaticamente em curto-circuito quando o XML em questão pode ser reconhecido como inválido, sem o carregamento dessas entidades remotas?

Além disso, não esta parece ser uma questão de segurança? Dado que JAX-WS depende de JAXB sob o capô, parece que eu poderia passar XML especialmente criado para qualquer serviço da Web JAX-WS base e causar o anfitrião WS para carregar qualquer URL arbitrário.

Eu sou um novato em relação a isso, então provavelmente há algo que eu estou sentindo falta. Por favor, deixe-me saber se assim!

Foi útil?

Solução

Uma pergunta bem trabalhada, que merece uma resposta:)

Algumas coisas a nota:

  1. O tempo de execução JAXB não é dependente de XML Schema. Ele usa um parser SAX para gerar um fluxo de eventos SAX que ele usa para se ligar para o modelo de objeto. Este modelo de objecto pode ser escrita à mão, ou pode ser gerado a partir de um esquema usando XJC, mas a ligação e o tempo de execução são muito distintos um do outro. Então, você pode saber que as boas conforma entrada XML para o esquema em tempo de execução, mas JAXB não.
  2. Forçar o tempo de execução para carregar uma referência DTD remoto não constitui uma brecha de segurança. Se há uma verdadeira DTD no final do mesmo, o pior caso é que ele não irá validar. Se não for uma verdadeira DTD, então ele vai ser ignorado.
  3. DTD é considerado obsoleto, e por isso não há suporte direto para ele no alto nível JAXB API. Se você precisa de um EntityResolver, você precisa cavar o API SAX, que você já fez.
  4. Se o seu modelo de classe foi gerada a partir de um esquema XML, então você deve considerar validar contra ela em tempo de execução, usando SchemaFactory e Unmarshaller.setSchema(). Isso irá instruir Xerces para validar os eventos SAX contra o esquema antes de ser passado para JAXB. Isso não vai parar o DTD sendo buscada, mas adiciona uma camada de segurança que você sabe os dados é bom.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top