Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

🏠 Back to Blog

HTTP Verb Tampering — Prevention

Two root causes: insecure server configurations and insecure application code. Both must be addressed.

Insecure Configuration

HTTP Verb Tampering vulnerabilities occur when authorization is limited to specific HTTP verbs, leaving remaining methods unprotected. This affects all major web servers.

Vulnerable Apache Configuration

Found in site config (e.g., 000-default.conf) or .htaccess:

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

<Limit GET> restricts auth to GET only — POST, HEAD, OPTIONS, etc. are all unprotected. Even listing both GET and POST still leaves other methods open.

Vulnerable Tomcat Configuration

Found in web.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> limits authorization to GET only.

Vulnerable ASP.NET Configuration

Found in web.config:

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

allow and deny scoped to GET only.

Fixes

Rule: never restrict authorization to a specific HTTP method. Always allow/deny all verbs.

To specify a single method while covering all others, use safe keywords:

ServerSafe keywordWhat it does
ApacheLimitExceptCovers all verbs except the specified ones
Tomcathttp-method-omissionCovers all verbs except the specified ones
ASP.NETadd/removeCovers all verbs except the specified ones

Additionally, consider disabling/denying all HEAD requests unless specifically required by the web application.

Insecure Coding

Harder to identify than config issues — requires finding inconsistencies in HTTP parameter usage across functions.

Vulnerable PHP Example

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

This looks secure against command injection — preg_match properly blocks special characters. The fatal error is inconsistent HTTP method usage:

  • The filter checks $_POST['filename']
  • The system() call uses $_REQUEST['filename'] (covers both GET and POST)

Attack: Send malicious input via GET. The $_POST parameter is empty (passes the filter), but $_REQUEST picks up the GET parameter and passes it to system() — command injection achieved.

In production, these inconsistencies are spread across the codebase (separate functions for validation and execution), making them much harder to catch.

Fixes

Rule: be consistent with HTTP methods. Use the same method for a given functionality across the entire application.

Expand the scope of security filters to test all request parameters:

LanguageUse this (covers all methods)
PHP$_REQUEST['param']
Javarequest.getParameter('param')
C#Request['param']

If security-related functions cover all methods, verb tampering bypasses are eliminated.