feat(paloalto-wildfire): add WildFire enrichment connector (#6730)#6731
feat(paloalto-wildfire): add WildFire enrichment connector (#6730)#6731SamuelHassine wants to merge 5 commits into
Conversation
…rdicts (#6730) Add an internal-enrichment connector for Palo Alto Networks WildFire. It enriches StixFile and Artifact observables by querying the WildFire public API by hash, maps the verdict (benign/grayware/phishing/malware/C2) to an OpenCTI score and label, completes the file hashes from the report, and attaches a STIX Malware Analysis object. Modeled on the hybrid-analysis-sandbox connector (connectors-sdk settings, playbook compatible). Includes client + connector unit tests, generated config schema/doc, README, manifest and docker-compose.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #6731 +/- ##
===========================================
- Coverage 32.30% 0.48% -31.82%
===========================================
Files 1985 1899 -86
Lines 122106 119834 -2272
===========================================
- Hits 39441 580 -38861
- Misses 82665 119254 +36589
📢 Thoughts on this report? Let us know! 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR introduces a new internal-enrichment connector (internal-enrichment/paloalto-wildfire) that enriches StixFile and Artifact observables by querying the Palo Alto Networks WildFire public API for hash verdicts/reports, then emitting an enriched STIX bundle (playbook compatible).
Changes:
- Adds the WildFire enrichment connector implementation (hash selection, verdict/score/label mapping, Malware Analysis object creation, TLP gating, bundle send flow).
- Adds a thin HTTP client for the WildFire API (
/get/verdict,/get/report) with retry/backoff and XML parsing. - Adds unit tests + connector packaging assets (Dockerfile, compose/config samples, metadata/schema/docs).
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| internal-enrichment/paloalto-wildfire/src/connector/connector.py | Core enrichment flow (hash lookup, verdict mapping, STIX bundle creation/sending). |
| internal-enrichment/paloalto-wildfire/src/connector/settings.py | Pydantic settings models for connector + WildFire config. |
| internal-enrichment/paloalto-wildfire/src/connector/init.py | Exposes connector/settings package entrypoints. |
| internal-enrichment/paloalto-wildfire/src/paloalto_wildfire_client/api_client.py | WildFire HTTP client with retries and XML parsing. |
| internal-enrichment/paloalto-wildfire/src/paloalto_wildfire_client/init.py | Exposes client + exception symbols. |
| internal-enrichment/paloalto-wildfire/src/main.py | Connector entrypoint (helper init, run, error handling). |
| internal-enrichment/paloalto-wildfire/src/requirements.txt | Runtime dependencies for the connector. |
| internal-enrichment/paloalto-wildfire/tests/conftest.py | Test fixtures + pycti helper mocking. |
| internal-enrichment/paloalto-wildfire/tests/test_main.py | Smoke tests for settings/helper/connector instantiation. |
| internal-enrichment/paloalto-wildfire/tests/test-requirements.txt | Test dependency pin for pytest. |
| internal-enrichment/paloalto-wildfire/tests/tests_connector/test_connector.py | Unit tests for the connector behavior and enrichment logic. |
| internal-enrichment/paloalto-wildfire/tests/tests_connector/test_settings.py | Unit tests for config validation. |
| internal-enrichment/paloalto-wildfire/tests/tests_connector/data/file_message.json | File enrichment message fixture. |
| internal-enrichment/paloalto-wildfire/tests/tests_connector/data/artifact_message.json | Artifact enrichment message fixture. |
| internal-enrichment/paloalto-wildfire/tests/tests_paloalto_wildfire_client/test_api_client.py | Unit tests for the WildFire API client. |
| internal-enrichment/paloalto-wildfire/README.md | Connector documentation (setup, behavior, env vars). |
| internal-enrichment/paloalto-wildfire/Dockerfile | Container build for the connector. |
| internal-enrichment/paloalto-wildfire/entrypoint.sh | Container entrypoint script. |
| internal-enrichment/paloalto-wildfire/docker-compose.yml | Example deployment configuration. |
| internal-enrichment/paloalto-wildfire/config.yml.sample | Example config.yml for manual deployment. |
| internal-enrichment/paloalto-wildfire/metadata/connector_manifest.json | Connector manifest metadata for the catalog. |
| internal-enrichment/paloalto-wildfire/metadata/connector_config_schema.json | Generated config JSON schema. |
| internal-enrichment/paloalto-wildfire/metadata/CONNECTOR_CONFIG_DOC.md | Generated config documentation. |
…ling (#6730) Bring WildFire to parity with the other sandbox connectors (FortiSandbox, PolySwarm, intezer, hybrid-analysis): - Submit unknown files to WildFire (POST /submit/file) and poll the verdict (POST /get/verdict) until it is final; enabled by default via submit_unknown so Artifacts uploaded to OpenCTI are detonated. - Add a robust file-download step that enforces max_file_size, rejects empty files, and logs a clear skip reason instead of failing silently. - Add max_file_size and submission_timeout settings; bound the verdict poll by submission_timeout and handle the pending (-100) verdict code. Updates client (submit_file, get_verdict_code, poll_verdict), tests, generated config schema/doc, README, config sample and docker-compose.
…le type Address the Copilot review threads plus an independent senior review. - api_client.py: set Retry(raise_on_status=False) so exhausted retries surface a consistent HTTPError via raise_for_status, and wrap every requests.RequestException (retry exhaustion, timeouts, connection errors), not just HTTPError, as WildfireAPIError in _post and submit_file. - connector.py: the enriched StixFile now carries the WildFire report file type in mime_type; the Malware Analysis object inherits the source observable's object_marking_refs (falling back to the connector default) so enrichment never emits an unmarked or TLP-downgraded object; the default marking is the OpenCTI TLP:CLEAR statement marking instead of the legacy stix2.TLP_WHITE. - Logging: structured context is passed via the meta= keyword across the client and connector. - README.md: fix the TOC anchor, align the OpenCTI minimum version with the manifest (6.8.12), and fix the Debugging typo and logger example. - tests: assert the mime_type completion and the Malware Analysis markings, cover the non-HTTP error wrapping, and fix an "== True" comparison.
Review and fix pass completeIndependent senior review of the full connector plus all 16 automated review threads addressed, fixes pushed in 55f0562. WildFire client (
Enrichment (
Docs and tests
CI: all checks green (the earlier Blocker: self-approval is not possible (I am the PR author), so one maintainer approving review is still required before merge. |
…opt-in Address the remaining Copilot review and keep the connector installable against current master: - connector.py: the Malware Analysis object now derives its markings from the source observable's OpenCTI markings (enrichment messages carry them in enrichment_entity["objectMarking"], not as STIX object_marking_refs), and the resolved marking objects are included in the bundle so the SDO is correctly marked and self-contained instead of being silently downgraded to the default TLP (or stripped by cleanup_inconsistent_bundle). - settings.py: submit_unknown now defaults to false (opt-in). File submission/detonation uploads the sample to a third party, and issue #6730 scopes the first version to verdict-by-hash only; the feature stays available via explicit opt-in. Updated the generated schema/doc, config.yml.sample, docker-compose.yml and the test accordingly. - README.md: corrected the base-connector table (CONNECTOR_TYPE INTERNAL_ENRICHMENT, auto key/default, optional flags) and rewrote the Usage section for an enrichment connector. - src/requirements.txt: bump the pinned pycti to 7.260615.0 to match the current connectors-sdk (support_version stays >=6.8.12, the connector's minimum).
…to-wildfire-enrichment
Review-and-fix pass summaryIndependent senior re-review of the full Code/test fixes (commit 1598ca9):
Independent-review note: the WildFire client uses a urllib3 CI fix (de-stale):
Verification:
Remaining (non-CI) blocker: |
Proposed changes
New internal-enrichment connector for Palo Alto Networks WildFire.
When a
StixFileorArtifactobservable is enriched, the connector:POST /get/verdict);POST /submit/file) and polls for the verdict (opt-in viasubmit_unknown, disabled by default, bounded bysubmission_timeout, withmax_file_sizeenforced on download);wildfire:<verdict>label;POST /get/report) to complete the file hashes and the file type (mime_type) when available;product = WildFire) referencing the observable, carrying the source observable's markings, with the result mapped to the STIXmalware-resultvocabulary.The connector is playbook compatible and always returns the (enriched) bundle. It is modeled on the existing
hybrid-analysis-sandboxconnector (connectors-sdk Pydantic settings, retry/backoff client,_process_messageflow).Related issues
Closes #6730
Types of changes
Checklist
black,isort) and linting (flake8, STIX id pylint) pass__metadata__config schema and documentationREADME.md,config.yml.sample,docker-compose.ymlandconnector_manifest.jsonFurther comments
The API base URL is configurable to support the different WildFire cloud regions and on-premise WildFire appliances. File submission/detonation of unknown samples is disabled by default (
submit_unknown); set it totrueto allow the connector to upload unknown samples to WildFire for analysis, otherwise it is restricted to hash-based verdict/report lookups only (the issue scopes the first version to verdict-by-hash).Maintainer review and fix pass
A follow-up review hardened the connector and addressed the automated review threads:
Retry(raise_on_status=False)so exhausted retries raise a consistentHTTPError, and everyrequests.RequestException(retry exhaustion, timeouts, connection errors) is wrapped asWildfireAPIErrorin_postandsubmit_file.enrichment_entity["objectMarking"], resolving each TLP to its stix2 MarkingDefinition) and includes the marking objects in the bundle, so enrichment never downgrades the TLP to the default or emits a marking reference thatcleanup_inconsistent_bundlewould strip; it falls back to the OpenCTI TLP:CLEAR statement marking only when the observable carries none.mime_type; the connector default marking is the OpenCTI TLP:CLEAR statement marking instead ofstix2.TLP_WHITE.submit_unknownnow defaults tofalse(opt-in). Submission uploads the sample to a third-party service and issue feat(paloalto-wildfire): create enrichment connector for file hash verdicts #6730 scopes the first version to verdict-by-hash only, so it is now an explicit opt-in (the feature stays available viasubmit_unknown=true).meta=keyword for structured context throughout the client and connector.CONNECTOR_TYPE=INTERNAL_ENRICHMENT, theautoconfig key,CONNECTOR_AUTOdefaultfalse, and the optional flags to match the generated schema); rewrote the Usage section for an internal-enrichment connector; and fixed the Debugging typo and logger example.mime_typecompletion and the source-derived Malware Analysis markings, the non-HTTP error wrapping, and thesubmit_unknownopt-in default.pyctito7.260615.0to match the currentconnectors-sdk, and merged currentmasterto de-stale so the localconnectors-sdkused byrun_test.shpins the samepyctiand the test environment resolves consistently.Status
All CI checks are green (tests, lint/format, STIX ID linter,
codecov/patchandcodecov/project) and there are 0 unresolved review threads.mergeStateStatusis BLOCKED only becausereviewDecisionisREVIEW_REQUIRED- the PR needs one approving review from a maintainer other than me (as the author I cannot self-approve). The branch carries a de-stale merge commit, so it should be squash-merged.