# Segurança

## **🔐 Validação de Assinatura de Webhooks**

Para garantir a **autenticidade** e a **integridade** das notificações enviadas pelo nosso sistema, todos os webhooks são assinados utilizando um segredo compartilhado (*webhook secret*), que realiza a assinatura do payload via HMAC SHA-256.

#### **📌 Como funciona**

Cada requisição enviada contém:

* O **payload** (corpo da requisição)
* Um header HTTP:

```
X-Signature: {assinatura}
```

Essa assinatura é gerada aplicando um **HMAC SHA-256** sobre o payload bruto utilizando o *token de segurança* configurado:

![image.png](/files/YhXiDhb3tPkAplKkDFX4)

***

#### **🎯 Objetivo da validação**

O sistema receptor deve validar a assinatura para garantir:

* ✔️ Que o payload **não foi alterado** (integridade)
* ✔️ Que a requisição foi **enviada por um remetente confiável** (autenticidade)
* ✔️ Que a comunicação é **segura contra ataques de replay ou spoofing**

***

### **⚙️ Passo a passo para validação**

Ao receber o webhook, seu sistema deve:

1. **Ler o payload bruto da requisição**
   * Importante: não utilize payload já parseado (ex: JSON decodificado)
2. **Obter o header `X-Signature`**
3. **Gerar uma nova assinatura localmente**
   * Utilizando:
     * O payload bruto
     * O *secret* compartilhado
4. **Comparar as assinaturas**
   * Utilize comparação segura (*timing-safe comparison*)
5. **Rejeitar a requisição caso a assinatura seja inválida**
   * Retorne HTTP `403 Forbidden`

***

### **💻 Exemplo em PHP (Laravel)**

```php
$payload = request()->getContent();
$secret = 'xuiq12' // aqui vai o token que é exibido na criação do webhook

$receivedSignature = request()->header('x-signature');

$expectedSignature = hash_hmac('sha256', $payload, $secret);

if (! hash_equals($expectedSignature, $receivedSignature)) {
    abort(403, 'Invalid signature');
}
```

### **💻 Exemplo em NodeJS**

```javascript
const crypto = require('crypto');
const express = require('express');

const app = express();

// ⚠️ Importante: precisamos do payload bruto
app.use(express.raw({ type: '*/*' }));

const SECRET = process.env.WEBHOOK_SECRET;

app.post('/webhook', (req, res) => {
    const payload = req.body; // Buffer (raw)
    const receivedSignature = req.header('x-signature');

    const expectedSignature = crypto
        .createHmac('sha256', SECRET)
        .update(payload)
        .digest('hex');

    const isValid = crypto.timingSafeEqual(
        Buffer.from(expectedSignature),
        Buffer.from(receivedSignature || '')
    );

    if (!isValid) {
        return res.status(403).send('Invalid signature');
    }

    // ✅ assinatura válida → processar webhook
    console.log('Webhook válido:', payload.toString());

    res.status(200).send('OK');
});

app.listen(3000, () => {
    console.log('Server running on port 3000');
});
```

***

### ⚠️ Boas práticas (importante)

#### 1. Use sempre o payload bruto

Qualquer transformação (ex: `json_decode` → `json_encode`) pode invalidar a assinatura.

***

#### 2. Nunca use comparação simples (`===`)

Utilize sempre:

```
hash_equals()
```

***

#### 3. Proteja seu webhook secret

* Nunca exponha no frontend
* Armazene em variáveis de ambiente seguras

***

#### 4. Valide antes de processar

A validação da assinatura deve ser o **primeiro passo** antes de qualquer lógica de negócio


---

# Agent Instructions: 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:

```
GET https://documentation.themembers.dev.br/webhooks/webhooks-do-checkout/seguranca.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
