Aller au contenu

XPath Injection Vulnerability

Vulnérabilité d'injection XPath

Description

L'injection XPath est un type d'attaque par injection ciblant les applications qui utilisent XPath pour interroger des données XML. Elle se produit lorsqu'un attaquant injecte une entrée malveillante dans une requête XPath, ce qui peut conduire à un accès non autorisé à des données sensibles, à la modification de données ou même à la compromission complète du système. Cette vulnérabilité peut être exploitée par des attaquants pour contourner les mécanismes d'authentification, exécuter du code arbitraire et accéder à des informations sensibles.

void _fetch_data(String _searchQuery) {

  final content = XmlDocument.parse(xmlFileContent);
  final xml_node = XmlXPath.node(content);
  final xpath = xml_node.query('//book[author=$_searchQuery');

  showDialog(
    context: context,
    builder: (context) => AlertDialog(
      title: Text('Search Result'),
      content: Text(result),
    ),
  );
  }
import Foundation
import SWXMLHash

func main() {
    print("Enter search term:")
    let searchTerm = readLine()!
    let xml = SWXMLHash.parse(xmlString)
    let results = xml["books"]["book"].all(withAttribute: "title", matchingXPath: "//title[contains(text(), '\(searchTerm)')]")

    for result in results {
        print(result["title"].element!.text)
        print(result["author"].element!.text)
    }
}
import javax.xml.parsers.DocumentBuilderFactory

fun main() {
    val userInput = readLine() ?: return
    val xpathQuery = "//*[username/text()='${userInput}']"

    val xmlData = """
        <users>
            <user>
                <username>Alice</username>
                <password>pass123</password>
            </user>
            <user>
                <username>Bob</username>
                <password>pass456</password>
            </user>
        </users>
    """.trimIndent()

    val xpath = XPathFactory.newInstance().newXPath()
    val result = xpath.evaluate(xpathQuery, xmlData)
}

Recommandation

Pour atténuer les vulnérabilités d'injection XPath, il est important de :

  • Utiliser des requêtes paramétrées ou des instructions préparées, qui séparent l'entrée utilisateur de la logique de la requête.
  • Valider et assainir correctement les entrées utilisateur avant de les utiliser dans des requêtes XPath.
bool _validate_query(String _searchQuery){
  // check for special characters
  for(var i = 0; i < tokens.length; i++){
      if (string.contains(new RegExp(r'[A-Z]')) == false){
        return false;
      }
    }
  return true;
}

void _fetch_data(String _searchQuery) {

  // validate user input
  if (_validate_query(_searchQuery) == false){
    // raise error
    return ;
  }
  final content = XmlDocument.parse(xmlFileContent);
  final xml_node = XmlXPath.node(content);
  final xpath = xml_node.query('//book[author=$_searchQuery');

  showDialog(
    context: context,
    builder: (context) => AlertDialog(
      title: Text('Search Result'),
      content: Text(result),
    ),
  );
  }
import Foundation
import SWXMLHash

func main() {
    print("Enter search term:")
    guard let searchTerm = readLine()?.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {
        print("Invalid search term")
        return
    }

    let xml = SWXMLHash.parse(xmlString)
    let results = xml["books"]["book"].all(withAttribute: "title", matchingXPath: "//title[contains(text(), '\(searchTerm)')]")

    for result in results {
        print(result["title"].element!.text)
        print(result["author"].element!.text)
    }
}
fun sanitize(input: String): String {
    // Replace all XPath special characters with their HTML entities
    return input.replace("&", "&amp;")
                .replace("<", "&lt;")
                .replace(">", "&gt;")
                .replace(""", "&quot;")
                .replace("'", "&apos;")
}

fun main() {
    val userInput = readLine() ?: return

    val xmlData = """
        <users>
            <user>
                <username>Alice</username>
                <password>pass123</password>
            </user>
            <user>
                <username>Bob</username>
                <password>pass456</password>
            </user>
        </users>
    """.trimIndent()

    val sanitizedInput = sanitize(userInput)
    val xpathQuery = "//*[username/text()='${sanitizedInput}']"

    val xpath = XPathFactory.newInstance().newXPath()
    val expression = xpath.compile(xpathQuery)

    val result = expression.evaluate(xmlData, XPathConstants.NODESET)

    val nodeList = result as? List<*> ?: emptyList<Any>()

    val matchedUsers = nodeList.filterIsInstance<org.w3c.dom.Node>()
        .map { node -> node.textContent }
        .joinToString(", ")

    println("Matched users: $matchedUsers")
}

Liens

Normes

  • OWASP_MASVS_L1:
    • MSTG_PLATFORM_2
  • OWASP_MASVS_L2:
    • MSTG_PLATFORM_2
  • CWE_TOP_25:
    • CWE_89
  • PCI_STANDARDS:
    • REQ_2_2
    • REQ_6_2
    • REQ_6_3
    • REQ_11_3
  • OWASP_MASVS_v2_1:
    • MASVS_CODE_4
  • SOC2_CONTROLS:
    • CC_2_1
    • CC_3_4
    • CC_4_1
    • CC_7_1
    • CC_7_2
    • CC_7_4
    • CC_7_5
  • HIPAA_CONTROLS:
    • SECURITY212
    • SECURITY213
    • SECURITY255