codejury 0.10.2__tar.gz → 0.10.4__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.
- codejury-0.10.4/PKG-INFO +241 -0
- codejury-0.10.4/README.md +211 -0
- codejury-0.10.4/codejury/data/capabilities/model_supply_chain.yaml +59 -0
- codejury-0.10.4/codejury/data/golden/sc_pinned_safe.yaml +11 -0
- codejury-0.10.4/codejury/data/golden/sc_safetensors_safe.yaml +12 -0
- codejury-0.10.4/codejury/data/golden/sc_torch_load_vuln.yaml +11 -0
- codejury-0.10.4/codejury/data/golden/sc_trust_remote_code_vuln.yaml +11 -0
- codejury-0.10.4/codejury.egg-info/PKG-INFO +241 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury.egg-info/SOURCES.txt +5 -0
- {codejury-0.10.2 → codejury-0.10.4}/pyproject.toml +2 -2
- codejury-0.10.2/PKG-INFO +0 -227
- codejury-0.10.2/README.md +0 -197
- codejury-0.10.2/codejury.egg-info/PKG-INFO +0 -227
- {codejury-0.10.2 → codejury-0.10.4}/LICENSE +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/__init__.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/agents/__init__.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/agents/base.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/agents/debate.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/agents/mock.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/agents/parsing.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/agents/refuter.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/agents/verifier.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/analysis/__init__.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/analysis/provenance.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/analysis/taint.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/assembly.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/baseline.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/cli.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/capabilities/authentication.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/capabilities/authorization.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/capabilities/business_logic.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/capabilities/crypto.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/capabilities/data_protection.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/capabilities/dependency_config.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/capabilities/error_logging.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/capabilities/excessive_agency.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/capabilities/input_validation.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/capabilities/insecure_output_handling.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/capabilities/output_encoding.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/capabilities/prompt_injection.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/capabilities/secrets.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/capabilities/session.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/ag_allowlist_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/ag_arbitrary_tool_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/ag_destructive_no_confirm_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/ag_fixed_enum_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/ag_human_approval_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/ag_model_confirmed_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/authn_bcrypt_password.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/authn_jwt_noverify_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/authn_jwt_verified_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/authn_sha256_checksum_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/authn_sha256_password.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/authn_weak_hash_indirect_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/authz_idor_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/authz_owner_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/business_logic_price_tamper_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/business_logic_server_checked_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/cmdi_fixed_argv_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/cmdi_ossystem_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/cmdi_subprocess_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/crypto_aesgcm_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/crypto_ecb_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/data_protection_plaintext_pii_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/data_protection_tokenized_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/dependency_config_tls_verify_off_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/dependency_config_tls_verify_on_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/deserialize_json_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/deserialize_pickle_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/error_logging_redacted_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/error_logging_secret_leak_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/ioh_escaped_output_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/ioh_exec_output_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/ioh_innerhtml_output_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/ioh_json_response_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/ioh_output_to_sql_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/ioh_schema_validated_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/literal_eval_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/path_basename_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/path_contained_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/path_traversal_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/pi_delimited_data_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/pi_format_role_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/pi_indirect_rag_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/pi_system_concat_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/pi_user_content_concat_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/pi_user_role_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/secrets_env_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/secrets_hardcoded_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/session_fixation_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/session_secure_cookie_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/sql_constant_concat_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/sqli_format_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/sqli_fstring_query.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/sqli_indirect_var_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/sqli_parameterized_query.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/ssrf_allowlist_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/ssrf_constant_url_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/ssrf_substring_allowlist_bypass_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/ssrf_user_url_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/xfile_idor_no_check_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/xfile_idor_owner_checked_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/xfile_path_sanitized_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/xfile_path_tainted_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/xss_innerhtml_constant_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/xss_innerhtml_vuln.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/golden/xss_textcontent_safe.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/suppressions.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/taint.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/tasks/audit_diff_debate.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/data/tasks/quick_scan_single.yaml +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/domain/__init__.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/domain/artifact.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/domain/capability.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/domain/context.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/domain/observation.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/domain/result.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/evaluation.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/infrastructure/__init__.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/infrastructure/cache.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/infrastructure/json_parse.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/integrations/__init__.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/integrations/github.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/orchestrators/__init__.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/orchestrators/adaptive.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/orchestrators/base.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/orchestrators/challenge.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/orchestrators/debate.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/orchestrators/pipeline.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/orchestrators/reflexion.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/orchestrators/single.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/orchestrators/taint_gate.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/providers/__init__.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/providers/anthropic.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/providers/base.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/providers/litellm.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/providers/mock.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/providers/openai.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/providers/openai_format.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/providers/retry.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/reporting.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/resources.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/sources/__init__.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/sources/base.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/sources/callers.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/sources/chunker.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/sources/diff.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/sources/function.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/sources/mock.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/sources/repo.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/suppression.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/tasks/__init__.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/tasks/base.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury/tasks/registry.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury.egg-info/dependency_links.txt +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury.egg-info/entry_points.txt +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury.egg-info/requires.txt +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/codejury.egg-info/top_level.txt +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/setup.cfg +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_adaptive.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_anthropic_provider.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_assembly.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_audit_pipeline.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_baseline.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_cache.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_callers.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_capability.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_challenge.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_cli_audit.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_context.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_debate_agents.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_debate_orchestrator.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_diff_source.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_evaluation.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_function_source.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_integrations.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_json_parse.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_litellm_provider.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_openai_provider.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_orchestrator.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_parsing.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_pipeline_orchestrator.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_provenance.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_reflexion_orchestrator.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_repo_source.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_reporting.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_retry_provider.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_review_fixes.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_sarif.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_suppression.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_taint.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_taint_crossfile.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_taint_gate.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_tasks.py +0 -0
- {codejury-0.10.2 → codejury-0.10.4}/tests/test_verifier.py +0 -0
codejury-0.10.4/PKG-INFO
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: codejury
|
|
3
|
+
Version: 0.10.4
|
|
4
|
+
Summary: General-purpose Application Security AI audit framework: five-layer architecture, capabilities as first-class data
|
|
5
|
+
Author: AISecLabs
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/aiseclabs/codejury
|
|
8
|
+
Project-URL: Repository, https://github.com/aiseclabs/codejury
|
|
9
|
+
Keywords: security,appsec,static analysis,llm,owasp,asvs,code review
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Topic :: Security
|
|
13
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Requires-Python: >=3.12
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Requires-Dist: pyyaml>=6.0
|
|
20
|
+
Provides-Extra: anthropic
|
|
21
|
+
Requires-Dist: anthropic>=0.40; extra == "anthropic"
|
|
22
|
+
Provides-Extra: openai
|
|
23
|
+
Requires-Dist: openai>=1.0; extra == "openai"
|
|
24
|
+
Provides-Extra: litellm
|
|
25
|
+
Requires-Dist: litellm>=1.0; extra == "litellm"
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
28
|
+
Requires-Dist: jsonschema>=4.0; extra == "dev"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# codejury
|
|
32
|
+
|
|
33
|
+
An AI security auditor for code whose knowledge lives in versioned YAML, not in
|
|
34
|
+
prompts. It reviews a diff or a whole repository against the OWASP ASVS and the
|
|
35
|
+
OWASP LLM Top 10, and reports a verdict per dimension: both what is **vulnerable**
|
|
36
|
+
and what is **verified safe**.
|
|
37
|
+
|
|
38
|
+
The name is the idea. Code goes before a "jury" of adversarial roles, Finder,
|
|
39
|
+
Challenger, and Judge, that argue and converge on a verdict.
|
|
40
|
+
|
|
41
|
+
## Why it is built this way
|
|
42
|
+
|
|
43
|
+
- **Knowledge is data.** Each OWASP ASVS area, and now the OWASP LLM Top 10, is a
|
|
44
|
+
YAML capability with safe patterns, anti-patterns, CWE ids, and examples. It is
|
|
45
|
+
versioned, reviewable in a PR, and editable by non-engineers, so the framework
|
|
46
|
+
core stays small.
|
|
47
|
+
- **Verdicts, not just alerts.** Every capability yields `SECURE`, `VULNERABLE`,
|
|
48
|
+
`PARTIAL`, or `NOT_PRESENT`, so a report shows what was checked and passed, not
|
|
49
|
+
only what failed.
|
|
50
|
+
- **Composable.** Seven orchestration strategies, three model backends, and diff,
|
|
51
|
+
repo, or function inputs are chosen per run and mix freely.
|
|
52
|
+
- **Deterministic.** Providers run at temperature 0 and verdicts are cached, so
|
|
53
|
+
the same input gives the same result.
|
|
54
|
+
|
|
55
|
+
## Install
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pip install codejury # core and CLI
|
|
59
|
+
pip install 'codejury[anthropic]' # the provider you will use: anthropic, openai, or litellm
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Quickstart
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# No API key needed: prove the pipeline runs end to end with mock layers
|
|
66
|
+
codejury dry-run
|
|
67
|
+
|
|
68
|
+
# A real audit of your staged changes
|
|
69
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
70
|
+
git diff | codejury audit --provider anthropic
|
|
71
|
+
|
|
72
|
+
# CI gate: exit 1 if a high-severity issue is found
|
|
73
|
+
git diff origin/main... | codejury audit --fail-on high -
|
|
74
|
+
|
|
75
|
+
# Inline review comments on a GitHub pull request, needs GITHUB_TOKEN
|
|
76
|
+
git diff origin/main... | codejury audit --github your-org/your-repo#123 -
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Commands
|
|
80
|
+
|
|
81
|
+
| Command | What it does |
|
|
82
|
+
|---|---|
|
|
83
|
+
| `codejury dry-run` | Run the mock pipeline with no key, a smoke test. |
|
|
84
|
+
| `codejury audit [diff]` | Audit a unified diff from a file or stdin (`-`). |
|
|
85
|
+
| `codejury scan <dir>` | Audit a whole directory tree, capability by capability. |
|
|
86
|
+
| `codejury run <task>` | Run a named task preset, see [Tasks](#tasks). |
|
|
87
|
+
| `codejury eval` | Score the golden cases and report precision, recall, and F1, overall and per capability. |
|
|
88
|
+
|
|
89
|
+
Shared flags: `--orchestrator`, `--provider {anthropic,openai,litellm}`,
|
|
90
|
+
`--model`, `--format {text,markdown,json,sarif}`.
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Multi-round adversarial debate, rendered as Markdown
|
|
94
|
+
git diff | codejury audit --orchestrator debate --format markdown - > report.md
|
|
95
|
+
|
|
96
|
+
# Deep whole-repo scan, scoped to a few capabilities to bound the cost
|
|
97
|
+
codejury scan ./myrepo --only secrets,input_validation,crypto
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Orchestration strategies
|
|
101
|
+
|
|
102
|
+
`--orchestrator` chooses how the agents run. They mix freely with any provider,
|
|
103
|
+
model, and input.
|
|
104
|
+
|
|
105
|
+
| Strategy | What it does |
|
|
106
|
+
|---|---|
|
|
107
|
+
| `single` | One verifier pass. The default for `audit`. |
|
|
108
|
+
| `pipeline` | One verifier, capability by capability. |
|
|
109
|
+
| `debate` | Finder, Challenger, and Judge argue across rounds. |
|
|
110
|
+
| `reflexion` | An actor and a critic iterate. |
|
|
111
|
+
| `challenge` | Verify, then a recall-safe refuter drops only provably-safe taint flags. |
|
|
112
|
+
| `taint` | Verify, then a static data-flow gate clears an `input_validation` finding only when provenance proves the value reaching the sink is constant, sanitized, or trusted. It uses cross-file caller and callee context and downgrades only on positive proof, so it removes false positives without dropping real findings. |
|
|
113
|
+
| `adaptive` | Run the cheap single verifier first and escalate to a full debate only when it pays off: any `VULNERABLE` verdict, or a low-confidence `PARTIAL`/`UNKNOWN` one. Clean, confident files pay a single model call. |
|
|
114
|
+
|
|
115
|
+
## CI and pull-request workflow
|
|
116
|
+
|
|
117
|
+
- `--fail-on {critical,high,medium,low}` exits 1 when a finding at or above that
|
|
118
|
+
severity is present, so the audit gates a build.
|
|
119
|
+
- `--github owner/repo#number` posts a review with inline comments on a pull
|
|
120
|
+
request, using `GITHUB_TOKEN`.
|
|
121
|
+
- `--baseline <report.json>` reports only findings new since a saved report. Save
|
|
122
|
+
the target branch once, then a PR shows only what it introduced, matched by a
|
|
123
|
+
line-tolerant fingerprint so shifted code is not re-reported. Combine with
|
|
124
|
+
`--fail-on` to gate on new issues only.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
git checkout main && codejury scan . --format json > baseline.json
|
|
128
|
+
git checkout pr-branch && codejury scan . --baseline baseline.json --fail-on high
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
- `--format sarif` emits a SARIF 2.1.0 log that validates against the official
|
|
132
|
+
schema, for CI and security dashboards. Each problem with a code location
|
|
133
|
+
becomes a result carrying its capability as the rule id, the CWE, and a precise
|
|
134
|
+
location.
|
|
135
|
+
- Findings in known-noise categories such as availability and DoS, rate limiting,
|
|
136
|
+
and memory safety outside C and C++ are dropped by versioned rules in
|
|
137
|
+
`codejury/data/suppressions.yaml`. Disable with `--no-suppress`.
|
|
138
|
+
|
|
139
|
+
## Determinism and caching
|
|
140
|
+
|
|
141
|
+
Providers query at temperature 0, and `audit` and `scan` cache each verdict on a
|
|
142
|
+
hash of the normalized code, the in-scope capability fingerprints, and the
|
|
143
|
+
orchestration. Re-auditing unchanged code returns the recorded verdicts without
|
|
144
|
+
re-querying the model. Editing a capability YAML changes its fingerprint and
|
|
145
|
+
invalidates affected entries. Pass `--no-cache` to always re-query.
|
|
146
|
+
|
|
147
|
+
## Configuration
|
|
148
|
+
|
|
149
|
+
Provider keys are read from the environment. codejury does **not** auto-load
|
|
150
|
+
`.env`; copy `.env.example` and `source` it.
|
|
151
|
+
|
|
152
|
+
| Variable | Used by |
|
|
153
|
+
|---|---|
|
|
154
|
+
| `ANTHROPIC_API_KEY` | `--provider anthropic` |
|
|
155
|
+
| `OPENAI_API_KEY` | `--provider openai` |
|
|
156
|
+
| `CODEJURY_API_BASE`, `CODEJURY_API_KEY`, `CODEJURY_MODEL` | defaults for `--api-base`, `--api-key`, and `--model`, for any provider |
|
|
157
|
+
|
|
158
|
+
The `CODEJURY_*` variables make a LiteLLM proxy a one-liner:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
# with CODEJURY_API_BASE, CODEJURY_API_KEY, CODEJURY_MODEL in a sourced .env
|
|
162
|
+
git diff | codejury audit --provider litellm -
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Tasks
|
|
166
|
+
|
|
167
|
+
A task is a named preset of capabilities, orchestrator, provider, and model. It
|
|
168
|
+
lives in a YAML file. The API key always stays in the environment.
|
|
169
|
+
|
|
170
|
+
```yaml
|
|
171
|
+
# mytasks/proxy_scan.yaml -> codejury run proxy_scan --tasks mytasks
|
|
172
|
+
name: proxy_scan
|
|
173
|
+
orchestrator: debate
|
|
174
|
+
provider: litellm
|
|
175
|
+
model: your-alias
|
|
176
|
+
api_base: https://litellm.example.com # key comes from CODEJURY_API_KEY
|
|
177
|
+
capabilities: [authn, input_validation, secrets] # omit to check all
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Capabilities
|
|
181
|
+
|
|
182
|
+
The library covers all 11 OWASP ASVS areas plus a growing set of OWASP LLM Top 10
|
|
183
|
+
capabilities, one YAML each under `codejury/data/capabilities/`. These ids are
|
|
184
|
+
what `--only` and a task's `capabilities:` accept:
|
|
185
|
+
|
|
186
|
+
`authn`, `authz`, `session`, `input_validation`, `output_encoding`, `crypto`,
|
|
187
|
+
`secrets`, `data_protection`, `error_logging`, `business_logic`,
|
|
188
|
+
`dependency_config`, `prompt_injection`, `insecure_output_handling`,
|
|
189
|
+
`excessive_agency`, `model_supply_chain`.
|
|
190
|
+
|
|
191
|
+
To tune for your codebase, edit these files, adding patterns or sharpening
|
|
192
|
+
wording. No code change is needed.
|
|
193
|
+
|
|
194
|
+
## eval
|
|
195
|
+
|
|
196
|
+
`codejury eval` scores the golden cases and reports a confusion matrix with
|
|
197
|
+
precision, recall, and F1, overall and per capability. It takes `--dataset <dir>`
|
|
198
|
+
for the golden directory, `--split <name>` to score only cases tagged with that
|
|
199
|
+
`split:` such as a held-out set, `--orchestrator` to measure any strategy, and
|
|
200
|
+
`--format {text,json}`. The JSON report is a stable, documented schema.
|
|
201
|
+
|
|
202
|
+
## Architecture
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
Layer 5 Task preset: source, capabilities, orchestrator, agents
|
|
206
|
+
Layer 4 Capability YAML domain knowledge: authn, authz, prompt_injection, ...
|
|
207
|
+
Layer 3 Orchestrator strategy: single, pipeline, debate, reflexion, challenge, taint, adaptive
|
|
208
|
+
Source input: diff, repo, function
|
|
209
|
+
Agent role: finder, challenger, judge, verifier, refuter
|
|
210
|
+
Layer 2 Provider model backend: anthropic, openai, litellm, mock
|
|
211
|
+
Layer 1 Infrastructure cross-cutting utilities: json parsing, verdict cache, retry
|
|
212
|
+
Analysis provenance and taint code-graph engine
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Layers talk only through typed data, and each is an abstract base class plus
|
|
216
|
+
implementations, so the axes of task, orchestration, model, and input compose
|
|
217
|
+
independently.
|
|
218
|
+
|
|
219
|
+
## Limitations
|
|
220
|
+
|
|
221
|
+
- **Prompts are a first pass.** Expect false positives and misses on real code.
|
|
222
|
+
Tune by editing the capability YAML and growing the golden set, and measure the
|
|
223
|
+
effect with `codejury eval`.
|
|
224
|
+
- **Local-pattern checks are sharper than data-flow ones.** A capability judged
|
|
225
|
+
from one spot, such as weak crypto or a hardcoded secret, is reliable. Taint
|
|
226
|
+
classes such as path traversal and SSRF over-flag in single-file review because
|
|
227
|
+
the verifier cannot see whether a value is attacker-controlled. `--orchestrator
|
|
228
|
+
taint` adds a static provenance gate that clears findings it can prove safe and
|
|
229
|
+
is recall-safe, but it is shallow on real code where the value flows through
|
|
230
|
+
object or module attributes. Decisive taint precision needs a deeper code
|
|
231
|
+
graph, which is in progress.
|
|
232
|
+
- **`scan` cost scales with files times capabilities.** It is a periodic deep
|
|
233
|
+
audit, not a quick check, so scope it with `--only`. Day to day, audit the diff.
|
|
234
|
+
|
|
235
|
+
## Development
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
python -m venv .venv && source .venv/bin/activate
|
|
239
|
+
pip install -e ".[dev]"
|
|
240
|
+
pytest
|
|
241
|
+
```
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# codejury
|
|
2
|
+
|
|
3
|
+
An AI security auditor for code whose knowledge lives in versioned YAML, not in
|
|
4
|
+
prompts. It reviews a diff or a whole repository against the OWASP ASVS and the
|
|
5
|
+
OWASP LLM Top 10, and reports a verdict per dimension: both what is **vulnerable**
|
|
6
|
+
and what is **verified safe**.
|
|
7
|
+
|
|
8
|
+
The name is the idea. Code goes before a "jury" of adversarial roles, Finder,
|
|
9
|
+
Challenger, and Judge, that argue and converge on a verdict.
|
|
10
|
+
|
|
11
|
+
## Why it is built this way
|
|
12
|
+
|
|
13
|
+
- **Knowledge is data.** Each OWASP ASVS area, and now the OWASP LLM Top 10, is a
|
|
14
|
+
YAML capability with safe patterns, anti-patterns, CWE ids, and examples. It is
|
|
15
|
+
versioned, reviewable in a PR, and editable by non-engineers, so the framework
|
|
16
|
+
core stays small.
|
|
17
|
+
- **Verdicts, not just alerts.** Every capability yields `SECURE`, `VULNERABLE`,
|
|
18
|
+
`PARTIAL`, or `NOT_PRESENT`, so a report shows what was checked and passed, not
|
|
19
|
+
only what failed.
|
|
20
|
+
- **Composable.** Seven orchestration strategies, three model backends, and diff,
|
|
21
|
+
repo, or function inputs are chosen per run and mix freely.
|
|
22
|
+
- **Deterministic.** Providers run at temperature 0 and verdicts are cached, so
|
|
23
|
+
the same input gives the same result.
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install codejury # core and CLI
|
|
29
|
+
pip install 'codejury[anthropic]' # the provider you will use: anthropic, openai, or litellm
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Quickstart
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# No API key needed: prove the pipeline runs end to end with mock layers
|
|
36
|
+
codejury dry-run
|
|
37
|
+
|
|
38
|
+
# A real audit of your staged changes
|
|
39
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
40
|
+
git diff | codejury audit --provider anthropic
|
|
41
|
+
|
|
42
|
+
# CI gate: exit 1 if a high-severity issue is found
|
|
43
|
+
git diff origin/main... | codejury audit --fail-on high -
|
|
44
|
+
|
|
45
|
+
# Inline review comments on a GitHub pull request, needs GITHUB_TOKEN
|
|
46
|
+
git diff origin/main... | codejury audit --github your-org/your-repo#123 -
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Commands
|
|
50
|
+
|
|
51
|
+
| Command | What it does |
|
|
52
|
+
|---|---|
|
|
53
|
+
| `codejury dry-run` | Run the mock pipeline with no key, a smoke test. |
|
|
54
|
+
| `codejury audit [diff]` | Audit a unified diff from a file or stdin (`-`). |
|
|
55
|
+
| `codejury scan <dir>` | Audit a whole directory tree, capability by capability. |
|
|
56
|
+
| `codejury run <task>` | Run a named task preset, see [Tasks](#tasks). |
|
|
57
|
+
| `codejury eval` | Score the golden cases and report precision, recall, and F1, overall and per capability. |
|
|
58
|
+
|
|
59
|
+
Shared flags: `--orchestrator`, `--provider {anthropic,openai,litellm}`,
|
|
60
|
+
`--model`, `--format {text,markdown,json,sarif}`.
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Multi-round adversarial debate, rendered as Markdown
|
|
64
|
+
git diff | codejury audit --orchestrator debate --format markdown - > report.md
|
|
65
|
+
|
|
66
|
+
# Deep whole-repo scan, scoped to a few capabilities to bound the cost
|
|
67
|
+
codejury scan ./myrepo --only secrets,input_validation,crypto
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Orchestration strategies
|
|
71
|
+
|
|
72
|
+
`--orchestrator` chooses how the agents run. They mix freely with any provider,
|
|
73
|
+
model, and input.
|
|
74
|
+
|
|
75
|
+
| Strategy | What it does |
|
|
76
|
+
|---|---|
|
|
77
|
+
| `single` | One verifier pass. The default for `audit`. |
|
|
78
|
+
| `pipeline` | One verifier, capability by capability. |
|
|
79
|
+
| `debate` | Finder, Challenger, and Judge argue across rounds. |
|
|
80
|
+
| `reflexion` | An actor and a critic iterate. |
|
|
81
|
+
| `challenge` | Verify, then a recall-safe refuter drops only provably-safe taint flags. |
|
|
82
|
+
| `taint` | Verify, then a static data-flow gate clears an `input_validation` finding only when provenance proves the value reaching the sink is constant, sanitized, or trusted. It uses cross-file caller and callee context and downgrades only on positive proof, so it removes false positives without dropping real findings. |
|
|
83
|
+
| `adaptive` | Run the cheap single verifier first and escalate to a full debate only when it pays off: any `VULNERABLE` verdict, or a low-confidence `PARTIAL`/`UNKNOWN` one. Clean, confident files pay a single model call. |
|
|
84
|
+
|
|
85
|
+
## CI and pull-request workflow
|
|
86
|
+
|
|
87
|
+
- `--fail-on {critical,high,medium,low}` exits 1 when a finding at or above that
|
|
88
|
+
severity is present, so the audit gates a build.
|
|
89
|
+
- `--github owner/repo#number` posts a review with inline comments on a pull
|
|
90
|
+
request, using `GITHUB_TOKEN`.
|
|
91
|
+
- `--baseline <report.json>` reports only findings new since a saved report. Save
|
|
92
|
+
the target branch once, then a PR shows only what it introduced, matched by a
|
|
93
|
+
line-tolerant fingerprint so shifted code is not re-reported. Combine with
|
|
94
|
+
`--fail-on` to gate on new issues only.
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
git checkout main && codejury scan . --format json > baseline.json
|
|
98
|
+
git checkout pr-branch && codejury scan . --baseline baseline.json --fail-on high
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
- `--format sarif` emits a SARIF 2.1.0 log that validates against the official
|
|
102
|
+
schema, for CI and security dashboards. Each problem with a code location
|
|
103
|
+
becomes a result carrying its capability as the rule id, the CWE, and a precise
|
|
104
|
+
location.
|
|
105
|
+
- Findings in known-noise categories such as availability and DoS, rate limiting,
|
|
106
|
+
and memory safety outside C and C++ are dropped by versioned rules in
|
|
107
|
+
`codejury/data/suppressions.yaml`. Disable with `--no-suppress`.
|
|
108
|
+
|
|
109
|
+
## Determinism and caching
|
|
110
|
+
|
|
111
|
+
Providers query at temperature 0, and `audit` and `scan` cache each verdict on a
|
|
112
|
+
hash of the normalized code, the in-scope capability fingerprints, and the
|
|
113
|
+
orchestration. Re-auditing unchanged code returns the recorded verdicts without
|
|
114
|
+
re-querying the model. Editing a capability YAML changes its fingerprint and
|
|
115
|
+
invalidates affected entries. Pass `--no-cache` to always re-query.
|
|
116
|
+
|
|
117
|
+
## Configuration
|
|
118
|
+
|
|
119
|
+
Provider keys are read from the environment. codejury does **not** auto-load
|
|
120
|
+
`.env`; copy `.env.example` and `source` it.
|
|
121
|
+
|
|
122
|
+
| Variable | Used by |
|
|
123
|
+
|---|---|
|
|
124
|
+
| `ANTHROPIC_API_KEY` | `--provider anthropic` |
|
|
125
|
+
| `OPENAI_API_KEY` | `--provider openai` |
|
|
126
|
+
| `CODEJURY_API_BASE`, `CODEJURY_API_KEY`, `CODEJURY_MODEL` | defaults for `--api-base`, `--api-key`, and `--model`, for any provider |
|
|
127
|
+
|
|
128
|
+
The `CODEJURY_*` variables make a LiteLLM proxy a one-liner:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# with CODEJURY_API_BASE, CODEJURY_API_KEY, CODEJURY_MODEL in a sourced .env
|
|
132
|
+
git diff | codejury audit --provider litellm -
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Tasks
|
|
136
|
+
|
|
137
|
+
A task is a named preset of capabilities, orchestrator, provider, and model. It
|
|
138
|
+
lives in a YAML file. The API key always stays in the environment.
|
|
139
|
+
|
|
140
|
+
```yaml
|
|
141
|
+
# mytasks/proxy_scan.yaml -> codejury run proxy_scan --tasks mytasks
|
|
142
|
+
name: proxy_scan
|
|
143
|
+
orchestrator: debate
|
|
144
|
+
provider: litellm
|
|
145
|
+
model: your-alias
|
|
146
|
+
api_base: https://litellm.example.com # key comes from CODEJURY_API_KEY
|
|
147
|
+
capabilities: [authn, input_validation, secrets] # omit to check all
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Capabilities
|
|
151
|
+
|
|
152
|
+
The library covers all 11 OWASP ASVS areas plus a growing set of OWASP LLM Top 10
|
|
153
|
+
capabilities, one YAML each under `codejury/data/capabilities/`. These ids are
|
|
154
|
+
what `--only` and a task's `capabilities:` accept:
|
|
155
|
+
|
|
156
|
+
`authn`, `authz`, `session`, `input_validation`, `output_encoding`, `crypto`,
|
|
157
|
+
`secrets`, `data_protection`, `error_logging`, `business_logic`,
|
|
158
|
+
`dependency_config`, `prompt_injection`, `insecure_output_handling`,
|
|
159
|
+
`excessive_agency`, `model_supply_chain`.
|
|
160
|
+
|
|
161
|
+
To tune for your codebase, edit these files, adding patterns or sharpening
|
|
162
|
+
wording. No code change is needed.
|
|
163
|
+
|
|
164
|
+
## eval
|
|
165
|
+
|
|
166
|
+
`codejury eval` scores the golden cases and reports a confusion matrix with
|
|
167
|
+
precision, recall, and F1, overall and per capability. It takes `--dataset <dir>`
|
|
168
|
+
for the golden directory, `--split <name>` to score only cases tagged with that
|
|
169
|
+
`split:` such as a held-out set, `--orchestrator` to measure any strategy, and
|
|
170
|
+
`--format {text,json}`. The JSON report is a stable, documented schema.
|
|
171
|
+
|
|
172
|
+
## Architecture
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
Layer 5 Task preset: source, capabilities, orchestrator, agents
|
|
176
|
+
Layer 4 Capability YAML domain knowledge: authn, authz, prompt_injection, ...
|
|
177
|
+
Layer 3 Orchestrator strategy: single, pipeline, debate, reflexion, challenge, taint, adaptive
|
|
178
|
+
Source input: diff, repo, function
|
|
179
|
+
Agent role: finder, challenger, judge, verifier, refuter
|
|
180
|
+
Layer 2 Provider model backend: anthropic, openai, litellm, mock
|
|
181
|
+
Layer 1 Infrastructure cross-cutting utilities: json parsing, verdict cache, retry
|
|
182
|
+
Analysis provenance and taint code-graph engine
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Layers talk only through typed data, and each is an abstract base class plus
|
|
186
|
+
implementations, so the axes of task, orchestration, model, and input compose
|
|
187
|
+
independently.
|
|
188
|
+
|
|
189
|
+
## Limitations
|
|
190
|
+
|
|
191
|
+
- **Prompts are a first pass.** Expect false positives and misses on real code.
|
|
192
|
+
Tune by editing the capability YAML and growing the golden set, and measure the
|
|
193
|
+
effect with `codejury eval`.
|
|
194
|
+
- **Local-pattern checks are sharper than data-flow ones.** A capability judged
|
|
195
|
+
from one spot, such as weak crypto or a hardcoded secret, is reliable. Taint
|
|
196
|
+
classes such as path traversal and SSRF over-flag in single-file review because
|
|
197
|
+
the verifier cannot see whether a value is attacker-controlled. `--orchestrator
|
|
198
|
+
taint` adds a static provenance gate that clears findings it can prove safe and
|
|
199
|
+
is recall-safe, but it is shallow on real code where the value flows through
|
|
200
|
+
object or module attributes. Decisive taint precision needs a deeper code
|
|
201
|
+
graph, which is in progress.
|
|
202
|
+
- **`scan` cost scales with files times capabilities.** It is a periodic deep
|
|
203
|
+
audit, not a quick check, so scope it with `--only`. Day to day, audit the diff.
|
|
204
|
+
|
|
205
|
+
## Development
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
python -m venv .venv && source .venv/bin/activate
|
|
209
|
+
pip install -e ".[dev]"
|
|
210
|
+
pytest
|
|
211
|
+
```
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# OWASP LLM Top 10 (2025), LLM03: Supply Chain.
|
|
2
|
+
id: model_supply_chain
|
|
3
|
+
name: Model Supply Chain
|
|
4
|
+
asvs_chapter: "" # OWASP LLM03, not an ASVS chapter
|
|
5
|
+
description: >-
|
|
6
|
+
Loading a model, its code, or its weights from an untrusted or unverified
|
|
7
|
+
source. The high-impact cases run code at load time: executing code shipped
|
|
8
|
+
with a third-party model, or deserializing weights through pickle. Pin and
|
|
9
|
+
verify artifacts, and do not enable remote code execution for a model you do
|
|
10
|
+
not control.
|
|
11
|
+
|
|
12
|
+
sub_capabilities:
|
|
13
|
+
remote_code:
|
|
14
|
+
correct_patterns:
|
|
15
|
+
- id: SC-OK-1
|
|
16
|
+
description: Load a model with remote code execution off and a pinned revision
|
|
17
|
+
signals: ["trust_remote_code=False", "revision="]
|
|
18
|
+
why_ok: The third-party repo cannot run code at load time and the artifact is pinned
|
|
19
|
+
|
|
20
|
+
anti_patterns:
|
|
21
|
+
- id: SC-BAD-1
|
|
22
|
+
cwe: CWE-494
|
|
23
|
+
severity: CRITICAL
|
|
24
|
+
description: >-
|
|
25
|
+
Load a model with trust_remote_code=True, which executes code shipped in
|
|
26
|
+
the model repository at load time
|
|
27
|
+
signals: ["trust_remote_code=True", "from_pretrained"]
|
|
28
|
+
why_bad: A malicious or compromised model repo runs arbitrary code in your process
|
|
29
|
+
example_bad: |
|
|
30
|
+
model = AutoModel.from_pretrained("vendor/model", trust_remote_code=True)
|
|
31
|
+
example_good: |
|
|
32
|
+
model = AutoModel.from_pretrained("vendor/model", revision="a1b2c3d")
|
|
33
|
+
|
|
34
|
+
artifact_integrity:
|
|
35
|
+
correct_patterns:
|
|
36
|
+
- id: SC-OK-2
|
|
37
|
+
description: Load weights from a data-only format such as safetensors
|
|
38
|
+
signals: ["safetensors", "load_file"]
|
|
39
|
+
why_ok: A data-only weights format cannot execute code on load
|
|
40
|
+
|
|
41
|
+
anti_patterns:
|
|
42
|
+
- id: SC-BAD-2
|
|
43
|
+
cwe: CWE-502
|
|
44
|
+
severity: HIGH
|
|
45
|
+
description: >-
|
|
46
|
+
Deserialize model weights or a checkpoint through pickle, for example
|
|
47
|
+
torch.load or joblib.load on a downloaded file, which can run code on load
|
|
48
|
+
signals: ["torch.load", "pickle.load", "joblib.load"]
|
|
49
|
+
why_bad: Pickle-based loaders execute code embedded in the file during deserialization
|
|
50
|
+
example_bad: |
|
|
51
|
+
state = torch.load(downloaded_checkpoint)
|
|
52
|
+
example_good: |
|
|
53
|
+
from safetensors.torch import load_file
|
|
54
|
+
state = load_file("model.safetensors")
|
|
55
|
+
|
|
56
|
+
trigger_signals:
|
|
57
|
+
- from_pretrained or a model or dataset download call
|
|
58
|
+
- trust_remote_code set on a model load
|
|
59
|
+
- torch.load, pickle.load, or joblib.load of model weights
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
capability: model_supply_chain
|
|
2
|
+
vulnerable: false
|
|
3
|
+
expected_verdict: SECURE
|
|
4
|
+
cwe: ""
|
|
5
|
+
source: synthetic
|
|
6
|
+
notes: >
|
|
7
|
+
An ordinary model load: remote code execution is off by default and the
|
|
8
|
+
revision is pinned, so a plain from_pretrained must not be flagged.
|
|
9
|
+
code: |
|
|
10
|
+
def load():
|
|
11
|
+
return AutoModel.from_pretrained("bert-base-uncased", revision="a1b2c3d")
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
capability: model_supply_chain
|
|
2
|
+
vulnerable: false
|
|
3
|
+
expected_verdict: SECURE
|
|
4
|
+
cwe: ""
|
|
5
|
+
source: synthetic
|
|
6
|
+
notes: >
|
|
7
|
+
safetensors is a data-only weights format that cannot execute code on load.
|
|
8
|
+
code: |
|
|
9
|
+
from safetensors.torch import load_file
|
|
10
|
+
|
|
11
|
+
def load_checkpoint(path):
|
|
12
|
+
return load_file(path)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
capability: model_supply_chain
|
|
2
|
+
vulnerable: true
|
|
3
|
+
expected_verdict: VULNERABLE
|
|
4
|
+
cwe: CWE-502
|
|
5
|
+
source: synthetic
|
|
6
|
+
notes: >
|
|
7
|
+
torch.load deserializes through pickle, so loading a downloaded checkpoint runs
|
|
8
|
+
any code embedded in the file. Use a data-only format such as safetensors.
|
|
9
|
+
code: |
|
|
10
|
+
def load_checkpoint(path):
|
|
11
|
+
return torch.load(path)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
capability: model_supply_chain
|
|
2
|
+
vulnerable: true
|
|
3
|
+
expected_verdict: VULNERABLE
|
|
4
|
+
cwe: CWE-494
|
|
5
|
+
source: synthetic
|
|
6
|
+
notes: >
|
|
7
|
+
trust_remote_code=True runs code shipped in the third-party model repo at load
|
|
8
|
+
time, so a malicious or compromised repo executes arbitrary code in the process.
|
|
9
|
+
code: |
|
|
10
|
+
def load(name):
|
|
11
|
+
return AutoModel.from_pretrained(name, trust_remote_code=True)
|