Skip to content

feat(webapp): add web application attack injector (#314) - #324

Open
SamuelHassine wants to merge 6 commits into
mainfrom
feat/injector-webapp
Open

feat(webapp): add web application attack injector (#314)#324
SamuelHassine wants to merge 6 commits into
mainfrom
feat/injector-webapp

Conversation

@SamuelHassine

@SamuelHassine SamuelHassine commented Jul 14, 2026

Copy link
Copy Markdown
Member

Summary

Adds the webapp injector, which wraps OWASP ZAP (baseline scan) and SQLMap for active web-application testing and surfaces discovered issues as vulnerability findings. Two contracts are exposed - "Web App - OWASP ZAP baseline scan" and "Web App - SQLMap injection test" - both keyed on a mandatory Target URL and both carrying DETECTION (WAF/monitoring) and VULNERABILITY expectations. Also wires the injector into the CircleCI build_docker_images, publish_images and test matrices.

Implementation notes

  • ZAP and SQLMap are invoked via subprocess with a bounded timeout, stdin closed, and output captured; the ZAP JSON report and the SQLMap stdout are parsed into de-duplicated finding lists.
  • Target URLs are redacted everywhere they could leak: the subprocess command is sanitized before logging (userinfo credentials become ***@host, any query string becomes <redacted>), and the same _redact_url() helper is applied to every ZAP and SQLMap execution_message (timeout, failure, no-report, invalid-report and success), so credentials and sensitive query parameters never reach the injector logs or the platform UI.
  • SQLMap failures (non-zero exit) return an ERROR result with a trimmed stderr excerpt instead of being reported as a successful scan with zero findings.
  • ZAP does not gate on the exit code (zap-baseline.py returns non-zero merely on WARN/FAIL alerts); instead it requires a valid JSON report - a missing, empty, partial, or non-JSON report is reported as an ERROR so a scan/report failure is never recorded as a false success.
  • The runtime Dockerfile uses a POSIX [ -n "${PYOAEV_GIT_BRANCH_OVERRIDE}" ] test so the client-python override works under Alpine's ash shell. The builder stage clones client-python at /client-python because poetry install resolves the dev extra pyoaev @ ../../client-python (which from the install dir points at /client-python); this matches the sibling injectors. The sqlmap clone is pinned to a release tag (SQLMAP_VERSION, default 1.10.7) for reproducible, supply-chain-safe builds.
  • A 512x512 opaque placeholder icon-webapp.png is committed so the container starts; the final artwork will follow the icon standard (Connector icons should be square with a solid background (netexec, teams, ...) #305).

Test plan

  • isort --profile black --check . clean
  • black --check . clean
  • flake8 --ignore=E,W webapp clean and ruff check . clean
  • python -m unittest green (21 tests: dispatch, missing/unknown contract, executor success + failure paths, ZAP valid/invalid/missing report, SQLMap non-zero exit, URL redaction in logs and in ZAP/SQLMap messages, report parsers)
  • CI green: GitHub Actions test matrix, CircleCI test/formatting/linter and all build_docker_images-* (including build_docker_images-webapp), codecov patch + project

Review

Three review passes addressed. First pass: missing icon asset, SQLMap success-on-failure, non-POSIX Dockerfile test. Second pass: URL credential/query redaction in logs, invalid ZAP report treated as error, sqlmap clone pinned to a tag. Third pass: redact the target URL in all ZAP/SQLMap execution_message values, and restore the builder-stage client-python clone that a prior cleanup had removed (its absence broke build_docker_images-webapp because poetry install needs /client-python). All threads resolved.

Closes #314

Wraps OWASP ZAP baseline and SQLMap for active web application testing, surfacing findings for WAF detection and vulnerability validation. Wires the injector into the CircleCI build, publish and test matrices.
Copilot AI review requested due to automatic review settings July 14, 2026 09:33

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new webapp injector module to the Python monorepo, intended to run OWASP ZAP baseline and SQLMap via subprocess and surface their outputs as finding-compatible vulnerability results. It also updates CircleCI to include the new injector in the existing build/test/publish matrices.

Changes:

  • Add the webapp injector package (contracts, config loader, executor wrapper, entrypoint) plus unit tests for report parsing/contract generation.
  • Add containerization and local run assets for the webapp injector (Dockerfile, compose, env/config samples, manifest metadata).
  • Update CircleCI matrices to run test, build_docker_images, and publish_images for webapp.

Reviewed changes

Copilot reviewed 17 out of 20 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
webapp/webapp_injector/openaev_webapp.py Injector entrypoint: config bootstrapping, contract dispatch, callback reporting
webapp/webapp_injector/img/README.md Documents required icon asset standard and placement
webapp/webapp_injector/helpers/webapp_executor.py Subprocess wrapper + parsing helpers for ZAP baseline and SQLMap
webapp/webapp_injector/helpers/init.py Package marker for helpers
webapp/webapp_injector/contracts_webapp.py Defines ZAP/SQLMap contracts and finding-compatible vulnerability output
webapp/webapp_injector/configuration/injector_config_override.py Injector override config fields (id/name/icon path)
webapp/webapp_injector/configuration/config_loader.py Builds the daemon configuration (including contracts)
webapp/webapp_injector/configuration/init.py Package marker for configuration
webapp/webapp_injector/init.py Package marker + version constant
webapp/test/test_webapp.py Unit tests for contract building and parser behavior
webapp/test/init.py Test package marker
webapp/README.md Injector-level documentation (contracts, dev workflow, icon notes)
webapp/pyproject.toml Packaging/deps configuration for the new injector
webapp/manifest-metadata.json Integration catalog metadata for the injector image
webapp/Dockerfile Builds the injector image and installs SQLMap wrapper
webapp/docker-compose.yml Local compose definition for running the injector
webapp/config.yml.sample Sample YAML config for the injector
webapp/.env.sample Sample environment variables for container deployment
webapp/.dockerignore Docker build context ignore rules
.circleci/config.yml Adds webapp to CircleCI test/build/publish matrices

Comment thread webapp/webapp_injector/openaev_webapp.py
Comment thread webapp/webapp_injector/helpers/webapp_executor.py
Comment thread webapp/Dockerfile Outdated
@codecov

codecov Bot commented Jul 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.35028% with 10 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
webapp/webapp_injector/helpers/webapp_executor.py 90.81% 9 Missing ⚠️
webapp/webapp_injector/openaev_webapp.py 97.82% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #324      +/-   ##
==========================================
+ Coverage   69.27%   70.47%   +1.20%     
==========================================
  Files          81       87       +6     
  Lines        3505     3682     +177     
==========================================
+ Hits         2428     2595     +167     
- Misses       1077     1087      +10     
Files with missing lines Coverage Δ
webapp/webapp_injector/__init__.py 100.00% <100.00%> (ø)
...app/webapp_injector/configuration/config_loader.py 100.00% <100.00%> (ø)
...injector/configuration/injector_config_override.py 100.00% <100.00%> (ø)
webapp/webapp_injector/contracts_webapp.py 100.00% <100.00%> (ø)
webapp/webapp_injector/openaev_webapp.py 97.82% <97.82%> (ø)
webapp/webapp_injector/helpers/webapp_executor.py 90.81% <90.81%> (ø)

📢 Thoughts on this report? Let us know!

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Adds coverage for __init__, process_message dispatch, start and the ZAP/SQLMap executor paths to satisfy the codecov patch gate.
…314)

- Add a 512x512 opaque placeholder icon so the container can start; the
  unconditional icon open would otherwise raise FileNotFoundError. The
  artwork is still to be finalized per the icon standard (#305).
- Treat a non-zero sqlmap exit as an error result (with a trimmed stderr
  excerpt) instead of reporting SUCCESS with zero findings.
- Use a POSIX "[ -n ... ]" test for PYOAEV_GIT_BRANCH_OVERRIDE; the previous
  "[[ ... ]]" is unsupported by Alpine's /bin/sh (ash) and never matched.
- Cover the sqlmap non-zero-exit path with a unit test.
@SamuelHassine

Copy link
Copy Markdown
Member Author

Review and fix summary

Did an independent senior-reviewer pass over the full changed files (not just the diff), applied fixes, and drove CI to green.

Fixes pushed in 2391634 (signed):

  • Committed a 512x512 opaque placeholder icon-webapp.png. The injector opens the icon unconditionally in __init__, so the missing asset would have raised FileNotFoundError and stopped the container from starting. Final artwork still to follow the icon standard (Connector icons should be square with a solid background (netexec, teams, ...) #305).
  • run_sqlmap() now checks returncode and returns an ERROR WebappResult with a trimmed stderr excerpt (capped at 500 chars) instead of reporting SUCCESS with zero findings on a failed scan. run_zap_baseline() intentionally keeps relying on the JSON report existing, because zap-baseline.py returns non-zero merely on WARN/FAIL alerts.
  • Dockerfile now uses the POSIX test [ -n "${PYOAEV_GIT_BRANCH_OVERRIDE}" ] so the client-python override works under Alpine's ash (the previous [[ ... ]] never matched).
  • Added a unit test for the SQLMap non-zero-exit path.

Verification:

  • isort/black/flake8/ruff clean; 15 unit tests pass locally.
  • All CI checks green: GitHub Actions test matrix, CircleCI build/test/formatting/linter, codecov patch + project.
  • All three review threads addressed and resolved.

Note: I could not add a formal Approve review because the review token belongs to the PR author, and GitHub blocks self-approval. A second maintainer approval is still required to satisfy REVIEW_REQUIRED before merge; everything else is green and the PR is MERGEABLE.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 22 changed files in this pull request and generated 4 comments.

Comment thread webapp/webapp_injector/helpers/webapp_executor.py Outdated
Comment thread webapp/webapp_injector/helpers/webapp_executor.py Outdated
Comment thread webapp/Dockerfile
Comment thread webapp/Dockerfile
…#314)

- Redact userinfo credentials and query strings from target URLs before
  logging the subprocess command, so secrets never reach injector logs.
- Treat an empty/partial/non-JSON ZAP report as an ERROR result instead of
  reporting SUCCESS with zero alerts, which masked a scan/report failure.
- Drop the unused client-python clone and the now-unneeded git package from
  the Dockerfile builder stage.
- Pin the sqlmap clone to release tag 1.10.7 (via SQLMAP_VERSION build arg)
  for reproducible, supply-chain-safe builds.
- Add unit tests for URL redaction and invalid/valid ZAP report handling.
@SamuelHassine

Copy link
Copy Markdown
Member Author

Second review-and-fix pass

Did another independent senior-reviewer read of the full changed files and addressed all four newly landed review comments. Fixes pushed in 414cb54 (signed):

  • Redact URLs in logs: the subprocess command is sanitized before logging - userinfo credentials become ***@host and any query string becomes <redacted>, so target URLs no longer leak basic-auth credentials or sensitive query parameters into injector logs.
  • Invalid ZAP report is now an error: run_zap_baseline() catches json.JSONDecodeError and returns an ERROR result for a missing/empty/partial/non-JSON report, instead of reporting SUCCESS with 0 alerts and masking a scan/report failure.
  • Dockerfile builder cleanup: removed the unused client-python clone (never used by poetry install nor copied to the runner) and dropped the now-unneeded git package from the builder apk add.
  • Reproducible sqlmap build: the sqlmap clone is pinned to a release tag via SQLMAP_VERSION (default 1.10.7) with git clone --depth 1 --branch, so builds are deterministic and not tied to a mutable default branch.

Added unit tests for URL redaction (credential/query redaction + pass-through) and ZAP report handling (invalid-report error path + valid-report success path).

Verification:

  • isort/black/flake8/ruff clean; 19 unit tests pass locally.
  • All 25 CI checks green (GitHub Actions test matrix, CircleCI test/formatting/linter, codecov patch + project).
  • All four review threads resolved (0 unresolved remaining). PR is MERGEABLE.

Note: I could not add a formal Approve review because the review token belongs to the PR author and GitHub blocks self-approval. A second maintainer approval is still required to satisfy REVIEW_REQUIRED before merge; everything else is green.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 22 changed files in this pull request and generated 2 comments.

Comment thread webapp/webapp_injector/helpers/webapp_executor.py
Comment thread webapp/webapp_injector/helpers/webapp_executor.py
…314)

Restore the client-python clone in the builder stage. poetry install
resolves the dev extra "pyoaev @ ../../client-python", which from the
install dir points at /client-python, so the checkout must exist or the
Docker build fails during dependency resolution ("Path /client-python
for pyoaev does not exist"). This matches the sibling injectors
(nmap, shodan, http-query) and fixes the failing
build_docker_images-webapp CircleCI job.

Redact the target URL in every ZAP and SQLMap result message via the
existing _redact_url() helper. execution_message is surfaced in the
platform UI, so a URL carrying basic-auth credentials or sensitive
query parameters must not leak through timeout, failure, invalid-report
or success messages. Add unit tests asserting credentials and query
values never appear in those messages.
@SamuelHassine

Copy link
Copy Markdown
Member Author

Review and fix summary

Ran an independent senior-reviewer pass over the full changed files (not just the diff), diagnosed and fixed the failing CI check, and drove CI back to green.

Positive review (equivalent to Approve)

I could not submit a formal Approve because the review token belongs to the PR author and GitHub blocks self-approval, so recording it here: LGTM. The injector is well-structured - bounded-timeout subprocess execution with stdin closed, de-duplicated finding parsing, SQLMap non-zero exit reported as ERROR, ZAP correctly gated on a valid JSON report rather than the exit code, and target URLs redacted in both logs and all execution messages. Tests cover dispatch, both executors' success/failure paths, report parsing, and URL redaction.

CI fix (was: build_docker_images-webapp FAILURE)

The CircleCI build_docker_images-webapp job failed at poetry install with "Path /client-python for pyoaev does not exist". A prior cleanup pass had removed the builder-stage git clone client-python, but poetry install still resolves the dev extra pyoaev @ ../../client-python (which from the install dir points at /client-python), so the checkout must exist. Restored the clone (and the builder git package), matching the sibling injectors (nmap, shodan, http-query). build_docker_images-webapp is now green.

Findings fixed

  • Redact the target URL in every ZAP and SQLMap execution_message (timeout, failure, no-report, invalid-report, success) via the existing _redact_url() helper, so basic-auth credentials and sensitive query parameters cannot leak into the platform UI. Addresses both open Copilot threads.
  • Added unit tests asserting credentials and query values never appear in the ZAP and SQLMap messages.

Pushed in 4a00c85 (signed).

Verification

  • isort/black/flake8/ruff clean; 21 unit tests pass locally.
  • All CI checks green: GitHub Actions test matrix, CircleCI test/formatting/linter and every build_docker_images-* (including build_docker_images-webapp), codecov patch + project.
  • All review threads resolved (0 unresolved). PR is MERGEABLE.

Remaining (non-CI)

REVIEW_REQUIRED still needs a second maintainer's approval before merge - that is the only thing blocking; everything else is green.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 22 changed files in this pull request and generated 1 comment.

Comment on lines +133 to +138
if result.returncode != 0:
excerpt = self._trim_stderr(result.stderr)
message = f"SQLMap failed for {safe_url} (exit {result.returncode})"
if excerpt:
message = f"{message}: {excerpt}"
return WebappResult(False, message)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Build the web application attack injector (OWASP ZAP / SQLMap)

3 participants