Skip to content

Commit

Permalink
[ODS-6057] Prevent security misconfiguration of relationship-based au…
Browse files Browse the repository at this point in the history
…thorization from authorizing requests without any filtering (#858)

Co-authored-by: Geoffrey McElhanon <[email protected]>
  • Loading branch information
simpat-jesus and gmcelhanon authored Oct 27, 2023
1 parent 35106f4 commit 24b189b
Show file tree
Hide file tree
Showing 5 changed files with 398 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using EdFi.Common;
using EdFi.Common.Extensions;
using EdFi.Ods.Api.Models;
using EdFi.Ods.Common;
using EdFi.Ods.Common.Extensions;

namespace EdFi.Ods.Api.ExceptionHandling.Translators
Expand All @@ -33,12 +32,14 @@ public bool TryTranslateMessage(Exception ex, out RESTError webServiceError)

webServiceError = new RESTError
{
Code = (int) ResponseCode,
Code = (int)ResponseCode,
Type = ResponseCode.ToString().NormalizeCompositeTermForDisplay(),
Message = ex.GetAllMessages()
Message = GetMessage(ex)
};

return true;
}

protected virtual string GetMessage(Exception ex) => ex.GetAllMessages();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,21 @@
using System;
using System.Net;
using EdFi.Ods.Common.Exceptions;
using log4net;

namespace EdFi.Ods.Api.ExceptionHandling.Translators
{
public class TypeBasedInternalServerErrorExceptionTranslator : TypeBasedExceptionTranslatorBase
{
private readonly ILog _logger = LogManager.GetLogger(typeof(TypeBasedInternalServerErrorExceptionTranslator));

// Exception types to be translated to a 500 status response with the error message intact.
private readonly Type[] _exceptionTypes =
private static readonly Type[] _exceptionTypes;

static TypeBasedInternalServerErrorExceptionTranslator()
{
typeof(ApiSecurityConfigurationException)
};
_exceptionTypes = new[] { typeof(ApiSecurityConfigurationException) };
}

protected override Type[] ExceptionTypes
{
Expand All @@ -26,5 +31,12 @@ protected override HttpStatusCode ResponseCode
{
get => HttpStatusCode.InternalServerError;
}

protected override string GetMessage(Exception ex)
{
_logger.Error(ex);

return "The request cannot be authorized due to a security misconfiguration.";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Security.Claims;
using EdFi.Common.Extensions;
using EdFi.Ods.Api.Extensions;
using EdFi.Ods.Common.Attributes;
using EdFi.Ods.Common.Exceptions;
using EdFi.Ods.Common.Models;
using EdFi.Ods.Common.Models.Domain;
using EdFi.Ods.Common.Security.Authorization;
Expand Down Expand Up @@ -88,6 +88,12 @@ public AuthorizationStrategyFiltering GetAuthorizationStrategyFiltering(

var authorizationSubjectEndpoints = GetAuthorizationSubjectEndpoints(authorizationContextTuples);

if (!authorizationSubjectEndpoints.Any())
{
throw new
ApiSecurityConfigurationException($"Authorization strategy '{_authorizationStrategyName.Value}' processed the authorization context names '{string.Join("', '", authorizationContextTuples.Select(t => t.name))}' and produced no authorization subjects, meaning no authorization filtering will be performed. Are you using the correct authorization strategy for this resource?");
}

var filters = authorizationSubjectEndpoints
.Select(subjectEndpoint =>
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
-- SPDX-License-Identifier: Apache-2.0
-- Licensed to the Ed-Fi Alliance under one or more agreements.
-- The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0.
-- See the LICENSE and NOTICES files in the project root for more information.

DECLARE
@claimSetId AS INT,
@resourceClaimId AS INT,
@authorizationStrategyId AS INT,
@createActionId AS INT,
@readActionId AS INT,
@updateActionId AS INT,
@deleteActionId AS INT,
@readChangesActionId AS INT

SELECT @createActionId = ActionId
FROM [dbo].[Actions] WHERE ActionName = 'Create';

SELECT @readActionId = ActionId
FROM [dbo].[Actions] WHERE ActionName = 'Read';

SELECT @updateActionId = ActionId
FROM [dbo].[Actions] WHERE ActionName = 'Update';

SELECT @deleteActionId = ActionId
FROM [dbo].[Actions] WHERE ActionName = 'Delete';

SELECT @readChangesActionId = ActionId
FROM [dbo].[Actions] WHERE ActionName = 'ReadChanges';

SELECT @claimSetId = ClaimSetId FROM ClaimSets WHERE claimSetName = 'Ed-Fi Sandbox'

SELECT @authorizationStrategyId = AuthorizationStrategyId FROM AuthorizationStrategies
WHERE AuthorizationStrategyName = 'NoFurtherAuthorizationRequired'

---- Update EvaluationRubricDimension Authorization Strategy -----

SELECT @resourceClaimId = ResourceClaimId FROM ResourceClaims WHERE ResourceName = 'EvaluationRubricDimension'

INSERT INTO ClaimSetResourceClaimActions (ClaimSetId, ResourceClaimId, ActionId)
VALUES
(@claimSetId, @resourceClaimId, @createActionId),
(@claimSetId, @resourceClaimId, @readActionId),
(@claimSetId, @resourceClaimId, @updateActionId),
(@claimSetId, @resourceClaimId, @deleteActionId),
(@claimSetId, @resourceClaimId, @readChangesActionId);

INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides
(ClaimSetResourceClaimActionId, AuthorizationStrategyId)
SELECT ClaimSetResourceClaimActionId, @authorizationStrategyId FROM ClaimSetResourceClaimActions
WHERE ClaimSetId = @claimSetId AND ResourceClaimId = @resourceClaimId AND ActionId = @createActionId

INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides
(ClaimSetResourceClaimActionId, AuthorizationStrategyId)
SELECT ClaimSetResourceClaimActionId, @authorizationStrategyId FROM ClaimSetResourceClaimActions
WHERE ClaimSetId = @claimSetId AND ResourceClaimId = @resourceClaimId AND ActionId = @readActionId

INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides
(ClaimSetResourceClaimActionId, AuthorizationStrategyId)
SELECT ClaimSetResourceClaimActionId, @authorizationStrategyId FROM ClaimSetResourceClaimActions
WHERE ClaimSetId = @claimSetId AND ResourceClaimId = @resourceClaimId AND ActionId = @updateActionId

INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides
(ClaimSetResourceClaimActionId, AuthorizationStrategyId)
SELECT ClaimSetResourceClaimActionId, @authorizationStrategyId FROM ClaimSetResourceClaimActions
WHERE ClaimSetId = @claimSetId AND ResourceClaimId = @resourceClaimId AND ActionId = @deleteActionId

INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides
(ClaimSetResourceClaimActionId, AuthorizationStrategyId)
SELECT ClaimSetResourceClaimActionId, @authorizationStrategyId FROM ClaimSetResourceClaimActions
WHERE ClaimSetId = @claimSetId AND ResourceClaimId = @resourceClaimId AND ActionId = @readChangesActionId

---- Update ProgramEvaluation Authorization Strategy -------------

SELECT @resourceClaimId = ResourceClaimId FROM ResourceClaims WHERE ResourceName = 'ProgramEvaluation'

INSERT INTO ClaimSetResourceClaimActions (ClaimSetId, ResourceClaimId, ActionId)
VALUES
(@claimSetId, @resourceClaimId, @createActionId),
(@claimSetId, @resourceClaimId, @readActionId),
(@claimSetId, @resourceClaimId, @updateActionId),
(@claimSetId, @resourceClaimId, @deleteActionId),
(@claimSetId, @resourceClaimId, @readChangesActionId);

INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides
(ClaimSetResourceClaimActionId, AuthorizationStrategyId)
SELECT ClaimSetResourceClaimActionId, @authorizationStrategyId FROM ClaimSetResourceClaimActions
WHERE ClaimSetId = @claimSetId AND ResourceClaimId = @resourceClaimId AND ActionId = @createActionId

INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides
(ClaimSetResourceClaimActionId, AuthorizationStrategyId)
SELECT ClaimSetResourceClaimActionId, @authorizationStrategyId FROM ClaimSetResourceClaimActions
WHERE ClaimSetId = @claimSetId AND ResourceClaimId = @resourceClaimId AND ActionId = @readActionId

INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides
(ClaimSetResourceClaimActionId, AuthorizationStrategyId)
SELECT ClaimSetResourceClaimActionId, @authorizationStrategyId FROM ClaimSetResourceClaimActions
WHERE ClaimSetId = @claimSetId AND ResourceClaimId = @resourceClaimId AND ActionId = @updateActionId

INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides
(ClaimSetResourceClaimActionId, AuthorizationStrategyId)
SELECT ClaimSetResourceClaimActionId, @authorizationStrategyId FROM ClaimSetResourceClaimActions
WHERE ClaimSetId = @claimSetId AND ResourceClaimId = @resourceClaimId AND ActionId = @deleteActionId

INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides
(ClaimSetResourceClaimActionId, AuthorizationStrategyId)
SELECT ClaimSetResourceClaimActionId, @authorizationStrategyId FROM ClaimSetResourceClaimActions
WHERE ClaimSetId = @claimSetId AND ResourceClaimId = @resourceClaimId AND ActionId = @readChangesActionId

---- Update ProgramEvaluationElement Authorization Strategy ------

SELECT @resourceClaimId = ResourceClaimId FROM ResourceClaims WHERE ResourceName = 'ProgramEvaluationElement'

INSERT INTO ClaimSetResourceClaimActions (ClaimSetId, ResourceClaimId, ActionId)
VALUES
(@claimSetId, @resourceClaimId, @createActionId),
(@claimSetId, @resourceClaimId, @readActionId),
(@claimSetId, @resourceClaimId, @updateActionId),
(@claimSetId, @resourceClaimId, @deleteActionId),
(@claimSetId, @resourceClaimId, @readChangesActionId);

INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides
(ClaimSetResourceClaimActionId, AuthorizationStrategyId)
SELECT ClaimSetResourceClaimActionId, @authorizationStrategyId FROM ClaimSetResourceClaimActions
WHERE ClaimSetId = @claimSetId AND ResourceClaimId = @resourceClaimId AND ActionId = @createActionId

INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides
(ClaimSetResourceClaimActionId, AuthorizationStrategyId)
SELECT ClaimSetResourceClaimActionId, @authorizationStrategyId FROM ClaimSetResourceClaimActions
WHERE ClaimSetId = @claimSetId AND ResourceClaimId = @resourceClaimId AND ActionId = @readActionId

INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides
(ClaimSetResourceClaimActionId, AuthorizationStrategyId)
SELECT ClaimSetResourceClaimActionId, @authorizationStrategyId FROM ClaimSetResourceClaimActions
WHERE ClaimSetId = @claimSetId AND ResourceClaimId = @resourceClaimId AND ActionId = @updateActionId

INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides
(ClaimSetResourceClaimActionId, AuthorizationStrategyId)
SELECT ClaimSetResourceClaimActionId, @authorizationStrategyId FROM ClaimSetResourceClaimActions
WHERE ClaimSetId = @claimSetId AND ResourceClaimId = @resourceClaimId AND ActionId = @deleteActionId

INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides
(ClaimSetResourceClaimActionId, AuthorizationStrategyId)
SELECT ClaimSetResourceClaimActionId, @authorizationStrategyId FROM ClaimSetResourceClaimActions
WHERE ClaimSetId = @claimSetId AND ResourceClaimId = @resourceClaimId AND ActionId = @readChangesActionId

---- Update ProgramEvaluationObjective Authorization Strategy ----

SELECT @resourceClaimId = ResourceClaimId FROM ResourceClaims WHERE ResourceName = 'ProgramEvaluationObjective'

INSERT INTO ClaimSetResourceClaimActions (ClaimSetId, ResourceClaimId, ActionId)
VALUES
(@claimSetId, @resourceClaimId, @createActionId),
(@claimSetId, @resourceClaimId, @readActionId),
(@claimSetId, @resourceClaimId, @updateActionId),
(@claimSetId, @resourceClaimId, @deleteActionId),
(@claimSetId, @resourceClaimId, @readChangesActionId);

INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides
(ClaimSetResourceClaimActionId, AuthorizationStrategyId)
SELECT ClaimSetResourceClaimActionId, @authorizationStrategyId FROM ClaimSetResourceClaimActions
WHERE ClaimSetId = @claimSetId AND ResourceClaimId = @resourceClaimId AND ActionId = @createActionId

INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides
(ClaimSetResourceClaimActionId, AuthorizationStrategyId)
SELECT ClaimSetResourceClaimActionId, @authorizationStrategyId FROM ClaimSetResourceClaimActions
WHERE ClaimSetId = @claimSetId AND ResourceClaimId = @resourceClaimId AND ActionId = @readActionId

INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides
(ClaimSetResourceClaimActionId, AuthorizationStrategyId)
SELECT ClaimSetResourceClaimActionId, @authorizationStrategyId FROM ClaimSetResourceClaimActions
WHERE ClaimSetId = @claimSetId AND ResourceClaimId = @resourceClaimId AND ActionId = @updateActionId

INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides
(ClaimSetResourceClaimActionId, AuthorizationStrategyId)
SELECT ClaimSetResourceClaimActionId, @authorizationStrategyId FROM ClaimSetResourceClaimActions
WHERE ClaimSetId = @claimSetId AND ResourceClaimId = @resourceClaimId AND ActionId = @deleteActionId

INSERT INTO ClaimSetResourceClaimActionAuthorizationStrategyOverrides
(ClaimSetResourceClaimActionId, AuthorizationStrategyId)
SELECT ClaimSetResourceClaimActionId, @authorizationStrategyId FROM ClaimSetResourceClaimActions
WHERE ClaimSetId = @claimSetId AND ResourceClaimId = @resourceClaimId AND ActionId = @readChangesActionId
Loading

0 comments on commit 24b189b

Please sign in to comment.