Verify signature ownership in esign accept/record-event flows
Any self-provisioned trust center visitor could accept another visitor's NDA signature or inject audit-trail events into it by supplying its GID, since AcceptSignature and RecordEvent trusted the client-supplied signature ID without checking it belonged to the caller (GHSA-22xj-f767-ppw6). SignerEmail/ActorEmail are always derived from the verified session identity, never client input, so comparing them against the signature's stored SignerEmail in pkg/esign/service.go closes the hole at its root without touching the resolver-level authorization already in place elsewhere. Adds an e2e regression test that self-provisions two trust center visitors through the real magic-link flow and confirms one cannot touch the other's signature. Signed-off-by: Bryan Frimin <bryan@probo.com>
This commit is contained in:
committed by
Sacha Al Himdani
parent
83e7b3bdd4
commit
f20c3d73d2
@@ -48,6 +48,10 @@ func (r *mutationResolver) AcceptElectronicSignature(ctx context.Context, input
|
||||
return nil, gqlutils.NotFoundf(ctx, "electronic signature %q not found", input.SignatureID)
|
||||
}
|
||||
|
||||
if errors.Is(err, esign.ErrSignatureAccessDenied) {
|
||||
return nil, gqlutils.Forbiddenf(ctx, "cannot accept electronic signature")
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot accept electronic signature", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
@@ -85,6 +89,10 @@ func (r *mutationResolver) RecordSigningEvent(ctx context.Context, input types.R
|
||||
return nil, gqlutils.NotFoundf(ctx, "electronic signature %q not found", input.SignatureID)
|
||||
}
|
||||
|
||||
if errors.Is(err, esign.ErrSignatureAccessDenied) {
|
||||
return nil, gqlutils.Forbiddenf(ctx, "cannot record signing event")
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot record signing event", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
|
||||
Reference in New Issue
Block a user