CVE-2023-34093 (JavaScript, published 2023-07-25T15:15Z)
Description: value: Strapi is an open-source headless content management system. Prior to version 4.10.8, anyone (Strapi developers, users, plugins) can make every attribute of a Content-Type public without knowing it. The vulnerability only affects the handling of content types by Strapi, not the actual content types themselves. Users can use plugins or modify their own content types without realizing that the `privateAttributes` getter is being removed, which can result in any attribute becoming public. This can lead to sensitive information being exposed or the entire system being taken control of by an attacker(having access to password hashes). Anyone can be impacted, depending on how people are using/extending content-types. If the users are mutating the content-type, they will not be affected. Version 4.10.8 contains a patch for this issue.
Severity: nan (CVSS v3 base score: 7.1)
Weakness: CWE-200 \u2014 Exposure of Sensitive Information to an Unauthorized Actor
The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
Repository: https://github.com/strapi/strapi
Files changed:
api-tests/core/database/transactions.test.api.js
packages/core/admin/server/services/__tests__/permissions-manager.test.js
packages/core/strapi/lib/core/domain/content-type/index.js
packages/core/strapi/lib/services/entity-service/__tests__/entity-service-events.test.js
packages/core/strapi/lib/services/entity-service/__tests__/entity-service.test.js
packages/core/strapi/lib/services/entity-validator/__tests__/biginteger-validators.test.js
packages/core/strapi/lib/services/entity-validator/__tests__/date-validators.test.js
packages/core/strapi/lib/services/entity-validator/__tests__/datetime-validators.test.js
packages/core/strapi/lib/services/entity-validator/__tests__/float-validators.test.js
packages/core/strapi/lib/services/entity-validator/__tests__/integer-validators.test.js
packages/core/strapi/lib/services/entity-validator/__tests__/string-validators.test.js
packages/core/strapi/lib/services/entity-validator/__tests__/time-validators.test.js
packages/core/strapi/lib/services/entity-validator/__tests__/timestamp-validators.test.js
packages/core/strapi/lib/services/entity-validator/__tests__/uid-validators.test.js
packages/core/utils/lib/__tests__/content-types.test.js
packages/core/utils/lib/content-types.js
packages/core/utils/lib/sanitize/visitors/remove-private.js
Commit message: fix(content-types): remove getter for private attributes

+ Fixes a flaky test (transactions.test.api.js)


Vulnerable code:
      expect(end[0].key).toEqual('strapi_content_types_schema');
      expect(end[0].key).toEqual('strapi_content_types_schema');
          privateAttributes: [],
const { hasDraftAndPublish, getPrivateAttributes } = require('@strapi/utils').contentTypes;
  Object.defineProperty(schema, 'privateAttributes', {
    get() {
      return getPrivateAttributes(schema);
    },
  });

      privateAttributes: [],
          return { kind: 'singleType', privateAttributes: [] };
          privateAttributes: [],
          privateAttributes: [],
      privateAttributes: [],
      privateAttributes: [],
      privateAttributes: [],
      privateAttributes: [],
      privateAttributes: [],
      privateAttributes: [],
      privateAttributes: [],
      privateAttributes: [],
    privateAttributes: [],
      Object.assign(model, { privateAttributes: getPrivateAttributes(model) });
      Object.assign(model, { privateAttributes: getPrivateAttributes(model) });
      Object.assign(model, { privateAttributes: getPrivateAttributes(model) });
const { has } = require('lodash/fp');
    strapi.config.get('api.responses.privateAttributes', []),
    _.get(model, 'options.privateAttributes', []),
  return model?.privateAttributes?.includes(attributeName) ?? false;
  const isPrivate = isPrivateAttribute(schema, key) || attribute.private === true;

Fixed code:
      expect(end[0].key).toEqual(original[0].key);
      expect(end[0].key).toEqual(original[0].key);
const { hasDraftAndPublish } = require('@strapi/utils').contentTypes;
          return { kind: 'singleType' };
const { getOr, has, union } = require('lodash/fp');
const getStoredPrivateAttributes = (model) => union(
  strapi?.config?.get('api.responses.privateAttributes', []) ?? [],
  getOr([], 'options.privateAttributes', model)
);

    getStoredPrivateAttributes(model),
  if (model?.attributes?.[attributeName]?.private === true) {
    return true;
  }
  return getStoredPrivateAttributes(model).includes(attributeName);
  const isPrivate = attribute.private === true || isPrivateAttribute(schema, key);