url_jail
SSRF-safe URL validation for Rust and Python.
The Problem
Your application fetches a user-provided URL:
response = requests.get(user_url)
An attacker submits http://169.254.169.254/latest/meta-data/iam/credentials.
Result: Your AWS keys are in their inbox. Your S3 buckets are public. Your cloud bill is six figures.
This is Server-Side Request Forgery (SSRF), the vulnerability behind:
- CVE-2024-0243: LangChain RecursiveUrlLoader (CVSS 8.6)
- CVE-2025-2828: LangChain RequestsToolkit (CVSS 9.1)
- Capital One 2019 breach (100M+ records)
"I'll just block 169.254.169.254"
Attackers encode IPs in ways your blocklist won't catch:
| Attack | Your Blocklist | url_jail |
|---|---|---|
http://0x7f000001/ (hex) |
Passes | Blocked |
http://0177.0.0.1/ (octal) |
Passes | Blocked |
http://2130706433/ (decimal) |
Passes | Blocked |
http://127.1/ (short-form) |
Passes | Blocked |
http://[::ffff:127.0.0.1]/ (IPv6-mapped) |
Passes | Blocked |
http://metadata.google.internal/ |
Maybe | Blocked |
| DNS rebinding | Passes | Blocked* |
* When using get_sync() or the returned Validated.ip directly.
url_jail validates after DNS resolution. Encoding tricks don't work.
Note: This library has not undergone a formal security audit. See SECURITY.md.
The Solution
Python (recommended):
from url_jail import get_sync
body = get_sync(user_url) # Validates URL and all redirects
Python (with existing HTTP client):
from url_jail.adapters import safe_session
s = safe_session()
response = s.get(user_url) # SSRF-safe requests.Session
Rust:
use url_jail::{validate, Policy};
use reqwest::Client;
let v = validate("https://example.com/api", Policy::PublicOnly).await?;
let client = Client::builder()
.resolve(&v.host, v.to_socket_addr())
.build()?;
let response = client.get(&v.url).send().await?;
Installation
pip install url_jail
# With HTTP client adapters
pip install url_jail[requests] # or [httpx], [aiohttp], [urllib3], [all]
[dependencies]
url_jail = "0.2"
# Enable fetch() for redirect chain validation
url_jail = { version = "0.2", features = ["fetch"] }
Policies
| Policy | Allows | Blocks |
|---|---|---|
PublicOnly |
Public IPs only | Private, loopback, link-local, metadata |
AllowPrivate |
Private + public | Loopback, metadata (for internal services) |
HTTP Client Adapters (Python)
# requests
from url_jail.adapters import safe_session
s = safe_session()
response = s.get(user_url)
# httpx (sync)
from url_jail.adapters import safe_httpx_client
client = safe_httpx_client()
response = client.get(user_url)
# httpx (async)
from url_jail.adapters import safe_httpx_async_client
async with safe_httpx_async_client() as client:
response = await client.get(user_url)
# aiohttp
from url_jail.adapters import safe_aiohttp_session
async with safe_aiohttp_session() as session:
async with session.get(user_url) as response:
body = await response.text()
# urllib3
from url_jail.adapters import safe_urllib3_pool
pool = safe_urllib3_pool()
response = pool.request("GET", user_url)
Advanced: Custom Blocklist
use url_jail::{PolicyBuilder, Policy};
let policy = PolicyBuilder::new(Policy::AllowPrivate)
.block_cidr("10.0.0.0/8")
.block_host("*.internal.example.com")
.build();
Error Handling
use url_jail::{validate_sync, Policy, Error};
match validate_sync("http://127.0.0.1/", Policy::PublicOnly) {
Ok(v) => println!("Safe: {}", v.ip),
Err(e) if e.is_blocked() => {
// Security rejection (SSRF, hostname, redirect)
println!("Blocked: {}", e);
}
Err(e) if e.is_retriable() => {
// Temporary error (DNS, timeout) - retry with caution
println!("Temporary: {}", e);
}
Err(e) => println!("Error: {}", e),
}
| Method | Returns true for |
|---|---|
is_blocked() |
SsrfBlocked, HostnameBlocked, RedirectBlocked |
is_retriable() |
DnsError, Timeout, HttpError |
url() |
Extracts the URL that caused the error |
What's Blocked
- Cloud metadata endpoints (AWS, GCP, Azure, Alibaba)
- Private IPs (10.x, 172.16.x, 192.168.x) with
PublicOnly - Loopback (127.x, ::1)
- Link-local (169.254.x, fe80::)
- IP encoding tricks: octal (
0177.0.0.1), decimal (2130706433), hex (0x7f000001), short-form (127.1) - IPv4-mapped IPv6 (
::ffff:127.0.0.1)
Features
| Feature | Description |
|---|---|
fetch |
fetch() / get_sync() with redirect validation |
tracing |
Logging for validation decisions |
License
MIT OR Apache-2.0
Metadata
Release files for url-jail 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
Total release size: 65.4 MB
Release files / url_jail-0.2.0-cp314-cp314-win_amd64.whl
| Download URL | url_jail-0.2.0-cp314-cp314-win_amd64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.14 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
bd3cb7db5ed861ae1698658835cb68c3c7c2ff18b064c88f9b9a32cf7aba3b0d
|
|
BLAKE2b-256 checksum How to use checksums |
45f526f6fbba6d5de227fe03e8432b50f21c73c86533dab348332705b78d1442
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp314-cp314-musllinux_1_2_x86_64.whl
| Download URL | url_jail-0.2.0-cp314-cp314-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 3.1 MB |
| Tags | CPython 3.14 Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
63ef2306de459a15719150443861511106b720002e7f026968377651d80197f9
|
|
BLAKE2b-256 checksum How to use checksums |
460aef7e23df3d82254a46c6dacfc6de69494773644c11144e67a38fa1f8bae7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | url_jail-0.2.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 2.9 MB |
| Tags | CPython 3.14 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
b03687bcab6b67a9f504a259dbc6021e936d7fdf5bb180656beed7c15c6b255b
|
|
BLAKE2b-256 checksum How to use checksums |
b88fd0ab1a12137e1efd0edbd27e8bed7bc8b8c26cff117b923423b272cba6bf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp314-cp314-macosx_11_0_arm64.whl
| Download URL | url_jail-0.2.0-cp314-cp314-macosx_11_0_arm64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.14 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
1a74ea8bc497aae1ef71114ad10cf61357877179dfb16c68b89c7f5c082534b8
|
|
BLAKE2b-256 checksum How to use checksums |
15ba02056349e78b34852038e2cfe525d63c2835d27bb2d169b8b0609c53aa97
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp313-cp313-win_amd64.whl
| Download URL | url_jail-0.2.0-cp313-cp313-win_amd64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.13 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
eacd3abb9a9b9ef4379fe5afa5d3a3a78f5e27df35f4fbf0be407b8cb1b9725e
|
|
BLAKE2b-256 checksum How to use checksums |
ed0896c1db77557556e7f5bd7f4114dafa4546f76b2ff5d17fa25c1c95ed3b72
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl
| Download URL | url_jail-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 3.1 MB |
| Tags | CPython 3.13 Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
6c5e060efaa4877d0ee2a9b0bc8c9c30405e526c72092a9b143ca255b49cbf86
|
|
BLAKE2b-256 checksum How to use checksums |
4a6a763e7fb9236865691c3d75ced81597ddb894f78d11ebd5486b6b9dc25fdf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | url_jail-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 2.9 MB |
| Tags | CPython 3.13 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
15de02b9ec8391b588507dcfc59386b2438ccb683ed58b0a36bc740dc8e5bf93
|
|
BLAKE2b-256 checksum How to use checksums |
7fdc0606bd72909037ea43dc84e7581ab4583d4ca41aaab7512b971875101f08
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp313-cp313-macosx_11_0_arm64.whl
| Download URL | url_jail-0.2.0-cp313-cp313-macosx_11_0_arm64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.13 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
a5465e7da76d1e157edb57d7b3c7922f0465d514c749254eb2c78fc10fc99aea
|
|
BLAKE2b-256 checksum How to use checksums |
3accdff74a084b14e5406c80602183ec58876c5861d553735ac5adc7d4c301ea
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp312-cp312-win_amd64.whl
| Download URL | url_jail-0.2.0-cp312-cp312-win_amd64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.12 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
76c5eb9596ac046f9cece20bf05c0c932f40ce5b0e7d9fc33c6003f5bae4ae24
|
|
BLAKE2b-256 checksum How to use checksums |
8850c4759ea7def68f27068f0b5478363e83b02032e3d3a0f93f7e42214f37a1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl
| Download URL | url_jail-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 3.1 MB |
| Tags | CPython 3.12 Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
296717c16ae7a30b0566df99f209a8b4cc419587e2bd6240fe49733c8d41223b
|
|
BLAKE2b-256 checksum How to use checksums |
52e97757faa0ccfc2aba822dbb0b3c4043c474e81ee770e54ced40c9aca4f5e7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | url_jail-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 2.9 MB |
| Tags | CPython 3.12 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
b8fec776db25a8fb178628787db86ad66991862f0e4624c3f296b42e91b7ea5a
|
|
BLAKE2b-256 checksum How to use checksums |
e31fbde057519c7396c4086d11b6b6e77d2ce7b49550d0d7eb8c857eebc1f2cf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp312-cp312-macosx_11_0_arm64.whl
| Download URL | url_jail-0.2.0-cp312-cp312-macosx_11_0_arm64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.12 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
30c8308e4c9013c09f3acd7fca1e2f8931371cad68090e73f2574f92ef472c4d
|
|
BLAKE2b-256 checksum How to use checksums |
ce776a97c4db295522e6bdee4952bdbbd2c70f194c45a0bf8f0f7e7e1f1e43f8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp311-cp311-win_amd64.whl
| Download URL | url_jail-0.2.0-cp311-cp311-win_amd64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.11 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
8f219cc899f911afc36df8e5fccf786fcf489eb192ea52de753f04dde12e93bd
|
|
BLAKE2b-256 checksum How to use checksums |
086a870c11fb4f3c583e942cecee29986ded62ec306a072308d9709795d35a56
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl
| Download URL | url_jail-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 3.1 MB |
| Tags | CPython 3.11 Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
89e7282c553b0de4a42ef90b325fea1235d0a8781e00cdfc24f7f8fff40e97c8
|
|
BLAKE2b-256 checksum How to use checksums |
3a0303172edc59794a6253f61cbba1ae5590caddefef9c8856e3e1cc394314ed
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | url_jail-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 2.9 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
85e4d6b57dee67bcc801369dfc01a5b33bdc94e86d5e07e039949c0f8f04634b
|
|
BLAKE2b-256 checksum How to use checksums |
17acb84aa1b5b45a8e83429b611be85cd5bf034d6a5592387793a010ea53d5f1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp311-cp311-macosx_11_0_arm64.whl
| Download URL | url_jail-0.2.0-cp311-cp311-macosx_11_0_arm64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.11 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
696dc79bc83e509986e86a64235a88ae2b14d32174b8f01c6078d1a745eb4227
|
|
BLAKE2b-256 checksum How to use checksums |
fabc59c50261754de4c963d378c2503f8497b54b7c4527a8748e3dd06e01425b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp310-cp310-win_amd64.whl
| Download URL | url_jail-0.2.0-cp310-cp310-win_amd64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.10 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
1b69196b618fe89b763a32b32730cd74ad1eaa7fcd1cccb8a7957ce2d8edc956
|
|
BLAKE2b-256 checksum How to use checksums |
3bb8dc967e1743143f8d0f6510260392d42aebe15a38e7fc3ad9354e98fd5d96
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl
| Download URL | url_jail-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 3.1 MB |
| Tags | CPython 3.10 Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
124f4560cf3aa0f510d2f764ad9caf67d08d99fe88d9ade4ec49d62db3f785e5
|
|
BLAKE2b-256 checksum How to use checksums |
1af3e576ceaefac69fa9eb7228996fbdf8163964b648c7ecfbcad31da5f7f64f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | url_jail-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 2.9 MB |
| Tags | CPython 3.10 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
ac7e4778cc86489665037ec357ec689d7d7693ebbe735b2ac5eeaff84d546c9e
|
|
BLAKE2b-256 checksum How to use checksums |
7c5512d3ac8363fa9a65bf4981138371dbef19a5aff903bcb1b4748e6f04685a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp310-cp310-macosx_11_0_arm64.whl
| Download URL | url_jail-0.2.0-cp310-cp310-macosx_11_0_arm64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.10 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
b6118aee9d8c0b588a3420cb5519a4ed7c20d46b6c10f6a64df70242174c26f6
|
|
BLAKE2b-256 checksum How to use checksums |
961e69530a05411e30b3af32557b0c331270264000f181f3bcc7cc588467dd38
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp39-cp39-win_amd64.whl
| Download URL | url_jail-0.2.0-cp39-cp39-win_amd64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.9 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
06655756c17633c56ec9be7d45460a0d1fc377bc57acfe28d081880e35b7ddb7
|
|
BLAKE2b-256 checksum How to use checksums |
6a9c67f4913a530f93be9bb4a503433295013ff1d0977e63ad5d8bd4a500e97e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp39-cp39-musllinux_1_2_x86_64.whl
| Download URL | url_jail-0.2.0-cp39-cp39-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 3.1 MB |
| Tags | CPython 3.9 Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
f995088faf333bbf5c7813c47d80ba4f5b5214935bf07f42ec00e6f88d6abc3d
|
|
BLAKE2b-256 checksum How to use checksums |
d1203978fe373de1892df860637e5b4e7548b08e78e8be31457eeef0edc59213
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | url_jail-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 2.9 MB |
| Tags | CPython 3.9 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
b77bc88aff055c5cad5ebb23811c735ab3283feadc36aa030635d179e0cc43e1
|
|
BLAKE2b-256 checksum How to use checksums |
beb1602df8707e6091a325fa03ed7ea4f08a245fb5a2b7a6b9a2bb26380b734b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / url_jail-0.2.0-cp39-cp39-macosx_11_0_arm64.whl
| Download URL | url_jail-0.2.0-cp39-cp39-macosx_11_0_arm64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.9 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
86e92c6a6f3d57666bfe47fd7f50134e8e75a67dd724397e216f60a9f9dd0142
|
|
BLAKE2b-256 checksum How to use checksums |
30f8ba32ff5f11c89d012b83bcbe828b022ab4a54aa4ccc018bdfa6de4f18fe3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Security for url-jail 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.