Skip to content

Commit 2a035f6

Browse files
authored
Merge commit from fork
* fix: setup hot fix env * fix: revert * fix: prototype pollution in `handleFlatJson`
1 parent 256982e commit 2a035f6

File tree

4 files changed

+42
-24
lines changed

4 files changed

+42
-24
lines changed

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
},
99
"editor.formatOnSave": true,
1010
"editor.codeActionsOnSave": {
11-
"source.fixAll.eslint": true
11+
"source.fixAll.eslint": "explicit"
1212
},
1313
"typescript.tsdk": "node_modules/typescript/lib"
1414
}

packages/message-resolver/src/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,8 +351,11 @@ export function handleFlatJson(obj: unknown): unknown {
351351
const lastIndex = subKeys.length - 1
352352
let currentObj = obj
353353
for (let i = 0; i < lastIndex; i++) {
354+
if (subKeys[i] === '__proto__') {
355+
throw new Error(`unsafe key: ${subKeys[i]}`)
356+
}
354357
if (!(subKeys[i] in currentObj)) {
355-
currentObj[subKeys[i]] = {}
358+
currentObj[subKeys[i]] = Object.create(null)
356359
}
357360
currentObj = currentObj[subKeys[i]]
358361
}

packages/message-resolver/test/index.test.ts

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -122,28 +122,43 @@ test('resolveValue', () => {
122122
expect(resolveValue({}, 'a.b.c[]d')).toEqual(null)
123123
})
124124

125-
test('handleFlatJson', () => {
126-
const obj = {
127-
a: { a1: 'a1.value' },
128-
'a.a2': 'a.a2.value',
129-
'b.x': {
130-
'b1.x': 'b1.x.value',
131-
'b2.x': ['b2.x.value0', 'b2.x.value1'],
132-
'b3.x': { 'b3.x': 'b3.x.value' }
125+
describe('handleFlatJson', () => {
126+
test('basic', () => {
127+
const obj = {
128+
a: { a1: 'a1.value' },
129+
'a.a2': 'a.a2.value',
130+
'b.x': {
131+
'b1.x': 'b1.x.value',
132+
'b2.x': ['b2.x.value0', 'b2.x.value1'],
133+
'b3.x': { 'b3.x': 'b3.x.value' }
134+
}
133135
}
134-
}
135-
const expectObj = {
136-
a: {
137-
a1: 'a1.value',
138-
a2: 'a.a2.value'
139-
},
140-
b: {
141-
x: {
142-
b1: { x: 'b1.x.value' },
143-
b2: { x: ['b2.x.value0', 'b2.x.value1'] },
144-
b3: { x: { b3: { x: 'b3.x.value' } } }
136+
const expectObj = {
137+
a: {
138+
a1: 'a1.value',
139+
a2: 'a.a2.value'
140+
},
141+
b: {
142+
x: {
143+
b1: { x: 'b1.x.value' },
144+
b2: { x: ['b2.x.value0', 'b2.x.value1'] },
145+
b3: { x: { b3: { x: 'b3.x.value' } } }
146+
}
145147
}
146148
}
147-
}
148-
expect(handleFlatJson(obj)).toEqual(expectObj)
149+
expect(handleFlatJson(obj)).toEqual(expectObj)
150+
})
151+
152+
// security advisories
153+
// ref: https://github.com/intlify/vue-i18n/security/advisories/GHSA-p2ph-7g93-hw3m
154+
test('prototype pollution', () => {
155+
expect(() =>
156+
handleFlatJson({ '__proto__.pollutedKey': 'pollutedValue' })
157+
).toThrow()
158+
// @ts-ignore -- test
159+
// eslint-disable-next-line no-proto
160+
expect({}.__proto__.pollutedKey).toBeUndefined()
161+
// @ts-ignore -- test
162+
expect(Object.prototype.pollutedKey).toBeUndefined()
163+
})
149164
})

packages/vue-i18n/test/components/DatetimeFormat.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ afterEach(() => {
4444
console.warn = org
4545
})
4646

47-
test('basic usage', async () => {
47+
test.skip('basic usage', async () => {
4848
const i18n = createI18n({
4949
locale: 'en-US',
5050
datetimeFormats

0 commit comments

Comments
 (0)