Skip to content

[bug-hunter] Proofpoint On Demand websocket cursor corrupts sinceTime values containing + #17875

Description

@github-actions

Impact

Proofpoint On Demand message stream reconnects can request the wrong cursor value when the stored timestamp has a positive timezone offset (for example +0000, +0530). Because sinceTime is concatenated directly into the URL, + is interpreted as a space during query parsing. This can cause duplicate ingestion or missed events after reconnect.

Reproduction Steps

  1. Save and run this new minimal repro script:
from urllib.parse import urlparse, parse_qs

base = "(example.test/redacted)
last_timestamp = "2026-03-10T10:00:00.000000+0000"
# Mirrors websocket.yml.hbs logic: state.url+"&sinceTime=" + state.cursor.last_timestamp
actual_url = base + "&sinceTime=" + last_timestamp
parsed = parse_qs(urlparse(actual_url).query)
actual_since = parsed.get("sinceTime", [None])[0]

expected_since = last_timestamp
print("constructed_url:", actual_url)
print("parsed_sinceTime:", repr(actual_since))
print("expected_sinceTime:", repr(expected_since))

if actual_since != expected_since:
    print("FAIL: sinceTime changed during query parsing because '+' was not URL-encoded")
    raise SystemExit(1)
print("PASS")
  1. Run:
python /tmp/gh-aw/agent/repro_proofpoint_since_time.py

Expected vs Actual

Expected: sinceTime remains 2026-03-10T10:00:00.000000+0000.

Actual: sinceTime becomes 2026-03-10T10:00:00.000000 0000 (plus sign decoded as space), and the script exits with status 1.

Actual output:

constructed_url: (example.test/redacted)
parsed_sinceTime: '2026-03-10T10:00:00.000000 0000'
expected_sinceTime: '2026-03-10T10:00:00.000000+0000'
FAIL: sinceTime changed during query parsing because '+' was not URL-encoded

Failing Test

from urllib.parse import urlparse, parse_qs

base = "(example.test/redacted)
last_timestamp = "2026-03-10T10:00:00.000000+0000"
actual_url = base + "&sinceTime=" + last_timestamp
parsed = parse_qs(urlparse(actual_url).query)
actual_since = parsed.get("sinceTime", [None])[0]

assert actual_since == last_timestamp

Evidence

  • packages/proofpoint_on_demand/data_stream/message/agent/stream/websocket.yml.hbs:3-4 concatenates sinceTime without URL encoding:
    • state.url+"&sinceTime="+state.cursor.last_timestamp
  • packages/proofpoint_on_demand/data_stream/message/agent/stream/websocket.yml.hbs:13 stores cursor from event timestamp:
    • "last_timestamp": body.ts
  • packages/proofpoint_on_demand/data_stream/message/sample_event.json:54 shows timestamp values include timezone offsets in this stream format.

What is this? | From workflow: Bug Hunter

Give us feedback! React with 🚀 if perfect, 👍 if helpful, 👎 if not.

  • expires on Mar 25, 2026, 11:28 AM UTC

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions