feat(audit): Apply TreatWarningsAsErrors=true to 160+ production csproj files

Sprint: SPRINT_20251229_049_BE_csproj_audit_maint_tests
Tasks: AUDIT-0001 through AUDIT-0147 APPLY tasks (approved decisions 1-9)

Changes:
- Set TreatWarningsAsErrors=true for all production .NET projects
- Fixed nullable warnings in Scanner.EntryTrace, Scanner.Evidence,
  Scheduler.Worker, Concelier connectors, and other modules
- Injected TimeProvider/IGuidProvider for deterministic time/ID generation
- Added path traversal validation in AirGap.Bundle
- Fixed NULL handling in various cursor classes
- Third-party GostCryptography retains TreatWarningsAsErrors=false (preserves original)
- Test projects excluded per user decision (rejected decision 10)

Note: All 17 ACSC connector tests pass after snapshot fixture sync
This commit is contained in:
StellaOps Bot
2026-01-04 11:21:16 +02:00
parent bc4dd4f377
commit e411fde1a9
438 changed files with 2648 additions and 668 deletions

View File

@@ -29,9 +29,9 @@ internal sealed record RuNkckiCursor(
{
var document = new DocumentObject
{
["pendingDocuments"] = new DocumentArray(PendingDocuments.Select(id => id.ToString())),
["pendingMappings"] = new DocumentArray(PendingMappings.Select(id => id.ToString())),
["knownBulletins"] = new DocumentArray(KnownBulletins),
["pendingDocuments"] = new DocumentArray(PendingDocuments.OrderBy(id => id).Select(id => id.ToString())),
["pendingMappings"] = new DocumentArray(PendingMappings.OrderBy(id => id).Select(id => id.ToString())),
["knownBulletins"] = new DocumentArray(KnownBulletins.OrderBy(id => id, StringComparer.Ordinal)),
};
if (LastListingFetchAt.HasValue)

View File

@@ -339,7 +339,7 @@ public sealed class RuNkckiConnector : IFeedConnector
}
var doc = StellaOps.Concelier.Documents.DocumentObject.Parse(JsonSerializer.Serialize(dto, SerializerOptions));
var dtoRecord = new DtoRecord(Guid.NewGuid(), document.Id, SourceName, "ru-nkcki.v1", doc, _timeProvider.GetUtcNow());
var dtoRecord = new DtoRecord(ComputeDeterministicId(document.Id.ToString(), "ru-nkcki/1.0"), document.Id, SourceName, "ru-nkcki.v1", doc, _timeProvider.GetUtcNow());
await _dtoStore.UpsertAsync(dtoRecord, cancellationToken).ConfigureAwait(false);
await _documentStore.UpdateStatusAsync(document.Id, DocumentStatuses.PendingMap, cancellationToken).ConfigureAwait(false);
@@ -609,7 +609,7 @@ public sealed class RuNkckiConnector : IFeedConnector
return false;
}
var recordId = existing?.Id ?? Guid.NewGuid();
var recordId = existing?.Id ?? ComputeDeterministicId(documentUri, "ru-nkcki-doc/1.0");
_ = await _rawDocumentStorage.UploadAsync(SourceName, documentUri, payload, "application/json", null, cancellationToken, recordId).ConfigureAwait(false);
var metadata = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
@@ -725,12 +725,12 @@ public sealed class RuNkckiConnector : IFeedConnector
return new ListingPageResult(attachments, uniquePagination);
}
private static string DeriveBulletinId(Uri uri)
private string DeriveBulletinId(Uri uri)
{
var fileName = Path.GetFileName(uri.AbsolutePath);
if (string.IsNullOrWhiteSpace(fileName))
{
return Guid.NewGuid().ToString("N");
return ComputeDeterministicSlug(uri.AbsoluteUri, "bulletin-id");
}
if (fileName.EndsWith(".zip", StringComparison.OrdinalIgnoreCase))
@@ -746,7 +746,7 @@ public sealed class RuNkckiConnector : IFeedConnector
return fileName.Replace('_', '-');
}
private static string BuildDocumentUri(RuNkckiVulnerabilityDto dto)
private string BuildDocumentUri(RuNkckiVulnerabilityDto dto)
{
if (!string.IsNullOrWhiteSpace(dto.FstecId))
{
@@ -761,7 +761,10 @@ public sealed class RuNkckiConnector : IFeedConnector
return $"https://nvd.nist.gov/vuln/detail/{dto.MitreId}";
}
return $"https://cert.gov.ru/materialy/uyazvimosti/{Guid.NewGuid():N}";
// Fallback: deterministic slug based on dto content
var dtoJson = JsonSerializer.Serialize(dto, SerializerOptions);
var slug2 = ComputeDeterministicSlug(dtoJson, "nkcki-doc");
return $"https://cert.gov.ru/materialy/uyazvimosti/{slug2}";
}
private string ResolveCacheDirectory(string? configuredPath)
@@ -791,7 +794,7 @@ public sealed class RuNkckiConnector : IFeedConnector
private string GetBulletinCachePath(string bulletinId)
{
var fileStem = string.IsNullOrWhiteSpace(bulletinId)
? Guid.NewGuid().ToString("N")
? ComputeDeterministicSlug("unknown-bulletin", _timeProvider.GetUtcNow().ToString("O"))
: Uri.EscapeDataString(bulletinId);
return Path.Combine(_cacheDirectory, $"{fileStem}.json.zip");
}
@@ -947,4 +950,17 @@ public sealed class RuNkckiConnector : IFeedConnector
return new ListingFetchSummary(attachments, visited);
}
private Guid ComputeDeterministicId(string source, string identifier)
{
var input = Encoding.UTF8.GetBytes($"{source}:{identifier}");
var hash = _hash.ComputeHash(input, HashAlgorithms.Sha256);
return new Guid(hash.AsSpan()[..16]);
}
private string ComputeDeterministicSlug(string source, string identifier)
{
var input = Encoding.UTF8.GetBytes($"{source}:{identifier}");
return _hash.ComputeHashHex(input, HashAlgorithms.Sha256)[..32];
}
}

View File

@@ -5,6 +5,7 @@
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>