Skip to content

Commit b8d8902

Browse files
authored
fix: field with read-deny can be used to filter due to a prisma bug (#1728)
1 parent 64198a3 commit b8d8902

File tree

2 files changed

+42
-6
lines changed

2 files changed

+42
-6
lines changed

packages/runtime/src/enhancements/node/policy/policy-utils.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -608,13 +608,13 @@ export class PolicyUtil extends QueryUtils {
608608
// to-one: direct-conditions/is/isNot
609609
// regular fields
610610
const mergedGuard = this.buildReadGuardForFields(db, model, args.where, {});
611-
this.mergeWhereClause(args.where, mergedGuard);
611+
args.where = this.mergeWhereClause(args.where, mergedGuard);
612612
}
613613

614614
if (args.where) {
615615
if (injected.where && Object.keys(injected.where).length > 0) {
616616
// merge injected guard with the user-provided where clause
617-
this.mergeWhereClause(args.where, injected.where);
617+
args.where = this.mergeWhereClause(args.where, injected.where);
618618
}
619619
} else if (injected.where) {
620620
// no user-provided where clause, use the injected one
@@ -630,7 +630,7 @@ export class PolicyUtil extends QueryUtils {
630630
if (!args.where) {
631631
args.where = this.and(...hoistedConditions);
632632
} else {
633-
this.mergeWhereClause(args.where, this.and(...hoistedConditions));
633+
args.where = this.mergeWhereClause(args.where, this.and(...hoistedConditions));
634634
}
635635
}
636636

@@ -1552,7 +1552,11 @@ export class PolicyUtil extends QueryUtils {
15521552
}
15531553

15541554
if (this.isTrue(extra)) {
1555-
return;
1555+
return where;
1556+
}
1557+
1558+
if (this.isFalse(extra)) {
1559+
return this.makeFalse();
15561560
}
15571561

15581562
// instead of simply wrapping with AND, we preserve the structure
@@ -1565,10 +1569,10 @@ export class PolicyUtil extends QueryUtils {
15651569
const combined: any = this.and(...conditions);
15661570

15671571
// make sure the merging always goes under AND
1568-
where.AND = combined.AND ?? combined;
1572+
return { ...where, AND: combined.AND ?? combined };
15691573
} else {
15701574
// insert an AND clause
1571-
where.AND = [extra];
1575+
return { ...where, AND: [extra] };
15721576
}
15731577
}
15741578

tests/integration/tests/enhancements/with-password/with-password.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,36 @@ describe('Password test', () => {
9393
})
9494
).toBeRejectedByPolicy(['must start with "abc" at "password"']);
9595
});
96+
97+
it('prevents query enumeration if password is not readable', async () => {
98+
const { prisma, enhance } = await loadSchema(
99+
`
100+
model User {
101+
id Int @id @default(autoincrement())
102+
email String @unique
103+
password String @password @omit @deny('read', true)
104+
@@allow('all', true)
105+
}
106+
`
107+
);
108+
109+
const db = enhance();
110+
111+
const user = await db.user.create({
112+
data: {
113+
114+
password: '123456',
115+
},
116+
});
117+
expect(user.password).toBeUndefined();
118+
119+
const u = await prisma.user.findFirstOrThrow();
120+
121+
await expect(db.user.findFirst({ where: { password: u.password } })).toResolveNull();
122+
await expect(
123+
db.user.findFirst({
124+
where: { password: { startsWith: u?.password.substring(0, 3) } },
125+
})
126+
).toResolveNull();
127+
});
96128
});

0 commit comments

Comments
 (0)