CVE-2019-19249 (C#, published 2019-11-25T17:15Z)
Description: value: Controllers/InvitationsController.cs in QueryTree before 3.0.99-beta mishandles invitations.
Severity: HIGH (CVSS v3 base score: 9.8)
Weakness: CWE-20 \u2014 Improper Input Validation
The product receives input or data, but it does
        not validate or incorrectly validates that the input has the
        properties that are required to process the data safely and
        correctly.
Repository: https://github.com/d4software/QueryTree
Files changed:
Web/Controllers/InvitationsController.cs
Web/ViewModels/InvitationViewModel.cs
Web/Views/Invitations/Index.cshtml
Commit message: Fixing security vunerability


Vulnerable code:
                InvitationViewModel viewModel = new InvitationViewModel();
            var organisation = db.Organisations.FirstOrDefault(ba => ba.OrganisationId == id);
            if (organisation == null)
                return NotFound("Organisation not found");
            // remove other invitations to other organisations
            db.OrganisationInvites.RemoveWhere(uc => uc.InviteEmail.ToLower() == CurrentUser.Email.ToLower() && uc.OrganisationId != id);
            db.SaveChanges();
            var invitationsToAccept = db.OrganisationInvites
                .Where(uc => uc.InviteEmail == CurrentUser.Email && uc.OrganisationId == id)
                .ToList();
            
            foreach (var invite in invitationsToAccept)
                invite.AcceptedOn = DateTime.Now;
        
            var invite = db.OrganisationInvites.First(i => i.InviteEmail.ToLower() == CurrentUser.Email.ToLower() && i.OrganisationId == id && i.AcceptedOn == null && i.RejectedOn == null);
							@Html.ActionLink("Accept", "Accept", new { id = item.OrganisationId }, new { @class = "btn btn-lg btn-success" })
							@Html.ActionLink("Reject", "Reject", new { id = item.OrganisationId }, new { @class = "btn btn-lg btn-warning rhs-delete" })

Fixed code:
                InvitationViewModel viewModel = new InvitationViewModel
                {
                    OrganisationInviteId = orgGrp.First().OrganisationInviteId
                };
            var invite = db.OrganisationInvites.FirstOrDefault(uc => uc.InviteEmail.ToLower() == CurrentUser.Email.ToLower() && uc.AcceptedOn == null && uc.RejectedOn == null && uc.OrganisationInviteId == id);
            if (invite == null)
                return NotFound("Invite not found");
            var organisation = db.Organisations.FirstOrDefault(ba => ba.OrganisationId == invite.OrganisationId);
            if (organisation == null)
            {
                return NotFound("Organisation not found");
            }
            invite.AcceptedOn = DateTime.Now;
            
            // reject other invitations to other organisations
            var invitesToReject = db.OrganisationInvites.Where(uc => uc.InviteEmail.ToLower() == CurrentUser.Email.ToLower() && uc.OrganisationInviteId != invite.OrganisationInviteId);
        
            foreach (var inviteToReject in invitesToReject)
                inviteToReject.RejectedOn = DateTime.Now;

            var invite = db.OrganisationInvites.FirstOrDefault(uc => uc.InviteEmail.ToLower() == CurrentUser.Email.ToLower() && uc.AcceptedOn == null && uc.RejectedOn == null && uc.OrganisationInviteId == id);

            if (invite == null)
            {
                return NotFound("Invite not found");
            }

        public int OrganisationInviteId { get; set; }

							@Html.ActionLink("Accept", "Accept", new { id = item.OrganisationInviteId }, new { @class = "btn btn-lg btn-success" })
							@Html.ActionLink("Reject", "Reject", new { id = item.OrganisationInviteId }, new { @class = "btn btn-lg btn-warning rhs-delete" })