Day 7 Campaign Update · March 27, 2026 | Phoenix Security Vulnerability Intelligence
Contents
ToggleExecutive Summary
On March 27, 2026 — seven days into the most consequential software supply chain campaign on record — TeamPCP struck again. The threat actor, also tracked as DeadCatx3, PCPcat, and ShellForce, published two backdoored versions of telnyx to PyPI without corresponding GitHub releases or tags. Telnyx is a telecommunications API SDK with approximately 742,000–790,000 monthly downloads; its SDK handles telephony credentials, session tokens, and API keys by design, making it a high-value target with maximum credential density per compromised host.
The telnyx payload shares the byte-for-byte identical RSA-4096 public key as the litellm compromise three days earlier, providing unambiguous attribution to TeamPCP. But the attacker has not stood still. Every major delivery and evasion mechanism has been redesigned: the 34,000-character inline payload from litellm is replaced by a 4,428-character thin dropper; the real 332-line credential harvester is now hidden inside a WAV audio file, fetched at runtime from a bare IP-address C2 server, invisible to static analysis. Windows targeting — absent from every prior TeamPCP campaign wave — appears for the first time, with a native binary extracted from a second WAV file and installed in the Startup folder masquerading as msbuild.exe.
The credential chain driving these attacks is propagating. TeamPCP’s March 24 litellm compromise harvested PyPI publishing tokens from thousands of CI/CD pipelines that import LiteLLM. Three days later, one of those stolen tokens enabled direct publication to telnyx’s PyPI account, bypassing GitHub entirely. Each compromised package produces credentials that unlock the next target. PyPI quarantined both malicious versions within approximately three hours of discovery by Endor Labs. Version 4.87.0, published March 26, is the last known-clean release.

TL;DR for Engineering Teams
What it is: Supply chain compromise of telnyx versions 4.87.1 and 4.87.2 on PyPI. Thin dropper in telnyx/_client.py fetches a 332-line credential harvester hidden inside a WAV audio file. Attributed to TeamPCP via identical RSA-4096 key. No CVE assigned.
Where it bites: Any Python environment with telnyx==4.87.1 or telnyx==4.87.2 installed. Payload fires at import time on both Linux/macOS (FetchAudio) and Windows (setup). Version 4.87.1 had a NameError typo that killed the payload — 4.87.2 fixed it sixteen minutes later.
Why it matters: New WAV steganography delivery makes the payload invisible to static analysis and most content filters. Windows targeting added for the first time. Kubernetes lateral movement deploys privileged pods across every node. Persistence via audiomon.service polls C2 every 45–55 minutes.
Patch status: Both versions quarantined by PyPI. Last known-clean version: telnyx 4.87.0 (published March 26, 2026, verified clean by Endor Labs).
Immediate action: Check pip show telnyx. Downgrade to 4.87.0 immediately if running 4.87.1 or 4.87.2. Block 83.142.209.203 at network perimeter. Remove audiomon.service and ~/.config/audiomon/. Delete Startup/msbuild.exe on Windows. Rotate all credentials accessible to the affected host.

Vulnerability Overview
| Field | Value |
|---|---|
| Vendor | BerriAI / telnyx maintainers |
| Product | telnyx (PyPI package) |
| Vulnerability Type | Supply chain compromise / credential theft / K8s lateral movement / Windows persistence |
| CWE | CWE-829 (Inclusion of Functionality from Untrusted Control Sphere) |
| CVE | Not assigned |
| Attack Vector | Network (PyPI package installation — fires at import time) |
| Active Exploitation | Confirmed — credentials exfiltrated via RSA-wrapped AES bundle |
| Attribution | TeamPCP (DeadCatx3 / PCPcat / ShellForce / CipherForce) |
| Exposure Window | ~3 hours: 4.87.1 at 03:51 UTC, 4.87.2 at 04:07 UTC, quarantine ~07:00 UTC |
| C2 Infrastructure | 83.142.209.203:8080 (bare IP, HTTP) |
| Persistence Mechanism | audiomon.service (Linux/macOS), msbuild.exe in Startup folder (Windows) |
Technical Anatomy

Root Cause: Stolen PyPI Token via Credential Cascade
There are no GitHub commits, tags, or releases for versions 4.87.1 or 4.87.2. The attacker bypassed telnyx’s automated release pipeline entirely and published using a stolen PyPI API token. Telnyx does not use PyPI Trusted Publishers (OIDC-based publishing) — it relies on a long-lived API token. Anyone holding that token can publish from any machine, anywhere.
The most probable acquisition vector is the litellm PyPI compromise of March 24. TeamPCP’s credential harvester sweeps environment variables, .env files, .npmrc files, and shell histories from every system that imports the compromised package. Any developer workstation or CI runner that had both litellm installed and access to the telnyx PyPI token had that token in TeamPCP’s exfiltration archive. The three-day gap between litellm and telnyx fits the operational tempo of sifting through harvested credentials and selecting the next high-value target.
Exploit Path
Step 1 — Entry point: TeamPCP published malicious telnyx wheels directly to PyPI using a stolen API token. No GitHub interaction, no CI pipeline, no code review. Users importing telnyx or any dependency that transitively imports it become victims.
Step 2 — Vulnerability trigger: All malicious code lives in a single modified file: telnyx/_client.py (7,825 lines). The legitimate SDK code ends around line 7,758. The attacker appended malicious imports (lines 4–10), a base64 decoder helper (lines 41–42), a 4,428-character base64 payload blob (line 459), and two attack functions (lines 7,761–7,825). Both attack paths are invoked at module scope, meaning execution begins the moment Python imports telnyx — before any application code runs.
Step 3 — Execution impact: On Linux/macOS, FetchAudio() spawns a detached subprocess (start_new_session=True) that decodes the inline payload and fetches the real harvester hidden inside ringtone.wav from 83.142.209.203:8080. On Windows, setup() downloads hangup.wav, extracts a native PE binary using the same XOR-key WAV steganography, and installs it as msbuild.exe in the Startup folder for persistence across reboots.
WAV Steganography: The Core Technical Innovation
The defining advancement in this attack is the use of WAV audio files as payload carriers. The WAV files (ringtone.wav on Linux/macOS, hangup.wav on Windows) are structurally valid audio files. They pass MIME-type checks, content filters, and inspection. The audio frame data, however, is not audio — it is base64-encoded, XOR-encrypted Python code.
Extraction: read WAV frames, base64 decode, take the first 8 bytes as an XOR key, XOR-decrypt the remainder. What emerges is the full 332-line Python credential harvester. To any network monitoring system watching the wire, the application downloaded a ringtone. The actual payload never exists on disk in the package and is not visible to any static analysis of the installed wheel.
Python:
with wave.open(wf, 'rb') as w:
b = base64.b64decode(w.readframes(w.getnframes()))
s, m = b[:8], b[8:]
payload = bytes([m[i] ^ s[i % len(s)] for i in range(len(m))])
Aikido researcher Charlie Eriksen first documented this technique on March 22 in the TeamPCP Kubernetes wiper payload, five days before it appeared in the telnyx package. This is not an experimental tactic — it is now an established TeamPCP delivery primitive.
This architecture has significant operational implications for defenders. The package footprint is 87% smaller than litellm. The payload is updatable without republishing. If the C2 server goes dark, forensic recovery of the full attack capability breaks down. No post-incident analysis can reconstruct what payload was delivered without a contemporaneous network capture.
Stage 1: The Thin Dropper and Credential Harvester
The base64-encoded _p variable in _client.py decodes to an 85-line audioimport() script whose sole purpose is to fetch the WAV file and extract the real harvester. The harvester is a 332-line Python orchestrator covering:
| Category | Targets |
|---|---|
| SSH | ~/.ssh/id_rsa, id_ed25519, id_ecdsa, authorized_keys, config — all users; /etc/ssh host keys |
| Cloud (AWS) | ~/.aws/credentials, config; AWS_* env vars; EC2 IMDSv2; ECS container credentials; Secrets Manager; SSM |
| Cloud (GCP) | ~/.config/gcloud/*, application_default_credentials.json, GOOGLE_APPLICATION_CREDENTIALS |
| Cloud (Azure) | ~/.azure/ directory tree, AZURE_* env vars |
| Kubernetes | ~/.kube/config, service account tokens, all secrets across all namespaces |
| Docker | ~/.docker/config.json, /kaniko/.docker/config.json |
| Dev credentials | .npmrc, .vault-token, .netrc, .git-credentials, .gitconfig |
| Database | .pgpass, my.cnf, redis.conf, .mongorc.js, DATABASE/DB_/MYSQL/POSTGRES env vars |
| Environment files | .env, .env.local, .env.production, .env.staging — searched 6 directories deep |
| CI/CD and IaC | terraform.tfvars, terraform.tfstate, .gitlab-ci.yml, Jenkinsfile, ansible.cfg |
| TLS/SSL private keys | *.pem, *.key, *.p12, *.pfx — /etc/ssl/private, /etc/letsencrypt |
| Crypto wallets | Bitcoin wallet.dat, Ethereum keystores, Solana keypairs, Cardano signing keys, Monero, Litecoin |
| Shell history | .bash_history, .zsh_history, .mysql_history, .psql_history |
| System | /etc/passwd, /etc/shadow, authentication logs |
Stage 2: Active Cloud Exploitation
The harvester does not stop at filesystem reads. If AWS credentials are found, it implements a full AWS SigV4 signing routine to directly query Secrets Manager (ListSecrets + GetSecretValue) and SSM Parameter Store (DescribeParameters). Secrets that exist only in managed services, never on disk, are pulled and included in the exfiltration archive.
Stage 3: Kubernetes Lateral Movement
If a Kubernetes service account token exists at /var/run/secrets/kubernetes.io/serviceaccount/token, the harvester deploys a privileged pod to every node in the cluster. Each pod runs in kube-system with privileged: true, hostPID, hostNetwork, and the host root filesystem mounted at /host. Pods tolerate all taints, ensuring they schedule on control-plane nodes as well as workers. Each pod chroots into the host filesystem to install the audiomon.service persistence implant directly on the node.
Stage 4: Encryption and Exfiltration
Collected data is encrypted with AES-256-CBC (32-byte random session key, PBKDF2 derivation), the session key wrapped with the hardcoded RSA-4096 public key using OAEP padding. The bundle is packaged as tpcp.tar.gz and POSTed to http://83.142.209.203:8080/ with the header X-Filename: tpcp.tar.gz. This C2 operates over plain HTTP on port 8080 — network inspection is possible if defenders are monitoring.
Windows Attack Path: setup()
The setup() function is the first Windows-targeting capability in the TeamPCP campaign. It builds a path to the Windows Startup folder using runtime-decoded base64 components, checks a hidden lock file (msbuild.exe.lock with a 12-hour cooldown), fetches hangup.wav from the C2, extracts a native Windows PE binary using identical XOR-key WAV steganography, drops it as msbuild.exe in the Startup folder, and launches it silently (CREATE_NO_WINDOW). The binary executes on every user login.
Persistence
On Linux/macOS, the WAV-delivered harvester installs audiomon.service (“Audio Controller”) as a systemd user service, writing the backdoor to ~/.config/audiomon/audiomon.py. The implant polls http://83.142.209.203:8080/raw every 45–55 minutes (jittered) for new WAV payloads. The kill switch is identical to litellm and the Checkmarx wave — if the response contains youtube.com, execution aborts.
Version 4.87.1: The Typo Wave
Version 4.87.1 was the attacker’s first publication attempt. A single-character typo — Setup() (capital S) instead of setup() (lowercase) — caused a Python NameError on import. Neither the Windows nor Linux attack chains executed. Sixteen minutes later at 04:07 UTC, the attacker pushed 4.87.2 with the fix. The error is consistent with the “vibe-coded” (AI-assisted, minimally reviewed) development pattern Aikido researchers observed in CanisterWorm.
Affected Versions
Telnyx (This Compromise)
| Component | Vulnerable | Safe Version | Notes |
|---|---|---|---|
| telnyx (PyPI) | 4.87.1 | 4.87.0 | NameError typo — payload non-functional on import |
| telnyx (PyPI) | 4.87.2 | 4.87.0 | Full attack chain confirmed — WAV steganography, Windows persistence, K8s lateral movement |
| telnyx (GitHub) | Not affected | v4.87.0 | No malicious commits; attack bypassed GitHub entirely |
Prior TeamPCP Waves — Cumulative Affected Scope
| Component | Vulnerable | Safe | Notes |
|---|---|---|---|
| trivy-action | Tags 0.0.1–0.34.2 | v0.35.0 (SHA: 57a97c7e) | 75 of 76 tags force-pushed; CVE-2026-33634 (CVSS 9.4) |
| setup-trivy | 7 tags | v0.2.6 | Same stealer payload |
| trivy binary | v0.69.4–0.69.6 | v0.69.3 | Docker Hub, GHCR, ECR |
| kics-github-action | All 35 tags | Verify SHA | Compromised via cx-plugins-releases |
| ast-github-action | v2.3.28 confirmed | Verify SHA | All tags suspected per Wiz |
| litellm (PyPI) | 1.82.7, 1.82.8 | 1.82.6 | .pth file in 1.82.8 fires on all Python startup |
| telnyx (PyPI) | 4.87.1, 4.87.2 | 4.87.0 | WAV steganography; 4.87.1 non-functional |
Exposure Analysis
| Environment | Risk | Reason |
|---|---|---|
| Python environments with telnyx installed | Critical | Payload fires at import time on any platform; no interaction required |
| CI/CD pipelines | Critical | Pipeline secrets, cloud tokens, registry credentials harvested; stolen tokens fuel next wave |
| Kubernetes clusters | Critical | Privileged pods deployed to every node including control plane; full host filesystem access |
| Cloud workloads (EC2/GCE/Azure VMs) | Critical | IMDS queried for IAM role credentials; Secrets Manager and SSM actively pulled |
| Developer workstations (Windows) | High | First Windows target — msbuild.exe Startup persistence; SSH keys, wallets, env files swept |
| Developer workstations (Linux/macOS) | High | audiomon.service persistent backdoor; SSH keys, .env files, shell history, crypto wallets |
| Environments using telnyx 4.87.0 or earlier | Not affected | Last known-clean version; GitHub source verified clean |
Detection Guidance
Indicators of Compromise
| Type | Indicator | Context |
|---|---|---|
| C2 server | 83.142.209.203:8080 | Primary C2 — all telnyx payload delivery, exfiltration, persistence polling |
| Payload endpoint | http://83.142.209.203:8080/ringtone.wav | Linux/macOS harvester via WAV steganography |
| Payload endpoint | http://83.142.209.203:8080/hangup.wav | Windows PE binary via WAV steganography |
| Exfiltration endpoint | http://83.142.209.203:8080/ | Receives tpcp.tar.gz POST with X-Filename header |
| Persistence polling | http://83.142.209.203:8080/raw | audiomon.service polls every 45–55 min |
| Exfil header | X-Filename: tpcp.tar.gz | Present in all TeamPCP stealer exfiltration POSTs |
| Linux persistence | ~/.config/audiomon/audiomon.py | Persistent backdoor script |
| Linux persistence | ~/.config/systemd/user/audiomon.service | systemd unit masquerading as “Audio Controller” |
| Linux state file | /tmp/.initd_state | Tracks last-fetched C2 URL |
| Windows persistence | %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\msbuild.exe | Native PE binary — executes on every login |
| Windows lock file | msbuild.exe.lock (hidden) | 12-hour re-download cooldown sentinel |
| K8s pods | node-setup-{nodename} in kube-system | Attacker-deployed privileged pods |
| Exfil archive | tpcp.tar.gz | Encrypted credential bundle |
| RSA key hash | 4eceb569b4330565b93058465beab0e6d5ea09cfba8e7f29d7be1b5a2abd958a | Identical to litellm and all prior TeamPCP waves |
File Hashes (SHA-256)
| Hash | Artifact |
|---|---|
7321caa303fe96ded0492c747d2f353c4f7d17185656fe292ab0a59e2bd0b8d9 | telnyx-4.87.1-py3-none-any.whl |
cd08115806662469bbedec4b03f8427b97c8a4b3bc1442dc18b72b4e19395fe3 | telnyx-4.87.2-py3-none-any.whl |
23b1ec58649170650110ecad96e5a9490d98146e105226a16d898fbe108139e5 | Backdoored _client.py (v4.87.1) |
ab4c4aebb52027bf3d2f6b2dcef593a1a2cff415774ea4711f7d6e0aa1451d4e | Backdoored _client.py (v4.87.2) |
Verification Steps
- Check installed version:
pip show telnyx 2>/dev/null | grep Version - Check all lock files:
grep telnyx requirements.txt poetry.lock uv.lock Pipfile.lock 2>/dev/null - Scan for Linux persistence:
ls -la ~/.config/audiomon/audiomon.py ~/.config/systemd/user/audiomon.service /tmp/.initd_state 2>/dev/null - Check Windows Startup:
dir "%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\msbuild.exe" - Check Kubernetes:
kubectl get pods -n kube-system | grep node-setup - Review network logs for outbound connections to
83.142.209.203port 8080 - Check systemd:
systemctl - user status audiomon.service 2>/dev/null
Remediation Guidance
Immediate Actions
- Identify affected systems:
pip show telnyx | grep Versionacross all environments, CI/CD runners, container images, and developer workstations. Check lock files. - Downgrade immediately:
pip install telnyx==4.87.0— the last known-clean version. - Remove Linux persistence:
systemctl --user stop audiomon.service && systemctl --user disable audiomon.service. Remove~/.config/audiomon/,~/.config/systemd/user/audiomon.service,/tmp/.initd_state, and any/tmp/pglog. - Remove Windows persistence: Delete
msbuild.exeandmsbuild.exe.lockfrom%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\. - Kubernetes cleanup:
kubectl get pods -n kube-system | grep node-setupand delete all hits. Inspect all nodes for~/.config/audiomon/persistence installed by privileged pods. - Block C2:
83.142.209.203(all ports). Also maintain blocks oncheckmarx[.]zoneandscan.aquasecurtiy[.]orgfrom prior waves. - Rotate every credential accessible to affected hosts: SSH keys, AWS/GCP/Azure credentials, Secrets Manager and SSM secrets, LLM API keys, database passwords, Docker registry tokens, CI/CD secrets, npm/PyPI tokens, Kubernetes service account tokens, telephony API keys and webhook secrets.
- Check cloud audit logs for unauthorised API calls: AWS CloudTrail for Secrets Manager and SSM access, GCP Audit Logs, Azure Activity Log.
Long-Term Hardening
- Pin all Python dependencies to exact versions with hash verification using
pip install --require-hashes - Enable PyPI Trusted Publishers (OIDC) for every package your organisation publishes — this single change would have prevented both the litellm and telnyx compromises
- Pin all GitHub Actions to full commit SHAs using Zizmor, pinact, or Renovate
pinGitHubActionDigests - Implement network-isolated builds where CI/CD runners only permit traffic to explicitly allowlisted registries
- Apply a 48–72 hour hold before adopting new package patch versions in production
Phoenix Security Recommendations
The telnyx compromise confirms the operational pattern: each compromised tool generates credentials that unlock the next target. TeamPCP is working through a credential cache assembled over seven days of CI/CD pipeline harvesting. Trivy credentials funded the first PyPI attack; litellm credentials funded telnyx. The next target is likely already selected.
This campaign has no CVE, no CVSS score, and no NVD entry — for any of the nine attack vectors to date. Traditional vulnerability management programmes that rely on CVE feeds and CVSS prioritisation have zero signal on this threat. The attack targets the security and developer tooling your teams trust most.
Attack surface management: Phoenix identifies which environments have telnyx, litellm, trivy-action, and Checkmarx actions installed and maps installed versions against known-compromised releases.
Contextual deduplication: A single compromised PyPI package deployed across 50 microservices and 20 CI pipelines generates 70 potential findings. Phoenix correlates across environments and teams into a single prioritised backlog.
Reachability analysis: Phoenix distinguishes between environments where the compromised telnyx version was installed versus where it was imported and the payload actually executed.
Remediation campaigns: Create a campaign in Phoenix to track across all affected waves: SHA migration, telnyx/litellm downgrade verification, persistence artifact removal, credential rotation, Kubernetes pod cleanup, and cloud audit log review.
Ownership attribution: When telnyx is deployed across multiple teams, Phoenix maps vulnerable components to responsible teams automatically.

Campaign Timeline: Day 7 Update
| Date | Event |
|---|---|
| October 2025 | Vulnerable pull_request_target workflow (apidiff.yaml) added to Trivy repo |
| November 29, 2025 | Boost Security’s poutine flags the workflow — no action taken |
| February 20, 2026 | hackerbot-claw GitHub account created; scanning begins |
| February 28, 2026 | Trivy fully compromised — org-wide PAT stolen; malicious VS Code extension pushed |
| March 1, 2026 | Aqua Security discloses; non-atomic credential rotation begins |
| March 19, 17:43 UTC | TeamPCP uses retained credentials: backdoored Trivy v0.69.4 + 75 trivy-action tags + 7 setup-trivy tags. CVE-2026-33634 (CVSS 9.4) subsequently assigned |
| March 20, 20:45 UTC | CanisterWorm first detected in npm — ICP blockchain C2 identified |
| March 22, 2026 | Docker images 0.69.5/0.69.6 backdoored; WAV steganography first observed by Aikido researcher Charlie Eriksen |
| March 23, 12:53 UTC | Malicious OpenVSX extensions: ast-results v2.53.0, cx-dev-assist v1.7.0 |
| March 23, 12:58–16:50 UTC | All 35 kics-github-action tags + ast-github-action v2.3.28 compromised |
| March 24, 10:39 UTC | litellm v1.82.7 published to PyPI with inline credential harvester |
| March 24, 10:52 UTC | litellm v1.82.8 published with .pth file (fires on all Python startup) |
| March 24, ~13:30 UTC | PyPI quarantines entire litellm project |
| March 27, 03:51 UTC | telnyx 4.87.1 published — NameError typo kills payload |
| March 27, 04:07 UTC | telnyx 4.87.2 published — NameError corrected, full attack chain live |
| March 27, ~07:00 UTC | PyPI quarantines telnyx 4.87.1 and 4.87.2 following Endor Labs report |
References
- Endor Labs — TeamPCP Strikes Again: telnyx Compromised Three Days After LiteLLM
- GitHub Issue #235 — [SECURITY] PyPI versions 4.87.1 and 4.87.2 are compromised (kiran-sec)
- Endor Labs — TeamPCP Isn’t Done: Threat Actor Behind Trivy and KICS Compromises Now Hits LiteLLM
- JFrog Security Research — Popular litellm Python package is the latest victim of TeamPCP
- Wiz Research — Trivy Compromised by TeamPCP
- Wiz Research — KICS GitHub Action Compromised: TeamPCP Supply Chain Attack
- CrowdStrike — From Scanner to Stealer: Inside the trivy-action Supply Chain Compromise
- Socket Security — Trivy Under Attack Again: Widespread GitHub Actions Tag Compromise
- Socket Security — CanisterWorm: npm Publisher Compromise Deploys Backdoor Across 29 Packages
- Aikido Security — TeamPCP Deploys CanisterWorm on NPM Following Trivy Compromise
- Sysdig TRT — TeamPCP Stealer Detected in Checkmarx ast-github-action
- StepSecurity — Trivy Compromised a Second Time
- PyPI Advisory — telnyx 4.87.1 and 4.87.2 quarantine (March 27, 2026)
How Phoenix Security Fixes What Actually Matters
Your team doesn’t have a finding problem. They have a fixing problem.
Most platforms hand you a list. Phoenix hands you a plan — ranked by real risk, mapped to the team that owns it, with a clear path to close it.
What remediation looks like with Phoenix:
- One backlog, not five. Findings from SAST, SCA, containers, and cloud — deduplicated, correlated, and surfaced in a single prioritized queue. No more reconciling lists across tools.
- Ownership that sticks. Team attribution and inheritance mean the right ticket goes to the right engineer, first time. No routing, no guessing, no back-and-forth.
- Campaigns that move the needle. Group related findings into targeted remediation campaigns. Track progress, measure closure rates, and report real reduction — not raw counts.
- AI that does the legwork, not the deciding. Phoenix’s Remediator agent drafts fixes, creates tickets, and opens PRs. Your team reviews, approves, and merges. Every fix is traceable.
Phoenix Security changes the game.

The pattern is the same every time: teams that move from find and report to analyze and fix close more risk with less effort.

The results are clear:
- Bazaarvoice saved $6.3M in developer time and for teams removed critical in the first weeks of adoption
- ClearBank cut critical container vulnerabilities by 96–99% and reclaimed 4 hours per engineer per week.
- IAS saved an equivalent of 1.5M in development hours and reduced SCA-to-container noise by 82.4%
- Optimizely has been able to act on vulnerabilities sitting on the backlog.
Or learn how Phoenix Security slashed millions in wasted dev time for fintech, retail, and adtech leaders.