fix(payments): verify member_id belongs to caller's space (IDOR)
logCashPayment and linkPaymentToMember accepted a uuid member_id without checking it belongs to the caller's space (the equipment/class paths were already hardened for exactly this). Look up the member scoped to the caller's space and reject a foreign id before writing. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
1aa0cd818a
commit
3243e4ce98
@@ -36,6 +36,19 @@ export async function logCashPayment(formData: {
|
||||
|
||||
const transactionDate = v.data.transaction_date ?? new Date().toISOString()
|
||||
|
||||
// A supplied member_id must belong to the caller's space before we stamp it
|
||||
// onto the payment, mirroring reserveEquipment. Without this a treasurer
|
||||
// could link a cash payment to a member id from another space.
|
||||
if (v.data.member_id) {
|
||||
const { data: tgt } = await supabase
|
||||
.from('space_members')
|
||||
.select('id')
|
||||
.eq('id', v.data.member_id)
|
||||
.eq('space_id', member.space_id)
|
||||
.maybeSingle()
|
||||
if (!tgt) return { error: 'That member was not found in this space.' }
|
||||
}
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('payments')
|
||||
.insert({
|
||||
@@ -92,6 +105,17 @@ export async function linkPaymentToMember(paymentId: string, memberId: string) {
|
||||
if (!auth.ok) return { error: auth.error }
|
||||
const { member: self } = auth
|
||||
|
||||
// The target member must belong to the caller's space before we link the
|
||||
// payment to it, mirroring reserveEquipment. Without this a treasurer could
|
||||
// link a payment to a member id from another space.
|
||||
const { data: tgt } = await supabase
|
||||
.from('space_members')
|
||||
.select('id')
|
||||
.eq('id', v.data.memberId)
|
||||
.eq('space_id', self.space_id)
|
||||
.maybeSingle()
|
||||
if (!tgt) return { error: 'That member was not found in this space.' }
|
||||
|
||||
const { data: payment } = await supabase
|
||||
.from('payments')
|
||||
.select('amount, transaction_date')
|
||||
|
||||
Reference in New Issue
Block a user