Skip to content

Commit 3c91426

Browse files
mcollinaclaude
andauthored
Fix safe handling of constructor null values (#142)
* Fix safe handling of constructor null values Add defensive null checking in scan function to prevent potential TypeError when constructor property is set to null. This addresses issue #141 where accessing constructor.prototype could fail if constructor is null. Changes: - Enhanced scan function with safe constructor value checking - Added test case for constructor null handling - Maintains existing security behavior and test coverage Fixes #141 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> Signed-off-by: Matteo Collina <[email protected]> * Fix linting issues and update CLAUDE.md - Remove trailing spaces in test file to satisfy neostandard linting - Update CLAUDE.md with current project structure and tooling: * Changed from standard to neostandard with ESLint 9 * Updated test commands and structure (test/ directory) * Added TypeScript support information * Enhanced security details about constructor.prototype handling 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> Signed-off-by: Matteo Collina <[email protected]> * Remove CLAUDE.md from tracking and update .gitignore - Remove CLAUDE.md from git tracking while keeping local copy - Add CLAUDE.md and .claude directory to .gitignore 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> Signed-off-by: Matteo Collina <[email protected]> --------- Signed-off-by: Matteo Collina <[email protected]> Co-authored-by: Claude <[email protected]>
1 parent 154751b commit 3c91426

File tree

3 files changed

+29
-0
lines changed

3 files changed

+29
-0
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,3 +153,9 @@ yarn.lock
153153

154154
**/._*
155155
**/*.pem
156+
157+
# CLAUDE.md
158+
CLAUDE.md
159+
160+
# Claude Code directory
161+
.claude

index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ function filter (obj, { protoAction = 'error', constructorAction = 'error', safe
7676

7777
if (constructorAction !== 'ignore' &&
7878
Object.prototype.hasOwnProperty.call(node, 'constructor') &&
79+
node.constructor !== null &&
80+
typeof node.constructor === 'object' &&
7981
Object.prototype.hasOwnProperty.call(node.constructor, 'prototype')) { // Avoid calling node.hasOwnProperty directly
8082
if (safe === true) {
8183
return null

test/index.test.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,27 @@ test('parse', t => {
257257
t.end()
258258
})
259259

260+
t.test('handles constructor null safely', t => {
261+
// Test that constructor: null doesn't trigger prototype pollution checks
262+
t.deepEqual(
263+
j.parse('{"constructor": null}', { constructorAction: 'remove' }),
264+
{ constructor: null }
265+
)
266+
267+
// Test that constructor: null doesn't throw error when using error action
268+
t.deepEqual(
269+
j.parse('{"constructor": null}', { constructorAction: 'error' }),
270+
{ constructor: null }
271+
)
272+
273+
// Test that constructor: null is preserved when using ignore action
274+
t.deepEqual(
275+
j.parse('{"constructor": null}', { constructorAction: 'ignore' }),
276+
{ constructor: null }
277+
)
278+
t.end()
279+
})
280+
260281
t.end()
261282
})
262283

0 commit comments

Comments
 (0)