Skip to content

fix(crewai): replace MD5 with SHA-256 for deterministic run IDs (VULN-115244) - #288

Merged
etserend merged 7 commits into
mainfrom
fix/vuln-115244-md5
Oct 30, 2026
Merged

etserend merged 7 commits into
mainfrom
fix/vuln-115244-md5

Conversation

@etserend

@etserend etserend commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • CrewAIEventListener._hash_to_uuid used hashlib.md5 to derive deterministic UUIDs for event correlation, which Semgrep flags (insecure-hash-algorithm-md5).
  • It now calls a new shared helper, deterministic_uuid4 in splunk_ao/utils/uuid_utils.py. The helper builds a UUID from the first 16 bytes of a SHA-256 digest, with the RFC 4122 version 4 and variant bits set.
  • uuid7_to_uuid4 now calls the same helper. Its output is byte-identical to before.
  • CrewAI run IDs derived from the same inputs change value. This is noted in CHANGELOG.md under [Unreleased].
  • Resolves VULN-115244.

Test plan

  • poetry run pytest tests/test_uuid_utils.py tests/test_crewai_handler.py -n 0: 6 passed, 121 skipped locally. All 6 passes are in test_uuid_utils.py, including the two new pinned-value tests. The CrewAI module is skipped on Python 3.14, so the CrewAI tests are covered by CI on 3.11-3.13.
  • ruff check --no-fix and ruff format --check clean on uuid_utils.py, crewai/handler.py, tests/test_uuid_utils.py and tests/test_crewai_handler.py

🤖 Generated with Claude Code

…-115244)

Co-Authored-By: Claude Code <noreply@anthropic.com>

@etserend etserend left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 This review was generated by the Astra agent (claude-opus-5-5). It may contain mistakes.

Verdict: approve — The one-line swap from MD5 to SHA-256 keeps run IDs deterministic and internally consistent, so CrewAI correlation still works.

Follow-ups

Suggested follow-up work that could be tracked as Jira tickets:

  • src/splunk_ao/handlers/crewai/handler.py:290-290: _hash_to_uuid builds a UUID from raw digest bytes and does not set the version or variant bits. This was also true with MD5. src/splunk_ao/utils/uuid_utils.py:74 uses UUID(bytes=digest[:16], version=4) for the same pattern. Passing version=4, or calling a shared helper, would give RFC 4122-compliant IDs. It would also stop a digest from looking like a UUIDv7 by chance. No current CrewAI path calls convert_uuid_if_uuid7, so this does not block the change.

Co-Authored-By: Claude Code <noreply@anthropic.com>

@etserend etserend left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 This review was generated by the Astra agent (claude-opus-5-5). It may contain mistakes.

Verdict: approve — The SHA-256 swap removes the MD5 finding and keeps run IDs deterministic, with RFC 4122 version bits now set.

Follow-ups

Suggested follow-up work that could be tracked as Jira tickets:

  • src/splunk_ao/handlers/crewai/handler.py:288-290: _hash_to_uuid and src/splunk_ao/utils/uuid_utils.py:71-74 repeat the same SHA-256-to-UUIDv4 logic. Extract a shared helper such as deterministic_uuid4(value: str) in uuid_utils.py. Both call sites can then use it, so the two derivations cannot drift apart.

etserend and others added 2 commits October 21, 2026 13:52
…LN-115244)

Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>

@etserend etserend left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 This review was generated by the Astra agent (claude-opus-5-5). It may contain mistakes.

Verdict: approve — The SHA-256 helper removes the only MD5 use, keeps run IDs deterministic, and keeps uuid7_to_uuid4 output byte-identical.

General Comments

  • 🔵 nit (documentation): The PR description is out of date with the branch, which can mislead the human reviewer:
  • The Summary does not say that the version and variant bits are now set.
  • The Summary does not mention the new shared deterministic_uuid4 helper in src/splunk_ao/utils/uuid_utils.py:37, or that uuid7_to_uuid4 now calls it.
  • The test plan reports "92 passed" and only handler.py lint. That predates commits 6efd50d and a66ec13, which add a test and touch two more files.

Update the Summary and re-run the test plan on the head commit.

Resolves import conflicts in crewai/handler.py and tests/test_crewai_handler.py
against #294 (keep both convert_time_delta_to_ns and deterministic_uuid4; keep
asyncio, hashlib and inspect test imports).

Co-Authored-By: Claude Code <noreply@anthropic.com>
@etserend
etserend requested a review from pradystar October 26, 2026 17:23

@opikalova opikalova 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.

🤖 This review was generated by the Astra agent (claude-opus-5-5). It may contain mistakes.

Verdict: approve — The SHA-256 helper removes the only MD5 use and keeps run IDs deterministic. The CHANGELOG entry now sits under a released version and should move.

General Comments

  • 🟡 minor (documentation): Astra found no Jira ticket in the branch name, the title or the description.
  • 🔵 nit (documentation): The PR description still does not match the branch. An earlier review raised this, and the text has not changed:
  • The Summary says only "the first 16 bytes of a SHA-256 digest". It does not mention the version 4 bits or the shared deterministic_uuid4 helper (src/splunk_ao/utils/uuid_utils.py:37).
  • The Summary does not say that uuid7_to_uuid4 now calls the helper.
  • The test plan reports "92 passed" and lint on handler.py only. Commits 6efd50d and a66ec13 came later and touch uuid_utils.py, the tests and CHANGELOG.md.

Update the Summary and test plan for the head commit.

Follow-ups

Suggested follow-up work that could be tracked as Jira tickets:

  • tests/test_uuid_utils.py:40-49: Add a pinned-value test for deterministic_uuid4 and uuid7_to_uuid4 in tests/test_uuid_utils.py. The only pinned test is tests/test_crewai_handler.py:995. That module is skipped on Python 3.14 (tests/test_crewai_handler.py:18). test_deterministic_conversion checks only self-consistency and version 4. A change to the shared helper would silently change LangChain run IDs on every version. It would also go untested on 3.14.

Comment thread CHANGELOG.md Resolved
etserend and others added 2 commits October 30, 2026 10:25
…(VULN-115244)

Add pinned-value tests for deterministic_uuid4 and uuid7_to_uuid4 so they run on
every Python version (the CrewAI module is skipped on 3.14), and move the CrewAI
run ID entry from the released 0.6.0 section to Unreleased.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@etserend

Copy link
Copy Markdown
Contributor Author

@opikalova thanks for the review. Addressed in 13229e1 and the updated description:

  • Pinned-value tests: added test_deterministic_uuid4_matches_pinned_sha256_value and test_uuid7_to_uuid4_matches_pinned_sha256_value in tests/test_uuid_utils.py. Both pin fixed UUIDs, so a change to the shared helper is caught on every Python version, including 3.14 where the CrewAI module is skipped. The expected values were computed with a standalone hashlib call, not from the repo code.
  • CHANGELOG: moved under ## [Unreleased] → ### Fixed (see the inline thread).
  • Jira ticket: this is tracked as VULN-115244, and the Summary now links it.
  • PR description: the Summary now covers the version 4 bits, the shared deterministic_uuid4 helper and uuid7_to_uuid4 calling it. The test plan covers the head commit; the CrewAI tests are skipped locally on 3.14, so they rely on CI.

@etserend
etserend merged commit ce02194 into main Oct 30, 2026
13 checks passed
@etserend
etserend deleted the fix/vuln-115244-md5 branch October 30, 2026 17:26
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 30, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants