Skip to content

Commit

Permalink
http method override challenges solution
Browse files Browse the repository at this point in the history
  • Loading branch information
eviltester committed Jan 1, 2025
1 parent 4416747 commit 7c7e6c9
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ public static ChallengeDefinitionData overridePostToPatchFor500(int challengeOrd
"Issue a POST request on the `/heartbeat` end point and receive 500 when you override the Method Verb to a PATCH");

aChallenge.addHint("Use a normal POST Request, but add an X-HTTP-Method-Override header");

aChallenge.addSolutionLink("Add a header 'X-HTTP-Method-Override: PATCH' to a POST /heartbeat request", "","");
//aChallenge.addSolutionLink("Read Solution", "HREF","https://www.eviltester.com/apichallenges/howto/25-26-27-28-status-codes-405-500-501-204/");
aChallenge.addSolutionLink("Read Solution", "HREF","/apichallenges/solutions/method-override/all-method-overrides");
//aChallenge.addSolutionLink("Watch Insomnia Solution", "YOUTUBE", "SGfKVFdylVI");
return aChallenge;
}
Expand All @@ -77,8 +78,9 @@ public static ChallengeDefinitionData overridePostToDeleteFor405(int challengeOr
"Issue a POST request on the `/heartbeat` end point and receive 405 when you override the Method Verb to a DELETE");

aChallenge.addHint("Use a normal POST Request, but add an X-HTTP-Method-Override header");

aChallenge.addSolutionLink("Add a header 'X-HTTP-Method-Override: DELETE' to a POST /heartbeat request", "","");
//aChallenge.addSolutionLink("Read Solution", "HREF","https://www.eviltester.com/apichallenges/howto/25-26-27-28-status-codes-405-500-501-204/");
aChallenge.addSolutionLink("Read Solution", "HREF","/apichallenges/solutions/method-override/all-method-overrides");
//aChallenge.addSolutionLink("Watch Insomnia Solution", "YOUTUBE", "SGfKVFdylVI");
return aChallenge;
}
Expand All @@ -90,9 +92,10 @@ public static ChallengeDefinitionData overridePostToTraceFor501(int challengeOrd
"POST /heartbeat as Trace (501)",
"Issue a POST request on the `/heartbeat` end point and receive 501 (Not Implemented) when you override the Method Verb to a TRACE");
aChallenge.addHint("Use a normal POST Request, but add an X-HTTP-Method-Override header");

aChallenge.addSolutionLink("Add a header 'X-HTTP-Method-Override: TRACE' to a POST /heartbeat request", "","");
aChallenge.addSolutionLink("Read Solution", "HREF","/apichallenges/solutions/method-override/all-method-overrides");

// aChallenge.addSolutionLink("Read Solution", "HREF","https://www.eviltester.com/apichallenges/howto/25-26-27-28-status-codes-405-500-501-204/");
// aChallenge.addSolutionLink("Watch Insomnia Solution", "YOUTUBE", "SGfKVFdylVI");
return aChallenge;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ description: A list of all the solutions for the API Challenges. Try them yourse

## HTTP Method Override Challenges

- [Solve the /heartbeat Method Override Challenges](/apichallenges/solutions/method-overrides/all-method-overrides)
- POST /heartbeat as DELETE (405)
- POST /heartbeat as PATCH (500)
- POST /heartbeat as Trace (501)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
date: 2025-01-01T14:54:00Z
title: API Challenges Solution For - Method Override Challenges
description: How to solve API challenges for Method Override DELETE, PATCH, TRACE.
---

# How to complete the HTTP Method Override Challenges

All of the method override challenges use the same mechanism so we can cover them all in this solution.

Sometimes tools and libraries will not issue TRACE or PATCH requests. There is a specific HTTP header we can use to try and have POST requests treated as other verbs.

The header "X-HTTP-Method-Override" is not guaranteed to work on every server, but some HTTP servers will take this header and treat the request using the value in the header:

`X-HTTP-Method-Override: DELETE`

This is worth understanding because it might also be used to bypass validation, or trigger functionality that the user is not authorized to trigger.


## POST /heartbeat

> Issue a `POST` request to `/heartbeat` with an `X-HTTP-Method-Override` header specifying the verb you actually want
- `POST` request can be sent by all tools
- We need to add the header `X-HTTP-Method-Override` to the request and the value should be the verb we want to send e.g. `TRACE`


## Basic Instructions

Each challenge requires a different verb, but the process is the same for each, the only difference is the value of the `X-HTTP-Method-Override` header

- Issue a POST request to end point "/heartbeat"
- The request should have an `X-HTTP-Method-Override` with the value associated with the challenge i.e. `DELETE`, `PATCH`, `TRACE`
- The request should have an `X-CHALLENGER` header to track challenge completion
- The response status code should match the value for teh challenge overridden verb
- for `DELETE` be `405`
- for `TRACE` be `501`
- for `PATCH` be `500` as the API is simulating a server error

NOTE: This header feature is normally implemented by the HTTP server so often development teams are not even aware that this is possible. Depending on how requests are validated in code it might be possible for someone, who has amend access using `POST` but who does not have `DELETE` access, to be able to use this header approach to delete something.

NOTE: As an additional exercise, you might want to see if you can DELETE todos using a POST and the `X-HTTP-Method-Override` header. Experiment and see what you can achieve using this approach.

## Example Request

~~~~~~~~
> POST /todos/3 HTTP/1.1
> Host: {{<HOST_URL>}}
> User-Agent: rest-client
> X-HTTP-Method-Override: DELETE
> X-CHALLENGER: x-challenger-guid
> Content-Type: application/json
> Accept: */*
> Content-Length: 108
~~~~~~~~





Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package uk.co.compendiumdev.challenger.restassured._16_http_method_override_challenges;

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.Test;
import uk.co.compendiumdev.challenger.payloads.Todo;
import uk.co.compendiumdev.challenger.restassured.api.RestAssuredBaseTest;
import uk.co.compendiumdev.challenger.restassured.api.TodosApi;

public class CXXXextraDeleteExistingTodo200Test extends RestAssuredBaseTest {

@Test
void canDeleteATodoItem(){

TodosApi api = new TodosApi();

Todo created = api.createTodo("my new todo",
"my description",
true);

RestAssured.
given().
header("X-CHALLENGER", xChallenger).
header("X-HTTP-Method-Override", "DELETE").
accept("application/json").
post(apiPath( "/todos/" + created.id)).
then().
statusCode(200).
contentType(ContentType.JSON);

// check it was actually deleted
RestAssured.
given().
accept("application/json").
get(apiPath( "/todos/" + created.id)).
then().
statusCode(404);
}

}

0 comments on commit 7c7e6c9

Please sign in to comment.