Skip to content

sfw uv pip install google-re2==1.1.20251105 crashes the CONNECT proxy #52

Description

Bug

sfw uv pip install google-re2==1.1.20251105 crashes the CONNECT proxy with a TypeError in artifactResultsToAlerts

Summary

When installing the Python package google-re2==1.1.20251105 (the current latest release) through Socket Firewall (free version) inside the official Docker Hardened Image dhi.io/python:3.12-debian13-sfw-dev, the firewall crashes inside its alert-lookup path with an unhandled TypeError. The crash occurs at the CONNECT-proxy boundary and aborts the in-flight TLS connection that uv is using to fetch the wheel's .metadata sidecar from files.pythonhosted.org. uv retries 3 times, all retries hit the same crash, the install fails, and the surrounding container build exits non-zero.

The wheel and its metadata sidecar are healthy on PyPI's CDN (HTTP 200, cache-HIT, served instantly when fetched directly without sfw), so this is purely an sfw bug, not a PyPI availability issue.

Environment

  • Image: dhi.io/python:3.12-debian13-sfw-dev (Docker Hardened Image with sfw preinstalled)
  • Builder: BuildKit via buildctl, running inside Kubernetes
  • Tool: sfw uv pip install (uv 0.6.16, Python 3.12.13)
  • Affected target: google-re2==1.1.20251105, cp312 manylinux_2_27_x86_64.manylinux_2_28_x86_64 wheel
    (google_re2-1.1.20251105-1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl)

Reproduction

Minimal Dockerfile:

FROM dhi.io/python:3.12-debian13-sfw-dev
COPY --from=ghcr.io/astral-sh/uv:0.6.16 /uv /usr/local/bin/uv
WORKDIR /app
RUN echo "google-re2==1.1.20251105" > requirements.txt
RUN sfw uv pip install --no-cache --target=/app/dependencies -r requirements.txt

Build with docker build . (or buildctl). The RUN sfw uv pip install ... step fails every time, deterministically, on the same package URL.

Observed output

#21 1.712 Using CPython 3.12.13 interpreter at: /opt/python/bin/python
#21 10.02 error: Failed to fetch: `https://files.pythonhosted.org/packages/0d/1c/8b1ccbeade96a21435d55b5185cd6d9b2ceab5a9af998a4d9099e0540759/google_re2-1.1.20251105-1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.metadata`
#21 10.02   Caused by: Request failed after 3 retries
#21 10.02   Caused by: error sending request for url (https://files.pythonhosted.org/packages/0d/1c/8b1ccbeade96a21435d55b5185cd6d9b2ceab5a9af998a4d9099e0540759/google_re2-1.1.20251105-1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.metadata)
#21 10.02   Caused by: client error (SendRequest)
#21 10.02   Caused by: connection closed before message completed
#21 10.07
#21 10.07 === Socket Firewall ===
#21 10.07
#21 10.10  - 135 packages fetched successfully
#21 10.10
#21 10.10 Error occurred: Error caught at boundary "CONNECT request"
#21 10.10   TypeError Cannot read properties of undefined (reading 'map')
#21 10.10   [sfw-free.js:76:43077 <- Array.flatMap (<anonymous>) <- artifactResultsToAlerts (sfw-free.js:76:43057) <- sfw-free.js:42:59527 <- process.processTicksAndRejections (task_queues:105:5) <- sfw-free.js:42:59762 <- async Promise.all (index 0) <- async fetchFreeAlerts (sfw-free.js:76:43272) <- async getPackageAlerts (sfw-free.js:78:157) <- async getPurlAlertInfo (sfw-free.js:110:4231)]

Diagnosis

The stack trace points squarely at the alert-lookup path:

getPurlAlertInfo
  -> getPackageAlerts
    -> fetchFreeAlerts
      -> Promise.all(...)
        -> artifactResultsToAlerts(<undefined>)  // sfw-free.js:76:43057
          -> Array.flatMap(...)                   // sfw-free.js:76:43077  TypeError

artifactResultsToAlerts is calling .flatMap on a value that is undefined for this particular purl. Likely root cause: the upstream alert-info response for pkg:pypi/google-re2@1.1.20251105 returns a shape (or an empty/null artifactResults) that the function does not guard against.

When the exception escapes the async chain, it bubbles out of the CONNECT-request handler, and sfw aborts the in-flight tunneled TLS connection. uv reports this as connection closed before message completed, retries, and hits the same crash on each retry — so the failure is deterministic, not transient.

Notable signal in the same banner: "135 packages fetched successfully" — every other package in the same requirements.txt works. The failure is specific to whatever getPurlAlertInfo returns for google-re2 1.1.20251105.

The PyPI URL in the error message is healthy:

$ curl -sI 'https://files.pythonhosted.org/packages/0d/1c/8b1ccbeade96a21435d55b5185cd6d9b2ceab5a9af998a4d9099e0540759/google_re2-1.1.20251105-1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.metadata' | head -1
HTTP/2 200

Same for the wheel itself.

Expected behavior

artifactResultsToAlerts should defensively handle a missing/empty alert-results payload (e.g. (results ?? []).flatMap(...)) instead of throwing. A failure to fetch alert metadata for a single purl should not crash the CONNECT proxy and abort the underlying TLS tunnel — at worst it should log the failure and pass the package through (or block it explicitly), not corrupt the connection.

Impact

  • Any build that pulls google-re2 1.1.20251105 through sfw (free version) inside the affected DHI image fails 100% of the time.
  • Affects production CI for the SAP Application Foundation deployer-service repository, which runs Python agent builds inside dhi.io/python:3.12-debian13-sfw-dev. Currently worked around by pinning google-re2==1.1.20240701 (the previous release).
  • Likely affects other consumers of the same DHI image installing the same package.

Workaround

Pin to the previous release google-re2==1.1.20240701, which does not trigger the artifactResultsToAlerts crash through sfw.

Asks

  1. Fix the unguarded Array.flatMap on undefined at sfw-free.js:76:43077 (artifactResultsToAlerts).
  2. Treat exceptions in the alert-lookup path as non-fatal to the CONNECT proxy — at minimum, do not abort the tunneled TLS connection on alert-fetch errors.
  3. Investigate why getPurlAlertInfo for pkg:pypi/google-re2@1.1.20251105 returns a shape that lacks the expected artifactResults field.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    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