Skip to content

Commit fb76520

Browse files
committed
feat: US-182 - Add bcryptjs project-matrix fixture
1 parent 88173ca commit fb76520

8 files changed

Lines changed: 73 additions & 10 deletions

File tree

docs/nodejs-compatibility.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ The [project-matrix test suite](https://github.com/rivet-dev/secure-exec/tree/ma
7979
| [drizzle-orm](https://npmjs.com/package/drizzle-orm) | Database | ORM schema definition, query building, ESM module graph |
8080
| [ws](https://npmjs.com/package/ws) | Networking | WebSocket client/server, HTTP upgrade, events |
8181
| [jsonwebtoken](https://npmjs.com/package/jsonwebtoken) | Crypto | JWT signing (HS256), verification, decode |
82+
| [bcryptjs](https://npmjs.com/package/bcryptjs) | Crypto | Pure JS password hashing and verification |
8283
| [zod](https://npmjs.com/package/zod) | Validation | Schema definition, parsing, safe parse, transforms |
8384
| [rivetkit](https://npmjs.com/package/rivetkit) | SDK | Local vendor package resolution |
8485
| crypto (builtin) | Crypto | `crypto.randomBytes`, `randomUUID`, `getRandomValues` |

packages/secure-exec-core/isolate-runtime/src/inject/apply-timing-mitigation-freeze.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ const __frozenTimeMs =
99
: Date.now();
1010
const __frozenDateNow = () => __frozenTimeMs;
1111

12-
// Freeze Date.now — non-configurable + non-writable prevents sandbox override
12+
// Freeze Date.now — getter always returns frozen fn, setter silently ignores
1313
try {
1414
Object.defineProperty(Date, "now", {
15-
value: __frozenDateNow,
15+
get: () => __frozenDateNow,
16+
set: () => {},
1617
configurable: false,
17-
writable: false,
1818
});
1919
} catch {
2020
Date.now = __frozenDateNow;
@@ -45,11 +45,11 @@ Object.defineProperty(__FrozenDate, "prototype", {
4545
__FrozenDate.now = __frozenDateNow;
4646
__FrozenDate.parse = __OrigDate.parse;
4747
__FrozenDate.UTC = __OrigDate.UTC;
48-
// Lock Date.now on the replacement constructor too
48+
// Lock Date.now on the replacement constructor — getter/setter silently ignores writes
4949
Object.defineProperty(__FrozenDate, "now", {
50-
value: __frozenDateNow,
50+
get: () => __frozenDateNow,
51+
set: () => {},
5152
configurable: false,
52-
writable: false,
5353
});
5454
try {
5555
Object.defineProperty(globalThis, "Date", {

packages/secure-exec-core/src/generated/isolate-runtime.ts

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"entry": "src/index.js",
3+
"expectation": "pass"
4+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"name": "project-matrix-bcryptjs-pass",
3+
"private": true,
4+
"type": "commonjs",
5+
"dependencies": {
6+
"bcryptjs": "2.4.3"
7+
}
8+
}

packages/secure-exec/tests/projects/bcryptjs-pass/pnpm-lock.yaml

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"use strict";
2+
3+
const bcrypt = require("bcryptjs");
4+
5+
// Hash a password with explicit salt rounds
6+
const password = "testPassword123";
7+
const salt = bcrypt.genSaltSync(4);
8+
const hash = bcrypt.hashSync(password, salt);
9+
10+
// Verify correct password
11+
const correctMatch = bcrypt.compareSync(password, hash);
12+
13+
// Verify wrong password
14+
const wrongMatch = bcrypt.compareSync("wrongPassword", hash);
15+
16+
// Hash format validation
17+
const isValidHash = hash.startsWith("$2a$04$") && hash.length === 60;
18+
19+
const result = {
20+
hashLength: hash.length,
21+
correctMatch,
22+
wrongMatch,
23+
isValidHash,
24+
};
25+
26+
console.log(JSON.stringify(result));

packages/secure-exec/tests/runtime-driver/node/index.test.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,7 +1183,9 @@ describe("NodeRuntime", () => {
11831183
it("Date.now cannot be overridden by sandbox code", async () => {
11841184
proc = createTestNodeRuntime();
11851185
const result = await proc.run(`
1186-
// Strict mode makes assignment to non-writable throw TypeError
1186+
const frozenBefore = Date.now();
1187+
1188+
// Assignment is silently ignored (setter is a no-op for Node.js compat)
11871189
let assignThrew = false;
11881190
try {
11891191
(function() { 'use strict'; Date.now = () => 999; })();
@@ -1204,11 +1206,11 @@ describe("NodeRuntime", () => {
12041206
module.exports = {
12051207
assignThrew,
12061208
defineThrew,
1207-
stillFrozen: Date.now() === Date.now(),
1209+
stillFrozen: Date.now() === frozenBefore,
12081210
};
12091211
`);
12101212
expect(result.exports).toEqual({
1211-
assignThrew: true,
1213+
assignThrew: false,
12121214
defineThrew: true,
12131215
stillFrozen: true,
12141216
});

0 commit comments

Comments
 (0)