This is a storefront window left uncovered, not a vault door blown off its hinges
CVE-2026-28766 is a missing-authentication flaw in Gardyn's cloud API where the /api/users endpoint exposed registered user account data to unauthenticated remote callers. NVD ties the vulnerable cloud component to mygardyn:cloud_api versions before 2.12.2026; Gardyn says fixes also landed via automatic ecosystem updates, with device firmware 619+ and mobile app 2.11.0+ carrying the broader remediation set.
The vendor's 9.3 CRITICAL score is technically understandable because the bug is pre-auth, internet-reachable, and cross-user in scope. In real operations, though, this behaves more like a high-grade data exposure than a hands-on-keyboard takeover: no code execution, no service outage, and Gardyn states there is no evidence of exploitation and that app login credentials were not at risk, which pulls it down from CRITICAL to HIGH.
3 steps from start to impact.
Find the Gardyn cloud surface
Burp Suite or simple HTTP clients like curl/httpie; nothing exotic is required if the endpoint is directly reachable.- Unauthenticated remote network access to the Gardyn cloud API
- The vulnerable cloud API version is still deployed
- This is a niche consumer-IoT ecosystem, so the exposed population is far smaller than mainstream enterprise SaaS or edge appliances
- If Gardyn's cloud-side fix was already rolled out globally, customers cannot be exploited through this flaw anymore even if local app/device versions lag
Call the unauthenticated data endpoint
CWE-306, the server performs the action without enforcing authentication, returning account records that should have been restricted to authorized requests.- The endpoint remains reachable from the internet
- No API gateway or WAF rule blocks anonymous requests to that path
- Modern API gateways, positive-security models, or explicit allowlists for authenticated routes should have stopped this at the edge
- Rate limits and anomaly detection can slow bulk harvesting even if a single request succeeds
GET requests with no auth headers or sessions. DAST/API security tooling is better suited than host scanners.Harvest and operationalize exposed user data
- The endpoint response includes real customer records
- The attacker has storage and parsing capability for the returned dataset
- Vendor statements indicate app login credentials were not exposed, which limits immediate pivot value
- This is primarily confidentiality impact; it does not directly provide device code execution or tenant administration
The supporting signals.
| In-the-wild status | No public exploitation is reported by CISA in the advisory material, and the CVE is not KEV-listed. |
|---|---|
| Proof-of-concept availability | No authoritative public PoC repo was identified in primary-source material reviewed. That said, exploit complexity is effectively trivial HTTP request replay if the endpoint is exposed. |
| EPSS | 0.00086 in the user-provided intel block, which is extremely low and consistent with a niche product and no public exploitation evidence. |
| KEV status | Not present in CISA's Known Exploited Vulnerabilities Catalog as of this assessment. |
| CVSS vector interpretation | Vendor/CNA scored CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:N = 9.3 CRITICAL; NVD enrichment separately scores it 7.5 HIGH with confidentiality-only impact. The disagreement matters: this is pre-auth and internet-reachable, but the practical blast radius is mostly data exposure rather than full compromise. |
| Affected versions | NVD lists mygardyn:cloud_api versions before 2.12.2026 as affected. Gardyn's broader ecosystem bulletin says the fixes are present in firmware 619+ and mobile app 2.11.0+. |
| Fixed versions | Use Cloud API 2.12.2026 or later where that versioning is visible; for customer-side validation Gardyn directs users to confirm firmware 619+ and app 2.11.0+. |
| Scanning/exposure data | No reliable public internet-scale exposure count was found in primary sources for this specific Gardyn API. Practically, exposure depends on Gardyn's cloud endpoint reachability rather than customers hosting a large on-prem population. |
| Disclosure timeline | CVE published 2026-04-03; Gardyn's public update was originally published 2026-02-24 and revised 2026-04-02; CISA CSAF Update A carries a 2026-04-02 current release date. |
| Reporting researcher | CISA's CSAF advisory credits Michael Groberman with reporting the vulnerabilities. |
noisgate verdict.
The decisive factor is that this is a pre-auth internet-facing bulk data exposure, which keeps it above medium even with no active exploitation. It stops short of critical because the real-world outcome is privacy loss and phishing fuel, not direct remote code execution, tenant admin takeover, or destructive impact.
Why this verdict
- Dropped from vendor 9.3 because the impact is mostly confidentiality: the strongest verified outcome is exposure of user account information, not code execution or service destruction.
- Unauthenticated remote access keeps it high:
AV:N/PR:N/UI:Nmeans there is no meaningful attacker-position barrier if the vulnerable cloud path is reachable. - Niche ecosystem narrows the reachable population: this is not a ubiquitous enterprise platform, so the real exposed population is materially smaller than the vendor baseline implies.
- No public exploitation evidence removes urgency pressure: CISA says no known public exploitation, the CVE is not KEV-listed, and the EPSS signal supplied is extremely low.
- Cross-user scope prevents a medium verdict: the bug is not a single-account self-data leak; it potentially exposes registered-user data broadly, which is a genuine breach-class condition.
Why not higher?
There is no verified code execution, no clear authentication-token exposure, and no availability impact. Gardyn also says app login credentials were not at risk and reports no evidence of exploitation, which is not what a true CRITICAL patch-management emergency usually looks like.
Why not lower?
This is still a pre-auth, internet-reachable API failure with high-confidence confidentiality impact against customer data. A flaw that lets anonymous callers pull user records at cloud scale is too operationally serious to bury as backlog hygiene.
What to do — in priority order.
- Verify cloud-side remediation status — Confirm with Gardyn support or your supplier contact that the vulnerable cloud API path has been remediated and that your deployed estate is on the fixed service generation. For a HIGH verdict, complete this validation and any vendor-side escalation within 30 days.
- Inventory every Gardyn asset — Identify all Gardyn devices and managed mobile clients in offices, labs, demo spaces, and break rooms so you know where customer-side version checks are required. For a HIGH verdict, finish the inventory and ownership mapping within 30 days.
- Enforce version compliance — Require Gardyn firmware 619+ and mobile app 2.11.0+ on all reachable assets, using MDM or manual attestation if you do not have direct API visibility. For a HIGH verdict, deploy this control within 30 days.
- Constrain outbound access — Place Gardyn devices on segmented networks and restrict outbound destinations to only required vendor endpoints so any future API or device flaw has less room to breathe. For a HIGH verdict, implement segmentation or egress policy updates within 30 days.
- Watch for anonymous API abuse — If you operate a proxy, CASB, or outbound monitoring layer that can see Gardyn traffic, alert on unusual anonymous requests, unusually large user-data responses, or spikes to Gardyn API paths. For a HIGH verdict, stand up this monitoring within 30 days.
- EDR on employee laptops does not fix a vendor cloud API authorization flaw; the vulnerable trust boundary is upstream.
- MFA for Gardyn app users does not help when the endpoint itself fails to require authentication.
- Password resets alone are low-yield here because Gardyn states app login credentials were not exposed by these vulnerabilities.
Crowdsourced verification payload.
Run this on an auditor workstation or in CI against your asset inventory, not on the Gardyn cloud service. Invoke it as python gardyn_verify.py --firmware 619 --app 2.11.0 --cloud-api 2.12.2026 or pass only the values you know; no administrative privileges are required.
#!/usr/bin/env python3
# gardyn_verify.py
# Purpose: Assess whether a Gardyn asset is likely patched for CVE-2026-28766
# Usage examples:
# python gardyn_verify.py --firmware 619 --app 2.11.0 --cloud-api 2.12.2026
# python gardyn_verify.py --firmware 618 --app 2.10.9
# Exit codes:
# 0 = PATCHED
# 1 = VULNERABLE
# 2 = UNKNOWN
import argparse
import re
import sys
from itertools import zip_longest
FIXED_FIRMWARE = 619
FIXED_APP = "2.11.0"
FIXED_CLOUD_API = "2.12.2026"
def normalize_version(v):
if v is None:
return None
parts = re.findall(r"\d+", str(v))
return [int(p) for p in parts] if parts else None
def compare_versions(a, b):
"""Return -1 if a<b, 0 if a==b, 1 if a>b, None if invalid."""
va = normalize_version(a)
vb = normalize_version(b)
if va is None or vb is None:
return None
for x, y in zip_longest(va, vb, fillvalue=0):
if x < y:
return -1
if x > y:
return 1
return 0
def main():
parser = argparse.ArgumentParser(description="Verify likely patch status for CVE-2026-28766 on Gardyn assets")
parser.add_argument("--firmware", help="Gardyn device firmware version, e.g. 619")
parser.add_argument("--app", help="Gardyn mobile app version, e.g. 2.11.0")
parser.add_argument("--cloud-api", dest="cloud_api", help="Observed/attested cloud API version, e.g. 2.12.2026")
args = parser.parse_args()
signals = []
reasons = []
if args.firmware:
try:
fw = int(re.findall(r"\d+", args.firmware)[0])
if fw < FIXED_FIRMWARE:
signals.append("vuln")
reasons.append(f"firmware {fw} < fixed {FIXED_FIRMWARE}")
else:
signals.append("patched")
reasons.append(f"firmware {fw} >= fixed {FIXED_FIRMWARE}")
except Exception:
reasons.append("firmware value invalid")
if args.app:
cmp_app = compare_versions(args.app, FIXED_APP)
if cmp_app is None:
reasons.append("app version invalid")
elif cmp_app < 0:
signals.append("vuln")
reasons.append(f"app {args.app} < fixed {FIXED_APP}")
else:
signals.append("patched")
reasons.append(f"app {args.app} >= fixed {FIXED_APP}")
if args.cloud_api:
cmp_cloud = compare_versions(args.cloud_api, FIXED_CLOUD_API)
if cmp_cloud is None:
reasons.append("cloud API version invalid")
elif cmp_cloud < 0:
signals.append("vuln")
reasons.append(f"cloud API {args.cloud_api} < fixed {FIXED_CLOUD_API}")
else:
signals.append("patched")
reasons.append(f"cloud API {args.cloud_api} >= fixed {FIXED_CLOUD_API}")
if "vuln" in signals:
print("VULNERABLE | " + "; ".join(reasons))
sys.exit(1)
elif signals and all(s == "patched" for s in signals):
print("PATCHED | " + "; ".join(reasons))
sys.exit(0)
else:
print("UNKNOWN | provide --firmware and/or --app and/or --cloud-api; current notes: " + "; ".join(reasons or ["no version data supplied"]))
sys.exit(2)
if __name__ == "__main__":
main()
If you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.