Cyber Injection Assistant: a local HTTP(S) MITM testing proxy
Project description
Cyber Injection Assistant (CIA)
Cyber Injection Assistant (CIA) is a local HTTP(S) MITM testing proxy built on mitmproxy. It records traffic to SQLite, runs external Python rules against requests, can generate blocking responses, and includes a small Mesop web UI for viewing and filtering captured flows.
Use it only for traffic you own or are authorized to inspect.
Features
- HTTP(S) proxy powered by mitmproxy.
- Async SQLAlchemy + SQLite traffic storage.
- External rule files with no dependency on CIA internals.
- Runtime rule enable/disable and global bypass switch.
- Web UI for Wireshark-style traffic browsing, filtering, request/response details, CA links, and clearing records.
- Local CA generation for HTTPS interception.
- Binary payload download from captured request/response bodies.
Requirements
- Python 3.13 or newer.
uvfor dependency management.- A browser or HTTP client configured to use the local proxy.
Install dependencies:
uv sync
Install CIA as a command:
uv tool install .
After installation, verify the command is available:
cia --help
During development you can run the command without installing it globally:
uv run cia --help
Quick Start
Start CIA with the default config:
cia
Or use an explicit config file:
cia -f userdata/config.toml
On startup CIA prints the rules directory it scanned and each discovered rule:
[cia] scanning rules: C:\repos\cia\userdata\rules
[cia] rules discovered: 1
[cia] - example [active] block www.baidu.com (C:\repos\cia\userdata\rules\example.py)
Default endpoints:
- Proxy:
127.0.0.1:2080 - Web UI:
http://127.0.0.1:5280/ - CA import page:
http://127.0.0.1:5280/_cia/install-ca
Configure your browser proxy as an HTTP proxy pointing to 127.0.0.1:2080. HTTPS websites are handled through HTTP CONNECT; do not configure the browser to use an HTTPS/SSL proxy endpoint.
Configuration
The default config is userdata/config.toml:
[userdata]
rules = "./rules"
net_logs = "./data" # also supports ::memory::
[proxy]
protocol = "http"
ca = "./ca.pem"
host = "127.0.0.1"
port = 2080
[web]
host = "0.0.0.0"
port = 5280
[rules]
# rule_name = true
Paths are resolved relative to the config file.
userdata.net_logs can be a directory, a SQLite file path, or ::memory::. When it is a directory, CIA stores logs in net_logs.sqlite3 inside that directory.
Rules are enabled by default. Add entries under [rules] to control initial activation:
[rules]
example = true
some_other_rule = false
HTTPS and CA Trust
CIA generates a local root CA at the path configured by proxy.ca. The web UI Settings tab shows the CA path and SHA-256 fingerprint.
Useful CA routes:
/_cia/install-ca: browser-friendly import instructions./_cia/ca.crt: DER certificate with.crtfilename./_cia/ca.cer: DER certificate with.cerfilename./_cia/ca.pem: PEM certificate./ca.pem: PEM certificate shortcut.
Chrome and Edge can usually trust the CA from the Windows Current User Root store. Use the Settings button in CIA to install it, or import the .crt manually.
Firefox normally uses its own certificate store. Import the CA from Firefox settings, or enable security.enterprise_roots.enabled in about:config so Firefox trusts the Windows Current User Root store.
If you regenerated the CA, delete the old CIA Local Root CA entry from your browser first, then import the new one and confirm the fingerprint.
Rule Files
Rules are external Python files loaded from the configured userdata.rules directory.
Rule files can import the public request/response models from cia.typing. Each rule module must export:
from cia.typing import Request, Response
rule_name = "block-example"
rule_description = "optional description"
def handle(request: Request) -> Response | None:
if request.host == "example.com":
return Response(
status_code=403,
content_type="text/plain",
body="blocked",
)
return None
rule_name must be a non-empty string. rule_description is optional and defaults to None.
handle is required and can be synchronous or asynchronous.
The handle function receives one Request object with:
host: request host.port: request port.path: request path and query string.request_body: raw request body asbytes.header: request headers asdict[str, list[str]].
Return None to allow the request to continue. Return a Response to block the request and generate that response.
Response fields:
status_code: HTTP status code. Defaults to200.content_type: response content type. Defaults toapplication/json.headers: extra response headers.body: response payload.str,bytes, and JSON-serializable values are supported.
Example with an asynchronous rule:
from cia.typing import Request, Response
rule_name = "block-by-host"
async def handle(request: Request) -> Response | None:
if request.host.endswith("example.test"):
return Response(status_code=403, body="blocked")
return None
CIA validates each rule at startup. A rule file fails to load if rule_name is missing or empty, rule_description is not str or None, handle is missing, or handle does not accept exactly one Request argument.
Web UI
The web UI shows captured traffic in a table with time, method, host, path, status, and matched rule. Selecting a row opens a right-side details panel with REQUEST and RESPONSE tabs.
The body viewer:
- Pretty-prints JSON with two-space indentation.
- Shows text bodies directly.
- Shows a
Download binary datalink for binary payloads.
The Rules tab lets you enable or disable individual rules and toggle Bypass all traffics, which skips all rule handling without unloading rules.
The Settings tab shows proxy and CA information, lets you install the CA, controls auto refresh, and includes Clear records to delete all captured traffic logs.
Display Filters
The traffic table supports simple display filters.
Examples:
host == 'example.com'
method == GET and status_code == 403
not is_blocked == true
url =~ 'baidu|example'
matches[0].rule_name == example
Supported operators:
==: exact string comparison.!=: string inequality.=~: regular expression search.and,or,not, and parentheses.- Dotted paths and list indexes such as
matches[0].rule_name.
Development Notes
Run a quick import check:
uv run cia --help
The proxy and web UI run together from the cia command. Stop the process with Ctrl+C.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ciamitm-0.2.1.tar.gz.
File metadata
- Download URL: ciamitm-0.2.1.tar.gz
- Upload date:
- Size: 27.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9990b1ba28420833bdc12cf7f87458aa7b2be45be14a5481f17823f312564160
|
|
| MD5 |
107825d57ed8f9c6729ae23952a7fba7
|
|
| BLAKE2b-256 |
5d5d1536b348fa9e276a71c90b778da480c819d55ce5c6fcd387e5fbc951549c
|
File details
Details for the file ciamitm-0.2.1-py3-none-any.whl.
File metadata
- Download URL: ciamitm-0.2.1-py3-none-any.whl
- Upload date:
- Size: 29.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f015fa18adbddaa0006c2e35113d636bc9e89edb9fd1eba123281397b9bf63d6
|
|
| MD5 |
d3ea23dd75cd58d8f3b9ac9905bb6388
|
|
| BLAKE2b-256 |
4de3dad423610e279d2edc51076bae3fafcbd47e570b7c9f7ebfbb777d9df39b
|