CVE-2022-25948: Exposure of Sensitive Information to an Unauthorized Actor (CWE-200)
value: The package liquidjs before 10.0.0 are vulnerable to Information Exposure when ownPropertyOnly parameter is set to False, which results in leaking properties of a prototype. Workaround For versions 9.34.0 and higher, an option to disable this functionality is provided.
CWE description: The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
CVSS v3 base score: 5.3
Published: 2022-12-22T05:15Z
Repository: https://github.com/harttle/liquidjs
Language: TypeScript
Files changed: package-lock.json, src/context/context.ts, src/liquid-options.ts
Commit date: 2022-11-27 14:04:01 +0800
Commit message: refactor: change `ownPropertyOnly` default value to `true`

BREAKING CHANGE: `ownPropertyOnly` default value changed to `true`

Diff: diff --git a/package-lock.json b/package-lock.json
index 0013b8fe..b77955c2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2584,13 +2584,13 @@
         "map-obj": "^2.0.0",
         "quick-lru": "^1.0.0"
       }
     },
     "caniuse-lite": {
-      "version": "1.0.30001335",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001335.tgz",
-      "integrity": "sha512-ddP1Tgm7z2iIxu6QTtbZUv6HJxSaV/PZeSrWFZtbY4JZ69tOeNhBCl3HyRQgeNZKE5AOn1kpV7fhljigy0Ty3w==",
+      "version": "1.0.30001431",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz",
+      "integrity": "sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ==",
       "dev": true
     },
     "cardinal": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz",
diff --git a/src/context/context.ts b/src/context/context.ts
index 0be465e8..2b75496c 100644
--- a/src/context/context.ts
+++ b/src/context/context.ts
@@ -101,23 +101,23 @@ export class Context {
     return this.globals
   }
 }
 
 export function readProperty (obj: Scope, key: PropertyKey, ownPropertyOnly: boolean) {
-  if (isNil(obj)) return obj
   obj = toLiquid(obj)
+  if (isNil(obj)) return obj
   if (isArray(obj) && key < 0) return obj[obj.length + +key]
-  const jsProperty = readJSProperty(obj, key, ownPropertyOnly)
-  if (jsProperty === undefined && obj instanceof Drop) return obj.liquidMethodMissing(key)
-  if (isFunction(jsProperty)) return jsProperty.call(obj)
+  const value = readJSProperty(obj, key, ownPropertyOnly)
+  if (value === undefined && obj instanceof Drop) return obj.liquidMethodMissing(key)
+  if (isFunction(value)) return value.call(obj)
   if (key === 'size') return readSize(obj)
   else if (key === 'first') return readFirst(obj)
   else if (key === 'last') return readLast(obj)
-  return jsProperty
+  return value
 }
 export function readJSProperty (obj: Scope, key: PropertyKey, ownPropertyOnly: boolean) {
-  if (ownPropertyOnly && !Object.hasOwnProperty.call(obj, key)) return undefined
+  if (ownPropertyOnly && !Object.hasOwnProperty.call(obj, key) && !(obj instanceof Drop)) return undefined
   return obj[key]
 }
 
 function readFirst (obj: Scope) {
   if (isArray(obj)) return obj[0]
diff --git a/src/liquid-options.ts b/src/liquid-options.ts
index 88a16f63..1be99d6b 100644
--- a/src/liquid-options.ts
+++ b/src/liquid-options.ts
@@ -151,11 +151,11 @@ export const defaultOptions: NormalizedFullOptions = {
   outputDelimiterLeft: '{{',
   outputDelimiterRight: '}}',
   preserveTimezones: false,
   strictFilters: false,
   strictVariables: false,
-  ownPropertyOnly: false,
+  ownPropertyOnly: true,
   lenientIf: false,
   globals: {},
   keepOutputType: false,
   operators: defaultOperators
 }

Vulnerable code:       "version": "1.0.30001335",
      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001335.tgz",
      "integrity": "sha512-ddP1Tgm7z2iIxu6QTtbZUv6HJxSaV/PZeSrWFZtbY4JZ69tOeNhBCl3HyRQgeNZKE5AOn1kpV7fhljigy0Ty3w==",
  if (isNil(obj)) return obj
  const jsProperty = readJSProperty(obj, key, ownPropertyOnly)
  if (jsProperty === undefined && obj instanceof Drop) return obj.liquidMethodMissing(key)
  if (isFunction(jsProperty)) return jsProperty.call(obj)
  return jsProperty
  if (ownPropertyOnly && !Object.hasOwnProperty.call(obj, key)) return undefined
  ownPropertyOnly: false,
Fixed code:       "version": "1.0.30001431",
      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz",
      "integrity": "sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ==",
  if (isNil(obj)) return obj
  const value = readJSProperty(obj, key, ownPropertyOnly)
  if (value === undefined && obj instanceof Drop) return obj.liquidMethodMissing(key)
  if (isFunction(value)) return value.call(obj)
  return value
  if (ownPropertyOnly && !Object.hasOwnProperty.call(obj, key) && !(obj instanceof Drop)) return undefined
  ownPropertyOnly: true,