> 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/http-verb-tampering.md).

# HTTP Verb Tampering

## Introducción

El protocolo HTTP acepta distintos **métodos (verbos)** al inicio de cada request. Según su configuración, el servidor y la app aceptan ciertos métodos para cada funcionalidad.

Los programadores suelen pensar solo en **GET** y **POST**, pero un cliente puede enviar **cualquier** método y ver cómo lo maneja el servidor.

> Si servidor y app solo aceptan GET/POST, otro método da una página de error (no crítico en sí). Pero si el servidor **no restringe** los métodos y la app **no maneja** los demás (HEAD, PUT...), se puede explotar para acceder a funcionalidades no autorizadas o **saltar controles de seguridad**.

### Verbos HTTP

HTTP tiene 9 verbos. Además de GET/POST, los comunes:

| Verbo       | Descripción                                                          |
| ----------- | -------------------------------------------------------------------- |
| **HEAD**    | Igual que GET, pero la respuesta solo trae headers, sin body.        |
| **PUT**     | Escribe el payload en la ubicación especificada.                     |
| **DELETE**  | Borra el recurso en la ubicación especificada.                       |
| **OPTIONS** | Muestra las opciones que acepta el servidor (ej. verbos permitidos). |
| **PATCH**   | Modificaciones parciales al recurso.                                 |

> Algunos son **sensibles**: `PUT` (escribir archivos en el webroot) o `DELETE` (borrarlos). Si el servidor no los gestiona bien, permiten tomar control del back-end.

Lo que hace al Verb Tampering común y crítico: nace de una **misconfiguración** en el servidor **o** en la app.

### Tipo 1 — Configuración insegura del servidor

La config de **autenticación** puede limitarse a ciertos métodos, dejando otros **sin autenticación**.

```xml
<Limit GET POST>
    Require valid-user
</Limit>
```

> La regla solo cubre GET y POST. Un atacante usando **otro método** (ej. `HEAD`) salta la autenticación por completo → **authentication bypass**, accediendo a páginas que no debería.

***

### Tipo 2 — Codificación insegura (más común)

El desarrollador aplica un filtro a un método pero **no a todos**. Ejemplo: mitigar SQLi solo en el parámetro GET:

```php
$pattern = "/^[A-Za-z\s]+$/";

if(preg_match($pattern, $_GET["code"])) {
    $query = "Select * from ports where port_code like '%" . $_REQUEST["code"] . "%'";
    ...SNIP...
}
```

| Línea                                 | Problema                                       |
| ------------------------------------- | ---------------------------------------------- |
| `preg_match($pattern, $_GET["code"])` | El filtro solo valida el parámetro **GET**.    |
| `$_REQUEST["code"]` en la query       | Usa GET **o** POST → inconsistencia de verbos. |

> El atacante envía la inyección por **POST**: el `$_GET["code"]` va vacío (pasa el filtro), pero `$_REQUEST["code"]` toma el valor POST → la query sigue siendo vulnerable a SQLi.

### Comparación

| Tipo                | Causa                                     | Frecuencia                                           |
| ------------------- | ----------------------------------------- | ---------------------------------------------------- |
| **Config insegura** | Reglas de auth limitadas a ciertos verbos | Menos común (la documentación advierte contra ello). |
| **Coding inseguro** | Filtros que no cubren todos los verbos    | **Más común** (errores de programación).             |

### Resumen rápido

| Concepto             | Detalle                                                                         |
| -------------------- | ------------------------------------------------------------------------------- |
| **Idea central**     | El servidor/app maneja distinto según el verbo → se abusa un verbo no cubierto. |
| **Verbos sensibles** | `PUT` (escribir), `DELETE` (borrar), `HEAD` (bypass de auth).                   |
| **Auth bypass**      | `<Limit GET POST>` → usar `HEAD` u otro verbo.                                  |
| **Filter bypass**    | Filtro en `$_GET` pero query usa `$_REQUEST` → inyectar por POST.               |

## Bypassing Basic Authentication

Explotar Verb Tampering es directo: probar métodos HTTP alternativos y ver cómo los maneja el servidor.

> Los scanners automáticos detectan bien el tipo por **config insegura** (se ve al saltar una auth), pero **fallan** con el de coding inseguro (requiere testing activo de los filtros).

Este caso ataca el tipo por **configuración insegura del servidor** → bypass del prompt de **HTTP Basic Auth**.

### 1. Identificar la página restringida

Ejemplo: un File Manager. El botón **Reset** (borrar todos los archivos) está restringido → aparece prompt de Basic Auth. Sin credenciales → **401 Unauthorized**.

Ver a qué apunta el botón (URL o request en Burp): `/admin/reset.php`. Visitar `/admin/` también pide login → **todo el directorio `/admin`** está restringido.

### 2. Identificar el método usado

Interceptar la request del Reset en Burp → usa **GET**.

Probar cambiarla a **POST** (Burp: clic derecho → **Change Request Method**):

> Sigue pidiendo login / 401 → la config cubre **GET y POST**. Toca probar otros verbos.

### 3. Descubrir métodos aceptados (OPTIONS)

```bash
curl -i -X OPTIONS http://<SERVER_IP>:<PORT>/
# HTTP/1.1 200 OK
# Server: Apache/2.4.41 (Ubuntu)
# Allow: POST,OPTIONS,HEAD,GET
```

| Elemento            | Descripción                                                            |
| ------------------- | ---------------------------------------------------------------------- |
| `-X OPTIONS`        | Pregunta al servidor qué métodos acepta.                               |
| `-i`                | Incluye los headers en la salida.                                      |
| `Allow: ...HEAD...` | El servidor acepta **HEAD** (config por defecto en muchos servidores). |

### 4. Explotar con HEAD

**HEAD** es idéntico a GET pero la respuesta **no trae body**. Si la auth solo cubre GET/POST, un HEAD **salta la autenticación** y la función Reset igual se ejecuta (aunque no veamos output).

Interceptar la request y cambiar el método a **HEAD** → forward.

> No aparece login ni 401, la salida es vacía (esperable en HEAD). Al volver al File Manager, **todos los archivos fueron borrados** → se disparó Reset **sin credenciales ni acceso admin**.

### Resumen rápido

| Paso           | Acción                                                             |
| -------------- | ------------------------------------------------------------------ |
| 1. Identificar | La función restringida (`/admin/reset.php`) y su directorio.       |
| 2. Probar POST | `Change Request Method` → sigue pidiendo auth → cubre GET+POST.    |
| 3. OPTIONS     | `curl -X OPTIONS` → ver `Allow:` → confirma HEAD.                  |
| 4. HEAD        | Cambiar método a HEAD → ejecuta la acción sin auth (output vacío). |

> La `<Limit GET POST>` deja **HEAD** (y otros) fuera de la autenticación. HEAD ejecuta la acción en el back-end aunque no devuelva body → bypass perfecto para funciones de estado (reset, delete).

## Bypassing Security Filters

El tipo más común de Verb Tampering: **coding inseguro** durante el desarrollo, donde la app no cubre **todos los métodos HTTP** en cierta funcionalidad. Frecuente en **filtros de seguridad** que detectan requests maliciosas.

> Si un filtro anti-inyección solo revisa parámetros **POST** (ej. `$_POST['parameter']`), se bypassea cambiando el método a **GET** (o viceversa). El filtro no ve el parámetro y la request pasa.

### 1. Identificar el filtro

En el File Manager, crear un archivo con caracteres especiales (ej. `test;`) → mensaje **"Malicious Request Denied!"**.

> La app usa filtros back-end para detectar inyecciones y bloquea. Hagamos lo que hagamos, bloquea → probamos Verb Tampering para saltar el filtro **por completo**.

### 2. Explotar — cambiar el método

Interceptar en Burp → **Change Request Method** (cambiar el verbo, ej. POST → GET):

> Esta vez **no** aparece "Malicious Request Denied!" y el archivo **se crea** → el filtro no cubría este método.

### 3. Confirmar la vulnerabilidad protegida (Command Injection)

Saltar el filtro no basta; hay que confirmar que la vuln que protegía es explotable. Inyectar un comando que cree **dos** archivos:

```
file1; touch file2;
```

Enviar con el método que bypassea el filtro (cambiar de vuelta a **POST** en el ejemplo del módulo, según cuál esté sin filtrar).

> Si se crean **ambos** (`file1` **y** `file2`) → el `touch file2` se ejecutó → **command injection** confirmada.

| Elemento              | Descripción                                                                  |
| --------------------- | ---------------------------------------------------------------------------- |
| `file1; touch file2;` | Nombre con inyección: `;` separa comandos, `touch file2` crea el 2º archivo. |
| Change Request Method | Cambia el verbo para evitar el parámetro que el filtro inspecciona.          |
| 2 archivos creados    | Prueba de que el comando inyectado se ejecutó.                               |

### Resumen rápido

| Paso           | Acción                                                                 |
| -------------- | ---------------------------------------------------------------------- |
| 1. Identificar | Input malicioso (`test;`) → "Malicious Request Denied!".               |
| 2. Bypass      | Burp → Change Request Method → el filtro deja de aplicar.              |
| 3. Confirmar   | Inyectar `file1; touch file2;` → si crea ambos, hay command injection. |

> Sin el Verb Tampering, la app estaría segura contra command injection. El filtro solo cubría un método → cambiar el verbo lo anula por completo. Conecta directo con el módulo de **Command Injection**: aquí el Verb Tampering es la llave que abre la inyección.

## Prevención

El Verb Tampering nace de **configuraciones inseguras** o **coding inseguro**. Veamos código/config vulnerables y cómo parchearlos.

### 1. Configuración insegura

Ocurre en la mayoría de servidores (Apache, Tomcat, ASP.NET) al limitar la autorización de una página a un **conjunto concreto de verbos**, dejando el resto sin proteger.

#### Apache (`000-default.conf` / `.htaccess`)

```xml
<Directory "/var/www/html/admin">
    AuthType Basic
    AuthName "Admin Panel"
    AuthUserFile /etc/apache2/.htpasswd
    <Limit GET>
        Require valid-user
    </Limit>
</Directory>
```

> `<Limit GET>` → la auth solo aplica a **GET**; POST (y HEAD, OPTIONS...) quedan accesibles.

#### Tomcat (`web.xml`)

```xml
<security-constraint>
    <web-resource-collection>
        <url-pattern>/admin/*</url-pattern>
        <http-method>GET</http-method>
    </web-resource-collection>
    <auth-constraint>
        <role-name>admin</role-name>
    </auth-constraint>
</security-constraint>
```

> `<http-method>GET</http-method>` limita la restricción a GET.

#### ASP.NET (`web.config`)

```xml
<system.web>
    <authorization>
        <allow verbs="GET" roles="admin">
            <deny verbs="GET" users="*">
        </deny>
        </allow>
    </authorization>
</system.web>
```

> `allow`/`deny` limitados a GET → accesible por otros métodos.

#### Fix — keywords que cubren TODOS los verbos excepto los indicados

| Servidor    | Keyword seguro         |
| ----------- | ---------------------- |
| **Apache**  | `LimitExcept`          |
| **Tomcat**  | `http-method-omission` |
| **ASP.NET** | `add` / `remove`       |

> No restringir la auth a un verbo específico: aplicar allow/deny a **todos**. Además, **deshabilitar/denegar HEAD** salvo que la app lo requiera.

### 2. Coding inseguro

Más difícil de detectar: hay que hallar **inconsistencias en el uso de parámetros HTTP** entre funciones.

#### Código vulnerable (File Manager)

```php
if (isset($_REQUEST['filename'])) {
    if (!preg_match('/[^A-Za-z0-9. _-]/', $_POST['filename'])) {
        system("touch " . $_REQUEST['filename']);
    } else {
        echo "Malicious Request Denied!";
    }
}
```

| Línea                                      | Problema                                     |
| ------------------------------------------ | -------------------------------------------- |
| `preg_match(..., $_POST['filename'])`      | El filtro solo valida el parámetro **POST**. |
| `system("touch " . $_REQUEST['filename'])` | Usa `$_REQUEST` → GET **o** POST.            |

> El fallo no es de command injection en sí, sino de **inconsistencia de métodos**: al enviar por **GET**, `$_POST['filename']` va vacío (pasa el filtro), pero `$_REQUEST['filename']` toma el valor GET → llega a `system()` → **command injection**.

> En producción esto es menos obvio: el filtro y la creación de archivos suelen estar en **funciones separadas**, no en líneas consecutivas → la inconsistencia sobrevive.

#### Fix — cubrir TODOS los métodos en los filtros

Ser consistente: usar siempre el mismo método para cada funcionalidad, y **testear todos los parámetros** en los filtros de seguridad.

| Lenguaje | Función que cubre todos los métodos |
| -------- | ----------------------------------- |
| **PHP**  | `$_REQUEST['param']`                |
| **Java** | `request.getParameter('param')`     |
| **C#**   | `Request['param']`                  |

> Si el filtro de seguridad usa la misma fuente que la lógica (ej. `$_REQUEST` en ambos), no hay inconsistencia que explotar.

### Resumen rápido (checklist)

| Capa        | Action point                                                                             |
| ----------- | ---------------------------------------------------------------------------------------- |
| **Config**  | No limitar auth a un verbo; usar `LimitExcept` / `http-method-omission` / `add-remove`.  |
| **HEAD**    | Deshabilitar/denegar salvo que sea necesario.                                            |
| **Coding**  | Consistencia de métodos: filtro y lógica deben leer la **misma** fuente.                 |
| **Filtros** | Cubrir todos los parámetros: `$_REQUEST` (PHP), `getParameter` (Java), `Request[]` (C#). |

> Regla de oro: si el filtro cubre **el mismo alcance de métodos** que la función que protege, el Verb Tampering deja de ser posible.


---

# 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/http-verb-tampering.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.
