From b301164102e1b1c941d485bab8096147d72ad778 Mon Sep 17 00:00:00 2001 From: aitbc Date: Sat, 18 Apr 2026 20:39:33 +0200 Subject: [PATCH] security: add timeouts to HTTP requests and fix temp directory usage - Add 30-second timeouts to all HTTP requests in enterprise_cli.py (5 instances) - Add 30-second timeouts to all HTTP requests in miner_management.py (4 instances) - Replace hardcoded /tmp with tempfile.gettempdir() in extended_features.py - Fix requires-python constraint from ^3.13 to >=3.13 in aitbc-core - Add missing dependencies: pynacl to aitbc-crypto, httpx to aitbc-sdk - Add poetry packages configuration to aitbc-core pyproject.toml - Add type --- cli/aitbc_cli/utils/__init__.py | 30 ++++++++++++++++++++++ cli/enterprise_cli.py | 10 ++++---- cli/extended_features.py | 3 ++- cli/miner_management.py | 12 ++++++--- docs/policies/DOTENV_DISCIPLINE.md | 2 ++ packages/py/aitbc-core/pyproject.toml | 7 ++++- packages/py/aitbc-crypto/pyproject.toml | 3 ++- packages/py/aitbc-sdk/pyproject.toml | 3 ++- packages/solidity/aitbc-token/package.json | 1 + 9 files changed, 58 insertions(+), 13 deletions(-) create mode 100644 cli/aitbc_cli/utils/__init__.py diff --git a/cli/aitbc_cli/utils/__init__.py b/cli/aitbc_cli/utils/__init__.py new file mode 100644 index 00000000..642e4f7c --- /dev/null +++ b/cli/aitbc_cli/utils/__init__.py @@ -0,0 +1,30 @@ +""" +CLI utility functions for output formatting and error handling +""" + +from click import echo, secho + + +def output(message: str, **kwargs): + """Print a regular output message""" + echo(message, **kwargs) + + +def error(message: str, **kwargs): + """Print an error message in red""" + secho(message, fg="red", **kwargs) + + +def success(message: str, **kwargs): + """Print a success message in green""" + secho(message, fg="green", **kwargs) + + +def info(message: str, **kwargs): + """Print an info message in blue""" + secho(message, fg="blue", **kwargs) + + +def warning(message: str, **kwargs): + """Print a warning message in yellow""" + secho(message, fg="yellow", **kwargs) diff --git a/cli/enterprise_cli.py b/cli/enterprise_cli.py index 67aaefc9..63b2f82a 100755 --- a/cli/enterprise_cli.py +++ b/cli/enterprise_cli.py @@ -125,7 +125,7 @@ def mining_operations(operation: str, wallet_name: str = None, threads: int = 1, elif operation == "stop": print("Stopping mining...") try: - response = requests.post(f"{rpc_url}/rpc/mining/stop") + response = requests.post(f"{rpc_url}/rpc/mining/stop", timeout=30) if response.status_code == 200: result = response.json() print(f"✅ Mining stopped") @@ -141,7 +141,7 @@ def mining_operations(operation: str, wallet_name: str = None, threads: int = 1, elif operation == "status": print("Getting mining status...") try: - response = requests.get(f"{rpc_url}/rpc/mining/status") + response = requests.get(f"{rpc_url}/rpc/mining/status", timeout=30) if response.status_code == 200: status = response.json() print("⛏️ Mining Status:") @@ -165,7 +165,7 @@ def marketplace_operations(operation: str, wallet_name: str = None, item_type: s if operation == "list": print("Getting marketplace listings...") try: - response = requests.get(f"{rpc_url}/rpc/marketplace/listings") + response = requests.get(f"{rpc_url}/rpc/marketplace/listings", timeout=30) if response.status_code == 200: listings = response.json().get("listings", []) print(f"🏪 Marketplace Listings ({len(listings)} items):") @@ -203,7 +203,7 @@ def marketplace_operations(operation: str, wallet_name: str = None, item_type: s } try: - response = requests.post(f"{rpc_url}/rpc/marketplace/create", json=listing_data) + response = requests.post(f"{rpc_url}/rpc/marketplace/create", json=listing_data, timeout=30) if response.status_code == 200: result = response.json() listing_id = result.get("listing_id") @@ -241,7 +241,7 @@ def ai_operations(operation: str, wallet_name: str = None, job_type: str = None, } try: - response = requests.post(f"{rpc_url}/rpc/ai/submit", json=job_data) + response = requests.post(f"{rpc_url}/rpc/ai/submit", json=job_data, timeout=30) if response.status_code == 200: result = response.json() job_id = result.get("job_id") diff --git a/cli/extended_features.py b/cli/extended_features.py index 92322108..00cbcb4d 100644 --- a/cli/extended_features.py +++ b/cli/extended_features.py @@ -204,7 +204,8 @@ def handle_extended_command(command, args, kwargs): result["metrics"] = {"tx_rate": 15, "block_time": 30.1} elif command == "analytics_export": - result["file"] = "/tmp/analytics_export.csv" + import tempfile + result["file"] = tempfile.gettempdir() + "/analytics_export.csv" elif command == "analytics_predict": result["prediction"] = "stable" diff --git a/cli/miner_management.py b/cli/miner_management.py index 5e2cc197..f6ae8f37 100644 --- a/cli/miner_management.py +++ b/cli/miner_management.py @@ -69,7 +69,8 @@ def register_miner( response = requests.post( f"{coordinator_url}/v1/miners/register", headers=headers, - json=payload + json=payload, + timeout=30 ) if response.status_code == 200: @@ -115,7 +116,8 @@ def get_miner_status( response = requests.get( f"{coordinator_url}/v1/admin/miners", - headers=headers + headers=headers, + timeout=30 ) if response.status_code == 200: @@ -188,7 +190,8 @@ def send_heartbeat( response = requests.post( f"{coordinator_url}/v1/miners/heartbeat", headers=headers, - json=payload + json=payload, + timeout=30 ) if response.status_code == 200: @@ -232,7 +235,8 @@ def poll_jobs( response = requests.post( f"{coordinator_url}/v1/miners/poll", headers=headers, - json=payload + json=payload, + timeout=30 ) if response.status_code == 200 and response.content: diff --git a/docs/policies/DOTENV_DISCIPLINE.md b/docs/policies/DOTENV_DISCIPLINE.md index c451c0d3..0729c1c4 100644 --- a/docs/policies/DOTENV_DISCIPLINE.md +++ b/docs/policies/DOTENV_DISCIPLINE.md @@ -16,6 +16,7 @@ silent configuration issues where: ### **Focused Dotenv Linter** Created a sophisticated linter that: + - **Scans all code** for actual environment variable usage - **Filters out script variables** and non-config variables - **Compares with `.env.example`** to find drift @@ -142,6 +143,7 @@ Created `.github/workflows/dotenv-check.yml` with: ### **Workflow Triggers** The dotenv check runs on: + - **Push** to any branch (when relevant files change) - **Pull Request** (when relevant files change) - File patterns: `.env.example`, `*.py`, `*.yml`, `*.toml`, `*.sh` diff --git a/packages/py/aitbc-core/pyproject.toml b/packages/py/aitbc-core/pyproject.toml index 8d335a8e..3cc95aa1 100644 --- a/packages/py/aitbc-core/pyproject.toml +++ b/packages/py/aitbc-core/pyproject.toml @@ -6,7 +6,7 @@ authors = [ {name = "AITBC Team", email = "team@aitbc.dev"} ] readme = "README.md" -requires-python = "^3.13" +requires-python = ">=3.13" dependencies = [ "cryptography>=41.0.0", "sqlmodel>=0.0.14", @@ -19,3 +19,8 @@ dependencies = [ [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" + +[tool.poetry] +packages = [ + { include = "aitbc_core", from = "src" } +] diff --git a/packages/py/aitbc-crypto/pyproject.toml b/packages/py/aitbc-crypto/pyproject.toml index 1bf42978..60ec1352 100644 --- a/packages/py/aitbc-crypto/pyproject.toml +++ b/packages/py/aitbc-crypto/pyproject.toml @@ -8,7 +8,8 @@ authors = [ readme = "README.md" requires-python = ">=3.13" dependencies = [ - "cryptography>=41.0.0" + "cryptography>=41.0.0", + "pynacl>=1.5.0" ] [build-system] diff --git a/packages/py/aitbc-sdk/pyproject.toml b/packages/py/aitbc-sdk/pyproject.toml index a50fb47e..c8c3f466 100644 --- a/packages/py/aitbc-sdk/pyproject.toml +++ b/packages/py/aitbc-sdk/pyproject.toml @@ -10,7 +10,8 @@ requires-python = ">=3.13" dependencies = [ "cryptography>=41.0.0", "requests>=2.31.0", - "pydantic>=2.5.0" + "pydantic>=2.5.0", + "httpx>=0.25.0" ] [build-system] diff --git a/packages/solidity/aitbc-token/package.json b/packages/solidity/aitbc-token/package.json index 95f0163a..bbb8f08c 100644 --- a/packages/solidity/aitbc-token/package.json +++ b/packages/solidity/aitbc-token/package.json @@ -2,6 +2,7 @@ "name": "@aitbc/aitbc-token", "version": "0.2.3", "private": true, + "type": "module", "description": "AITBC Solidity contracts for attested receipt-based minting", "scripts": { "build": "hardhat compile",