Security hardening for authentication, uploads, and public endpoints#3895
Draft
bbingz wants to merge 85 commits into
Draft
Security hardening for authentication, uploads, and public endpoints#3895bbingz wants to merge 85 commits into
bbingz wants to merge 85 commits into
Conversation
Author
|
Security hardening status update (head
|
This was referenced May 30, 2026
Author
|
Splitting this broad draft into smaller reviewable PRs. Opened slices:
This PR can remain as the umbrella branch/evidence bundle for the full HuWang hardening set. The smaller PRs are intended to be reviewed and merged independently where possible. Current note: #3896 still needs Snyk org visibility because the Snyk check reports private failures without public details. #3897 has Snyk green and is waiting on Azure. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This draft PR contains a security hardening pass across authentication, authorization, password storage, upload handling, preview rendering, editor XSS filtering, public STL endpoints, public SMS endpoints, login and search rate-limit counter concurrency, security response headers, request/form size limits, cloud token storage, SSRF-sensitive downloads, SQL-sensitive template filters, raw STL where-clause validation, regex-sensitive search highlighting, ZIP extraction safety, plugin upload/install staging, cloud restore object-key validation, Docker example secrets, public source-map exposure, public UEditor sample config exposure, STL include recursion limiting, one-time SMS code consumption, signed trigger replay limiting, and NuGet/npm dependency posture.
Key changes include:
wwwrootand remove public references to the removed mapswwwrootwhile keeping the runtime editor config on the backend/common/editorpathstl:includerecursion depth and restore include parser state withfinallyafter nested parsingPathManager.ExtractZipHttpClientUtilsandRestUtils, including non-HTTP(S), private, loopback, link-local, reserved-IP, and unsafe redirect targetswherecondition fragments before feeding them intoWhereRawor legacy SQL-string paths, rejecting comments, statement separators, unterminated literals, and compound/mutating SQL keywordsVerification
Passed:
/opt/homebrew/opt/dotnet@8/bin/dotnet test tests/SSCMS.Web.Tests/SSCMS.Web.Tests.csproj --filter "FullyQualifiedName~PublicSourceMapTests|FullyQualifiedName~DockerExampleSecurityTests|FullyQualifiedName~UeditorXssFilterConfigTests|FullyQualifiedName~StlIncludeSafetyTests|FullyQualifiedName~CloudRestoreSafetyTests|FullyQualifiedName~SmsCodeConsumptionSourceTests|FullyQualifiedName~PluginUploadInstallSourceTests|FullyQualifiedName~ZipExtractionSafetyTests|FullyQualifiedName~PasswordHashUtilsTests|FullyQualifiedName~PasswordStorageSourceTests|FullyQualifiedName~SecurityHeadersTests|FullyQualifiedName~CloudTokenStorageTests|FullyQualifiedName~PreviewControllerAuthorizationTests|FullyQualifiedName~HomeSmsRateLimitTests|FullyQualifiedName~ChannelRepositorySqlSafetyTests|FullyQualifiedName~RestUtilsTests|FullyQualifiedName~SitesControllerTests|FullyQualifiedName~AuthManagerPermissionsTests|FullyQualifiedName~AgentControllerTests|FullyQualifiedName~ContentsControllerTests|FullyQualifiedName~RequestSizeLimitTests|FullyQualifiedName~PathManagerUploadImageTests|FullyQualifiedName~UsersControllerTests|FullyQualifiedName~DatabaseManagerSqlSafetyTests|FullyQualifiedName~ActionsDownloadControllerTests|FullyQualifiedName~ActionsHitsControllerTests|FullyQualifiedName~ActionsTriggerControllerTests|FullyQualifiedName~ActionsPublicRateLimitTests|FullyQualifiedName~ActionsPageContentsControllerTests|FullyQualifiedName~AdministratorsControllerTests|FullyQualifiedName~LoginControllerTests|FullyQualifiedName~LostPasswordControllerTests|FullyQualifiedName~FormDataAddControllerTests|FullyQualifiedName~ActionsControllerTests|FullyQualifiedName~Admin.Cms.Editor.EditorControllerTests|FullyQualifiedName~Home.Write.EditorControllerTests|FullyQualifiedName~ContentsLayerAddControllerTests|FullyQualifiedName~ContentImportCheckPermissionTests|FullyQualifiedName~ErrorControllerAuthorizationTests|FullyQualifiedName~StartupAuthenticationTests|FullyQualifiedName~Admin.Settings.Administrators.AdministratorsControllerTests" --no-restore- 118 passed/opt/homebrew/opt/dotnet@8/bin/dotnet test tests/SSCMS.Web.Tests/SSCMS.Web.Tests.csproj --filter "FullyQualifiedName~PublicSourceMapTests" --no-restore- 2 passed/opt/homebrew/opt/dotnet@8/bin/dotnet test tests/SSCMS.Web.Tests/SSCMS.Web.Tests.csproj --filter "FullyQualifiedName~DockerExampleSecurityTests" --no-restore- 5 passed/opt/homebrew/opt/dotnet@8/bin/dotnet test tests/SSCMS.Web.Tests/SSCMS.Web.Tests.csproj --filter "FullyQualifiedName~UeditorXssFilterConfigTests" --no-restore- 2 passed/opt/homebrew/opt/dotnet@8/bin/dotnet test tests/SSCMS.Web.Tests/SSCMS.Web.Tests.csproj --filter "FullyQualifiedName~StlIncludeSafetyTests" --no-restore- 2 passed/opt/homebrew/opt/dotnet@8/bin/dotnet test tests/SSCMS.Web.Tests/SSCMS.Web.Tests.csproj --filter "FullyQualifiedName~CloudRestoreSafetyTests" --no-restore- 8 passed/opt/homebrew/opt/dotnet@8/bin/dotnet test tests/SSCMS.Web.Tests/SSCMS.Web.Tests.csproj --filter "FullyQualifiedName~ActionsTriggerControllerTests" --no-restore- 3 passed/opt/homebrew/opt/dotnet@8/bin/dotnet test tests/SSCMS.Web.Tests/SSCMS.Web.Tests.csproj --filter "FullyQualifiedName~ZipExtractionSafetyTests" --no-restore- 3 passed/opt/homebrew/opt/dotnet@8/bin/dotnet test tests/SSCMS.Web.Tests/SSCMS.Web.Tests.csproj --filter "FullyQualifiedName~SmsCodeConsumptionSourceTests" --no-restore- 8 passed/opt/homebrew/opt/dotnet@8/bin/dotnet test tests/SSCMS.Web.Tests/SSCMS.Web.Tests.csproj --filter "FullyQualifiedName~PluginUploadInstallSourceTests" --no-restore- 2 passedrg --files src/SSCMS.Web/wwwroot | rg '\.map$'- no published source maps remainSSCMS_SECURITY_KEY=00000000-0000-4000-8000-000000000001 SSCMS_DATABASE_PASSWORD=change-me SSCMS_MYSQL_ROOT_PASSWORD=change-root docker compose -f docker/mysql/docker-compose.yml configSSCMS_SECURITY_KEY=00000000-0000-4000-8000-000000000001 SSCMS_DATABASE_PASSWORD=change-me docker compose -f docker/postgres/docker-compose.yml configSSCMS_SECURITY_KEY=00000000-0000-4000-8000-000000000001 SSCMS_REDIS_PASSWORD=change-redis docker compose -f docker/cluster/docker-compose.yml configgit diff --check/opt/homebrew/opt/dotnet@8/bin/dotnet build sscms.sln -v:minimal/opt/homebrew/opt/dotnet@8/bin/dotnet list /Users/bing/-Code-/cms-official-security-pr/sscms.sln package --vulnerable --include-transitive- no vulnerable packages reported for all projectsNot fully runnable in this local environment:
SSCMS.Web.Testsincludes an integration/api/pingpath that currently returns 500 becausesettingsManager.SecurityKeyis null in the test host configurationSSCMS.Testsaborts becauseAngleSharp.dllis missing from the testhost dependency outputSSCMS.Core.Testsdirect execution aborts in this environment becauseAliyun.OSS.Core.dllis missing from the testhost dependency outputRemaining security work intentionally not mixed into this draft
Update after CI feedback:
Skipped Win32 application icons on non-Windows builds so Linux CI does not compile Windows resources from
.icofiles.Regenerated npm lockfile as v2 so Node 12/npm 6 and Snyk-compatible scanners can consume the committed dependency graph.
Updated .NET Docker base images from old/floating tags to supported
8.0-bookworm-slimtags.Removed a committed ASP.NET DataProtection key file and isolated WebApplicationFactory test keys into a temp directory.
Regenerated malformed Windows
.icoresources that failed .NET 8 Win32 resource compilation.Disabled broken Win32 application icon resource compilation so .NET 8 Windows CI can build.