No exploit. No zero-day. No fancy tooling.

Just curl, a subdomain I almost skipped, and two API endpoints that forgot authentication existed.

This is how CVE-2026–34723 happened.

The Target

I was working through a responsible disclosure program — mapping the in-scope surface: main site, customer portal, webmail, status page. Standard stuff. I ran subdomain enumeration alongside it, because bug bounty rule #1: the asset the program lists is rarely where the interesting bugs are.

One subdomain flagged immediately: newzammad.[redacted].net.

"New" in a hostname is researcher catnip. New deployments, staging migrations, fresh configs — someone somewhere made a decision to spin this up and didn't audit it the same way they audit production. I've learned to always pull that thread.

Zammad is a popular open-source helpdesk/ticketing system. The instance gave me a login page unauthenticated. Standard. But Zammad is heavily API-driven, and its JavaScript bundle is essentially a map of everything it talks to. I started curling endpoints blind to see which ones 401'd and which ones didn't.

Most locked me out. Two didn't.

The Endpoints

/api/v1/getting_started

curl -s https://newzammad.[redacted].net/api/v1/getting_started | python3 -m json.tool

No credentials. No session cookie. Clean response.

What came back:

  • 5 internal email addressessupport@, billing@, and a handful of testing accounts
  • 10 department/group names — Support 1st line, 2nd line, 3rd line, HR, Legal, Finance, VIP, Development-testing
  • Per-department SLA configs — response time windows, escalation thresholds
  • Developer notes baked into the config — including a note that read something like "For testing contact form integration… creating tickets from cosmos2"
  • Email channel configuration
  • System history dating back to 2007

That last one tells you this isn't a throwaway instance. This is a migrated production system with years of config drift baked in.

/api/v1/signshow

The second endpoint hit differently:

  • GitLab OAuth configured as SSO backend
  • WebSocket server on port 6042 — exposed
  • Both API token AND password auth enabled simultaneously — dual attack surface
  • 28-day session lifetime — a stolen cookie stays valid for a month

Why "Just Info Disclosure" Was Wrong

This is the part that matters.

"Info disclosure" gets triaged into the bin constantly. Researchers find leaked emails or internal service names and watch their reports get closed as informational. The mistake is evaluating each piece in isolation.

Let me stack what I had:

  1. I know billing@[redacted] exists and sits in a "Finance" group with defined SLA windows.
  2. I know the org uses GitLab SSO, which means compromising any developer's GitLab account is a direct pivot to Zammad.
  3. I know API tokens are enabled alongside passwords — multiple auth paths to attack.
  4. I know sessions last 28 days — plenty of window after a phishing hit.
  5. I know the internal department structure well enough to write a pretext email that matches how they actually operate.

That's not a paper cut. That's a spear-phishing campaign assembled from a single unauthenticated curl command. An attacker who lands a developer's GitLab creds now has a clear, already-mapped path into the helpdesk — where customer data, tickets, and support history live.

I assessed this at CVSS 5.5 MEDIUM in my initial report. The vendor security team re-scored it 8.7 HIGH. They were right.

Disclosure Timeline

Date Event 2026–03–20 Reported to the affected org via their security disclosure address (PGP encrypted). Shortly after, the security contact confirmed and escalated upstream to the vendor 2026–04–08 Vendor shipped patches in 6.5.4 and 7.0.1. GitHub Advisory GHSA-hcm9-ch62–5727 issued. 2026–04–13 Credit added to advisory as 0xrajdip Today, CVE-2026-34723 was published, indexed on SentinelOne, Tenable, and other commercial vulnerability databases

One note on the credit: when the vendor migrated advisories from their own site to GitHub, attribution got dropped in the process. It wasn't intentional — migrations are messy — but it took a follow-up to get it restored. If you're a researcher and your credit disappears after a platform migration, politely follow up. It happens more than it should, and most vendors will fix it.

Takeaways

Enumerate subdomains, always. The primary portal was clean. The finding was on a secondary host that casual recon would have missed entirely. The "new" subdomain was live, in scope, and unaudited.

Unauthenticated endpoint enumeration is still underrated. No CVE-chaining here. No deserialization, no RCE. The bug was that two endpoints didn't check if the request came from an authenticated user. That's it. Sometimes the most impactful bugs are the dumbest ones.

Context transforms severity. A leaked department name is nothing. A leaked department structure + auth backend + session policy + email addresses, all available without credentials, is a phishing campaign in a box. Always evaluate findings in combination, not isolation.

Vendor relationship quality matters. Good triage contacts don't just close the ticket — they escalate upstream, push for patching, and follow through on attribution. Responsible disclosure works when there's a competent, engaged human on the other side of the intake address.

Affected Versions and Fix

The vulnerability affected Zammad prior to 6.5.4 / 7.0.1. The fix restricts /api/v1/getting_started and /api/v1/signshow to authenticated sessions.

If you're running Zammad, update. If you're a security team with Zammad in your environment, check your version and verify the endpoints are gated.

References

Thanks to the vendor security team for a clean patch cycle and an honest severity reassessment, and to the security contact who pushed to get my CVE credit restored after it was lost in an advisory migration.

Find me on GitHub: @0xrajdip

#bugbounty #cybersecurity #appsec #cve #securityresearch