Migrated ABP Framework- 8.2.3 t0 ABP Framework- 10.5.0 and .NET 8 to NET Framework to .NET 10.
After upgrading our project's .NET version and ABP packages (and separately migrating AutoMapper → Mapperly, which we've ruled out as the cause), we observed that entities which are not explicitly updated in the current unit of work are still getting their audit columns (LastModificationTime, LastModifierId) stamped and persisted on SaveChanges().
_financialCounselingRepository.InsertAsync(financialCounseling, autoSave: true) — inserting a new FinancialCounseling (a FullAuditedEntity<long>).Patient entity (also FullAuditedEntity<long>) via a repository read (tried both tracked and AsNoTracking() — issue persists once the entity re-enters the change tracker through navigation fixup).UpdateAsync on Patient, nor modify any of its business properties.SaveChanges(), we instrumented ChangeTracker.Entries() right before EF Core's save call and observed:
Patient → EntityState.Modified, with only LastModificationTime reported as an IsModified property.FinancialCounseling → EntityState.Modified, with only LastModificationTime,LastModifierId reported as IsModified.Encounter, TransactionLocking_TR) correctly show a full, expected set of business properties as modified — confirming those are legitimate changes.Patient and FinancialCounseling rows get a LastModificationTime/LastModifierId update in the database even though no business column changed and no explicit update call was made against them.Entities that are EntityState.Modified purely because EF Core's DetectChanges()/navigation fixup flagged them (with zero non-audit, non-concurrency-stamp properties actually dirty) should not be audit-stamped by ABP's IAuditPropertySetter. Today, AuditPropertySetter (called from AbpDbContext's SaveChanges pipeline / HandlePropertiesBeforeSave) appears to stamp any entry with EntityState.Modified implementing IHasModificationTime, without checking whether any actual business property is dirty.
AuditPropertySetter.SetModificationAuditProperties intentionally stamp any Modified entry regardless of which properties changed?LastModificationTime, LastModifierId, ConcurrencyStamp)?DetectChanges()/relationship-fixup more aggressive about marking loaded-but-unmodified entities as Modified (e.g. due to shadow FK re-evaluation, concurrency token comparison, or navigation collection fixup)? We did not see this behavior prior to the .NET/ABP upgrade with the same code paths.IAuditPropertySetter the correct/supported extension point to override this (e.g., replacing the DI registration with a custom implementation that checks for non-audit dirty properties before stamping), or is there a more idiomatic ABP configuration option (e.g. under AbpAuditingOptions) we're missing?Ignore() all audit-related members (Id, CreationTime, CreatorId, LastModificationTime, LastModifierId) on create/update DTO→entity mappings — ruled out as cause.AsNoTracking() to the relevant repository read methods — did not resolve the issue (entity still ends up Modified in the tracker by the time SaveChanges runs, likely via navigation fixup from a related tracked aggregate).AppDbContext.HandlePropertiesBeforeSave() override that detects entries where all IsModified properties are in {"LastModificationTime", "LastModifierId", "ConcurrencyStamp"} and resets entry.State = EntityState.Unchanged before calling UpdateConcurrencyStamp(entry). This resolves the symptom but feels like it's masking a framework-level behavior we don't fully understand.Patient : FullAuditedEntity<long>, FinancialCounseling : FullAuditedEntity<long> (has ICollection<FCEncounterRelation> FCEncounters navigation).FCEncounterRelation (also FullAuditedEntity<long>) does not exhibit this false-positive — its modification-time column stays untouched in the same save batch, which is somewhat inconsistent with the parent aggregates being falsely flagged.Modified-state entity in the same SaveChanges batch regardless of relation to the actually-changed root entity, and whether there's a supported switch to opt out per-property rather than per-entity.I am currently using ABP Framework v10.5.0 with the following setup:
UI Type: React Database System: EF Core (SQL Server) Auth Server Separated: Yes .NET Version: .NET 10
Finding 1: SAST – Unchecked Input For Loop Condition
Component: Chart.js (chart.umd.js)
Description: Checkmarx identified an Unchecked Input For Loop Condition vulnerability in the Chart.js library.
Method Lambda at line 13 of /src/src/eFC.Web/wwwroot/libs/chart.js/chart.umd.js obtains user input from data. The range of this value is not validated, and is eventually used in a loop condition in et at line 7 of /src/src/eFC.Web/wwwroot/libs/chart.js/chart.umd.js, allowing attackers to provide a very high number of iterations.
Please advise: The remediation approach and target version (if upgrading Chart.js), or An alternative mitigation/compensating control if the library cannot be upgraded immediately. If this is assessed as a false positive or non-exploitable finding, please provide supporting justification.
Finding 2: SCA – CWE-843 Type Confusion
Package: uppy@5.2.4 (T) Category: CWE-843 | Access of Resource Using Incompatible Type ("Type Confusion")
Description: An SCA vulnerability has been identified in the third-party package uppy@5.2.4 (T).
CVE Details:
Published: 15 Apr 2026
Checkmarx Research Notes:
Our info regarding the package versions affected by this vulnerability differs from the one shown in NVD. This is based on research done by our AppSec Research team.
Please advise: Whether the package is actively used by the application. The planned upgrade path to a fixed version, if available. Any alternative mitigation/workaround if an upgrade cannot be performed at this time. If the package is not utilized or the finding is not applicable, please provide justification for review and closure.
Please provide your proposed remediation or alternative solution for both findings so that the security team can assess the next course of action and closure requirements.
I am currently using ABP Framework v8.2.3 with the following setup:
UI Type: React Database System: EF Core (SQL Server) Auth Server Separated: Yes .NET Version: .NET 8
I have identified a vulnerability in one of the transitive dependencies used by ABP: Scriban@5.9.0 (Transitive) Scriban versions prior to 7.0.2 are affected by a CWE-770 | Allocation of Resources Without Limits or Throttling CVE Details Published: May 19, 2026 ArrayFunctions.InsertAt in Scriban allocates index - list.Count null entries in a tight C# for loop with no bound on index. The function is exposed to template authors as array.insert_at, and the fill loop ignores every existing safety control: LoopLimit, LimitToString, ObjectRecursionLimit, and RecursiveLimit. A single template such as {{ [1] | array.insert_at 200000000 'x' | array.size }} causes OutOfMemoryException in well under a second on a host with 1 GB of memory, even when LoopLimit is set to 10 and LimitToString is set to 100. Because OutOfMemoryException is generally not caught by the template renderer or by typical host applications, the vulnerability terminates the host process, not just the template.
I understand that this issue is fixed in Scriban 7.0.2, but upgrading to that version would require .NET 9, which I am not able to migrate to at this time. I would like to stay on ABP 8.2.3 and .NET 8.
My question is: Is there a recommended mitigation or usage pattern within ABP to safely address this Scriban issue without upgrading the framework or runtime?
Thank you.
[maliming] said: Hi,
Quick context: in ABP 8.2.3, the
@abp/uppynpm wrapper declares"uppy": "^3.0.0", and npm resolves that to the latest 3.x — which is 3.27.3. The wrapper has no JS code of its own; it just copiesnode_modules/uppy/dist/*towwwroot/libs/uppy/viaabp.resourcemapping.js. So you can change the resolveduppyversion without touching ABP server-side (NuGet) packages.Two important signals before we pick a fix:
- Your report shows
uppy@3.27.3 (Transitive). In most SCA tools,(Transitive)means uppy is brought in through another package (here,@abp/uppy). The finding can either be in uppy's own code or in one of uppy's own sub-dependencies, and scanners often display the top-level package as the "vulnerable" one.- The public databases we can check do not flag
uppy@3.27.3itself:
- Snyk: https://security.snyk.io/package/npm/uppy/3.27.3 — "No direct vulnerabilities have been found for this package."
- GitHub Advisory Database / NVD: no advisory matching
uppy + CWE-843.This strongly suggests the actual vulnerable package is a sub-dependency of uppy, not uppy itself. To pinpoint it, please share:
- Output of
npm ls uppy(full chain, so we can confirm whether it comes through@abp/uppyor something else)- The exact advisory ID from your scanner (CVE / GHSA / SNYK-ID), and ideally the "vulnerable package" field — that one is the package you actually need to bump, not necessarily
uppyWhile you collect those, here are the upgrade paths in order of safety:
Option 1 — Bump only the
@abp/*npm packages to~8.3.x(recommended). Keep ABP NuGet at 8.2.3.@abp/uppy@~8.3.xdeclares"uppy": "^3.27.0", so you stay on the 3.x line and just get the latest 3.27 patch. This is the smallest change and may already pull a fresh enough sub-dependency to clear the finding.# In your client project, change @abp/* packages to ~8.3.x in package.json, then: rm -rf node_modules package-lock.json npm install npm ls uppyOption 2 — npm
overridesto pin the actual vulnerable package. Once you know which sub-dependency the scanner is flagging, override that one directly (not necessarilyuppy). Example shape:{ "overrides": { "<the-actual-vulnerable-package>": "<fixed-version>" } }If the scanner really is flagging
uppyitself, pin uppy to the latest 3.x patch and stay on the 3.x major.Don't blindly jump to
uppy@4.xor5.xvia overrides. Uppy 4.x went ESM-only and 5.x changed bundle/plugin internals further. ABP's MVC pages callUppy.Dashboard,Uppy.XHRUpload,uppy.use(), etc. via the global bundle, and although ABP itself moved to uppy 4 in v9.0 and uppy 5 in v10.0, that came with corresponding npm-pack updates and library-refresh runs (abp install-libs). Overriding the major across a wrong@abp/uppyversion risks runtime errors in upload UI (file-management, cms-kit-admin, identity user import, account profile picture, etc.).For reference, this is how ABP itself has moved uppy:
|
@abp/uppyversion |uppyrange | | --- | --- | | 8.0.x – 8.2.x |^3.0.0| | 8.3.x |^3.27.0| | 9.x |^4.4.1| | 10.x |^5.1.2|Also note: there is no ABP configuration switch that mitigates an npm-level vulnerability. It is purely a dependency-version question. If your client app does not actually use any Uppy-based upload UI at runtime, removing the package that pulls it in is also an option, but again
npm ls uppyis the first step to know what to remove.Thanks
Hi,
Thanks for the detailed explanation. The vulnerability flagged by our scanner is CVE-2025-70023, affecting uppy@3.27.3, which is currently resolved as a transitive dependency in our project. At the moment, the scanner indicates that no remediated (fixed) version is available yet. Based on this, I would like to clarify a few points:
Since there is no patched version available upstream, is there any recommended mitigation approach from ABP’s side (temporary or compensating control)? Would it be advisable to remove or replace @abp/uppy entirely if the functionality is not actively used, to eliminate the vulnerable dependency? Are there any safe workarounds (e.g., restricting features, usage patterns, or runtime configurations) that could reduce the risk exposure until an official fix is released? Lastly, does ABP have any planned update or advisory regarding this CVE for upcoming releases?
We understand this is an upstream issue, but any guidance on minimizing risk within the current ABP 8.2.3 setup would be very helpful. Thanks in advance for your support.
ABP Framework version: v8.2.3
UI Type: React
Database System: EF Core (SQL Server)
Tiered (for MVC) or Auth Server Separated (for Angular): yes
I am currently using ABP Framework 8.2.3 and have identified the following vulnerability in my project dependencies:
uppy@3.27.3 (Transitive) An issue pertaining to CWE-843: Access of Resource Using Incompatible Type was discovered in transload it uppy.
My question is: Is there a recommended way to mitigate or fix these vulnerabilities without upgrading the ABP Framework version? For example:
Can this transitive dependency be safely overridden? Are there configuration-based mitigations?
[maliming] said: Hi,
The CWE-693 vulnerability (GHSA-5wr9-m6jw-xx44) in Scriban is about
TemplateContextcaching type member accessors byTypeonly. It can be exploited when aTemplateContextinstance is reused across renders and theMemberFilterorMemberRenameris tightened between renders — previously cached accessors may still be exposed.
However, ABP's Scriban usage does not trigger this vulnerability:
- ABP creates a new
TemplateContextinstance for every render call — it never reusesTemplateContextacross renders.
- ABP does not configure
MemberFilterorMemberRenameronTemplateContextat all.
Since the vulnerability requires reusing a
TemplateContextwith dynamically tightened member access restrictions, and ABP doesn't do that, the actual risk is very low.
That said, if you want to eliminate the warning entirely, you can override the Scriban version to 7.0.0 in your project file. We tested this with ABP 8.2.3 on .NET 8 and it works without any issues:
This will resolve all Scriban-related security warnings.
Alternatively, if you prefer to keep the original version, you can suppress specific advisories:
Thanks
Hi,
I tried adding
<ItemGroup> <PackageReference Include="Scriban" Version="7.0.0" /> </ItemGroup> but getting below execption:
2026-04-13 14:15:10.552 +08:00 [ERR] Could not load type 'Scriban.Parsing.ParserOptions' from assembly 'Volo.Abp.TextTemplating.Scriban, Version=8.2.3.0, Culture=neutral, PublicKeyToken=null' due to value type mismatch.
System.TypeLoadException: Could not load type 'Scriban.Parsing.ParserOptions' from assembly 'Volo.Abp.TextTemplating.Scriban, Version=8.2.3.0, Culture=neutral, PublicKeyToken=null' due to value type mismatch.
at Volo.Abp.TextTemplating.Scriban.ScribanTemplateRenderingEngine.RenderTemplateContentWithScribanAsync(TemplateDefinition templateDefinition, String templateContent, Dictionary2 globalContext, Object model) at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine) at Volo.Abp.TextTemplating.Scriban.ScribanTemplateRenderingEngine.RenderTemplateContentWithScribanAsync(TemplateDefinition templateDefinition, String templateContent, Dictionary2 globalContext, Object model)
at Volo.Abp.TextTemplating.Scriban.ScribanTemplateRenderingEngine.RenderSingleTemplateAsync(TemplateDefinition templateDefinition, Dictionary2 globalContext, Object model) at Volo.Abp.TextTemplating.Scriban.ScribanTemplateRenderingEngine.RenderInternalAsync(String templateName, Dictionary2 globalContext, Object model)
at Volo.Abp.TextTemplating.Scriban.ScribanTemplateRenderingEngine.RenderAsync(String templateName, Object model, String cultureName, Dictionary2 globalContext) at Volo.Abp.TextTemplating.AbpTemplateRenderer.RenderAsync(String templateName, Object model, String cultureName, Dictionary2 globalContext)
at eFC.Common.ReportGenerator.SetHeaderTemplate(String FCNo, Encounter encounter, String mrn, Patient patient, String Specialty, String surgicalProcedure, String basedOn, String pGender, String residentialStatus, String specilaty, String headerText, String headerBody, String institutionCode, String campusCode, String encounterNoForheader, String fcmodecode) in C:\DIM\OctRelease\eFC\src\src\eFC.Application\Common\ReportGenerator.cs:line 814
at eFC.Common.ReportGenerator.GenerateETBSDetailedAsync(BillDetailDto bill, Int64 FCId, String priceMode, Boolean IsDetailed, Nullable1 columnId, String username, Boolean calcEstimatedMSVHPay) in C:\DIM\OctRelease\eFC\src\src\eFC.Application\Common\ReportGenerator.cs:line 203 at eFC.BT.BTAppService.DownloadPdfAsync(DownloadPdfDto input) in C:\DIM\OctRelease\eFC\src\src\eFC.Application\BT\BTAppService.cs:line 780 at lambda_method4575(Closure, Object) at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
2026-04-13 14:27:07.103 +08:00 [ERR] An error occurred using a transaction.
2026-04-13 14:27:08.505 +08:00 [ERR] ---------- RemoteServiceErrorInfo ----------
{
"code": null,
"message": "An internal error occurred during your request!",
"details": null,
"data": {},
"validationErrors": null
}
I am currently using ABP Framework v8.2.3 with the following setup:
UI Type: React Database System: EF Core (SQL Server) Auth Server Separated: Yes .NET Version: .NET 8
I have identified a vulnerability in one of the transitive dependencies used by ABP: Scriban@5.9.0 (Transitive) Scriban versions prior to 7.0.0 are affected by a CWE‑693 Protection Mechanism Failure, where TemplateContext caches type member accessors by Type only. If a TemplateContext instance is reused and the MemberFilter or MemberRenamer is tightened for later renders, Scriban may continue to expose members that should now be restricted. I understand that this issue is fixed in Scriban 7.0.0+, but upgrading to that version would require .NET 9, which I am not able to migrate to at this time. I would like to stay on ABP 8.2.3 and .NET 8.
My question is: Is there a recommended mitigation or usage pattern within ABP to safely address this Scriban issue without upgrading the framework or runtime?
Thank you.
ABP Framework version: v8.2.3
UI Type: React
Database System: EF Core (SQL Server)
Tiered (for MVC) or Auth Server Separated (for Angular): yes
I am currently using ABP Framework 8.2.3 and have identified the following vulnerabilities in my project dependencies:
select2@4.0.13 (Transitive) Select2 versions prior to 4.0.8 are vulnerable to Cross-Site Scripting (XSS). This occurs in scenarios where rich select lists use AJAX-based remote data loading along with HTML templates to render list items, allowing potentially unsafe HTML to be injected and executed. AutoMapper@13.0.1 (Transitive) AutoMapper is vulnerable to a Denial-of-Service (DoS) attack. In versions prior to 15.1.1 (and 16.x prior to 16.1.1), mapping deeply nested object graphs can lead to unbounded recursive calls, potentially causing a StackOverflowException and terminating the application.
At the moment, I am unable to upgrade the ABP Framework version because I want to remain on .NET 8 and avoid moving to .NET 9.
My question is: Is there a recommended way to mitigate or fix these vulnerabilities without upgrading the ABP Framework version? For example:
Can these transitive dependencies be safely overridden? Are there configuration-based mitigations (e.g., limiting mapping depth in AutoMapper)? Any best practices to address such issues in ABP without a full framework upgrade?
ABP Framework version: v8.2.3
UI Type: React
Database System: EF Core (SQL Server)
Tiered (for MVC) or Auth Server Separated (for Angular): yes
How to get the current retry count of any background job, my requirement is if all retry count is finished (which is 10 in my case), I need to add that job in a table and give flexibility to the user to re-run it (if required).
[maliming] said: hi
You can enable the Debug log first and then reproduce the error and share logs
Set
.MinimumLevel.Debug()everywhere.var loggerConfiguration = new LoggerConfiguration() .MinimumLevel.Debug() .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) .Enrich.FromLogContext() .WriteTo.Async(c => c.File("Logs/logs.txt"))Thanks
this is already there in my application, let me know if I need to add or remove anything else?