Skip to content

Update dependency @payloadcms/next to v3.78.0 [SECURITY]#62

Open
renovate[bot] wants to merge 1 commit intomainfrom
renovate/npm-payloadcms-next-vulnerability
Open

Update dependency @payloadcms/next to v3.78.0 [SECURITY]#62
renovate[bot] wants to merge 1 commit intomainfrom
renovate/npm-payloadcms-next-vulnerability

Conversation

@renovate
Copy link
Copy Markdown
Contributor

@renovate renovate bot commented Aug 31, 2025

ℹ️ Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Change Age Confidence
@payloadcms/next (source) 3.34.03.78.0 age confidence

Warning

Some dependencies could not be looked up. Check the Dependency Dashboard for more information.

GitHub Vulnerability Alerts

CVE-2025-4643

Payload uses JSON Web Tokens (JWT) for authentication. After log out JWT is not invalidated, which allows an attacker who has stolen or intercepted token to freely reuse it until expiration date (which is by default set to 2 hours, but can be changed).

This issue has been fixed in version 3.44.0 of Payload.

CVE-2025-4644

A Session Fixation vulnerability existed in Payload's SQLite adapter due to identifier reuse during account creation. A malicious attacker could create a new account, save its JSON Web Token (JWT), and then delete the account, which did not invalidate the JWT. As a result, the next newly created user would receive the same identifier, allowing the attacker to reuse the JWT to authenticate and perform actions as that user.

This issue has been fixed in version 3.44.0 of Payload.

CVE-2026-34748

Impact

A stored Cross-site Scripting (XSS) vulnerability existed in the admin panel. An authenticated user with write access to a collection could save content that, when viewed by another user, would execute in their browser.

Consumers are affected if ALL of these are true:

  • Payload version < v3.78.0
  • At least one collection with versions enabled
  • An authenticated user has create or update access to that collection

Patches

This vulnerability has been patched in v3.78.0. Output encoding has been added to prevent user-supplied content from being interpreted as markup.

Users should upgrade to v3.78.0 or later.

Workarounds

If consumers cannot upgrade immediately:

  • Restrict create and update access to versioned collections to trusted roles only.

Release Notes

payloadcms/payload (@​payloadcms/next)

v3.78.0

Compare Source

🚀 Features

Feature Details

TypeScript Plugin for Component Paths - New @payloadcms/typescript-plugin validates PayloadComponent import paths directly in your IDE. It checks that referenced files and exports exist, provides autocomplete for file paths and export names, supports go-to-definition on component path strings, and understands all Payload path conventions including absolute paths, relative paths, tsconfig aliases, and package imports. #​15779

screenshot.2026-02-26.at.15.55.40.mp4
pnpm add -D @&#8203;payloadcms/typescript-plugin
{
  "compilerOptions": {
    "plugins": [{ "name": "next" }, { "name": "@&#8203;payloadcms/typescript-plugin" }]
  }
}

Trash Out of Beta with Granular Delete Access - Trash is now a stable feature. Delete access control can now distinguish between trashing and permanently deleting — allowing you to permit users to soft-delete documents while restricting permanent deletion to admins. When data.deletedAt is being set, the operation is a trash; otherwise it's a permanent delete. #​15210

import type { CollectionConfig } from 'payload'

export const Posts: CollectionConfig = {
  slug: 'posts',
  trash: true,
  access: {
    delete: ({ req: { user }, data }) => {
      // Not logged in - no access
      if (!user) {
        return false
      }

      // Admins can do anything (trash or permanently delete)
      if (user.roles?.includes('admin')) {
        return true
      }

      // Regular users: check what operation they're attempting
      // If data.deletedAt is being set, it's a trash operation - allow it
      if (data?.deletedAt) {
        return true
      }

      // Otherwise it's a permanent delete - deny for non-admins
      return false
    },
  },
  fields: [
    // ...
  ],
}

Widget Fields (next, ui) - Dashboard widgets can now declare configurable fields, similar to Blocks. Widget data is editable from a new drawer UI when in dashboard editing mode. Full type generation is included — WidgetInstance<T> is generic with typed data and width, and WidgetServerProps is generic so widget components receive typed widgetData. #​15700

Screen.Recording.2026-02-23.at.16.25.40.mov
import { buildConfig } from 'payload'

export default buildConfig({
  admin: {
    dashboard: {
      widgets: [
        {
          slug: 'sales-summary',
          ComponentPath: './components/SalesSummary.tsx#default',
          fields: [
            { name: 'title', type: 'text' },
            {
              name: 'timeframe',
              type: 'select',
              options: ['daily', 'weekly', 'monthly', 'yearly'],
            },
            { name: 'showTrend', type: 'checkbox' },
          ],
          minWidth: 'small',
          maxWidth: 'medium',
        },
      ],
    },
  },
})
import type { WidgetServerProps } from 'payload'

import type { SalesSummaryWidget } from '../payload-types'

export default async function SalesSummaryWidgetComponent({
  widgetData,
}: WidgetServerProps<SalesSummaryWidget>) {
  const title = widgetData?.title ?? 'Sales Summary'
  const timeframe = widgetData?.timeframe ?? 'monthly'

  return (
    <div className="card">
      <h3>
        {title} ({timeframe})
      </h3>
    </div>
  )
}

MCP Plugin Out of Beta (plugin-mcp) - @payloadcms/plugin-mcp is now stable and ready for production use. #​15711

Virtual Field Filtering in MCP (plugin-mcp) - Virtual fields (virtual: true) are now automatically stripped from MCP tool input schemas and filtered from parsed data before create, update, and updateGlobal operations. This prevents non-stored fields from appearing as accepted MCP parameters. #​15680

Markdown Transformer for Upload Nodes (richtext-lexical) - Upload nodes are now properly converted when using convertLexicalToMarkdown. Previously, upload nodes were silently dropped during markdown conversion. Now populated image uploads output ![alt text](/uploads/image.jpg), non-image uploads output link syntax, and non-populated uploads output a reference placeholder so data is never lost. #​15630

Dashed Button Style (ui) - Adds a new dashed button style variant. Also replaces box-shadow with border on all buttons and fixes icon-only button padding. #​15728

Button styles overview

Editable Query Presets from Form View (ui) - Query presets can now be created and edited directly from the document form view using a full WhereBuilder, column picker, and groupBy selector — no longer requiring the list view to build queries first. #​15657

Screen.Recording.2026-02-17.at.18.15.34.mov

🐛 Bug Fixes
  • getFieldsToSign crashes when user missing group/tab fields (#​15775) (9f0c101)
  • improve mobile touch support for dnd (#​15771) (418bb92)
  • prevent silent data overwrites on concurrent edits (#​15749) (7a3f43f)
  • preserve block metadata in mergeLocalizedData and filterDataToSelectedLocales (#​15715) (6557292)
  • return 400 for malformed JSON request bodies (#​15706) (4861fa1)
  • globals not updating updatedAt when saving drafts (#​15764) (df17cb1)
  • return early if pasteURL is not defined (#​15748) (23d52a0)
  • prevent req.file leak between sequential duplicate() calls on upload collections (#​15620) (2baea2e)
  • sanitize filenames in storage adapters (#​15746) (45bd2f1)
  • throw error for unknown query operators (#​15739) (08226db)
  • preserve locale data in unnamed groups with localizeStatus (#​15658) (38b8c68)
  • next: conditionally query snapshot field based on localization (#​15693) (d5706ee)
  • plugin-import-export: update docs on jobs and basic usage as well as visibility (#​15695) (a40210c)
  • plugin-mcp: use inline block schemas in JSON output (#​15675) (a66e844)
  • plugin-multi-tenant: hasMany tenant fields double-wrap arrays in filterOptions (#​15709) (aaddeac)
  • plugin-multi-tenant: return false instead of query when no tenants (#​15679) (f5a5bd8)
  • richtext-lexical: bump acorn to resolve type mismatch with transitive dep (#​15791) (801e851)
  • richtext-lexical: link markdown regex should not match similar looking image markdown (#​15713) (0a0afb0)
  • richtext-lexical: use headingLevel in danish heading label (#​15685) (ad4c0f6)
  • richtext-lexical: strip server-only properties from blocks in lexical client schema map (#​15756) (c05ace2)
  • templates: ecommerce find my order access functionality to use email (#​15736) (b317eaa)
  • ui: array field add button margin not applying consistently (#​15773) (ee298f5)
  • ui: respect custom Cell components on richText fields in list view (#​15762) (139cf3e)
  • ui: use correct translation key for collection version restore modal (#​15757) (c1892eb)
  • ui: encode HTML special characters in version diff view (#​15747) (30fee83)
  • ui: flash of border on list selection buttons (#​15735) (7f3c6c8)
🛠 Refactors
🎨 Styles
  • richtext-lexical: lists and quotes have inconsistent letter spacing (#​15682) (f2397a8)
🧪 Tests
📝 Templates
  • fix cloudflare logger error in with-cloudflare-d1 template (#​15752) (8791a72)
  • ecommerce add missing access control on collections (#​15744) (c74d91d)
  • fix ecommerce webhooks url and update docs on using stripe webhooks (#​15681) (677596c)
🏡 Chores
🤝 Contributors

v3.77.0

Compare Source

🚀 Features

Feature Details

Local API Depth Consistency - The depth option passed to Local API calls like payload.find() is now automatically set on req.query.depth. Previously, hooks relying on req.query.depth would behave differently between Local API and REST/GraphQL calls unless you manually passed req: { query: { depth: x } } in addition to depth: x. This change ensures consistent behavior across all API methods. #​15023

Custom ID Support in db.create (db-*) - New customID argument on payload.db.create allows creating documents with a specific ID without requiring a custom ID field in your collection schema. #​15653

payload.db.create({ collection: 'posts', customID: 'ce98d6c4-c3ab-45de-9dfc-bf33d94cc941', data: { } })

MCP Plugin Migration (plugin-mcp) - Migrates from the deprecated @vercel/mcp-adapter to mcp-handler and bumps @modelcontextprotocol/sdk to 1.25.2 addressing a security vulnerability. Exposes new handler options: disableSse, onEvent, and redisUrl. #​15661

import { mcpPlugin } from '@&#8203;payloadcms/plugin-mcp'

export default buildConfig({
  plugins: [
    mcpPlugin({
      // Optional: Enable SSE transport (disabled by default)
      disableSse: false,
      // Optional: Redis URL for SSE session management (defaults to REDIS_URL env)
      redisUrl: 'redis://localhost:6379',
      // Optional: Track MCP events for analytics/debugging
      onEvent: (event) => {
        console.log('MCP event:', event)
      },
    }),
  ],
})

🐛 Bug Fixes
  • hasMany text fields cannot be filtered with contains operator (#​15671) (4513a05)
  • use consistent empty state styling between list and folder views (#​15555) (8953b37)
  • populate previousValue correctly in afterChange hooks for nested lexical fields (#​15623) (1cc3bb9)
  • add i18n support for dashboard edit mode buttons (#​15564) (818e31d)
  • next: handle undefined fieldTab in version diff tabs (#​15590) (bbacab8)
  • plugin-cloud-storage: ensure file data persists across operations (#​15570) (6af3673)
  • plugin-cloud-storage: generateFileURL only ran when disablePayloadAccessControl was true (#​15667) (6c5611c)
  • plugin-import-export: remove deprecated import (#​15666) (733b1df)
  • plugin-import-export: export and import issues when using custom IDs (#​15518) (7e2a3ab)
  • plugin-import-export: columns being duplicated when using toCSV hook (#​15597) (28e07dc)
  • plugin-mcp: resolve union type fields failing in update tool (#​15660) (9ae89dd)
  • plugin-multi-tenant: improve translation for "Tenant" (use "Mandant" instead of "Mieter") (#​15537) (4d4033b)
  • plugin-multi-tenant: tenant selector not appearing after login (#​15617) (dd09f67)
  • storage-r2: build error due to types issue in R2 Bucket type (#​15670) (7d1e233)
  • ui: fix broken polymorphic join edit drawer (#​15621) (d450e99)
📚 Documentation
🧪 Tests
🏡 Chores
🤝 Contributors

v3.76.1

Compare Source

🐛 Bug Fixes
  • use optional chaining for adminThumbnail size lookup to prevent crash (#​15586) (6937eec)
  • non-image files should not recieve 0 bytes with useTempFiles (#​15538) (a313627)
  • add CSP headers to SVG uploads to prevent XSS (#​15506) (8283c25)
  • richtext-lexical: link tooltip overflows outside viewport with long URLs (#​15584) (af6b1a1)
  • ui: prevent Tabs field crash when stored tabIndex exceeds tab count (#​15588) (a9e296e)
  • ui: copy to locale function swallowing errors (#​15562) (8ce62d8)
  • ui: ensure unpublish button only shows when drafts are enabled (#​15459) (69dc5e6)
⚙️ CI

v3.76.0

Compare Source

🚀 Features
  • plugin-import-export: adds new exportLimit, importLimit and per collection limit control (#​15405) (a7beeca)
🐛 Bug Fixes
  • drizzle: use dynamic import for typescript to avoid dependency in production (#​15545) (98a756c)
  • live-preview-vue: update build config to compile as esm (#​14293) (60c65ed)
  • next: drop support for Next.js versions with known CVEs, add canary 16.2.0 support (#​15547) (2b3061a)
  • next: suppress webpack "Critical dependency" warning in dynamicImport (#​15534) (6158489)
  • plugin-import-export: errors when import/export files were stored in a storage adapter such as S3 (#​15441) (73a9650)
  • ui: tab error badge not counting required array validation errors (#​15563) (0ce6193)
  • ui: folder view toggle button styles overridden due to equal specificity (#​15544) (df42bec)
  • ui: remove clearData call in dropzone drop handler (#​10475) (b4e6761)
📝 Templates
⚙️ CI
🏡 Chores
  • fix deprecation warning when running reinstall or clean:all monorepo script (#​15535) (03bfaf4)
  • drizzle: add logs indicating which migration statements are generated (#​15374) (306974d)
🤝 Contributors

v3.75.0

Compare Source

🚀 Features
  • adds beforeNav and afterNav component slots (#​15493) (f23a1df)
  • next: pass full initReq context to server functions and dashboard widgets (#​15427) (ce13e97)
🐛 Bug Fixes
  • handle absolute paths correctly with tempFileDir upload option (#​14436) (5ca9bd4)
  • ungenerated image sizes should not store original URL (#​15454) (fa1cd62)
  • add safety check to redirects from external file URL uploads (#​15458) (1041bb6)
  • sass warning not hidden during webpack build (#​15442) (dec0ea7)
  • add collection property to auth documents, fixing multi tenancy access control issue (#​15404) (d6aa6cc)
  • graphql: blocks return null with select: true (#​15464) (c2baef4)
  • next: versions diff error when swapping blocks with relationship fields (#​15478) (5ba0055)
  • next: export SlugField from the client dir not rsc (#​15461) (6c07f3b)
  • next: sync modular dashboard widgets when server component re-renders (#​15439) (5495b47)
  • plugin-ecommerce: variant creation blocked by variants in trash (#​15449) (3f01682)
  • plugin-mcp: create and update resource tools now support point fields (#​15381) (a28261d)
  • ui: extra padding rendering in list view when no description exists (#​15507) (3ff6be4)
  • ui: remove slug field from rsc exports (#​15480) (8f66035)
⚡ Performance
  • next: avoid re-calculating permissions in some server functions, pass missing args (#​15428) (9c8be5c)
📚 Documentation
🎨 Styles
🧪 Tests
⚙️ CI
🏡 Chores
🤝 Contributors

v3.74.0

Compare Source

🚀 Features

Override Access in Document-Level Hooks - Access the overrideAccess value inside collection and global hooks. Useful when hook logic needs to know whether access control was bypassed, such as when querying related documents up a hierarchy. #​15421

export const Posts: CollectionConfig = {
  slug: 'posts',
  hooks: {
    beforeChange: [
      ({ overrideAccess, req }) => {
        if (overrideAccess) {
          // Access control was bypassed
        }
      },
    ],
  },
}

Extended strictDraftTypes to All Operations - When strictDraftTypes: true is enabled, TypeScript now enforces draft type safety across all Local API operations (not just queries). The draft option is forbidden for collections/globals without drafts enabled, preventing silent runtime behavior where draft flags are ignored. #​15292

import { buildConfig } from 'payload'

export default buildConfig({
  typescript: {
    strictDraftTypes: true, // Enables compile-time draft enforcement
  },
  // ...
})

⚠️ Note: Generic collection slugs may require explicit type assertions when using draft options.


Custom UnpublishButton Component - Customize the UnpublishButton in collection and global configs, following the same pattern as PublishButton and SaveButton. Previously hardcoded. #​15400

export const Posts: CollectionConfig = {
  slug: 'posts',
  admin: {
    components: {
      edit: {
        UnpublishButton: '/components/CustomUnpublishButton',
      },
    },
  },
}

R2 Multipart Client Uploads (storage-r2) - Upload large files directly from the client using R2's multipart API. Files are split into smaller parts and uploaded separately, avoiding Cloudflare Worker memory limits. #​14733


Popup Prevent Close Attribute (ui) - Add interactive elements inside popups without triggering close behavior by adding the data-popup-prevent-close attribute. #​15407

<Popup>
  <button data-popup-prevent-close onClick={handleClick}>
    Click me without closing
  </button>
</Popup>

Popup Portal className (ui) - Customize the Popup component's portal container with the new portalClassName prop. #​15406

<Popup portalClassName="my-custom-portal-class">
  {/* content */}
</Popup>
🐛 Bug Fixes
  • isolate payload-preferences by auth collection (#​15425) (2dc2e7c)
  • traverseFields returning wrong parentPath dot notation for non-localised tabs (#​15394) (99b051e)
  • widgets and other features failing with transitive dependency imports (#​15392) (5561799)
  • replace deprecated scmp with crypto.timingSafeEqual (#​15322) (2511c02)
  • find afterRead hooks should behave like findByID (#​15357) (3e27155)
  • remove depth from count operation types (#​15356) (dfc1600)
  • publish button incorrectly shown after saving draft when access denied (#​15319) (e833fe6)
  • next: version view throws useLocale() server error (#​15380) (2ce26fa)
  • next: ensure query preset from url is applied (#​15323) (592f404)
  • next: ensure save preset button is not shown when there are no changes (#​15320) (e9af097)
  • plugin-cloud-storage: prevent infinite loop when cropping media (#​15393) (345a9c7)
  • plugin-cloud-storage: adds beforeChange hook to generate url on create (#​15401) (d269d39)
  • richtext-slate: localized indicator not displaying in label (#​15412) (126f713)
  • ui: use the formatAdminUrl function to generate unpublish url (#​15375) (453e8a6)
  • ui: restore default columns after clearing query preset (#​15360) (029699d)
  • ui: prevent globals crash with arrays fields when lock state user is undefined in handleDocumentLocking (#​15259) (ea76ca0)
  • ui: getEntityConfig did not respect globalSlug if collectionSlug is undefined (#​15362) (b54059c)
📚 Documentation
  • clarify beforeValidate and beforeChange hook data behavior (#​15300) (ba9605e)
  • add payload.logger.error usage guidelines to CLAUDE.md (#​15398) (cdbfda2)
  • updated redirects plugin integration docs and postgres connection troubleshooting (#​15383) (9b2221e)
  • improve select jsdocs and empty select docs (#​15336) (4181a12)
🧪 Tests
  • make integration tests for the fields and select suites faster (#​15434) (26ba779)
📝 Templates
🔨 Build
⚙️ CI
🏡 Chores

Configuration

📅 Schedule: (UTC)

  • Branch creation
    • ""
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate bot force-pushed the renovate/npm-payloadcms-next-vulnerability branch from a86fbff to 1c5fa7e Compare December 31, 2025 13:07
@renovate renovate bot force-pushed the renovate/npm-payloadcms-next-vulnerability branch from 1c5fa7e to 9baed56 Compare January 8, 2026 16:37
@renovate renovate bot force-pushed the renovate/npm-payloadcms-next-vulnerability branch from 9baed56 to 9ec7099 Compare March 5, 2026 17:41
@renovate renovate bot force-pushed the renovate/npm-payloadcms-next-vulnerability branch from 9ec7099 to e8eec04 Compare March 13, 2026 15:34
@renovate renovate bot changed the title Update dependency @payloadcms/next to v3.44.0 [SECURITY] Update dependency @payloadcms/next to v3.44.0 [SECURITY] - autoclosed Mar 27, 2026
@renovate renovate bot closed this Mar 27, 2026
@renovate renovate bot deleted the renovate/npm-payloadcms-next-vulnerability branch March 27, 2026 01:25
@renovate renovate bot changed the title Update dependency @payloadcms/next to v3.44.0 [SECURITY] - autoclosed Update dependency @payloadcms/next to v3.44.0 [SECURITY] Mar 30, 2026
@renovate renovate bot reopened this Mar 30, 2026
@renovate renovate bot force-pushed the renovate/npm-payloadcms-next-vulnerability branch 2 times, most recently from dd27272 to 5e2ccfb Compare April 1, 2026 22:51
@renovate renovate bot changed the title Update dependency @payloadcms/next to v3.44.0 [SECURITY] Update dependency @payloadcms/next to v3.78.0 [SECURITY] Apr 1, 2026
@renovate renovate bot force-pushed the renovate/npm-payloadcms-next-vulnerability branch from 5e2ccfb to 625d262 Compare April 8, 2026 17:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants