XXE et Java

XXE et Java

Qu'est-ce que XXE

XXE (XML External Entity) est un acte frauduleux d'acquisition (fuite) du contenu d'un fichier à l'intérieur du serveur ou d'accès à un fichier sur le réseau interne en utilisant la fonction de référence externe de XML.

Puisque XXE peut être exprimé dans des applications qui gèrent XML, il faut être prudent lors de la manipulation de documents XML.

Java et XML

Pour gérer XML en Java, envisagez d'utiliser javax.xml.parsers.DocumentBuilder. Être terminé.

Par conséquent, après cela, vous pouvez le reproduire en utilisant javax.xml.parsers.DocumentBuilder. Pensons aux contre-mesures.

Conclusion

Il existe également un moyen de contrôler le lien des bases de XXE avec les propriétés JavaVM, ce qui peut être le moyen le plus rapide. D'un autre côté, si vous êtes un programmeur Java, il ne devrait pas être difficile de créer et de contrôler le résolveur vous-même.

Express XXE en Java

Le programme de code source suivant est conçu pour spécifier le fichier XML comme premier argument et le mode de fonctionnement de la référence externe comme deuxième argument, de sorte que le fichier XML ([C: \ z \ xmlxxe] est le mode de fonctionnement par défaut. \ in1.xml](https://qiita.com/tomoki0sanaki/items/015b6e8b807ed256a6e4#xml%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB--in1xml)) Je lirai.

Comme ça.

xxe-java-defo.png

Dans le cas de Java, cela signifie qu'il sera attaqué par XXE par défaut.

Rendre les objets xréf NULL

Vient ensuite la [méthode javax.xml.parsers.DocumentBuilder # setEntityResolver ()](https://docs.oracle.com/javase/jp/6/api/javax/xml/parsers/DocumentBuilder.html#setEntityResolver (org.xml) Essayez de donner "NULL" dans .sax.EntityResolver)).

Comme ça.

xxe-java-null.png

Contrairement au .NET Framework, ** Null est l'objet de résolution par défaut, donc dans le cas de Java, même NULL est sujet aux attaques XXE. ** **

Créez votre propre objet Xréf

Vient ensuite "** Je veux utiliser la fonction de référence externe de manière limitée, mais je veux empêcher XXE ". Ou, si vous dites " Je veux empêcher la fonction de référence externe en modifiant le résolveur **", vous pouvez créer votre propre résolveur.

Autrement dit, [méthode javax.xml.parsers.DocumentBuilder # setEntityResolver ()](https://docs.oracle.com/javase/jp/6/api/javax/xml/parsers/DocumentBuilder.html#setEntityResolver (org.xml) .sax.EntityResolver))) a le premier argument "org.xml.sax.EntityResolver Puisqu'il s'agit d'un type d'interface, créez une classe qui en hérite et utilisez-la [méthode javax.xml.parsers.DocumentBuilder # setEntityResolver ()](https://docs.oracle.com/javase/jp/6/api/ En l'attribuant au premier argument de javax / xml / parsers / DocumentBuilder.html # setEntityResolver (org.xml.sax.EntityResolver)), vous pouvez contrôler librement la référence externe.

La méthode qui doit être écrasée est "org.xml.sax.InputSource.InputSource resolutionEntity (String publicId, String systemId) /EntityResolver.html#resolveEntity (java.lang.String,% 20java.lang.String)) "méthode uniquement.

L'élément clé de ceci est le type String qui indique l'URL de la référence externe dans le deuxième argument, donc le "[org.xml.sax.InputSource.InputSource] correspondant (https://docs.oracle.com/" javase / jp / 6 / api / org / xml / sax / InputSource.html) ”est simplement renvoyé.

Et le approprié de ce type "org.xml.sax.InputSource.InputSource" Classe "Java.io.InputStream" ou "[java.io.Reader](https :: //docs.oracle.com/javase/jp/6/api/java/io/Reader.html) ”doit être renvoyé.

Par exemple, une personnalisation individuelle est possible, comme exiger une authentification ou autoriser uniquement des URI spécifiques.

La "classe exEntityResolver" du code source "exEntityResolver.java" est finalement vide java.io.ByteArrayInputStream pour l'ID système indiquant tous les URI. J'ai décidé de retourner la classe "exInputSource" qui ne renvoie que jp / 6 / api / java / io / ByteArrayInputStream.html).

Ça ressemble à ça.

xxe-java-cust.png

Code source (XXEtest.java)

XXEtest.java


import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import java.io.File;
import org.xml.sax.EntityResolver;

public class XXEtest{
 public static void main(String args[]){
  System.out.println("java.exe test <<inFile>> <<Resolver>>");
  if(0 < args.length){
   Boolean IsResolve = false;
   exEntityResolver myExEntityResolver = null;
   if(1 < args.length){
    if(args[1].equals("null") == true){
     IsResolve = true;
    }else{
     myExEntityResolver = new exEntityResolver();
    }
   }
   try{
    DocumentBuilderFactory tempDocumentBuilderFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder tempDocumentBuilder = tempDocumentBuilderFactory.newDocumentBuilder();
    if(IsResolve == true){
     tempDocumentBuilder.setEntityResolver(null);
    }else if(myExEntityResolver != null){
     tempDocumentBuilder.setEntityResolver(myExEntityResolver);
    }
    Document tempDocument = tempDocumentBuilder.parse(new File(args[0]));
    System.out.println("getTextContent  : " + tempDocument.getTextContent());
    System.out.print("getXmlStandalone: ");
    tempDocument.setXmlStandalone(true);
    System.out.println(tempDocument.getXmlStandalone());
    System.out.println("========Detail=================");
    PrintNode(tempDocument.getChildNodes(), "");
   }catch(Exception e){
    e.printStackTrace();
   }
  }
 }
 static void PrintNode(NodeList nodeList, String spacer){
  Node node = null;
  for(int i=0; i< nodeList.getLength(); i++){
   node = nodeList.item(i);
   String typeStr = "unknown";
   switch(node.getNodeType()){
    case Node.ELEMENT_NODE:
     typeStr = "ELEMENT_NODE";
     break;
    case Node.ATTRIBUTE_NODE:
     typeStr = "ATTRIBUTE_NODE";
     break;
    case Node.TEXT_NODE:
     typeStr = "TEXT_NODE";
     break;
    case Node.CDATA_SECTION_NODE:
     typeStr = "CDATA_SECTION_NODE";
     break;
    case Node.ENTITY_REFERENCE_NODE:
     typeStr = "ENTITY_REFERENCE_NODE";
     break;
    case Node.ENTITY_NODE:
     typeStr = "ENTITY_NODE";
     break;
    case Node.PROCESSING_INSTRUCTION_NODE:
     typeStr = "PROCESSING_INSTRUCTION_NODE";
     break;
    case Node.COMMENT_NODE:
     typeStr = "COMMENT_NODE";
     break;
    case Node.DOCUMENT_NODE:
     typeStr = "DOCUMENT_NODE";
     break;
    case Node.DOCUMENT_TYPE_NODE:
     typeStr = "DOCUMENT_TYPE_NODE";
     break;
    case Node.NOTATION_NODE:
     typeStr = "NOTATION_NODE";
     break;
   }
   System.out.println(spacer + "name =" + node.getNodeName() + ", type=" + typeStr);
   System.out.println(spacer + "value=" + node.getNodeValue());
   System.out.println(spacer + "getTextContent=" + node.getTextContent());
   if(node.hasChildNodes() == true){
    PrintNode(node.getChildNodes(), spacer + " ");
   }
  }
 }
}

Code source (exEntityResolver.java)

Un résolveur qui renvoie simplement une classe InputSource qui renvoie simplement un ByteArrayInputStream vide

exEntityResolver.java


import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import java.io.IOException;

public class exEntityResolver implements EntityResolver{
 public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException{
  System.out.println("publicId: " + publicId);
  System.out.println("systemId: " + systemId);
  return (InputSource)new exInputSource();
 }
}

Code source (exInputSource.java)

Une classe InputSource qui renvoie simplement un ByteArrayInputStream vide.

exInputSource.java


import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.io.Reader;
import java.io.InputStreamReader;

public class exInputSource extends InputSource{
 ByteArrayInputStream myStream;
 public exInputSource(){
  byte[] hako = new byte[0];
  this.myStream = new ByteArrayInputStream(hako);
 }
 public InputStream getByteStream(){
  return (InputStream)this.myStream;
 }
 public Reader getCharacterStream(){
  return (Reader)new InputStreamReader(this.myStream);
 }
}

Revenir

Retour aux principes de base de XXE

Recommended Posts

XXE et Java
Java et JavaScript
Getter et Setter (Java)
[Java] Thread et exécutable
Java vrai et faux
[Java] Comparaison des chaînes de caractères et && et ||
Java - Sérialisation et désérialisation
[Java] Arguments et paramètres
timedatectl et Java TimeZone
[Java] Branchement et répétition
[Java] Types de variables et types
java (classe et instance)
[Java] Surcharge et remplacement
Etudier Java # 2 (\ marque et opérateur)
Java version 8 et fonctionnalités ultérieures
[Java] Différence entre == et égal
[Java] Zone de pile et zone statique
[Java] Classe générique et méthode générique
Programmation Java (variables et données)
Cryptage et décryptage Java PDF
Java et Iterator Part 1 External Iterator Edition
Instructions Java if et switch
Définition et instanciation de classe Java
Apache Hadoop et Java 9 (partie 1)
[Java] À propos de String et StringBuilder
[Java] HashCode et remplacement égal
Java
☾ Instruction Java / Repeat et instruction de contrôle de répétition
Méthodes Java et surcharges de méthodes
java Generics T et? Différence
Avantages et inconvénients de Java
java (branchement conditionnel et répétition)
À propos du package Java et de l'importation
Java
[Java] Téléchargez une image et convertissez-la en Base64
Histoire de remplacement C # et Java
Méthodes et classes abstraites Java
Instructions Java while et for
Encapsulation Java et getters et setters
À propos des méthodes Java statiques et non statiques
Différences entre Java "débutant" et Kotlin
Utiliser java avec MSYS et Cygwin
Traçage distribué avec OpenCensus et Java
[Java] Différence entre Hashmap et HashTable
Déclaration, initialisation et types de variables Java
Installez Java et Tomcat avec Ansible
SDK AWS pour Java 1.11.x et 2.x
[Java] Types de base et notes d'instructions
Date de sortie de Java et résumé EOL
Java et fonctions principales - au-delà de l'interface fonctionnelle -
À propos de Biocontainers fastqc et Java
Java pour les débutants, les expressions et les opérateurs 1
Série Java Primer (variations et types)
Exemple d'encodage et de décodage en Java
Types de données de base et types de référence (Java)
[Java] Traitement en boucle et table de quatre-vingt-dix-neuf
Arguments Java, valeurs de retour et surcharges
Aide sur les commandes OpenJDK 8 java et javac
Mécanisme de référence Java (pile et tas)
Utilisez JDBC avec Java et Scala.
Java pour les débutants, les expressions et les opérateurs 2