Skip to content

Commit

Permalink
docs(json-threat-protection): add docs for json-threat-protection plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
Water-Melon committed Aug 29, 2024
1 parent 7bc3362 commit 24fc2f4
Show file tree
Hide file tree
Showing 5 changed files with 286 additions and 0 deletions.
5 changes: 5 additions & 0 deletions app/_hub/kong-inc/json-threat-protection/_changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Changelog

### {{site.base_gateway}} 3.8.0.0

* Introduced the new **JSON Threat Protection** plugin.
23 changes: 23 additions & 0 deletions app/_hub/kong-inc/json-threat-protection/_metadata/_index.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: JSON Threat Protection
search_aliases:
- json threat protection
- json-threat-protection
dbless_compatible: 'yes'
free: false

publisher: Kong Inc.

type: plugin

categories:
- security

desc: Apply size checks on JSON payload and minimize risk of content-level attacks

enterprise: true

konnect: false

network_config_opts: All

notes: --
255 changes: 255 additions & 0 deletions app/_hub/kong-inc/json-threat-protection/overview/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
---
nav_title: Overview
---

The JSON Threat Protection plugin provides security validation against various aspects of JSON structure.
The plugin validates the incoming JSON request body to ensure the payload adheres to the policy limits, regardless of whether the `Content-Type` header exists or is set to `application/json`.
Requests violating the policy are considered malicious.
You can configure the plugin to drop such requests, which stops them from reaching the service.
Optionally, the plugin can operate in tap mode to monitor the traffic.

## How it works

The plugin checks the following limits:

- Maximum container depth of the entire JSON
- Maximum number of array elements
- Maximum number of object entries
- Maximum length of object keys
- Maximum length of strings

For example, for the following JSON:

```
{
"name": "Jason",
"age": 20,
"gender": "male",
"parents": ["Joseph", "Viva"]
}
```

- Maximum container depth: 2
- Maximum number of array elements: 2
- Maximum number of object entries: 4
- Maximum length of object keys: 7 (`parents`)
- Maximum length of strings: 6 (`Joseph`)

{:.note}
> **Note**: Length calculation for JSON strings and object entry names is based on UTF-8 characters, not bytes.

Additionally, there is a limit named `max_body_size`, which is used to restrict the request body size.
This can effectively reduce resource overhead and potential attack risks associated with excessively large bodies.
The plugin reads the `Content-Length` header and compares its value with `max_body_size`.
Therefore, in block mode, if the `Content-Length` header is missing or its value exceeds `max_body_size`, the request will be terminated.
In tap mode, only the body size is checked, and logs are recorded.


## Using the plugin

The following example assumes you have a service listening on port 80.
When accessed successfully, the service responds with `200 OK`.
In the example, you'll configure the following:
* A service in {{site.base_gateway}} that points to the service you just deployed
* A route for this service
* Enable the JSON threat protection policy on the route to enforce payload limits.
Specifically, you'll configure the plugin to reject violating requests.

Kong inspects the incoming requests, validates the payload adheres to the limits, and rejects requests that violate the policy.



### Create a service

```bash
curl -i -s -X POST http://localhost:8001/services \
--data name=example_service \
--data url='http://localhost/'
```

The response is:

```json
{
"tls_verify": null,
"created_at": 1718876195,
"tls_verify_depth": null,
"connect_timeout": 60000,
"write_timeout": 60000,
"host": "localhost",
"updated_at": 1718876195,
"name": "example_service",
"protocol": "http",
"enabled": true,
"ca_certificates": null,
"id": "1c5ba231-a3fe-4884-b422-ce6395fa227f",
"port": 80,
"read_timeout": 60000,
"tags": null,
"client_certificate": null,
"retries": 5,
"path": "/"
}
```



### Create a route

```bash
curl -i -X POST http://localhost:8001/services/example_service/routes \
--data 'paths[]=/' \
--data name=example_route
```

The response is:

```json
{
"created_at": 1718876213,
"https_redirect_status_code": 426,
"protocols": [
"http",
"https"
],
"hosts": null,
"methods": null,
"path_handling": "v0",
"updated_at": 1718876213,
"destinations": null,
"preserve_host": false,
"name": "example_route",
"headers": null,
"paths": [
"/"
],
"service": {
"id": "1c5ba231-a3fe-4884-b422-ce6395fa227f"
},
"sources": null,
"snis": null,
"id": "8ec673f6-3399-4b74-b3dc-f31632770dd1",
"regex_priority": 0,
"tags": null,
"strip_path": true,
"request_buffering": true,
"response_buffering": true
}
```



### Create a JSON threat protection policy

```bash
curl -X POST http://localhost:8001/plugins \
--data "name=json-threat-protection" \
--data "service.name=example_service" \
--data "config.max_body_size=1024" \
--data "config.max_container_depth=2" \
--data "config.max_object_entry_count=4" \
--data "config.max_object_entry_name_length=7" \
--data "config.max_array_element_count=2" \
--data "config.max_string_value_length=6" \
--data "config.enforce_mode=block" \
--data "config.error_status_code=400" \
--data "config.error_message=BadRequest1"
```

The configuration fields have the following meanings:

- `config.max_body_size=1024`: The request body must not exceed 1024 bytes.
- `config.max_container_depth=2`: The maximum depth of the container is 2.
- `config.max_object_entry_count=4`: The number of object entries must not exceed 4.
- `config.max_object_entry_name_length=7`: The key for an object entry must not exceed 7 bytes.
- `config.max_array_element_count=2`: The number of array elements must not exceed 2.
- `config.max_string_value_length=6`: The length of string values must not exceed 6 bytes.
- `config.enforce_mode=block`: Enables `block` mode, where the request will not be proxied to the upstream service if the JSON violates the above limits.
- `config.error_status_code=400`: When a JSON violation occurs, Kong returns an error code `400`.
- `config.error_message=BadRequest1`: When a JSON violation occurs, Kong returns the error message `BadRequest1`.

### Tap mode
In tap mode, the plugin inspects the JSON in the request body, but if there are any violations of the limits, it doesn't block the request. Instead, it logs a warning and proxies the request to the upstream service. In other words, in tap mode, the plugin only monitors the traffic.

To enable tap mode, set `config.enforce_mode` to `log_only`:

```
config.enforce_mode=log_only
```


The response will look something like this:

```json
{
"updated_at": 1718876232,
"created_at": 1718876232,
"consumer": null,
"config": {
"max_body_size": 1024,
"max_container_depth": 2,
"max_array_element_count": 2,
"max_object_entry_count": 4,
"max_object_entry_name_length": 7,
"max_string_value_length": 6,
"enforce_mode": "block",
"error_status_code": 400,
"error_message": "BadRequest1"
},
"protocols": [
"grpc",
"grpcs",
"http",
"https"
],
"service": {
"id": "1c5ba231-a3fe-4884-b422-ce6395fa227f"
},
"name": "json-threat-protection",
"id": "d8ef3743-f97e-4c98-87f1-53621cb28958",
"tags": null,
"route": null,
"ordering": null,
"consumer_group": null,
"instance_name": null,
"enabled": true
}
```



### Example requests and responses

This request is successfully proxied and returns a response:

```bash
curl -XPOST http://localhost:8000/ \
-H "Content-Type: application/json" \
-d '{"name": "Jason","age": 20,"gender": "male","parents": ["Joseph", "Viva"]}'
```

The response is:

```html
200 OK
```



The following request is intercepted by the JSON Threat Protection plugin and returns the configured message instead of the standard response:

```bash
curl -XPOST http://localhost:8000/ \
-H "Content-Type: application/json" \
-d '{"name": "Jason","age": 20,"gender": "male","parents": ["Dad Joseph", "Viva"]}'
```

The response is:

```json
{
"message":"BadRequest1",
"request_id":"176e093c766974458e8de53b907ff25f"
}
```
3 changes: 3 additions & 0 deletions app/_hub/kong-inc/json-threat-protection/versions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
strategy: gateway
releases:
minimum_version: '3.8.x'
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 24fc2f4

Please sign in to comment.