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.
Files changed (64) hide show
  1. {veritensor-1.7.0/src/veritensor.egg-info → veritensor-1.8.0}/PKG-INFO +30 -3
  2. {veritensor-1.7.0 → veritensor-1.8.0}/README.md +27 -2
  3. {veritensor-1.7.0 → veritensor-1.8.0}/pyproject.toml +3 -1
  4. veritensor-1.8.0/src/veritensor/__init__.py +2 -0
  5. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/cli/main.py +23 -2
  6. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/core/streaming.py +12 -4
  7. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/static/dependency_engine.py +15 -2
  8. veritensor-1.8.0/src/veritensor/engines/static/mcp_permission_auditor.py +787 -0
  9. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/static/mcp_scanner.py +50 -9
  10. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/static/notebook_engine.py +33 -10
  11. veritensor-1.8.0/src/veritensor/reporting/excel_report.py +347 -0
  12. {veritensor-1.7.0 → veritensor-1.8.0/src/veritensor.egg-info}/PKG-INFO +30 -3
  13. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor.egg-info/SOURCES.txt +2 -0
  14. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor.egg-info/requires.txt +2 -0
  15. veritensor-1.7.0/src/veritensor/__init__.py +0 -2
  16. {veritensor-1.7.0 → veritensor-1.8.0}/LICENSE +0 -0
  17. {veritensor-1.7.0 → veritensor-1.8.0}/MANIFEST.in +0 -0
  18. {veritensor-1.7.0 → veritensor-1.8.0}/setup.cfg +0 -0
  19. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/__main__.py +0 -0
  20. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/cli/__init__.py +0 -0
  21. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/core/__init__.py +0 -0
  22. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/core/cache.py +0 -0
  23. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/core/config.py +0 -0
  24. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/core/entropy.py +0 -0
  25. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/core/file_utils.py +0 -0
  26. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/core/networking.py +0 -0
  27. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/core/safe_zip.py +0 -0
  28. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/core/text_utils.py +0 -0
  29. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/core/types.py +0 -0
  30. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/__init__.py +0 -0
  31. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/container/__init__.py +0 -0
  32. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/container/archive_engine.py +0 -0
  33. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/content/__init__.py +0 -0
  34. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/content/injection.py +0 -0
  35. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/content/pii.py +0 -0
  36. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/data/__init__.py +0 -0
  37. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/data/dataset_engine.py +0 -0
  38. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/data/excel_engine.py +0 -0
  39. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/hashing/__init__.py +0 -0
  40. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/hashing/calculator.py +0 -0
  41. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/hashing/lfs.py +0 -0
  42. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/hashing/readers.py +0 -0
  43. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/static/__init__.py +0 -0
  44. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/static/keras_engine.py +0 -0
  45. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/static/pickle_engine.py +0 -0
  46. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/static/rules.py +0 -0
  47. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/engines/static/signatures.yaml +0 -0
  48. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/integrations/__init__.py +0 -0
  49. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/integrations/chroma_guard.py +0 -0
  50. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/integrations/cosign.py +0 -0
  51. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/integrations/enterprise_scanner.py +0 -0
  52. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/integrations/huggingface.py +0 -0
  53. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/integrations/langchain_guard.py +0 -0
  54. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/integrations/llamaindex_guard.py +0 -0
  55. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/integrations/unstructured_guard.py +0 -0
  56. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/reporting/html_report.py +0 -0
  57. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/reporting/manifest.py +0 -0
  58. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/reporting/sarif.py +0 -0
  59. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/reporting/sbom.py +0 -0
  60. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor/reporting/telemetry.py +0 -0
  61. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor.egg-info/dependency_links.txt +0 -0
  62. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor.egg-info/entry_points.txt +0 -0
  63. {veritensor-1.7.0 → veritensor-1.8.0}/src/veritensor.egg-info/top_level.txt +0 -0
  64. {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.7.0
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. **Governance:** Generates cryptographic **Data Manifests** (Provenance) and signs containers via **Sigstore**.
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. **Governance:** Generates cryptographic **Data Manifests** (Provenance) and signs containers via **Sigstore**.
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.0"
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
 
@@ -0,0 +1,2 @@
1
+ __version__ = "1.8.0"
2
+
@@ -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
- logger.warning(f"Security Warning: Accessing external domain: {domain}")
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
+