2015-08-19 7 views
6

Ho ricercato su questo argomento, ma non sono riuscito a trovare alcuna info utili per quanto riguarda cheCome proteggere javax.xml.transform.TransformerFactory da attacchi esterni XML

abbiamo bisogno di prendere tutte le misure di sicurezza per garantire javax.xml .transform.Transformer contro gli attacchi di entità esterne XML?

Ho fatto quanto segue e sembra espandere il dtd.

String fileData = "<!DOCTYPE acunetix [ <!ENTITY sampleVal SYSTEM \"file:///media/sample\">]><username>&sampleVal;</username>"; 
TransformerFactory transformerFactory = TransformerFactory.newInstance(); 
transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); 
Transformer transformer = transformerFactory.newTransformer(); 
StringWriter buff = new StringWriter(); 
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
transformer.transform(new StreamSource(new StringReader(fileData)), new StreamResult(buff)); 
System.out.println(buff.toString()); 

uscita contiene il valore dal file

<username>test</username> 

risposta

3

Il tuo codice sembra corretto. Quando ho eseguito questo leggermente modificato caso di test JUnit:

@Test 
public void test() throws TransformerException, URISyntaxException { 
    File testFile = new File(getClass().getResource("test.txt").toURI()); 
    assertTrue(testFile.exists()); 
    String fileData = "<!DOCTYPE acunetix [ <!ENTITY foo SYSTEM \"file://" + 
        testFile.toString() + 
        "\">]><xxe>&foo;</xxe>"; 
    TransformerFactory transformerFactory = TransformerFactory.newInstance(); 
    System.out.println(transformerFactory.getClass().getName()); 
    transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); 
    Transformer transformer = transformerFactory.newTransformer(); 
    StringWriter buff = new StringWriter(); 
    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
    transformer.transform(new StreamSource(new StringReader(fileData)), new StreamResult(buff)); 
    assertEquals("<xxe>&foo;</xxe>", buff.toString()); 
} 

ottengo il seguente output:

com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl 
[Fatal Error] :1:182: External Entity: Failed to read external document 'test.txt', because 'file' access is not allowed due to restriction set by the accessExternalDTD property. 
ERROR: 'External Entity: Failed to read external document 'test.txt', because 'file' access is not allowed due to restriction set by the accessExternalDTD property.' 

Dal setFeatureJavaDocs:

Tutte le implementazioni sono tenuti a sostenere le XMLConstants. Funzione FEATURE_SECURE_PROCESSING. Quando la funzione è:

  • true: l'implementazione limiterà l'elaborazione XML per conformarsi ai limiti di implementazione e comportarsi in modo sicuro come definito dall'implementazione. Gli esempi includono la risoluzione di fogli di stile definiti dall'utente e funzioni. Se l'elaborazione XML è limitata per motivi di sicurezza, verrà segnalata tramite una chiamata all'errore ErrorListener.fatalError registrato (eccezione TransformerException). Vedi setErrorListener (listener ErrorListener).

Tale errore va via se io commento transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); e poi il test fallisce perché l'entità è stato risolto.

Prova ad aggiungere un ErrorListener sia al TransformerFactory e Transformer:

transformerFactory.setErrorListener(new ErrorListener() { 

    @Override 
    public void warning(TransformerException exception) throws TransformerException { 
    System.out.println("In Warning: " + exception.toString()); 
    } 

    @Override 
    public void error(TransformerException exception) throws TransformerException { 
    System.out.println("In Error: " + exception.toString()); 
    } 

    @Override 
    public void fatalError(TransformerException exception) throws TransformerException { 
    System.out.println("In Fatal: " + exception.toString()); 
    } 
}); 

Transformer transformer = transformerFactory.newTransformer(); 
transformer.setErrorListener(transformerFactory.getErrorListener()); 

vedo il seguente nuovo output della console ora:

In Error: javax.xml.transform.TransformerException: External Entity: Failed to read external document 'test.txt', because 'file' access is not allowed due to restriction set by the accessExternalDTD property. 

Forse l'implementazione è trattare come un avvertimento? Altrimenti, forse è l'implementazione che stai utilizzando? Sembra che le specifiche di JavaDoc non siano precise, quindi un'implementazione potrebbe fare qualcosa di diverso da un'altra. Sarei interessato a conoscere implementazioni difettose!

Problemi correlati