Budibase/budibase · error

Invalid object store key: path traversal is not allowed.

Error message

Invalid object store key: path traversal is not allowed.

What it means

sanitizeKey normalizes object store keys and then rejects any key whose path segments contain '.' or '..', since S3-style keys are used to build filesystem/storage paths and traversal could escape the intended bucket prefix. This is a deliberate security guard against path traversal.

Source

Thrown at packages/backend-core/src/objectStore/objectStore.ts:101

  form: "multipart/form-data",
}

const STRING_CONTENT_TYPES = [
  CONTENT_TYPE_MAP.html,
  CONTENT_TYPE_MAP.css,
  CONTENT_TYPE_MAP.js,
  CONTENT_TYPE_MAP.json,
]

// does normal sanitization and then swaps dev apps to apps
export function sanitizeKey(input: string): string {
  const key = sanitize(sanitizeBucket(input)).replace(/\\/g, "/")
  if (
    key
      .split("/")
      .some((segment: string) => segment === "." || segment === "..")
  ) {
    throw new Error("Invalid object store key: path traversal is not allowed.")
  }
  return key
}

// simply handles the dev app to app conversion
export function sanitizeBucket(input: string): string {
  return input.replace(new RegExp(WORKSPACE_DEV_PREFIX, "g"), WORKSPACE_PREFIX)
}

/**
 * Gets a connection to the object store using the S3 SDK.
 * @param bucket the name of the bucket which blobs will be uploaded/retrieved from.
 * @param opts configuration for the object store.
 * @return an S3 object store object, check S3 Nodejs SDK for usage.
 * @constructor
 */
export function ObjectStore(
  opts: { presigning: boolean } = { presigning: false }

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Sanitize the filename before calling object store APIs — strip path components and use only the base name
  2. Generate your own safe key (e.g. uuid or hash-based) instead of using raw user input as the key
  3. Reject the request upstream with a validation error if it contains '.' or '..' segments
  4. Audit data sources feeding keys (imports, package names) for traversal payloads

Example fix

// before
await upload({ bucket, filename: userProvidedName }) // "../../evil"
// after
const safeName = path.posix.basename(userProvidedName).replace(/\.+/g, "_")
await upload({ bucket, filename: `${uuid()}__${safeName}` })
Defensive patterns

Strategy: validation

Validate before calling

function assertSafeKey(input) {
  const segments = input.replace(/\\/g, "/").split("/")
  if (segments.some(s => s === "." || s === "..")) {
    throw new Error("key contains path traversal segments")
  }
}

Type guard

function isSafeKey(key: string): boolean {
  return key.replace(/\\/g, "/").split("/").every(s => s !== "." && s !== "..")
}

Try / catch

try {
  await objectStore.deleteFile(bucket, key)
} catch (err) {
  if (String(err.message).startsWith("Invalid object store key")) {
    // treat as a client error: reject the request, do not retry
  }
}

Prevention

When it happens

Trigger: Calling any objectStore operation that takes a key (upload, download, delete, headDetails, clientLibraryPath, client3rdPartyLibrary) with a filename containing '../' or a '.'/'..' segment after backslash-to-slash normalization.

Common situations: User-supplied filenames containing '../' (e.g. uploads named '../../etc/passwd'); importing app data with crafted keys; Windows-style paths using backslashes that normalize into traversal; client library paths built from untrusted package names.

Related errors


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/a3c02aa646ec1795. Report an issue: GitHub.