Browse Source

Merge pull request #25138 from abpframework/fix/automapper-maxdepth-vulnerability

Set default MaxDepth for all AutoMapper maps to mitigate GHSA-rvv3-g6hj-g44x
pull/25141/head
Engincan VESKE 6 months ago
committed by GitHub
parent
commit
46ae2e38c4
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 11
      framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs
  2. 7
      framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperOptions.cs
  3. 102
      framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_MaxDepth_Tests.cs

11
framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs

@ -40,6 +40,17 @@ public class AbpAutoMapperModule : AbpModule
configurator(autoMapperConfigurationContext);
}
if (options.DefaultMaxDepth.HasValue)
{
mapperConfigurationExpression.Internal().ForAllMaps((typeMap, _) =>
{
if (typeMap.MaxDepth == 0)
{
typeMap.MaxDepth = options.DefaultMaxDepth.Value;
}
});
}
var mapperConfiguration = new MapperConfiguration(mapperConfigurationExpression);
foreach (var profileType in options.ValidatingProfiles)

7
framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperOptions.cs

@ -12,6 +12,13 @@ public class AbpAutoMapperOptions
public ITypeList<Profile> ValidatingProfiles { get; set; }
/// <summary>
/// Default MaxDepth applied to all maps that don't have an explicit MaxDepth configured.
/// Set to null to disable the default MaxDepth behavior.
/// Default: 64.
/// </summary>
public int? DefaultMaxDepth { get; set; } = 64;
public AbpAutoMapperOptions()
{
Configurators = new List<Action<IAbpAutoMapperConfigurationContext>>();

102
framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_MaxDepth_Tests.cs

@ -0,0 +1,102 @@
using AutoMapper;
using AutoMapper.Internal;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Volo.Abp.AutoMapper.SampleClasses;
using Volo.Abp.Modularity;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Testing;
using Xunit;
namespace Volo.Abp.AutoMapper;
public class AbpAutoMapperModule_MaxDepth_Tests : AbpIntegratedTest<AutoMapperTestModule>
{
private readonly IConfigurationProvider _configurationProvider;
public AbpAutoMapperModule_MaxDepth_Tests()
{
_configurationProvider = ServiceProvider.GetRequiredService<IConfigurationProvider>();
}
[Fact]
public void Should_Set_Default_MaxDepth_For_All_Maps()
{
var typeMap = _configurationProvider.Internal().FindTypeMapFor<MyEntity, MyEntityDto>();
typeMap.ShouldNotBeNull();
typeMap.MaxDepth.ShouldBe(64);
}
}
public class AbpAutoMapperModule_CustomMaxDepth_Tests : AbpIntegratedTest<AbpAutoMapperModule_CustomMaxDepth_Tests.TestModule>
{
private readonly IConfigurationProvider _configurationProvider;
public AbpAutoMapperModule_CustomMaxDepth_Tests()
{
_configurationProvider = ServiceProvider.GetRequiredService<IConfigurationProvider>();
}
[Fact]
public void Should_Not_Override_Custom_MaxDepth()
{
var typeMap = _configurationProvider.Internal().FindTypeMapFor<MyEntity, MyEntityDto>();
typeMap.ShouldNotBeNull();
typeMap.MaxDepth.ShouldBe(10);
}
[DependsOn(
typeof(AbpAutoMapperModule),
typeof(AbpObjectExtendingTestModule)
)]
public class TestModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpAutoMapperOptions>(options =>
{
options.Configurators.Add(ctx =>
{
ctx.MapperConfiguration.CreateMap<MyEntity, MyEntityDto>().MaxDepth(10);
});
});
}
}
}
public class AbpAutoMapperModule_DisabledMaxDepth_Tests : AbpIntegratedTest<AbpAutoMapperModule_DisabledMaxDepth_Tests.TestModule>
{
private readonly IConfigurationProvider _configurationProvider;
public AbpAutoMapperModule_DisabledMaxDepth_Tests()
{
_configurationProvider = ServiceProvider.GetRequiredService<IConfigurationProvider>();
}
[Fact]
public void Should_Not_Set_MaxDepth_When_Disabled()
{
var typeMap = _configurationProvider.Internal().FindTypeMapFor<MyEntity, MyEntityDto>();
typeMap.ShouldNotBeNull();
typeMap.MaxDepth.ShouldBe(0);
}
[DependsOn(
typeof(AbpAutoMapperModule),
typeof(AbpObjectExtendingTestModule)
)]
public class TestModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpAutoMapperOptions>(options =>
{
options.DefaultMaxDepth = null;
options.Configurators.Add(ctx =>
{
ctx.MapperConfiguration.CreateMap<MyEntity, MyEntityDto>();
});
});
}
}
}
Loading…
Cancel
Save