> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hub2.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Security

# Security considerations

Security remains the top priority when it comes to online financial transactions.

## Integration

To ensure that exchanges between the merchant and HUB2 remain confidential, and that only the merchant is at the origin of the transactions (and therefore of the amount and other properties of these transactions), **the integration of the API must only take place on the server side**.

Sensitive data, such as API keys, **must never be disclosed**, whether on a website or in a mobile application.

This approach strengthens security by avoiding direct exposure of API keys and sensitive information on the client side. By performing transactions on the server side, the risk of malicious attacks, such as client-side data manipulation, is considerably reduced.

## CORS

To protect against potential client-side integrations, the HUB2 API is set up so that it can never be loaded from the end-client's browser.

In other words, the HTTP headers for *cross origin resource sharing* ([CORS](https://developer.mozilla.org/fr/docs/Web/HTTP/CORS)) have been correctly set.

# Signature

To enhance the security and integrity of API interactions, an optional payload signature mechanism is available. This feature enables merchants to cryptographically sign the JSON request body sent to the API. By verifying this signature, it can be ensured that the data has not been tampered with in transit and originates from a trusted source. This added layer of security is particularly valuable for sensitive financial transactions.

Check out the [integration page](/integration/en/other_products/payload_signature) to understand how to use out.

# Platform security mechanisms

To protect the HUB2 platform, several security components are implemented at different levels of the infrastructure.

At the perimeter, a *Web Application Firewall* (WAF) analyzes every single HTTP request before forwarding it to the backend. Its primary role is to detect and block malicious HTTP requests before they can reach the application layer.

For **rejected requests**, clients will face the following behavior:

<Card title="WAF behavior" img="https://mintcdn.com/hub2-83/QRWPuZcG9DMHOF_6/assets/HUB2-WAF-HTTP-403-Forbidden.png?fit=max&auto=format&n=QRWPuZcG9DMHOF_6&q=85&s=6da143e2693f14c8d428dc2ed9443bbb" width="633" height="434" data-path="assets/HUB2-WAF-HTTP-403-Forbidden.png">
  Here, an SQL injection (SQLi attack) is simulated on the HUB2 API.<br />The web application firewall immediately rejects the request and returns a response with the status `HTTP 403 Forbidden`.
</Card>

<Warning>
  **Note:** The <Tooltip headline="WAF" tip="Web Application Firewall">WAF</Tooltip> will *always* return a `text/html` response Body.<br />
  **Please keep this in mind when integrating the HUB2 API.**
</Warning>

### Troubleshooting `HTTP 403 Forbidden` common errors

If a legitimate request faces an `HTTP 403 Forbidden`, please first follow the below guidelines to ensure your integration complies with our security standards.

<Note>
  If your request is still rejected after applying the below guidelines, feel free to file a ticket with the HUB2 Support team.
</Note>

#### 1. `GET` HTTP request with Body content

* `GET` requests must **NOT** include any Body content. All non-compliant requests will be rejected by the HUB2 security gateway.
* The `Content-Length` header is not mandatory for a `GET` request. However, if included, it must be set to `0` and the body must remain completely empty.

For example:

<AccordionGroup>
  <Accordion title="Bad practice" icon="xmark" defaultOpen>
    Notice the `Content-Type` & `Content-Length` headers sent, along with the **Body content** for a `GET` request. Such requests will be rejected. <Icon icon="xmark" iconType="solid" color="#ff1b62" />

    ```http theme={null}
    GET /webhooks/ HTTP/1.1
    Host: api.hub2.io
    Accept: application/json
    User-Agent: Example Merchant backend/1.0
    Content-Type: application/json <------------ Here
    Content-Length: 184 <----------------------- Here

    {"url":"https://my.webhook.target","events":["payment.created","payment_intent.created"],"description":"This is a webhook trigger upon payment & payment_intent creation","metadata":{}}
    ^----------- Here
    ```

    See the ***Good practice*** below to fix this. <Icon icon="check" iconType="solid" color="#07c983" />
  </Accordion>

  <Accordion title="Good practice" icon="check">
    Apply the following recommendations to avoid triggering the security gateway:

    1. Remove the Body content entirely.
    2. Remove the `Content-Type` & `Content-Length` headers (`Content-Length` is generally computed automatically by your HTTP client library, so there is usually nothing extra to configure).

    ```http theme={null}
    GET /webhooks/ HTTP/1.1
    Host: api.hub2.io
    Accept: application/json
    User-Agent: Example Merchant backend/1.0

    ```
  </Accordion>
</AccordionGroup>

#### 2. Non-stringified JSON body

All HTTP `POST` requests using `application/json` must be **stringified** as a **single line of text**. Multi-line JSON payloads will be rejected by the HUB2 security gateway. Formatting the JSON string with carriage returns (CR/LF) or spaces (except inside the values themselves) can trigger filtering rules.

For example:

<AccordionGroup>
  <Accordion title="Bad practice" icon="xmark" defaultOpen>
    Notice the **multi-line JSON object** in the Body content below:

    ```http theme={null}
    POST /webhooks/ HTTP/1.1
    Host: api.hub2.io
    Accept: application/json
    User-Agent: Example Merchant backend/1.0
    Content-Type: application/json
    Content-Length: 214

    v----------- Here
    {
        "url": "https://my.webhook.target",
        "events": [
            "payment.created",
            "payment_intent.created"
        ],
        "description": "This is a webhook trigger upon payment & payment_intent creation",
        "metadata": {}
    }
    ```

    See the ***Good practice*** below to fix this. <Icon icon="check" iconType="solid" color="#07c983" />
  </Accordion>

  <Accordion title="Good practice" icon="check">
    To avoid triggering the security gateway, transform the multi-line Body content into a **single line of text**, as follows:

    ```http theme={null}
    POST /webhooks/ HTTP/1.1
    Host: api.hub2.io
    Accept: application/json
    User-Agent: Example Merchant backend/1.0
    Content-Type: application/json
    Content-Length: 184

    {"url":"https://my.webhook.target","events":["payment.created","payment_intent.created"],"description":"This is a webhook trigger upon payment & payment_intent creation","metadata":{}}
    ```
  </Accordion>
</AccordionGroup>

#### 3. Body content differs from the `Content-Type` header

The HUB2 API currently only accepts JSON payloads. If an HTTP request is sent with valid JSON content, but the `Content-Type` header is set to a different value (e.g., `text/plain`, `text/xml`, or `application/x-www-form-urlencoded`), the security gateway will parse it incorrectly and block the request.

For example:

<AccordionGroup>
  <Accordion title="Bad practice" icon="xmark" defaultOpen>
    Notice the incorrect `Content-Type` header given the JSON payload:

    ```http theme={null}
    POST /webhooks/ HTTP/1.1
    Host: api.hub2.io
    Accept: application/json
    User-Agent: Example Merchant backend/1.0
    Content-Type: application/x-www-form-urlencoded <------------ Here
    Content-Length: 184

    {"url":"https://my.webhook.target","events":["payment.created","payment_intent.created"],"description":"This is a webhook trigger upon payment & payment_intent creation","metadata":{}}
    ```

    See the ***Good practice*** below to fix this. <Icon icon="check" iconType="solid" color="#07c983" />
  </Accordion>

  <Accordion title="Good practice" icon="check">
    Always set the `Content-Type` header **to match the Body content** format:

    ```http theme={null}
    POST /webhooks/ HTTP/1.1
    Host: api.hub2.io
    Accept: application/json
    User-Agent: Example Merchant backend/1.0
    Content-Type: application/json <------------ Here
    Content-Length: 184

    {"url":"https://my.webhook.target","events":["payment.created","payment_intent.created"],"description":"This is a webhook trigger upon payment & payment_intent creation","metadata":{}}
    ```
  </Accordion>
</AccordionGroup>
