{"record":{"id":"83b79910e2ba05b9","repo":"payloadcms/payload","slug":"invalid-field-path","errorCode":null,"errorMessage":"Invalid field path.","messagePattern":"Invalid field path\\.","errorType":"validation","errorClass":"APIError","httpStatus":400,"severity":"error","filePath":"packages/plugin-import-export/src/utilities/getSelect.ts","lineNumber":24,"sourceCode":"\nconst createSelect = (): SelectIncludeType => Object.create(null) as SelectIncludeType\n\n/**\n * Takes an input of array of string paths in dot notation and returns a select object.\n * Used for both export and import to build Payload's select query format.\n *\n * @example\n * getSelect(['id', 'title', 'group.value', 'createdAt', 'updatedAt'])\n * // Returns: { id: true, title: true, group: { value: true }, createdAt: true, updatedAt: true }\n */\nexport const getSelect = (fields: string[]): SelectIncludeType => {\n  const select = createSelect()\n\n  fields.forEach((field) => {\n    const segments = field.split('.')\n\n    if (hasUnsupportedFieldPathSegment(segments)) {\n      throw new APIError('Invalid field path.', 400, null, true)\n    }\n\n    let selectRef = select\n\n    segments.forEach((segment, i) => {\n      if (i === segments.length - 1) {\n        selectRef[segment] = true\n      } else {\n        if (!Object.prototype.hasOwnProperty.call(selectRef, segment)) {\n          selectRef[segment] = createSelect()\n        }\n        selectRef = selectRef[segment] as SelectIncludeType\n      }\n    })\n  })\n\n  return select\n}","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/plugin-import-export/src/utilities/getSelect.ts#L6-L42","documentation":"getSelect builds a Payload select object from dot-notation field paths. Before traversing, it rejects any path whose segments include __proto__, constructor, or prototype (hasUnsupportedFieldPathSegment). This is a prototype-pollution guard; the 400 is intentional and security-relevant.","triggerScenarios":"A field path contains a dangerous segment, e.g. '__proto__.x', 'constructor.prototype', or a CSV/export field list sourced from untrusted input that includes such keys.","commonSituations":"Export/import field selection driven by user-supplied query params; CSV headers that happen to be '__proto__'; mapping table built from external data.","solutions":["Sanitize field paths: strip/reject __proto__, constructor, prototype before calling getSelect.","Do not pass untrusted user input directly as the fields array; allowlist field names.","Validate paths against the collection's known field names."],"exampleFix":"// before\nconst select = getSelect(userSuppliedFields)\n// after\nconst SAFE = /__proto__|constructor|prototype/\nconst safeFields = userSuppliedFields.filter((f) => !SAFE.test(f))\nconst select = getSelect(safeFields)","handlingStrategy":"validation","validationCode":"const UNSUPPORTED = new Set(['__proto__', 'constructor', 'prototype'])\nfunction sanitizeFields(fields: string[]): string[] {\n  return fields.filter((f) => !f.split('.').some((seg) => UNSUPPORTED.has(seg)))\n}\nconst select = getSelect(sanitizeFields(userFields))","typeGuard":"const isSafeFieldPath = (path: string): boolean =>\n  !path.split('.').some((seg) => UNSUPPORTED.has(seg))","tryCatchPattern":null,"preventionTips":["Never pass raw user input as the fields array; allowlist against schema field names.","Strip prototype-polluting segments at the trust boundary.","Add a unit test that getSelect rejects __proto__/constructor/prototype."],"tags":["security","prototype-pollution","validation","plugin-import-export"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}