veritensor 1.7.0__tar.gz → 1.8.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {veritensor-1.7.0/src/veritensor.egg-info → veritensor-1.8.0}/PKG-INFO +30 -3
- {veritensor-1.7.0 → veritensor-1.8.0}/README.md +27 -2
- {veritensor-1.7.0 → veritensor-1.8.0}/pyproject.toml +3 -1
- veritensor-1.8.0/src/veritensor/__init__.py +2 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/cli/main.py +23 -2
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/core/streaming.py +12 -4
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/static/dependency_engine.py +15 -2
- veritensor-1.8.0/src/veritensor/engines/static/mcp_permission_auditor.py +787 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/static/mcp_scanner.py +50 -9
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/static/notebook_engine.py +33 -10
- veritensor-1.8.0/src/veritensor/reporting/excel_report.py +347 -0
- {veritensor-1.7.0 → veritensor-1.8.0/src/veritensor.egg-info}/PKG-INFO +30 -3
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor.egg-info/SOURCES.txt +2 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor.egg-info/requires.txt +2 -0
- veritensor-1.7.0/src/veritensor/__init__.py +0 -2
- {veritensor-1.7.0 → veritensor-1.8.0}/LICENSE +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/MANIFEST.in +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/setup.cfg +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/__main__.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/cli/__init__.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/core/__init__.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/core/cache.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/core/config.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/core/entropy.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/core/file_utils.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/core/networking.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/core/safe_zip.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/core/text_utils.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/core/types.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/__init__.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/container/__init__.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/container/archive_engine.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/content/__init__.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/content/injection.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/content/pii.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/data/__init__.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/data/dataset_engine.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/data/excel_engine.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/hashing/__init__.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/hashing/calculator.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/hashing/lfs.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/hashing/readers.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/static/__init__.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/static/keras_engine.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/static/pickle_engine.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/static/rules.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/static/signatures.yaml +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/integrations/__init__.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/integrations/chroma_guard.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/integrations/cosign.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/integrations/enterprise_scanner.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/integrations/huggingface.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/integrations/langchain_guard.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/integrations/llamaindex_guard.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/integrations/unstructured_guard.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/reporting/html_report.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/reporting/manifest.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/reporting/sarif.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/reporting/sbom.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/reporting/telemetry.py +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor.egg-info/dependency_links.txt +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor.egg-info/entry_points.txt +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor.egg-info/top_level.txt +0 -0
- {veritensor-1.7.0 → veritensor-1.8.0}/veritensor.yaml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: veritensor
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.8.0
|
|
4
4
|
Summary: Antivirus for the AI Supply Chain. Scans models, datasets, notebooks, and RAG documents for threats.
|
|
5
5
|
Author-email: Arsenii Brazhnyk <veritensor@gmail.com>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -29,6 +29,8 @@ Requires-Dist: huggingface_hub>=0.19.0
|
|
|
29
29
|
Requires-Dist: cyclonedx-python-lib>=6.0.0
|
|
30
30
|
Requires-Dist: jinja2>=3.1.0
|
|
31
31
|
Requires-Dist: pillow>=12.2.0
|
|
32
|
+
Requires-Dist: lxml>=6.1.0
|
|
33
|
+
Requires-Dist: gitpython>=3.1.47
|
|
32
34
|
Provides-Extra: test
|
|
33
35
|
Requires-Dist: pytest>=7.0.0; extra == "test"
|
|
34
36
|
Requires-Dist: pytest-mock>=3.10.0; extra == "test"
|
|
@@ -77,7 +79,8 @@ Unlike standard SAST tools (which focus on code), Veritensor understands the bin
|
|
|
77
79
|
2. **Data & RAG:** Streaming scan of **Parquet, CSV, Excel, PDF** to detect Data Poisoning, Prompt Injections, and PII.
|
|
78
80
|
3. **Notebooks:** Hardening of **Jupyter (.ipynb)** files by detecting leaked secrets (using Entropy analysis), malicious magics, and XSS.
|
|
79
81
|
4. **Supply Chain:** Audits **dependencies** (`requirements.txt`, `poetry.lock`) for Typosquatting and known CVEs (via OSV.dev).
|
|
80
|
-
5. **
|
|
82
|
+
5. **Agentic AI & MCP Servers:** Pure AST analysis of Python files to detect Agent Hijacking risks in `@mcp.tool()` functions. Scans `claude_desktop_config.json` and `mcp.json` for over-privileged permissions.
|
|
83
|
+
6. **Governance:** Generates cryptographic **Data Manifests** (Provenance) and signs containers via **Sigstore**.
|
|
81
84
|
|
|
82
85
|
---
|
|
83
86
|
|
|
@@ -183,6 +186,24 @@ Create a standalone, interactive HTML dashboard of your scan results:
|
|
|
183
186
|
veritensor scan ./project --html
|
|
184
187
|
```
|
|
185
188
|
|
|
189
|
+
### 11. Scan MCP Servers for Agent Hijacking
|
|
190
|
+
Detect dangerous tool logic and over-privileged permissions in your AI agent infrastructure:
|
|
191
|
+
```bash
|
|
192
|
+
# Scan MCP server Python files (AST analysis — no code execution)
|
|
193
|
+
veritensor scan ./mcp_servers/
|
|
194
|
+
|
|
195
|
+
# Also audit MCP configuration files
|
|
196
|
+
veritensor scan ./claude_desktop_config.json
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**Example output:**
|
|
200
|
+
```
|
|
201
|
+
CRITICAL: MCP Agent Hijacking Risk [OS_COMMAND_EXECUTION] in tool 'run_script'
|
|
202
|
+
(line 14): os.system() inside agent tool — no human-in-the-loop confirmation
|
|
203
|
+
HIGH: MCP Config [LETHAL_TRIFECTA] server 'everything':
|
|
204
|
+
filesystem + network + private data — prompt injection can silently exfiltrate all data
|
|
205
|
+
```
|
|
206
|
+
|
|
186
207
|
**Example Output:**
|
|
187
208
|
```Text
|
|
188
209
|
╭────────────────────────────────╮
|
|
@@ -325,7 +346,11 @@ For custom parsers and SOAR automation:
|
|
|
325
346
|
```bash
|
|
326
347
|
veritensor scan ./models --json
|
|
327
348
|
```
|
|
328
|
-
|
|
349
|
+
### 5. Excel report
|
|
350
|
+
Create an Excel report with data about the problems:
|
|
351
|
+
```bash
|
|
352
|
+
veritensor scan ./models --excel
|
|
353
|
+
```
|
|
329
354
|
---
|
|
330
355
|
|
|
331
356
|
## 🔐 Supply Chain Security (Container Signing)
|
|
@@ -403,6 +428,8 @@ veritensor_audit:
|
|
|
403
428
|
script:
|
|
404
429
|
- veritensor scan . --jobs 4
|
|
405
430
|
allow_failure: false
|
|
431
|
+
```
|
|
432
|
+
|
|
406
433
|
---
|
|
407
434
|
|
|
408
435
|
## 📂 Supported Formats
|
|
@@ -17,7 +17,8 @@ Unlike standard SAST tools (which focus on code), Veritensor understands the bin
|
|
|
17
17
|
2. **Data & RAG:** Streaming scan of **Parquet, CSV, Excel, PDF** to detect Data Poisoning, Prompt Injections, and PII.
|
|
18
18
|
3. **Notebooks:** Hardening of **Jupyter (.ipynb)** files by detecting leaked secrets (using Entropy analysis), malicious magics, and XSS.
|
|
19
19
|
4. **Supply Chain:** Audits **dependencies** (`requirements.txt`, `poetry.lock`) for Typosquatting and known CVEs (via OSV.dev).
|
|
20
|
-
5. **
|
|
20
|
+
5. **Agentic AI & MCP Servers:** Pure AST analysis of Python files to detect Agent Hijacking risks in `@mcp.tool()` functions. Scans `claude_desktop_config.json` and `mcp.json` for over-privileged permissions.
|
|
21
|
+
6. **Governance:** Generates cryptographic **Data Manifests** (Provenance) and signs containers via **Sigstore**.
|
|
21
22
|
|
|
22
23
|
---
|
|
23
24
|
|
|
@@ -123,6 +124,24 @@ Create a standalone, interactive HTML dashboard of your scan results:
|
|
|
123
124
|
veritensor scan ./project --html
|
|
124
125
|
```
|
|
125
126
|
|
|
127
|
+
### 11. Scan MCP Servers for Agent Hijacking
|
|
128
|
+
Detect dangerous tool logic and over-privileged permissions in your AI agent infrastructure:
|
|
129
|
+
```bash
|
|
130
|
+
# Scan MCP server Python files (AST analysis — no code execution)
|
|
131
|
+
veritensor scan ./mcp_servers/
|
|
132
|
+
|
|
133
|
+
# Also audit MCP configuration files
|
|
134
|
+
veritensor scan ./claude_desktop_config.json
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Example output:**
|
|
138
|
+
```
|
|
139
|
+
CRITICAL: MCP Agent Hijacking Risk [OS_COMMAND_EXECUTION] in tool 'run_script'
|
|
140
|
+
(line 14): os.system() inside agent tool — no human-in-the-loop confirmation
|
|
141
|
+
HIGH: MCP Config [LETHAL_TRIFECTA] server 'everything':
|
|
142
|
+
filesystem + network + private data — prompt injection can silently exfiltrate all data
|
|
143
|
+
```
|
|
144
|
+
|
|
126
145
|
**Example Output:**
|
|
127
146
|
```Text
|
|
128
147
|
╭────────────────────────────────╮
|
|
@@ -265,7 +284,11 @@ For custom parsers and SOAR automation:
|
|
|
265
284
|
```bash
|
|
266
285
|
veritensor scan ./models --json
|
|
267
286
|
```
|
|
268
|
-
|
|
287
|
+
### 5. Excel report
|
|
288
|
+
Create an Excel report with data about the problems:
|
|
289
|
+
```bash
|
|
290
|
+
veritensor scan ./models --excel
|
|
291
|
+
```
|
|
269
292
|
---
|
|
270
293
|
|
|
271
294
|
## 🔐 Supply Chain Security (Container Signing)
|
|
@@ -343,6 +366,8 @@ veritensor_audit:
|
|
|
343
366
|
script:
|
|
344
367
|
- veritensor scan . --jobs 4
|
|
345
368
|
allow_failure: false
|
|
369
|
+
```
|
|
370
|
+
|
|
346
371
|
---
|
|
347
372
|
|
|
348
373
|
## 📂 Supported Formats
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "veritensor"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.8.0"
|
|
8
8
|
description = "Antivirus for the AI Supply Chain. Scans models, datasets, notebooks, and RAG documents for threats."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -34,7 +34,9 @@ dependencies = [
|
|
|
34
34
|
"cyclonedx-python-lib>=6.0.0",
|
|
35
35
|
"jinja2>=3.1.0",
|
|
36
36
|
"pillow>=12.2.0",
|
|
37
|
+
"lxml>=6.1.0",
|
|
37
38
|
# Fickling removed from here to avoid installing PyTorch (800MB+) for regular users
|
|
39
|
+
"gitpython>=3.1.47",
|
|
38
40
|
]
|
|
39
41
|
|
|
40
42
|
|
|
@@ -45,7 +45,7 @@ from veritensor.reporting.sarif import generate_sarif_report
|
|
|
45
45
|
from veritensor.reporting.sbom import generate_sbom
|
|
46
46
|
from veritensor.reporting.manifest import generate_manifest
|
|
47
47
|
from veritensor.reporting.html_report import generate_html_report
|
|
48
|
-
|
|
48
|
+
from veritensor.reporting.excel_report import generate_excel_report
|
|
49
49
|
from veritensor.integrations.enterprise_scanner import EnterpriseScanner
|
|
50
50
|
from veritensor.engines.static.mcp_scanner import scan_mcp_server
|
|
51
51
|
|
|
@@ -324,7 +324,12 @@ def scan_worker(args: Tuple[str, VeritensorConfig, Optional[str], bool, bool, bo
|
|
|
324
324
|
if mcp_result.mcp_tools_found:
|
|
325
325
|
for t in mcp_result.to_threat_strings():
|
|
326
326
|
scan_res.add_threat(t)
|
|
327
|
-
|
|
327
|
+
elif ext == ".json" and file_path:
|
|
328
|
+
if is_mcp_config_file(file_path):
|
|
329
|
+
from veritensor.engines.static.mcp_permission_auditor import audit_mcp_config
|
|
330
|
+
perm_result = audit_mcp_config(file_path)
|
|
331
|
+
for t in perm_result.to_threat_strings():
|
|
332
|
+
scan_res.add_threat(t)
|
|
328
333
|
else:
|
|
329
334
|
# If the format is unknown to any engine at all.
|
|
330
335
|
# We add INFO, but DO NOT call add_threat(),
|
|
@@ -509,6 +514,7 @@ def scan(
|
|
|
509
514
|
api_key: Optional[str] = typer.Option(None, envvar="VERITENSOR_API_KEY", help="API Key for reporting"),
|
|
510
515
|
verbose: bool = typer.Option(False, "--verbose", "-v", help="Show detailed logs"),
|
|
511
516
|
html_output: bool = typer.Option(False, "--html", help="Generate a beautiful HTML report"),
|
|
517
|
+
excel_output: bool = typer.Option(False, "--excel", help="Generate an Excel report for auditors (.xlsx)"),
|
|
512
518
|
output_file: Optional[str] = typer.Option(None, "--output-file", "-o", help="Save machine-readable output (JSON/SARIF/SBOM) to a file instead of stdout"),
|
|
513
519
|
):
|
|
514
520
|
"""
|
|
@@ -593,6 +599,21 @@ def scan(
|
|
|
593
599
|
if not is_machine_output:
|
|
594
600
|
console.print(f"\n[bold green]✅ HTML Report saved to: {report_path}[/bold green]")
|
|
595
601
|
|
|
602
|
+
if excel_output:
|
|
603
|
+
try:
|
|
604
|
+
excel_path = generate_excel_report(filtered_results)
|
|
605
|
+
if not is_machine_output:
|
|
606
|
+
console.print(f"\n[bold green]✅ Excel Report saved to: {excel_path}[/bold green]")
|
|
607
|
+
except ImportError as e:
|
|
608
|
+
console.print(f"[bold yellow]⚠️ Excel export requires openpyxl: pip install veritensor[excel][/bold yellow]")
|
|
609
|
+
# Usage:
|
|
610
|
+
# veritensor scan ./models/ --excel
|
|
611
|
+
# veritensor scan ./models/ --excel --output-file report.xlsx
|
|
612
|
+
#
|
|
613
|
+
# Note: --output-file with --excel saves to the specified path.
|
|
614
|
+
# To support custom path, replace the generate_excel_report call with:
|
|
615
|
+
# excel_path = generate_excel_report(filtered_results, output_path=output_file or "veritensor-report.xlsx")
|
|
616
|
+
|
|
596
617
|
machine_text = None
|
|
597
618
|
if sarif_output:
|
|
598
619
|
machine_text = generate_sarif_report(results)
|
|
@@ -39,13 +39,21 @@ class RemoteStream(io.IOBase):
|
|
|
39
39
|
parsed = urlparse(url)
|
|
40
40
|
if parsed.scheme not in ("http", "https"):
|
|
41
41
|
raise ValueError(f"Invalid scheme: {parsed.scheme}")
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
domain = parsed.netloc.lower()
|
|
44
44
|
is_allowed = (domain in ALLOWED_DOMAINS) or (domain.endswith(".huggingface.co"))
|
|
45
|
-
|
|
45
|
+
|
|
46
|
+
# warning-only allowed any URL through,
|
|
47
|
+
# completely bypassing the domain allowlist.
|
|
46
48
|
if not is_allowed:
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
raise ValueError(
|
|
50
|
+
f"SSRF Protection: Domain '{domain}' is not in the allowed list "
|
|
51
|
+
f"({', '.join(ALLOWED_DOMAINS)}). "
|
|
52
|
+
f"Only HuggingFace domains are permitted for remote streaming."
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
except ValueError:
|
|
56
|
+
raise
|
|
49
57
|
except Exception as e:
|
|
50
58
|
raise ValueError(f"Invalid URL format: {e}")
|
|
51
59
|
|
|
@@ -149,8 +149,19 @@ def _check_osv_batch(packages: Dict[str, str]) -> List[str]:
|
|
|
149
149
|
"""Queries OSV.dev API in a single batch request."""
|
|
150
150
|
threats = []
|
|
151
151
|
payload = {"queries": []}
|
|
152
|
-
pkg_list = []
|
|
153
|
-
|
|
152
|
+
pkg_list = []
|
|
153
|
+
|
|
154
|
+
# OSV.dev does not publish a hard batch limit, but large payloads risk
|
|
155
|
+
# 413 / rate-limiting. Cap at 500 packages per call to stay well within limits.
|
|
156
|
+
# For most real-world lock files (poetry.lock, Pipfile.lock) this is sufficient.
|
|
157
|
+
OSV_BATCH_LIMIT = 500
|
|
158
|
+
if len(packages) > OSV_BATCH_LIMIT:
|
|
159
|
+
logger.warning(
|
|
160
|
+
f"Dependency list has {len(packages)} packages — "
|
|
161
|
+
f"truncating OSV check to first {OSV_BATCH_LIMIT} entries."
|
|
162
|
+
)
|
|
163
|
+
packages = dict(list(packages.items())[:OSV_BATCH_LIMIT])
|
|
164
|
+
|
|
154
165
|
for name, version in packages.items():
|
|
155
166
|
payload["queries"].append({
|
|
156
167
|
"package": {"name": name, "ecosystem": "PyPI"},
|
|
@@ -292,3 +303,5 @@ def _safe_read_text(path: Path) -> str:
|
|
|
292
303
|
except UnicodeDecodeError:
|
|
293
304
|
continue
|
|
294
305
|
return raw_bytes.decode('utf-8', errors='ignore')
|
|
306
|
+
|
|
307
|
+
|