PyPI / posthog / 7.73.0

posthog 7.73.0

Source
https://github.com/posthog/posthog-python
Tag scanned
posthog-v7.73.0
Compared with
posthog-v7.72.0 (0 signals introduced since)
Files
430 scanned, 277 skipped (binary, oversized, or unrecognised)
Signals
0 critical · 0 warn · 10 info
Scan time
10.0 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 9 of 9 warn and critical signals; 9 demoted to info.
Disclude version
4.0.0
Scanned (UTC)
2026-10-20 07:11

Signals

Ordered by severity, then signals introduced in this release. Hidden characters are shown as ⟨U+…⟩.

  1. info warn → info by review dynamic-execution examples/example-ai-openai-agents/multi_agent.py:29:23

    `eval` called on a non-literal expression (ast pass, confidence 0.70)

            return "Error: invalid characters"
        return f"Result: {eval(expression.replace('^', '**'))}"
    likely benign LLM, confidence 0.70 A calculator tool in an OpenAI agents example evaluates a sanitized arithmetic expression with eval.
    Reasoning

    The eval call sits behind an invalid-character check, so it is an attempted sanitizer, not a bypassable free-form eval. Evaluating model-supplied input in an agent tool is still a real injection risk, so this is not fully dismissable, but in an example calculator it reads as a deliberate simplification.

  2. info warn → info by review dynamic-execution examples/example-ai-openai-agents/single_agent.py:29:23

    `eval` called on a non-literal expression (ast pass, confidence 0.70)

            return "Error: invalid characters"
        return f"Result: {eval(expression.replace('^', '**'))}"
    likely benign LLM, confidence 0.70 A single-agent calculator example uses eval on a filtered arithmetic expression.
    Reasoning

    Same calculator pattern as multi_agent.py: an invalid-character filter precedes eval of a power-operator-rewritten expression. The filter limits the risk, but eval on model-controlled input remains a weakness rather than malicious intent.

  3. info warn → info by review frame-introspection posthog/exception_utils.py:1060:21

    `sys._getframe` — call-stack frame introspection (ast pass, confidence 0.70)

            try:
                frame = sys._getframe(depth)
                depth += 1
            except ValueError:
    dismissed LLM, confidence 0.92 Stack-walking helper in the PostHog SDK's exception utilities uses sys._getframe to collect frames.
    Reasoning

    sys._getframe in a loop with a ValueError guard is the standard way to walk the stack when building exception frame information for an error-tracking SDK. This is expected for the library's purpose.

  4. info warn → info by review encoding-base64 posthog/test/mcp/test_session_token.py:68:15

    base64-like blob (95 bytes, compression ratio 1.12) (raw pass, confidence 0.60)

        )
        frozen = "eyJzaWQiOiJzZXNfZml4dHVyZSIsImNuIjoiQ2xhdWRlIENvZGUiLCJjdiI6IjEuMi4zIiwicHYiOiIyMDI1LTA2LTE4In0"
    
        # Encode side: our output is byte-identical to the shared wire format.
    likely benign LLM, confidence 0.90 A base64url-encoded JSON session-token fixture used in an MCP test.
    Reasoning

    The blob is a short base64url-encoded JSON fixture (session id, client name, version, timestamp) in a test file, with a comment saying the encode side is compared against the wire format. It is test data, not a hidden payload.

  5. info warn → info by review decoder-decompress-payload posthog/test/test_capture_v1.py:456:24

    file imports decoder module(s) zlib and calls `.decompress()` — embedded payload decompressed at runtime (ast pass, confidence 0.75)

            self.assertEqual(call["data"][0], 0x78)  # zlib header
            roundtripped = zlib.decompress(call["data"]).decode("utf-8")
            self.assertNotIn("api_key", json.loads(roundtripped))
    dismissed LLM, confidence 0.95 Test code decompresses a captured zlib request body to check its contents.
    Reasoning

    The test decompresses its own captured request body and asserts that the api_key is absent. This is ordinary round-trip verification of the SDK's compression, not runtime execution of a hidden payload.

  6. info warn → info by review decoder-decompress-payload posthog/test/test_metrics.py:55:23

    file imports decoder module(s) gzip and calls `.decompress()` — embedded payload decompressed at runtime (ast pass, confidence 0.75)

        body = kwargs.get("data")
        return json.loads(gzip.decompress(body).decode("utf-8"))
    dismissed LLM, confidence 0.95 Test helper gunzips and parses a mocked metrics request body.
    Reasoning

    gzip.decompress is applied to a mocked HTTP request body and parsed as JSON in a test helper. This is standard test assertion plumbing.

  7. info warn → info by review decoder-decompress-payload posthog/test/test_request.py:227:27

    file imports decoder module(s) gzip, zlib and calls `.decompress()` — embedded payload decompressed at runtime (ast pass, confidence 0.75)

            self.assertEqual(headers["Content-Encoding"], "gzip")
            body = json.loads(gzip.decompress(data))
            self.assertEqual(body["batch"], [])
            self.assertEqual(body["api_key"], TEST_API_KEY)
    dismissed LLM, confidence 0.95 Test decompresses a gzip request body to assert on its JSON contents.
    Reasoning

    The test gunzips the request data it sent and checks batch and api_key fields. It is ordinary test verification of compressed transport.

  8. info warn → info by review decoder-decompress-payload posthog/test/tracing/test_client_traces.py:60:23

    file imports decoder module(s) gzip and calls `.decompress()` — embedded payload decompressed at runtime (ast pass, confidence 0.75)

        args, kwargs = session.post.call_args
        return json.loads(gzip.decompress(kwargs["data"])), args[0], kwargs
    dismissed LLM, confidence 0.95 Tracing test helper gunzips a captured POST body for assertions.
    Reasoning

    A test helper decompresses the mocked session.post payload and returns it as JSON for assertions. This is benign test code.

  9. info warn → info by review decoder-decompress-payload posthog/test/tracing/test_transport.py:71:27

    file imports decoder module(s) gzip and calls `.decompress()` — embedded payload decompressed at runtime (ast pass, confidence 0.75)

            assert kwargs["headers"]["Content-Type"] == "application/json"
            assert json.loads(gzip.decompress(kwargs["data"])) == PAYLOAD
    
        def test_falls_back_to_the_default_timeout(self):
    dismissed LLM, confidence 0.95 Transport test gunzips the request body to compare it with the expected payload.
    Reasoning

    The test gunzips the mocked request data and compares it with the expected payload. It is ordinary test assertion code with no evidence of hidden execution.

  10. line length 1545 characters (raw pass, confidence 0.50)

    class posthog.client.Client(project_api_key: str, host=None, debug=False, max_queue_size=10000, send=True, on_error=None, flush_at=100, flush_interval=5.0, gzip=False, max_retries=3, sync_mode=False, timeout=15, thread=1, poll_interval=30, personal_api_key=None, disabled=False, disable_geoip=True, is_server=True, histo

Reproduce This Scan

Run disclude locally to verify. Add --format sarif for SARIF output. Add --llm (with an API key in the environment) to include the LLM review.

cargo install disclude --version 4.0.0
git clone https://github.com/posthog/posthog-python posthog-python && cd posthog-python
git checkout posthog-v7.73.0
disclude scan --severity info --diff posthog-v7.72.0 .