Files
angular__angular/packages/core
arturovt 0deac976f3 fix(core): use Object.create(null) for LOCALE_DATA as a hardening measure
Prior to this commit, `LOCALE_DATA` was initialized as a plain object literal:

```typescript
let LOCALE_DATA: {[localeId: string]: any} = {};
```

While `__proto__` is neutralized by the `replace(/_/g, '-')` sanitization step (becoming `--proto--`), keys like `constructor` and `prototype` pass through unchanged and would modify special properties on `Object.prototype` if used as bracket notation keys on a plain object.

**Example attack through the public API:**

```typescript
// attacker calls the public registerLocaleData API with a crafted localeId
registerLocaleData(data, 'constructor');

// internally becomes:
LOCALE_DATA['constructor'] = data;
// → modifies Object.prototype.constructor for every object in the process

// or with extraData:
registerLocaleData(data, 'constructor', extraData);
// LOCALE_DATA['constructor'][LocaleDataIndex.ExtraData] = extraData;
// → Object.prototype[LocaleDataIndex.ExtraData] = extraData
// → every plain object in the process now has this property
// → affects JSON serialization, property enumeration, and framework internals

// consequence — any subsequent object created in the process is affected:
const user = getUserFromSession();
console.log(user[LocaleDataIndex.ExtraData]); // → attacker-controlled value
```

In a long-running SSR server this pollution persists for the lifetime of the process and affects all subsequent requests from all users.

**The fix** initializes `LOCALE_DATA` with `Object.create(null)`:

```typescript
let LOCALE_DATA: {[localeId: string]: any} = Object.create(null);
```

A null-prototype object has no prototype chain, so any key is treated as a plain string with no special behavior, making prototype pollution impossible regardless of input — without relying on the sanitization step as the sole protection.
2026-05-29 14:55:47 +02:00
..
…