Skip to content

Commit

Permalink
Merge pull request #270 from betwixt-labs/ts-proto-pollution
Browse files Browse the repository at this point in the history
feat: prevent Javascript prototype pollution
  • Loading branch information
andrewmd5 authored Jun 22, 2023
2 parents 843a831 + 12d58eb commit 761f89f
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 6 deletions.
4 changes: 2 additions & 2 deletions .env
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VERSION="2.8.1"
VERSION="2.8.2"
MAJOR=2
MINOR=8
PATCH=1
PATCH=2
2 changes: 1 addition & 1 deletion Core/Meta/BebopSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ public List<SpanException> Validate()
{
errors.Add(new MultipleDefinitionsException(definition));
}
if (ReservedWords.Identifiers.Contains(definition.Name))
if (ReservedWords.Identifiers.Contains(definition.Name, StringComparer.OrdinalIgnoreCase))
{
errors.Add(new ReservedIdentifierException(definition.Name, definition.Span));
}
Expand Down
5 changes: 4 additions & 1 deletion Core/Meta/WellKnownTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ public static class ReservedWords
"BebopMirror",
"BebopConstants",
"BopConstants",
"Service"
"Service",
"prototype",
"constructor",
"__proto__"
};
}

Expand Down
5 changes: 5 additions & 0 deletions Laboratory/Schemas/ShouldFail/reserved.bop
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
struct BebopRecord {
string prototype;
string constructor;
string __proto__;
}
15 changes: 14 additions & 1 deletion Runtime/TypeScript/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { BebopTypeGuard, BebopRuntimeError, BebopJson, GuidMap, Guid } from "./index";
import {
BebopTypeGuard,
BebopRuntimeError,
BebopJson,
GuidMap,
Guid,
} from "./index";

import { describe, expect, it } from "vitest";

Expand Down Expand Up @@ -73,6 +79,13 @@ describe("BebopJson", () => {
expect(() => BebopJson.ensureKeysExist(["a.b.c", "e"], obj)).toThrow();
});
});

describe("security checks", () => {
it("should not be vulnerable to prototype pollution", () => {
const json = '{"user":{"__proto__":{"admin": true}}}';
expect(() => JSON.parse(json, BebopJson.reviver)).toThrow(BebopRuntimeError);
});
});
});

describe("BebopTypeGuard", () => {
Expand Down
3 changes: 2 additions & 1 deletion Runtime/TypeScript/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -809,8 +809,8 @@ const replacer = (_key: string, value: any): any => {
* @returns The modified value for the property, or the original value if not a marked type.
*/
const reviver = (_key: string, value: any): any => {
if (_key === "__proto__" || _key === "prototype" || _key === "constructor") throw new BebopRuntimeError("potential prototype pollution");
if (_key === "") return value;

if (value && typeof value === "object") {
if (value[typeMarker]) {
switch (value[typeMarker]) {
Expand Down Expand Up @@ -846,6 +846,7 @@ const reviver = (_key: string, value: any): any => {
}
} else {
for (let k in value) {
if (k === "__proto__" || k === "prototype" || k === "constructor") throw new BebopRuntimeError("potential prototype pollution");
const v = value[k];
if (!isPrimitive(v)) {
value[k] =reviver(k, v);
Expand Down

0 comments on commit 761f89f

Please sign in to comment.