CodeQL documentation

Server-side template injection

ID: java/server-side-template-injection
Kind: path-problem
Security severity: 9.3
Severity: error
Precision: high
Tags:
   - security
   - external/cwe/cwe-1336
   - external/cwe/cwe-094
Query suites:
   - java-code-scanning.qls
   - java-security-extended.qls
   - java-security-and-quality.qls

Click to see the query in the CodeQL repository

Template injection occurs when user input is embedded in a template’s code in an unsafe manner. An attacker can use native template syntax to inject a malicious payload into a template, which is then executed server-side. This permits the attacker to run arbitrary code in the server’s context.

Recommendation

To fix this, ensure that untrusted input is not used as part of a template’s code. If the application requirements do not allow this, use a sandboxed environment where access to unsafe attributes and methods is prohibited.

Example

In the example given below, an untrusted HTTP parameter code is used as a Velocity template string. This can lead to remote code execution.

@Controller
public class VelocitySSTI {

	@GetMapping(value = "bad")
	public void bad(HttpServletRequest request) {
		Velocity.init();

		String code = request.getParameter("code");

		VelocityContext context = new VelocityContext();

		context.put("name", "Velocity");
		context.put("project", "Jakarta");

		StringWriter w = new StringWriter();
		// evaluate( Context context, Writer out, String logTag, String instring )
		// BAD: code is controlled by the user
		Velocity.evaluate(context, w, "mystring", code);
	}
}

In the next example, the problem is avoided by using a fixed template string s. Since the template’s code is not attacker-controlled in this case, this solution prevents the execution of untrusted code.

@Controller
public class VelocitySSTI {

	@GetMapping(value = "good")
	public void good(HttpServletRequest request) {
		Velocity.init();
		VelocityContext context = new VelocityContext();

		context.put("name", "Velocity");
		context.put("project", "Jakarta");

		String s = "We are using $project $name to render this.";
		StringWriter w = new StringWriter();
		Velocity.evaluate(context, w, "mystring", s); // GOOD: s is a constant string
		System.out.println(" string : " + w);
	}
}

References

  • © GitHub, Inc.
  • Terms
  • Privacy
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy