Commit Graph
729 Commits
Author SHA1 Message Date
TianHengZhuang d41039773e docs: add module docstrings 2026-09-07 11:06:32 +08:00
TianHengZhuang c78f4ced91 docs: add module docstrings 2026-09-07 11:06:25 +08:00
TianHengZhuang 587cbe53f3 docs: fix external_module.md examples 2026-09-07 11:05:46 +08:00
TianHengZhuang 66a38574a5 docs: add ModuleProtocol 2026-09-07 11:05:40 +08:00
Alexander Myasoedov 73f84b7aa8 Merge pull request #338 from rwinkelman/fix/scan-route-logging-199
feat: add structured logging to scan API routes (#199)
2026-09-01 16:16:22 +03:00
Ray Winkelman 35ae256729 feat: add structured logging to scan API routes (#199)
Log verify/scan/stop/scan-csv entry points and outcomes for easier debugging.
MCP was removed per #306; this covers the equivalent HTTP scan surface.
2026-09-01 15:25:20 +07:00
Alexander Myasoedov 797180ca3a Merge pull request #336 from rwinkelman/fix/verify-integration-error-status-173
fix(ui): mark integration verify failure on network errors
2026-08-31 14:17:34 +03:00
Ray Winkelman 723460768f fix(ui): mark integration verify failure on network errors
Fixes #173
2026-08-29 16:04:18 +07:00
Alexander Myasoedov 1ef131421e feat: move to python 3.14 baseline, patch remaining dependabot alerts
- requires-python >=3.14, pyupgrade --py314-plus, Dockerfile python:3.14-slim
- test matrix 3.14 only
- fastapi ^0.141.1 + starlette 1.6.0 (unblocks 5 starlette alerts)
- python-multipart ^0.0.31 (4 alerts)
- fix TemplateResponse for starlette 1.x request-first signature
- drop teyit hook: abandoned, incompatible with python 3.14
2026-08-18 19:14:05 +03:00
Alexander Myasoedov 11024e6fca fix(deps): patch 47 dependabot alerts via lock bump 2026-08-18 19:07:13 +03:00
Alexander Myasoedov 2f128ae16c fix(deps): bump pyarrow to 25.0.1 for cp314 wheels 2026-08-18 19:01:16 +03:00
Alexander Myasoedov 3b1067c317 fix(pc): 2026-08-18 18:49:56 +03:00
Alexander Myasoedov 27c160eaa3 Merge pull request #326 from chiruu12/fix/hybrid-classifier-guards
fix(hybrid): guard zero total weight and log skipped detectors
2026-08-18 18:40:07 +03:00
Alexander Myasoedov de16779806 Merge pull request #328 from feiiiiii5/fix-circuit-breaker-half-open
fix(circuit-breaker): reopen on failure during half-open probation
2026-08-18 18:39:03 +03:00
Alexander Myasoedov 017ba7c168 Merge pull request #329 from feiiiiii5/fix-p95-percentile-index
fix(executor): compute p95 latency as a real 95th percentile
2026-08-18 18:38:25 +03:00
Alexander Myasoedov 43922ced3d Merge pull request #330 from ChrisJr404/code-block-stenography
Add code_block stenography transform (embed prompt in a docstring)
2026-08-18 18:37:40 +03:00
Alexander Myasoedov 14e45f3788 Merge pull request #331 from ChrisJr404/feat/owasp-llm-badges
Add OWASP LLM Top 10 category badges to the scan UI
2026-08-18 18:36:50 +03:00
Chris (ChrisJr404) 79f450bbae Tag probe datasets with OWASP LLM Top 10 categories in the scan UI 2026-08-17 23:49:11 -04:00
Chris (ChrisJr404) 95c14c3ee5 Add code_block stenography transform that hides prompts in a Python docstring 2026-08-17 21:57:08 -04:00
fei cf3498264f fix(executor): compute p95 latency as a real 95th percentile
ExecutorMetrics.get_stats picked the p95 element with
int(n * 0.95), which collapses to the last index (the maximum)
for any batch of 20 or fewer requests, so the reported p95 was
actually the worst-case latency for typical scan batches. Use
ceil(n * 0.95) - 1, the standard nearest-rank index.
2026-08-16 18:39:10 +08:00
fei fcd1fd20ae fix(circuit-breaker): reopen on failure during half-open probation
record_failure ignored the half_open state: the minimum-sample gate
(total >= 10) and the success counter meant a failure during
probation neither re-opened the circuit nor prevented it from
closing. One failure followed by three successes closed the circuit
with the failure forgotten. Trip back to open on the first half-open
failure, with fresh counters.
2026-08-16 18:23:29 +08:00
chiruu12 2f411b90dc fix(hybrid): guard zero total weight and log skipped detectors 2026-08-14 17:04:47 +05:30
Alexander Myasoedov c8458d73c5 Merge pull request #320 from DevamShah/fix-cors-credentials-and-icon-traversal
fix: wildcard CORS + credentials spec violation, path-traversal guard on /icons proxy
2026-07-31 19:27:20 +03:00
Alexander Myasoedov 42615e506a fix(build): 2026-06-23 10:20:10 +03:00
Alexander Myasoedov e6459a551a Merge pull request #321 from DevamShah/config-pluggable-detectors
feat: config-pluggable refusal classifiers and leak detectors
2026-06-23 10:12:26 +03:00
Devam Shah d28c4b4b1e feat: config-pluggable refusal classifiers and leak detectors
PIIDetector and SandboxEscapeDetector were wired directly in
probe_actor/refusal.py and the refusal classifier manager was populated from
a hardcoded list, so the only way to toggle a bundled detector or add an
organization-specific signature was to patch the module.

Add a DetectorRegistry mapping plugin names to factories, assembled from an
agentic_security.toml [detectors] section via build_from_config. Custom
detectors load by import path ("pkg.module:ClassName"). refusal.py gains
build_refusal_manager(config=None) reading the [detectors] table; all public
symbols are preserved. Built-in leak detectors ship registered but disabled,
so default refusal_heuristic behaviour is unchanged.

Closes #82

Signed-off-by: Devam Shah <devamshah91@gmail.com>
2026-06-22 19:40:33 +05:30
Devam Shah dd59704fdf fix: wildcard CORS + credentials spec violation, path-traversal guard on /icons proxy
CORS: drop allow_credentials=True. With allow_origins=['*'] Starlette reflects
the request Origin and emits Access-Control-Allow-Credentials: true on any
credentialed request — a reflect-any-origin hole. The app authenticates with
Bearer tokens in the Authorization header, so credentialed CORS was never needed.

/icons/{icon_name}: validate against a strict allowlist (re.fullmatch
[A-Za-z0-9._-]+\.png) and assert the resolved path stays inside ICONS_DIR before
any filesystem write or outbound fetch. Closes the path-traversal / arbitrary-write
(CWE-22) and controlled-URL (CWE-73) surface on the unsanitized icon_name.

Adds CORS middleware tests and icon-name validation tests (traversal, encoded
slash, null byte, trailing newline, wrong extension).

Closes #298

Signed-off-by: Devam Shah <devamshah91@gmail.com>
2026-06-22 10:10:43 +05:30
Alexander Myasoedov 8e12141df8 Merge pull request #318 from nakshaatraa/docs/fuzzer-module-docstring
docs: add module-level docstring and document constants in fuzzer.py
2026-06-15 12:55:19 +03:00
Alexander Myasoedov b90b80a0af Merge pull request #317 from nakshaatraa/fix/image-generator-matplotlib-warnings
fix: set matplotlib Agg backend and sanitize prompt whitespace
2026-06-15 12:54:41 +03:00
Alexander Myasoedov b827a0b186 Merge pull request #316 from jasoncobra3/chore/delete-agno-dead-code-v2
chore: delete Agno dead code (Phase 1)
2026-06-15 12:52:19 +03:00
Nakshatra Mote 30566b9d4d Add module-level docstring and document constants in fuzzer.py 2026-06-15 14:44:55 +05:30
Nakshatra Mote 6dec776700 Fix matplotlib warnings and TclError in image generator 2026-06-15 14:44:16 +05:30
Aniket 5ccab6ba3b chore: delete Agno dead code (Phase 1)
Closes #307

Agno was imported by nothing, had undefined-variable bugs,
and was not a declared dependency.

Removed:
- agentic_security/agents/ (operator_agno.py)
- docs/mcp_agno_integration.md
- .gitignore reference to operator_agno.py

No agno references remain in source code.
Pre-existing test failures (missing tabulate module) confirmed
unrelated to this change via git stash verification.
2026-06-11 23:22:36 +05:30
Alexander Myasoedov 21f7517ef9 Merge pull request #314 from JackSpiece/chore/remove-mcp
chore: delete MCP server and client
2026-06-11 17:46:04 +03:00
JackSpiece cb8bceb16a chore: delete MCP server and client (#308) 2026-06-10 21:30:07 +00:00
Alexander Myasoedov 438f30bfb2 Merge pull request #313 from JackSpiece/chore/remove-agno
chore: remove leftover Agno artifacts
2026-06-10 23:55:45 +03:00
JackSpiece 92e3feb42d chore: remove leftover Agno artifacts (#307) 2026-06-10 20:48:26 +00:00
Alexander Myasoedov 13b03b958f Merge pull request #310 from zhanz5/fix/cost-calculation-model-aware
fix: make cost calculation model-aware instead of hardcoded to deepseek-chat
2026-06-05 10:12:41 +03:00
zhanz5 ab33513561 style: apply black formatting to fuzzer.py 2026-06-05 14:19:33 +08:00
zhanz5 f25520869f merge: resolve conflict with upstream msoedov/agentic_security
Merged upstream/main into fix/cost-calculation-model-aware.

Conflict resolved in cost_module.py:
- Kept upstream's updated PRICING table (2026-06-03 verified prices)
- Kept upstream's DEFAULT_MODEL = "claude-sonnet"
- Kept upstream's 50/50 input/output token split
- Preserved our float | None return type for unknown models
- Preserved our logger.warning instead of raise ValueError
2026-06-05 14:15:08 +08:00
zhanz5 02b68b06ee fix: make cost calculation model-aware instead of hardcoded to deepseek-chat
Previously, calculate_cost() was always called without a model parameter,
causing all scans to report costs based on deepseek-chat pricing regardless
of the actual target model (e.g. gpt-4, claude-3-opus).

Changes:

- http_spec.py: Add 'model_name' property to LLMSpec that extracts the
  model field from the JSON request body. Returns 'unknown' if the body
  is not valid JSON or has no 'model' field.

- probe_data/image_generator.py: Add 'model_name' pass-through property
  to RequestAdapter, delegating to the underlying LLMSpec.

- probe_data/audio_generator.py: Same as above - add 'model_name'
  pass-through property to RequestAdapter.

- probe_actor/cost_module.py:
  - Change return type from float to float | None.
  - Unknown models now log a warning and return None instead of raising
    ValueError, so scans are not interrupted by unsupported model names.
  - Add logger import for the warning message.

- probe_actor/fuzzer.py: Pass model_name to calculate_cost() in both
  scan_module() and perform_many_shot_scan() using
  getattr(request_factory, 'model_name', 'unknown').

- primitives/models.py: Update ScanResult.cost type from float to
  float | None to accommodate unknown model pricing.
2026-06-05 13:59:59 +08:00
Alexander Myasoedov 6ae9ea8bfe fix(pc): 2026-06-04 18:32:42 +03:00
Alexander Myasoedov 40a8284656 feat(clean readme): 2026-06-04 18:29:25 +03:00
Alexander Myasoedov ead8f85836 feat(feat(refusal): detect Docker/K8s sandbox escape probes (#280)): 2026-06-04 18:28:12 +03:00
Alexander Myasoedov 6dcda7c931 fix(fix(security): bind server to 127.0.0.1 instead of 0.0.0.0 by default): 2026-06-04 17:53:35 +03:00
Alexander Myasoedov 7b8d238254 Merge pull request #305 from zhanz5/fix/remove-duplicate-probedataset-msj
fix: remove duplicate ProbeDataset class from msj_data.py
2026-06-04 17:47:17 +03:00
zhanz5 5e5469a1a7 fix: remove duplicate ProbeDataset class from msj_data.py
msj_data.py contained a full copy of the ProbeDataset dataclass that
was already defined canonically in probe_data/models.py, violating DRY
and leaving a stale TODO comment in the source.

Changes:
- probe_data/msj_data.py: delete the 19-line duplicate ProbeDataset
  definition and the now-unused 'from dataclasses import dataclass'
  import; replace with a single re-export:
    from agentic_security.probe_data.models import ProbeDataset
  All call-sites inside the file (load_dataset_generic, prepare_prompts)
  continue to work unchanged because the field signatures are identical.
  The TODO comment is removed as the refactor is now complete.

No changes required in consumers (fuzzer.py, test_msj_data.py) because
they access ProbeDataset through msj_data's re-export.
2026-06-04 21:46:22 +08:00
Alexander Myasoedov 3b26e57b9e fix(pc): 0.7.5 2026-06-03 15:13:19 +03:00
Alexander Myasoedov 5ce4ed5d91 Merge pull request #301 from JackSpiece/fix/tailwind-v4-static-classes
fix: migrate static UI to Tailwind v4
2026-06-03 15:10:49 +03:00
Alexander Myasoedov 816c8c6bc7 fix(make litellm optional import): 2026-06-03 15:08:23 +03:00