1
0
mirror of https://github.com/bitwarden/server synced 2025-12-25 04:33:26 +00:00

[PM-20550] Add JSON validation to Cipher Delete/Update attachment sprocs (#5656)

* Add JSON validation to Cipher Delete/Update attachment sprocs

* Remove [Attachment] assignment from cipher create/update sprocs

* Add additional validation and use JSON_PATH_EXISTS for delete sproc check

* Update migration script date
This commit is contained in:
Shane Melton
2025-04-30 08:43:39 -07:00
committed by GitHub
parent cf7a59c077
commit 92701d8cd0
6 changed files with 468 additions and 29 deletions

View File

@@ -6,7 +6,7 @@
@Data NVARCHAR(MAX),
@Favorites NVARCHAR(MAX), -- not used
@Folders NVARCHAR(MAX), -- not used
@Attachments NVARCHAR(MAX),
@Attachments NVARCHAR(MAX), -- not used
@CreationDate DATETIME2(7),
@RevisionDate DATETIME2(7),
@FolderId UNIQUEIDENTIFIER,
@@ -50,7 +50,6 @@ BEGIN
ELSE
JSON_MODIFY([Favorites], @UserIdPath, NULL)
END,
[Attachments] = @Attachments,
[Reprompt] = @Reprompt,
[CreationDate] = @CreationDate,
[RevisionDate] = @RevisionDate,

View File

@@ -6,7 +6,7 @@
@Data NVARCHAR(MAX),
@Favorites NVARCHAR(MAX),
@Folders NVARCHAR(MAX),
@Attachments NVARCHAR(MAX),
@Attachments NVARCHAR(MAX), -- not used
@CreationDate DATETIME2(7),
@RevisionDate DATETIME2(7),
@DeletedDate DATETIME2(7),
@@ -25,7 +25,6 @@ BEGIN
[Data],
[Favorites],
[Folders],
[Attachments],
[CreationDate],
[RevisionDate],
[DeletedDate],
@@ -41,7 +40,6 @@ BEGIN
@Data,
@Favorites,
@Folders,
@Attachments,
@CreationDate,
@RevisionDate,
@DeletedDate,

View File

@@ -10,20 +10,59 @@ BEGIN
DECLARE @UserId UNIQUEIDENTIFIER
DECLARE @OrganizationId UNIQUEIDENTIFIER
DECLARE @CurrentAttachments NVARCHAR(MAX)
DECLARE @NewAttachments NVARCHAR(MAX)
-- Get current cipher data
SELECT
@UserId = [UserId],
@OrganizationId = [OrganizationId]
FROM
@OrganizationId = [OrganizationId],
@CurrentAttachments = [Attachments]
FROM
[dbo].[Cipher]
WHERE [Id] = @Id
UPDATE
[dbo].[Cipher]
SET
[Attachments] = JSON_MODIFY([Attachments], @AttachmentIdPath, NULL)
WHERE
[Id] = @Id
-- If there are no attachments, nothing to do
IF @CurrentAttachments IS NULL
BEGIN
RETURN;
END
-- Validate the initial JSON
IF ISJSON(@CurrentAttachments) = 0
BEGIN
THROW 50000, 'Current initial attachments data is not valid JSON', 1;
RETURN;
END
-- Check if the attachment exists before trying to remove it
IF JSON_PATH_EXISTS(@CurrentAttachments, @AttachmentIdPath) = 0
BEGIN
-- Attachment doesn't exist, nothing to do
RETURN;
END
-- Create the new attachments JSON with the specified attachment removed
SET @NewAttachments = JSON_MODIFY(@CurrentAttachments, @AttachmentIdPath, NULL)
-- Validate the resulting JSON
IF ISJSON(@NewAttachments) = 0
BEGIN
THROW 50000, 'Failed to create valid JSON when removing attachment', 1;
RETURN;
END
-- Check if we've removed all attachments and have an empty object
IF @NewAttachments = '{}'
BEGIN
-- If we have an empty JSON object, set to NULL instead
SET @NewAttachments = NULL;
END
-- Update with validated JSON
UPDATE [dbo].[Cipher]
SET [Attachments] = @NewAttachments
WHERE [Id] = @Id
IF @OrganizationId IS NOT NULL
BEGIN

View File

@@ -6,7 +6,7 @@
@Data NVARCHAR(MAX),
@Favorites NVARCHAR(MAX),
@Folders NVARCHAR(MAX),
@Attachments NVARCHAR(MAX),
@Attachments NVARCHAR(MAX), -- not used
@CreationDate DATETIME2(7),
@RevisionDate DATETIME2(7),
@DeletedDate DATETIME2(7),
@@ -25,7 +25,6 @@ BEGIN
[Data] = @Data,
[Favorites] = @Favorites,
[Folders] = @Folders,
[Attachments] = @Attachments,
[CreationDate] = @CreationDate,
[RevisionDate] = @RevisionDate,
[DeletedDate] = @DeletedDate,
@@ -42,4 +41,4 @@ BEGIN
BEGIN
EXEC [dbo].[User_BumpAccountRevisionDate] @UserId
END
END
END

View File

@@ -8,21 +8,75 @@ AS
BEGIN
SET NOCOUNT ON
-- Validate that AttachmentData is valid JSON
IF ISJSON(@AttachmentData) = 0
BEGIN
THROW 50000, 'Invalid JSON format in AttachmentData parameter', 1;
RETURN;
END
-- Validate that AttachmentData has the expected structure
-- Check for required fields
IF JSON_VALUE(@AttachmentData, '$.FileName') IS NULL OR
JSON_VALUE(@AttachmentData, '$.Size') IS NULL
BEGIN
THROW 50000, 'AttachmentData is missing required fields (FileName, Size)', 1;
RETURN;
END
-- Validate data types for critical fields
DECLARE @Size BIGINT = TRY_CAST(JSON_VALUE(@AttachmentData, '$.Size') AS BIGINT)
IF @Size IS NULL OR @Size <= 0
BEGIN
THROW 50000, 'AttachmentData has invalid Size value', 1;
RETURN;
END
DECLARE @AttachmentIdKey VARCHAR(50) = CONCAT('"', @AttachmentId, '"')
DECLARE @AttachmentIdPath VARCHAR(50) = CONCAT('$.', @AttachmentIdKey)
DECLARE @NewAttachments NVARCHAR(MAX)
UPDATE
[dbo].[Cipher]
SET
[Attachments] =
CASE
WHEN [Attachments] IS NULL THEN
CONCAT('{', @AttachmentIdKey, ':', @AttachmentData, '}')
ELSE
JSON_MODIFY([Attachments], @AttachmentIdPath, JSON_QUERY(@AttachmentData, '$'))
END
WHERE
[Id] = @Id
-- Get current attachments
DECLARE @CurrentAttachments NVARCHAR(MAX)
SELECT @CurrentAttachments = [Attachments] FROM [dbo].[Cipher] WHERE [Id] = @Id
-- Prepare the new attachments value based on current state
IF @CurrentAttachments IS NULL
BEGIN
-- Create new JSON object with the attachment
SET @NewAttachments = CONCAT('{', @AttachmentIdKey, ':', @AttachmentData, '}')
-- Validate the constructed JSON
IF ISJSON(@NewAttachments) = 0
BEGIN
THROW 50000, 'Failed to create valid JSON when adding new attachment', 1;
RETURN;
END
END
ELSE
BEGIN
-- Validate existing attachments
IF ISJSON(@CurrentAttachments) = 0
BEGIN
THROW 50000, 'Current attachments data is not valid JSON', 1;
RETURN;
END
-- Modify existing JSON
SET @NewAttachments = JSON_MODIFY(@CurrentAttachments, @AttachmentIdPath, JSON_QUERY(@AttachmentData, '$'))
-- Validate the modified JSON
IF ISJSON(@NewAttachments) = 0
BEGIN
THROW 50000, 'Failed to create valid JSON when updating existing attachments', 1;
RETURN;
END
END
-- Update with validated JSON
UPDATE [dbo].[Cipher]
SET [Attachments] = @NewAttachments
WHERE [Id] = @Id
IF @OrganizationId IS NOT NULL
BEGIN
@@ -34,4 +88,4 @@ BEGIN
EXEC [dbo].[User_UpdateStorage] @UserId
EXEC [dbo].[User_BumpAccountRevisionDate] @UserId
END
END
END