Skip to content

Budibase, Gogs, Actual, skillctl, Nuxt, and automation boundary checks

Source: hourly offensive-security scan, 2026-06-22. Primary entries: GitHub advisories GHSA-jj36-r9w3-3pfh / CVE-2026-50136, GHSA-v7j5-vc4m-723w / CVE-2026-50132, GHSA-4q6h-8p4v-67vq / CVE-2026-48153, GHSA-c4v7-xg93-qf8g / CVE-2026-47267, GHSA-74p7-6h78-gw8p, GHSA-mqpr-49jj-32rc / CVE-2026-56357, GHSA-c9cv-mq2m-ppp3 / CVE-2026-56326, GHSA-9m6g-wc8r-q59c / CVE-2026-48170, and GHSA-ghmh-jhmj-wcmf. Late same-day updates added GHSA-35c4-rvc8-frhm / CVE-2026-50137, GHSA-rgvg-3wpc-h44p / CVE-2026-54351, GHSA-gfq7-5x4g-3xhf / CVE-2026-54353, GHSA-w7mq-r738-x278 / CVE-2026-54352, GHSA-wv27-2vqp-j7g5 / CVE-2026-52801, GHSA-pwx3-qcgw-vh7h / CVE-2026-52800, GHSA-p9f5-h3rx-j5qw / CVE-2026-52799, GHSA-jq8v-rmf6-65jw / CVE-2026-52798, GHSA-xqjm-27pc-rvwm / CVE-2026-50179, and GHSA-cq9c-6w48-qmfg / CVE-2026-49229.

June 23 Gogs updates added GHSA-744x-3838-5r56 / CVE-2026-52815, GHSA-c39w-43gm-34h5 / CVE-2026-52813, GHSA-6p9m-q3jp-47h4 / CVE-2026-52812, GHSA-89mr-xqfv-758m / CVE-2026-52811, GHSA-wmfg-5p4h-5fw3 / CVE-2026-52810, GHSA-268j-37xf-pp52 / CVE-2026-52808, GHSA-vcm5-gvmp-78mp / CVE-2026-52807, GHSA-qf6p-p7ww-cwr9 / CVE-2026-52806, GHSA-g2f5-gjr4-qjvm / CVE-2026-52805, GHSA-4565-r4x7-hg8j / CVE-2026-52804, and GHSA-xxhq-69mf-w8cr / CVE-2026-52802.

This batch is durable because each item exposes a repeatable operator workflow around trusted automation boundaries: low-code builders and public routes reaching stored cloud credentials, redirect-following webhook clients bypassing internal-host filters, skill-library metadata steering local filesystem and Git operations, framework navigation helpers normalizing URLs after validation, SCIM patch documents mutating process-global prototypes, and enrollment tokens becoming identity material after database exposure.

What changed

Advisory Component Boundary Operator value
GHSA-jj36-r9w3-3pfh / CVE-2026-50136 Budibase S3 attachment URL route unauthenticated /api/attachments/:datasourceId/url requests could generate PutObject presigned URLs using stored workspace datasource credentials when the caller knew the workspace and datasource IDs Low-code reviews should test whether public/static routes can invoke datasource-backed operations without builder/table permissions; prove with disposable buckets and inert object keys only.
GHSA-v7j5-vc4m-723w / CVE-2026-50132 Budibase chat identity handoff a public, state-changing GET could bind an attacker-controlled Slack/Discord/Teams identity token to an authenticated user's Budibase account without consent or CSRF protection ChatOps identity-link flows need victim-session and attacker-session separation tests; evidence is a disposable identity mapping, not access to real workspaces.
GHSA-4q6h-8p4v-67vq / CVE-2026-48153 Budibase OAuth2 validation builder-supplied OAuth2 token endpoint URLs reached node-fetch without the usual outbound blacklist and followed redirects Builder-controlled integration URLs are SSRF surfaces; prove with owned callbacks and synthetic internal canary services, never cloud metadata or production loopback targets.
GHSA-c4v7-xg93-qf8g / CVE-2026-47267 Gogs webhook deliveries webhook URL validation blocked local CIDRs at creation/run time but did not re-check redirect destinations Git forge webhook clients need post-redirect allowlist checks; prove with an owned redirector and harmless callback target, not metadata endpoints.
GHSA-74p7-6h78-gw8p skillctl 0.1.2 follow-up committed .skills.toml, skill folders, and --dest options could steer Git arguments, FIFO/device reads, hardlinks, commit trailers, or outside-root deletion in agent-driven skill workflows Treat skill libraries as executable-adjacent supply chain inputs; validate with scratch repos, marker files, and inert Git refs only.
GHSA-mqpr-49jj-32rc / CVE-2026-56357 n8n GitHub Webhook Trigger workflows using the GitHub trigger accepted unsigned POSTs from callers who knew the webhook URL Automation platforms should verify event signatures before tool/workflow execution; prove with inert fake events that write only to a canary sink.
GHSA-c9cv-mq2m-ppp3 / CVE-2026-56326 Nuxt navigateTo / reloadNuxtApp validation inspected raw paths before browser/WHATWG normalization, and the open option skipped script-protocol checks Redirect and navigation testing should include normalized path, encoded-dot, protocol-relative, and script-scheme parser differentials.
GHSA-9m6g-wc8r-q59c / CVE-2026-48170 scim-patch SCIM PATCH values containing __proto__-style keys polluted Object.prototype for the Node process Identity provisioning endpoints should test JSON patch paths as process-wide object mutation surfaces; prove with same-process canary properties only.
GHSA-ghmh-jhmj-wcmf nebula-mesh enrollment tokens raw enrollment UUIDs were stored in SQLite and could be consumed by whoever read the DB before legitimate enrollment Post-read identity-boundary reviews should treat pending enrollment tokens like credentials; evidence should stop at synthetic DB rows and canary enrollment attempts.
GHSA-35c4-rvc8-frhm / CVE-2026-50137 Budibase S3 attachment URL route follow-up the same public route could source workspace context from caller-controlled app headers/body/query material, instantiate a stored S3 datasource, and return a presigned PutObject URL for caller-selected bucket/key values Confirm that workspace and datasource identifiers are authorized for the caller and that buckets are pinned to datasource configuration; prove with disposable IAM keys and inert object names only.
GHSA-rgvg-3wpc-h44p / CVE-2026-54351 Budibase public webhook trigger request-body mass assignment could override the internal appId passed into asynchronous automation execution Public automation triggers need server-derived context sealing; prove with two disposable workspaces and an inert canary automation, never production table writes.
GHSA-gfq7-5x4g-3xhf / CVE-2026-54353 Budibase outbound fetch validation blacklist checks resolved DNS before node-fetch, but the connection performed a second lookup that could rebind to a blocked address SSRF reviews should include DNS time-of-check/time-of-use tests with owned domains that change answers between validation and connection.
GHSA-w7mq-r738-x278 / CVE-2026-54352 Budibase PWA ZIP processing builder-uploaded ZIP symlinks could pass path-string checks and stream out-of-tree file bytes into a served PWA asset object Low-code asset importers need archive symlink and served-object containment tests; prove with synthetic outside-root marker files, not .env or credentials.
GHSA-wv27-2vqp-j7g5 / CVE-2026-52801 Gogs mirror settings mirror configuration could import local repositories through a path that lacked the local-repository validation present in new-migration flows Git forge tests should compare initial import and later mirror-edit validation paths; prove only with scratch local repositories and marker commits.
GHSA-pwx3-qcgw-vh7h / CVE-2026-52800 Gogs organization teams team member management accepted state-changing GET requests without CSRF validation, enabling owner-role changes from a victim owner session Organization-admin workflows need GET-vs-POST and CSRF parity checks; prove with disposable orgs and attacker/victim lab users only.
GHSA-p9f5-h3rx-j5qw / CVE-2026-52799 Gogs attachment downloads /attachments/:uuid returned raw files by UUID without checking repository, issue, comment, or release visibility Attachment routes need object-parent authorization checks; evidence should use high-entropy synthetic UUIDs and harmless files in private lab repos.
GHSA-jq8v-rmf6-65jw / CVE-2026-52798 Gogs .ipynb preview sanitized notebook HTML was re-rendered client-side with Markdown handling that could recreate dangerous link schemes Repository preview testing should include post-sanitization client re-render sinks; prove with harmless click-only DOM markers in disposable repos.
GHSA-xqjm-27pc-rvwm / CVE-2026-50179 Actual transaction CSV export imported payee, notes, account, or category fields beginning with formula metacharacters survived into exported CSV files Finance/export features need formula-injection tests from import to export; prove with inert formulas that call only owned callbacks or local markers.
GHSA-cq9c-6w48-qmfg / CVE-2026-49229 Actual sync-server OpenID sessions disabling an OpenID user blocked future login but did not revoke existing session tokens accepted by protected routes Account-disable controls need stale-session validation; prove with disposable users and harmless authenticated endpoints, not financial data.
GHSA-744x-3838-5r56 / CVE-2026-52815 Gogs organization teams API GET /api/v1/orgs/:orgname/teams returned team IDs, names, descriptions, and permission levels without token middleware Recon self-hosted Git forges by comparing web UI auth to API route families; evidence is disposable org/team metadata, not private repo access.
GHSA-c39w-43gm-34h5 / CVE-2026-52813 Gogs organization names and repository paths traversal sequences in org names influenced repository filesystem paths, enabling nested repository writes that could overwrite Git hook configuration Validate namespace-to-filesystem canonicalization with scratch orgs and marker hooks only.
GHSA-6p9m-q3jp-47h4 / CVE-2026-52812 Gogs Git LFS dedupe existing content-addressed LFS objects could be bound to another repo without re-hashing the claimed upload body Treat LFS object IDs as authorization material; prove with synthetic blobs across two lab repos, never customer files.
GHSA-89mr-xqfv-758m / CVE-2026-52811 Gogs repository file upload upload paths checked only the leaf target for symlinks, while committed parent symlinks plus preserved backslashes could write outside the working tree Test every-path-component symlink checks with disposable outside-root markers; never write shell keys, hooks, or config on production.
GHSA-wmfg-5p4h-5fw3 / CVE-2026-52810 Gogs Git smart HTTP git-receive-pack authorization trusted the caller-controlled service=git-upload-pack query parameter instead of the executed RPC path Test path-vs-query authorization parity with readonly collaborators and marker commits in scratch repos.
GHSA-268j-37xf-pp52 / CVE-2026-52808 Gogs repository settings API writer-gated API endpoints could mutate admin-only issue tracker, wiki, and mirror-sync settings Check API/UI authorization drift with reversible settings on disposable repos.
GHSA-vcm5-gvmp-78mp / CVE-2026-52807 Gogs issue milestone UI the issue-creation milestone dropdown missed a sanitization fix and could recreate stored milestone-name HTML in Semantic UI Test repository metadata fields in every duplicated UI sink with harmless DOM markers and lab users only.
GHSA-qf6p-p7ww-cwr9 / CVE-2026-52806 Gogs pull request rebase merge attacker-controlled branch names could inject git rebase --exec arguments during "Rebase before merging" Test branch/refname-to-command boundaries with inert marker commands only in an isolated lab instance.
GHSA-g2f5-gjr4-qjvm / CVE-2026-52805 Gogs repository migration migration URL validation checked the initial host, but git clone --mirror followed redirects to blocked internal repository endpoints Test import/migration redirect-final-destination validation with owned redirectors and synthetic Git servers, never internal production repos.
GHSA-4565-r4x7-hg8j / CVE-2026-52804 Gogs collaboration access mode an off-by-one access-mode check allowed repo admins to set owner-level collaboration mode Include raw integer/API parameters beyond UI options; prove with disposable repos and lab accounts.
GHSA-xxhq-69mf-w8cr / CVE-2026-52802 Gogs redirect_to validation same-site checks inspected leading slashes before browser backslash and traversal normalization converted paths into protocol-relative off-origin URLs Include slash/backslash parser differentials; use owned or example.invalid destinations and stop at navigation proof.

Adjacent GHSA-qc2x-6f54-m6h9 was processed but not promoted because the public impact is LAN-local mDNS cache corruption without a specific cross-privilege or data-access workflow. GHSA-hvqh-jw65-wcpq was processed without promotion as a standalone item because the autocomplete formatter XSS pattern is generic unless tied to a privileged suggestion source. Picklescan follow-up advisories GHSA-6w4w-5w54-rjvr, GHSA-6556-fwc2-fg2p, and GHSA-xp4f-hrf8-rxw7 were processed as additional unsafe-pickle gadget coverage for the existing ML archive-boundary workflow. GHSA-4j89-2c4f-44c6 and GHSA-xp79-5mx3-jx52 were processed without promotion because the public detail is Gogs denial of service without a data-access, authorization, or code-execution boundary. GHSA-5c3f-6486-3g7g was processed without promotion because password-reset lifetime drift is mainly an account-policy weakness unless paired with token capture. GHSA-p6qx-ghxm-389h was processed without a new page because the OctoPrint printer-output-to-admin-DOM pattern is useful but narrower than the Git forge wave; keep future printer/web-control items scoped to benign UI markers and never device-disrupting print actions.

Operator triage

  1. Map who controls each trigger. Distinguish anonymous public callers, authenticated builders, organization owners, repository contributors, low-privilege app users, IdP provisioning clients, CSV importers, and holders of leaked database backups.
  2. Separate validation-time from use-time. For SSRF, redirects, mirror URLs, ZIP paths, and URL helpers, record whether allowlists run before or after normalization, redirect following, DNS lookup, symlink resolution, and final request construction.
  3. Use canary-only proofs. Disposable buckets, owned redirectors and DNS names, fake chat identities, scratch repositories, harmless attachments, marker notebooks, synthetic LFS blobs, inert branch-name commands, marker Git protocol pushes, inert webhook events, synthetic SCIM users, CSV rows, stale-session status checks, and fake enrollment tokens are sufficient.
  4. Avoid sensitive endpoints. Do not target cloud metadata, production loopback panels, real datasource buckets, real chat accounts, real skill libraries, live workflow side effects, private customer attachments, financial exports, or production enrollment tokens.
  5. Preserve role and topology evidence. Strong reports show route family, required auth role, datasource/workspace visibility, redirect or DNS-rebind chain, archive path resolution, process owner, and patched-vs-vulnerable comparisons.

Replayable validation boundaries

Budibase datasource, chat identity, and OAuth2 harness

  • Preconditions: owned Budibase lab or explicit customer scope, disposable workspace, fake S3-compatible bucket, owned chat workspace identities, and one low-privilege builder/user account.
  • For signed uploads, create a synthetic S3 datasource with throwaway credentials, then request a presigned URL from a session that should lack datasource access. Upload only an inert marker object to a disposable bucket/key.
  • For chat identity handoff, create the attacker-side link token, then visit the handoff URL from a separate disposable authenticated victim browser profile. Evidence is the resulting mapping between two lab identities.
  • For OAuth2 SSRF, submit token endpoint URLs pointing to owned callback collectors and owned redirectors. Capture callback timing and validation-envelope behavior only.
  • For DNS-rebinding SSRF, configure an owned hostname that returns an allowed public IP for the validation lookup and a blocked lab canary IP for the later connection. Keep the second target under your control; do not use metadata, loopback admin panels, or production RFC1918 services.
  • For public webhook trigger mass assignment, seed two disposable workspaces and a webhook whose only side effect is writing a marker to a canary table. Send a body containing an appId collision and record whether execution crosses workspace context.
  • For PWA ZIP imports, include a symlink entry pointing to a synthetic outside-root marker and list that symlink path in icons.json; evidence is whether the served asset contains the marker bytes. Never point symlinks at .env, database files, cloud credentials, or user uploads.
  • Negative controls: authentication and builder/table permission checks on attachment routes, CSRF/consent on chat-link handoff, URL allowlists applied after redirects, and no response-body leakage from failed OAuth2 validation.

Gogs webhook redirect SSRF harness

  • Preconditions: scoped Gogs instance, disposable repository, permission to create/test webhooks, and an owned redirector domain.
  • Create a webhook pointing to the owned redirector. Make the redirector return a 30x to a second owned URL that simulates a blocked host class without using real metadata or internal services.
  • Positive evidence is the Gogs server following the redirect and reaching the second canary despite creation-time URL checks.
  • Negative controls: redirect disabled or manually handled, final URL host/IP revalidated after every redirect, DNS rebinding resistance, and egress segmentation.

Gogs local import, organization, attachment, and notebook harness

  • Preconditions: scoped Gogs lab, disposable organization, attacker/victim lab users, private scratch repositories, harmless attachments, and local scratch repositories containing marker commits only.
  • Compare new-migration validation against mirror-settings edits with file:// or local-path repository values that should be blocked. Positive evidence is import of the marker repository through mirror settings when the new-migration path rejects it.
  • For organization CSRF, create a disposable Owners team and test whether a GET request from the victim-owner browser adds the attacker user. Evidence is a role-change table for lab accounts only.
  • For attachment authorization, upload a harmless marker attachment to a private repo, then request /attachments/:uuid as unauthenticated and unauthorized lab users. Capture status, content hash of the marker, and parent-object permissions.
  • For notebook previews, commit an .ipynb whose Markdown contains a harmless click-only DOM marker link. Capture whether client-side re-rendering recreates a dangerous scheme after server sanitization.
  • Negative controls: identical local-import validation on create and edit paths, CSRF tokens on all state-changing methods, parent-object authorization before attachment file open, and no client re-render after sanitized notebook insertion.

Gogs Git forge tenant, protocol, and merge harness

  • Preconditions: isolated Gogs lab, disposable orgs/repos, attacker/victim lab users, a synthetic Git HTTP server, a synthetic LFS object corpus, and temporary filesystem marker directories owned by the lab process.
  • For organization-team API disclosure, request GET /api/v1/orgs/:orgname/teams as unauthenticated and low-privilege users; record only route, status, and synthetic team metadata exposure.
  • For org-name path traversal, create only scratch organizations and repositories whose resolved paths point at disposable temp directories. Evidence is path resolution or marker repository placement; do not overwrite real hooks, SSH keys, config, or service files.
  • For LFS dedupe, seed a private lab repo with a harmless LFS marker blob, then attempt to bind the same OID from a second repo without uploading matching bytes. Evidence is whether the second repo can fetch the marker through its own authorization context.
  • For repository file uploads, commit a parent-directory symlink to a disposable target, then upload a marker filename that exercises backslash/path cleanup. Capture whether the marker appears outside the work tree.
  • For Git smart HTTP confusion, grant a collaborator read-only access, then send a receive-pack request whose query string claims service=git-upload-pack. Evidence is acceptance or rejection of a marker commit to a scratch repo.
  • For repository settings API drift, compare write-level collaborator calls against UI-visible admin-only controls for issue tracker, wiki, and mirror-sync settings. Keep changes reversible and scoped to throwaway repos.
  • For milestone DOM sinks, create a milestone with a harmless visible marker and test each issue page/dropdown that renders it; do not include credential theft or privileged action payloads.
  • For rebase-merge command injection, use a lab-only branch/refname that can run an inert marker command if accepted, such as writing to a temp file. Never run shell payloads on shared or customer-hosted Gogs.
  • For migration redirect SSRF, submit an owned public Git URL that redirects to a synthetic blocked-host Git server you control. Evidence is redirect following and import attempt metadata, not internal repository contents.
  • For collaboration owner escalation, submit raw access-mode values from a repo-admin lab account and record role transitions for disposable users only.
  • For redirect_to, use example.invalid or an owned benign destination to prove browser-normalized off-origin navigation from slash/backslash traversal inputs.
  • Negative controls: namespace validation before filesystem writes, every path component checked for symlinks, LFS body hash verified even on dedupe hits, authorization keyed to the actual Git RPC endpoint, API routes requiring the same role as UI routes, branch names passed after -- or rejected before shell/Git execution, final migration URL validation after redirects, owner mode unreachable by collaborator APIs, and URL validation after browser-equivalent normalization.

skillctl hostile library harness

  • Preconditions: scratch project, scratch skill library, fake outside-root marker files, and no real credentials or home-directory paths.
  • Test .skills.toml source_sha values that look like Git flags and confirm whether the tool rejects them before invoking git ls-tree.
  • Add FIFO, device, socket, and hardlink canaries to a malicious skill folder and verify the copy path rejects non-regular files instead of blocking, reading unbounded data, or preserving hardlink relationships.
  • Exercise add --dest only against temp directories and confirm absolute paths or .. traversal cannot delete or replace outside-root markers.
  • Capture command, version, resolved paths, before/after trees, and rejection messages.

Automation and identity-parser harnesses

  • For n8n, send one unsigned fake GitHub webhook and one properly signed canary event to a lab workflow whose only action writes a harmless marker. Positive evidence is workflow execution without valid X-Hub-Signature-256.
  • For Nuxt, build a route table covering /..//host, /.//host, encoded-dot variants, protocol-relative paths, and javascript: targets passed through navigateTo(..., { open }); capture only redirect locations or blocked decisions.
  • For scim-patch, apply a PATCH with __proto__.skillz_canary=true to a disposable SCIM user in a same-process lab and verify whether unrelated plain objects inherit the marker.
  • For nebula-mesh, seed a lab SQLite DB with a pending synthetic enrollment token and show whether reading the DB reveals a consumable raw token; stop before touching real overlay identities.

Actual CSV and stale-session harness

  • Preconditions: owned Actual lab, OpenID multi-user mode when testing session revocation, disposable transactions, and two lab users.
  • For CSV formula injection, import or edit transaction Payee, Notes, Account, or Category fields with inert spreadsheet formulas that reference only owned callback URLs or local markers, then export CSV and confirm whether formula metacharacters survive as the first character of a cell.
  • For disabled-user session validation, log in as a disposable OpenID user, preserve the session token, disable the user as admin, then call a harmless authenticated endpoint with the old token. Evidence is route/status parity before and after disablement; do not access budgets, bank-sync data, or real transactions.
  • Negative controls: formula-prefix neutralization on export, import-to-export round-trip tests, session validation checking the user enabled flag on every protected route, and session invalidation during account disablement.

Reporting notes

  • Lead with the exact crossed boundary: public route to stored datasource credentials, attacker chat token to victim account identity, builder OAuth URL to server-side fetch, DNS-rebinding name to blocked fetch target, ZIP symlink to served asset bytes, mirror edit to local repository import, CSRF GET to organization ownership, attachment UUID to private file, notebook Markdown to same-origin DOM sink, CSV cell to spreadsheet formula, disabled account to still-valid session, webhook redirect to blocked host, skill metadata to Git/filesystem side effects, unsigned webhook to workflow execution, raw navigation string to normalized browser destination, SCIM JSON to process-global prototype, or database read to enrollment identity claim.
  • Keep evidence boring and reversible: canary object keys, redirect and DNS logs, fake chat IDs, scratch path trees, inert workflow markers, route decision tables, synthetic SCIM properties, lab enrollment rows, marker repositories, harmless attachments, click-only DOM markers, CSV cells, and stale-token status codes.
  • Do not include secrets, cloud metadata output, real customer files, private repository content, real bank/chat identities, live workflow payloads, or production database contents.

June 23 Budibase and Gogs follow-up updates

The June 23 GitHub Advisory Database wave added two adjacent items that belong with this boundary batch instead of separate pages:

  • GHSA-8qv3-p479-cj62 / CVE-2026-54350: Budibase published-app query templates could accept anonymous NoSQL operator injection.
  • GHSA-3w28-36p9-w929 / CVE-2026-52816: Gogs' unauthenticated .ipynb sanitizer accepted arbitrary data: URIs, adding another notebook-preview XSS sink next to the earlier stored .ipynb preview issue.

Operator value:

  • Budibase public app endpoints should be tested for anonymous filter/query material to database selector semantics, not just stored datasource and webhook boundaries.
  • Gogs notebook rendering should be tested across both authenticated repository preview paths and unauthenticated sanitizer/helper routes; dangerous schemes can reappear as same-origin DOM even when no private repo content is involved.

Safe validation boundaries:

  1. For Budibase, seed a disposable public app with canary records and submit paired baseline and operator-shaped filters such as harmless $ne/comparison probes. Evidence should be result-count or canary-record selection differences only; do not dump real tables or stored datasource credentials.
  2. For Gogs, upload or submit a synthetic notebook containing a harmless data: URI marker that proves scheme acceptance or DOM insertion. Keep the marker click-only or visually inert; do not include credential-access scripts or private notebook data.
  3. Negative controls: query templates bind values as literals, operator keys are rejected or escaped, notebook URI schemes are allowlisted after final rendering, and sanitizer routes require the same repository/auth context as previews.

Adjacent GHSA-p6qx-ghxm-389h remains tracked but not promoted here because the OctoPrint suppressed-command notification XSS pattern is narrower unless paired with printer-admin workflow scope and benign UI markers.

July 21 Gitea migration, revocation, and branch-policy follow-up

Four Gitea advisories extend the Git-forge workflow beyond the analogous Gogs checks above:

Advisory Affected path Durable operator boundary
GHSA-82f7-87hm-852x / CVE-2026-57894 Gitea before 1.27.0; web/API repository migration and pull-mirror fetch Gitea validates the submitted migration URL, but Git's default http.followRedirects=initial can move clone/fetch traffic to a blocked final host and keep using it for object requests.
GHSA-w5pg-649r-p6gg / CVE-2026-58439 Gitea before 1.27.0; pull-request target changes An approval recorded as official on an unprotected target remains official after retargeting to a protected branch, so merge policy trusts stale branch-relative state.
GHSA-qf2f-qh6p-7v89 / CVE-2026-59766 Gitea before 1.27.0; /api/v1/user/starred and /api/v1/user/times Revoking repository access does not filter relationship-backed API output, leaving private repository metadata and synthetic issue titles visible to the former collaborator.
GHSA-66m4-5jjr-2rg5 / CVE-2026-58440 Gitea before 1.27.0; collaborator-created repository webhooks A webhook can remain active after its creator loses repository access, so later private repository events continue to reach the creator's callback.

Replayable Gitea lab matrix

  1. Use Gitea 1.25.4 or another affected build and 1.27.0 as the fixed control. Create one private scratch repository, public and synthetic-local Git HTTP services, an owned redirector/callback, protected and unprotected branches, and disposable owner/writer/former-collaborator accounts.
  2. Migration redirect: submit the owned public Git URL and redirect it only to the synthetic-local Git service. Capture the submitted URL, DNS/redirect chain, Git request paths, imported marker commit, and whether a pull mirror repeats the fetch. Compare git -c http.followRedirects=false, a direct blocked URL, and 1.27.0. Never point the redirect at metadata, loopback administration, or real internal repositories.
  3. PR retargeting: require one approval from a designated reviewer on the protected branch. Obtain a harmless approval from a non-designated lab reviewer while the PR targets the unprotected branch, retarget it, and record the review's official, dismissed, and stale fields plus the marker-only merge decision. Do not merge executable code or touch a production branch.
  4. Revocation residue: while the collaborator is authorized, star the private repo, log time on an issue whose title is a synthetic sentinel, and create a marker-only webhook. Revoke access, establish that direct repository access fails, then query only the two relationship endpoints and trigger one post-revocation canary issue event. Record field presence and callback receipt; do not include source, comments, credentials, or real issue bodies.
  5. Report the boundaries separately: validated migration URL -> Git follows an unvalidated final destination, approval state computed for branch A -> retarget to protected branch B -> stale approval satisfies B, access revoked -> relationship API still returns synthetic private metadata, or webhook creator revoked -> future canary event still delivered.

The relationship-endpoint issue is metadata-only; do not describe it as repository-content access. The webhook result requires that the former collaborator created the hook while authorized. Package presence alone is not proof: preserve the route, role history, branch policy, callback ownership, and fixed-version decisions.

Late July 21 Gitea forge-control boundary wave

The next reviewed-advisory wave exposed a larger set of reusable Gitea checks. Treat these as boundary families rather than 42 disconnected alerts. The adjacent Accept-Language, SSH-key, NPM, Debian, and Arch package entries are availability-only and are intentionally not promoted.

Outbound fetch and transport trust

Advisory Confirmed boundary Bounded operator proof
GHSA-2fcr-jfvc-vgg2, GHSA-2r5c-gw76-rh3w The default webhook/migration external classifier misses CGNAT and other special-use or IPv6-transition ranges; OpenID provider discovery also uses an unrestricted default client when OpenID sign-in is enabled. Send webhook, migration, and anonymous OpenID discovery requests only to owned listeners representing allowed and synthetic-special ranges. Record dialed address and whether a harmless response is retained.
GHSA-h2x6-g7q6-344v Migration validation accepts a multi-answer hostname when any answer is allowed, while Git resolves it again when cloning. Use an owned short-TTL zone returning only owned public and synthetic-local addresses; prove validation-answer vs dial-answer drift with a marker repository.
GHSA-rqhx-647v-wx32 Another migration path follows an HTTP redirect after validating only the initial URL. Reuse the earlier migration-redirect harness and compare redirect disabled, every-hop validation, and final-address validation. Do not duplicate this as a separate finding when it has the same reachable sink as GHSA-82f7-87hm-852x.
GHSA-xmj7-xj85-hfc3, GHSA-5ggr-2f2h-jmvm Operator-supplied restore archives can place an unchecked PR Head.CloneURL into git fetch, or a release DownloadURL into a helper that accepts file://. In a disposable restore environment, use an owned Git callback and a synthetic temp file. Prove only a marker fetch or marker attachment; the operator/archive-supply precondition must be explicit.
GHSA-x77v-q46j-393g With OAuth avatar updates enabled, an attacker-influenced OIDC picture URL is fetched without the forge's outbound host matcher. Use a fake IdP, owned avatar callback, and synthetic-local image listener; capture the final destination and one inert image update.
GHSA-94v3-77j7-vm48 In split-host or multi-pod HTTPS deployments, the internal API client accepts any TLS certificate and carries a static privileged internal token. Use a fake token and lab CA between disposable hook/serv and Gitea processes. Record certificate acceptance and redacted marker-header receipt; never intercept a live instance.
GHSA-f75j-4cw6-rmx4 Gitea Docker templates default REVERSE_PROXY_TRUSTED_PROXIES to *; when reverse-proxy authentication is enabled, a directly reachable container can trust caller-supplied identity headers. Compare direct vs proxy-origin requests with disposable users and a marker-only profile endpoint. This requires reverse-proxy auth to be enabled and the container port to be reachable.

Token, session, OAuth, and visibility decisions

Advisory Confirmed boundary Bounded operator proof
GHSA-683j-3ff6-hh2x A scoped PAT presented through Gitea's OAuth-style Basic syntax is classified as password Basic auth, passes the token-creation guard, and can request broader scopes. With a disposable user and narrow fake token, compare bearer, Basic-token, and password Basic methods; create only a harmless read-only canary token and delete it immediately.
GHSA-mg4f-x9v4-6h2p /login/oauth/userinfo returns identity claims for an API token whose scopes deny equivalent user REST routes. Build a route/scope matrix with synthetic identity claims and record field presence only.
GHSA-vxv2-8j6r-pcpg One OAuth client can introspect a token issued to another client and receive active/user/audience metadata. Use two fake clients and one disposable user; redact tokens and prove only cross-client metadata presence.
GHSA-vrhc-jjfc-m3m3 OAuth sign-in can reactivate an administrator-deactivated account when the auth source normally issues no refresh token. Deactivate a lab user, confirm local/direct access fails, then attempt one provider login and record account/session state. Distinguish deactivation from ProhibitLogin.
GHSA-rgv6-xp99-6mgj A stolen remember-me token can rotate successfully; later hash-mismatch detection clears only the victim cookie and leaves the attacker's rotated token valid. Use two browser profiles and a disposable account. After the mismatch, call only a marker session endpoint from both profiles and then invalidate every lab token.
GHSA-6cqf-375w-639g, GHSA-3pww-vcvm-3gmj, GHSA-cp3q-vrj2-ghhh, GHSA-7p4h-3gxq-x3h3 Repository RSS/Atom, repository home, and limited-owner repository/package routes can exceed a PAT's category or public-only confinement while ordinary RBAC still permits the user. Use one private and one limited synthetic owner/repo plus tokens that vary only scope/public-only flags. Compare feed, home, raw/content, package, and anonymous responses without collecting real commit or package data.
GHSA-xxjv-752h-3vp2 A public-only write token is checked against the public PR base but can make Gitea update a private head branch. Use public base/private head scratch repos and a marker commit; record token decision for direct private write vs PR-update route.
GHSA-8p9h-49rc-qgxj Owner/admin push options can mutate existing repository visibility/template flags outside the normal settings workflow. On a throwaway repo, push a marker commit with one documented upstream canary option and capture visibility, activity, webhook, timestamp, and team-permission state before restoring it. This is an owner/admin alternate-control-path issue, not low-privilege escalation.

Repository, Actions, LFS, and artifact authorization

Advisory Confirmed boundary Bounded operator proof
GHSA-rh79-75qm-gwjr An LFS JWT minted for a write deploy key uses the repository owner's user ID, enabling source-object checks with the owner's broader authority. Use one owner with two private repos and a deploy key scoped to only one; fetch a synthetic LFS marker from the sibling repo and retain JWT claims only in redacted form.
GHSA-7wvc-rvp7-w99x A malformed SSH LFS sub-verb falls through to AccessModeNone in production and can yield credentials for an unauthorized private repository. Use a lab SSH account and canary LFS object; compare valid upload/download, malformed sub-verb, nonexistent repo, and unauthorized repo decisions.
GHSA-2m9v-5q2g-58vq LFS object reuse treats broad source-repository accessibility as sufficient instead of requiring Code access. Give a user Issues-only access to a source repo and Code write to a target repo; attempt to associate only a known synthetic object ID.
GHSA-hg5r-vq93-9fv6 Actions Artifacts V4 signs ambiguous concatenated fields, allowing a signed URL to be rewritten across task/repository contexts. Use two canary jobs and artifact names/IDs from the upstream collision shape. Prove a marker read or staging-state change, never workflow secrets or build outputs.
GHSA-777r-4v59-6486 One approved benign fork PR can leave a durable approval record that authorizes future workflows from the same attacker/repository. Approve one inert workflow, close it, then submit a second marker-only fork PR and compare approval identity, commit, PR, and run binding.
GHSA-fj8v-hjwv-qm88 A fork-PR Actions token can read a third private repo through the collaborative-owner branch because that branch omits the fork-PR guard. Create three scratch repos and clone only a one-line private marker from the third repo; never place secrets in any workflow.
GHSA-j2w3-9c3r-g83q Starred/subscription relationship endpoints continue returning changing private-repository metadata after collaborator revocation. Extend the earlier revocation matrix to both routes and synthetic description/title changes; do not call this source-code access.
GHSA-xv9x-fj9g-vj6h Issue-dependency removal resolves the other issue by global ID without permission checks, removes the relationship, and writes a comment in an inaccessible private repo. Use public attacker and private victim issues containing marker-only text. Prove dependency/comment state changes, then restore the relationship.
GHSA-rjvx-x5h2-6px5 The API fork path checks only organization membership, unlike repository creation paths that enforce CanCreateOrgRepo. With a team explicitly denied repo creation, compare create, generate, web fork, and API fork using a disposable public source repo.

Attachments and metadata oracles

Advisory Confirmed boundary Bounded operator proof
GHSA-6c6r-5xr4-cr5m Issue/comment edits can re-link a known attachment UUID across repositories, after which download authorization follows the attacker's parent object. Use two private scratch repos and a one-line attachment marker. Show owner repo, linked parent, and download decision before/after; never guess production UUIDs.
GHSA-q9pg-jj6x-j9p6 UUID-based web attachment routes omit the draft-release check present on release API routes. Upload a harmless draft asset, obtain its UUID as the authorized writer, and request it from an unauthenticated lab profile.
GHSA-25gq-j9jx-43pg The web release-edit path renames attachments without applying the configured extension allowlist used by the API path. Rename only an inert text marker to a forbidden-looking extension, compare web/API decisions, and do not serve executable content.
GHSA-jr5x-6h83-wrxf, GHSA-p4mj-98mv-xq26, GHSA-pgqf-926r-548m Private-organization public-member checks, ?go-get=1, and global label-ID delete responses expose membership, repository existence, or label-ID existence without the expected parent visibility. Build positive/negative route matrices with synthetic names and sequential canary IDs. Report only the exact oracle; no private content or label metadata is proven.

Consolidated lab sequence

  1. Run a disposable Gitea instance with an owned DNS zone, redirector, mock IdP, Git server, artifact runner, reverse proxy, and two-user/two-organization repository fixture. Put only markers in repos, LFS, releases, attachments, feeds, OAuth claims, and Actions artifacts.
  2. Preserve four independent dimensions for every test: principal (anonymous/user/token/deploy key/job), route or protocol, parent resource, and final sink. Change one dimension at a time.
  3. For outbound fetches, capture submitted URL, validation answers, redirect chain, re-resolution, final owned address, and response-retention behavior. Never point at cloud metadata, loopback administration, cluster APIs, or real internal repositories.
  4. For token tests, record auth method, original scope/public-only flag, route category, ordinary user RBAC, returned marker fields, and any newly minted token's exact scope. Redact and revoke every token after the run.
  5. For forge objects, use two repositories whenever possible. Capture object owner, parent repository, caller permission, global ID/UUID/OID, authorization decision, and before/after state. A known object identifier is a precondition where the advisory requires one; do not brute-force it.
  6. For Actions and LFS, use marker-only workflows and blobs. Never place CI secrets, cloud credentials, source code, package tokens, or production artifacts in the fixture.
  7. Report each boundary narrowly: SSRF classifier/redirect/re-resolution, token confinement, stale session, cross-parent object authorization, workflow-approval binding, or alternate API/UI control path. Do not combine unrelated transitions into an unproven full-account or host-compromise chain.

Final July 21 Gitea authentication, visibility, and lifecycle wave

Thirteen adjacent advisories extend the consolidated fixture above. They are grouped by state transition so operators can reuse one lab instead of treating each route as a disconnected alert.

Advisory Confirmed boundary Bounded proof
GHSA-gx3v-q759-g323 / CVE-2026-20779 A web TOTP check has a read-check-write race, while Basic authentication's X-Gitea-OTP path omits the replay check; fixed in 1.26.3. Use one disposable account and one current canary code. Compare sequential reuse, two barrier-synchronized web requests, Basic-auth reuse, next-window code, and the fixed build; immediately invalidate the lab secret.
GHSA-fq2p-5p22-8g6j, GHSA-h56g-4qw7-2mxg Public-only PAT confinement is omitted on organization/permission and team route families, allowing private metadata or activity otherwise available to the user but denied to that token. Use one user who ordinarily belongs to a private canary org/team and compare full, public-only, anonymous, and fixed-build responses. This is token-scope bypass, not user-RBAC bypass.
GHSA-2wm4-vwp6-v7xc Migration release-asset/patch download and OAuth avatar helpers use unfiltered fetch/file-opening paths instead of the protected host-matching client. Migrate only marker assets from an owned forge and direct the secondary URL to an owned synthetic-local listener or temp marker file. Never use metadata, real internal services, or Gitea configuration files.
GHSA-3r5c-2xxx-h872 / CVE-2026-58511 Webhook list/detail APIs return another administrator's decrypted Authorization header rather than treating it as write-only. Set a fake fixed token on a disposable webhook as admin A; query as admin B and preserve only whether the marker is present/redacted, then delete it.
GHSA-frpw-3h2q-4jj6 / CVE-2026-57897 Organization-level Actions run/job APIs require membership but omit per-repository ACL filtering. Seed public, permitted-private, and denied-private repos with marker-only job names; compare org and per-repo routes without reading logs or artifacts.
GHSA-q423-49rw-g9mh / CVE-2026-58510 Changing a repository from public to private through the API misses the watcher cleanup used by the web path, leaving subscription metadata visible. Subscribe while public, change visibility through web and API in separate repos, and compare only synthetic repository fields after direct access is denied.
GHSA-prr9-9mp4-5gp2, GHSA-v73x-hx65-6pf4 Private organization member and label endpoints omit the organization-visibility checks applied to neighboring route families. Use synthetic member names and labels, compare outsider/member and read/write routes, and report metadata disclosure only.
GHSA-g9g6-qhrc-p3qc / CVE-2026-58422 OAuth callback handling can reactivate an administrator-disabled linked account and issue a session; fixed in 1.26.4. Disable a disposable linked account, establish local/direct denial, perform one fake-IdP login, and check only a harmless profile/session marker.
GHSA-44qc-pgvp-wx7v / CVE-2026-58419 Notification subjects and latest-comment metadata remain visible and can keep updating after private-repository access is revoked. Seed a sentinel issue/title, revoke the collaborator, add one marker comment, and compare direct repo denial with notification field presence; never collect real issue text.
GHSA-649p-mmhf-85c7 / CVE-2026-27775 A branch-specific maintainer-edit decision is cached once for a multi-ref receive-pack session and reused for later refs. Batch a marker update to the authorized PR branch with a second marker ref in a scratch repo; do not target protected production branches or executable content.
GHSA-wrf9-r3h7-7x5v / CVE-2026-24451 merge-upstream continues copying new commits into an existing fork after the parent changes from public to private. Fork while public, privatize the parent, add one sentinel commit, confirm direct denial, and synchronize only the disposable fork.

Consolidated transition matrix

  1. Start from Gitea 1.26.2 where applicable and the stated fixed version. Use disposable accounts, one fake IdP, public/private organizations, paired parent/fork repositories, an owned forge/HTTP listener, marker Actions runs, fake webhook credentials, and one synthetic TOTP seed.
  2. Capture principal, credential form/scope, route or protocol, resource state before/after, and returned marker fields independently. For visibility bugs, establish direct-resource denial before testing relationship or aggregate routes.
  3. Treat web/API, org/repo, and initial-use/later-use paths as paired controls: web vs API privatization, organization vs repository Actions, normal vs Basic TOTP, full vs public-only PAT, and direct parent read vs fork synchronization.
  4. For the multi-ref push, use only non-production marker refs and preserve the ref order plus per-ref permission decision. Stop once the unauthorized marker ref is accepted; never force-update real protected branches.
  5. Keep impact narrow. Public-only PAT findings retain the user's ordinary membership; notification/watch/fork findings depend on prior access or a prior public state; webhook secret exposure requires an administrative peer; migration fetches require the migration/import path.

Report these as one-time code -> replayed authentication, token flag -> route-family omission, migration metadata -> unfiltered secondary fetch, write-only webhook secret -> peer-admin API response, aggregate org API -> private child metadata, visibility transition -> stale relationship, disabled local account -> OAuth callback reactivation, single-branch grant -> cached multi-ref write, or public-era fork -> private-era commit synchronization. Do not combine them into an unproven account-takeover or host-compromise chain.

July 24 Budibase identity, role, metadata, and SQL follow-up

Five Budibase advisories add a reusable tenant-control matrix:

Advisory Boundary Safe proof
GHSA-c8vc-7pv3-g98p POST /api/v2/email checks the caller's currentEmail but does not bind body accountId to the session, so mailbox verification can update another known account Use two disposable accounts and an attacker-owned mailbox; stop after the victim account's synthetic email changes, restore it, and do not reset a production password. The victim UUID is an out-of-band precondition, not normally enumerable through the documented API surface.
GHSA-j9fc-w3mr-x6mv an app-scoped builder can self-issue an API key and pass an uncontrolled target app in appBuilder or role to /api/public/v1/roles/assign Use app A/app B and marker-only roles; prove only that an A-scoped builder gains a reversible B canary grant.
GHSA-fcrw-f7gg-6g9f POWER-readable user metadata returns stored SSO oauth2 fields Seed fake OAuth marker values, preserve only field presence/hash, and compare list/single-user routes. Version 3.39.25 is the fixed control.
GHSA-4qcj-m5wp-jmf4 GET /api/global/groups omits the builder/admin middleware used by sibling group routes Compare BASIC, builder, and admin against synthetic group names, memberships, and app-role mappings; report authorization-topology disclosure only.
GHSA-q6x4-v3qx-85qw the MySQL datasource enables multipleStatements, amplifying a reachable concatenation flaw into stacked SQL statements Instrument a disposable database and use a second harmless SELECT that returns a canary row. multipleStatements: true alone is not SQL injection: identify the exact user-controlled field and query-construction path before reporting.

Run the identity and role cases as a two-user/two-app decision table. Capture caller account, session-bound account, body target, app header, current role, requested grant, response, and before/after server state. Keep fake OAuth values out of screenshots and revoke every lab key.

For SQL validation, grant the datasource user access only to a scratch schema. Start with a quote/error probe, then a boolean result-count differential, and use a stacked canary SELECT only if the exact route concatenates untrusted input. Never use DROP, DELETE, GRANT, file-write functions, sleep-heavy payloads, or production datasource credentials.

Late July 24 Budibase datasource, identity, and automation wave

The next Budibase wave belongs in the same two-user/two-app fixture:

Advisories Confirmed boundary Bounded proof
GHSA-hfhx-w8p8-4hc7, GHSA-v42f-v8xc-j435, GHSA-xg5g-26x8-cvf4 AI table attachment URLs use a bare fetch; REST/OpenAPI datasource DNS pinning is lost or omitted across fetch paths, allowing a later re-resolution through the active dispatcher Use an owned callback plus owned short-TTL DNS that switches only between tester-controlled public and synthetic-local listeners. Capture validation answer vs dial address; never use metadata or real internal services.
GHSA-pmpg-2mxq-6xwr, GHSA-qw6m-8fw2-2v64 Handlebars interpolation with escaping disabled changes JSON structure before MongoDB driver calls, letting ordinary query parameters become operators Seed two users' canary documents in a scratch collection. Compare a literal baseline with one harmless result-set operator and preserve only marker IDs/counts. Do not run $where, update/delete, or collection-dump payloads.
GHSA-2xgg-r2wc-c5r2 MySQL introspection wraps database-controlled table names in unescaped backticks while multipleStatements is enabled Create one oddly named table in a scratch schema and instrument final SQL. If execution is approved, append only a second canary SELECT; never use destructive statements.
GHSA-pvcr-8mvp-w8qr chat-link confirmation token and victim session are not bound with CSRF protection, allowing an attacker-owned chat identity to become the logged-in lab user's identity Use attacker/victim lab profiles and a fake chat tenant. Prove only the resulting synthetic mapping, then remove it; do not invoke agent tools as the victim.
GHSA-hp6v-6jw7-gv2f OIDC fallback links by email without requiring email_verified=true after a subject miss Use a fake IdP, owned aliases, and disposable users. Compare verified/unverified email claims and preserve only account IDs/roles from canary accounts.
GHSA-gh4h-34gr-87r7 automation test results include the initiating SSO user's OAuth fields and are broadcast/cached at app scope rather than user scope Seed fake token markers, run a test as builder A, and query/listen as builder B. Record only marker hashes and field presence, never real OAuth tokens.
GHSA-mqhr-6j6h-74p5 an absolute query path can move a REST request off the datasource origin after stored auth headers are attached, including for a PUBLIC query Use a disposable datasource with a fake fixed token and an owned alternate origin. Prove only redacted marker-header receipt.
GHSA-xcx6-4f2g-hhgx, GHSA-ppr4-5f46-j9c6 BASIC users can obtain S3 upload URLs for caller-selected buckets; builder-controlled MongoDB TLS file options become server-side filesystem reads/oracles Use a disposable bucket and temp certificate canary. Do not write public executable objects or probe host/config/credential paths.

Preserve each precondition independently: AI enabled, datasource type, BASIC/builder role, public-query publication, same-app co-builder, configured trusted IdP, or known datasource ID. Do not collapse the wave into a generic “Budibase compromise.” Strong reports name the exact transition: parameter string to MongoDB object, validated DNS answer to independently resolved dial, datasource credential to alternate authority, app-wide test channel to another builder, or identity claim/handoff to the wrong local user.

August 27 attachment signed-URL datasource-credential minting follow-up

GHSA-6x9p-4r67-5gjx / CVE-2026-54356 (@budibase/server ≤ 3.38.1) extends the existing "BASIC users can obtain S3 upload URLs for caller-selected buckets" boundary with a sharper transition: a low-privilege published-app BASIC user can mint S3 pre-signed PUT URLs for attacker-chosen bucket/key using the workspace datasource's stored server-side credentials.

  • Endpoint: POST /api/attachments/:datasourceId/url
  • Caller controls: bucket, key
  • Returns: signedUrl, publicUrl

Because the signature is produced from the datasource's server-side S3 credentials, the minted URL writes to the attacker-chosen object destination under that credential's access — the workspace's S3 identity, not the caller's. This is the "datasource credential to alternate authority" transition in its clearest form: the endpoint hands a bearer-capable URL to a role that should not control object destinations.

Check

  1. Lab: Budibase with an S3 datasource holding valid (lab) credentials. Two roles: an admin who creates/publishes the app and a BASIC published-app user.
  2. As the BASIC user, POST /api/attachments/<datasourceId>/url with a bucket/key naming a disposable bucket/key the tester controls. Secure result: destination confined to the app's attachment prefix or the request is rejected. Vulnerable result: a signedUrl that PUTs the canary to the attacker-chosen key.
  3. Prove only with a marker object in a disposable bucket. Do not write public executable objects, do not target host/config/credential paths, and do not exfiltrate via publicUrl of real data.

Report it as BASIC published-app role -> POST /api/attachments/:datasourceId/url -> caller-chosen bucket/key -> datasource-credential S3 signed PUT, distinct from the earlier caller-selected-bucket finding and from the REST-URL re-resolution findings.