5.6 KiB
QA Security Audit Report
Date: December 12, 2025 QA Agent: QA_Security Scope: CrowdSec preset apply bug fix, regression tests, Markdownlint integration Overall Status: ✅ PASS
Summary
| Check | Status | Details |
|---|---|---|
| CrowdSec Tests | ✅ PASS | All 62 tests pass in internal/crowdsec/... |
| Backend Build | ✅ PASS | go build ./... compiles without errors |
| Pre-commit | ✅ PASS | All hooks pass (85.1% coverage met) |
| JSON Validation | ✅ PASS | All JSON/JSONC files valid |
| YAML Validation | ✅ PASS | .pre-commit-config.yaml valid |
1. CrowdSec Preset Apply Bug Fix
File: hub_sync.go
Fix Description
The bug fix addresses an issue where the preset archive file handle could become invalid during the apply process. The root cause was that the backup step was moving files that were still being referenced by the cache.
Key Fix (Lines 530-543)
// Read archive into memory BEFORE backup, since cache is inside DataDir.
// If we backup first, the archive path becomes invalid (file moved).
var archive []byte
var archiveReadErr error
if metaErr == nil {
archive, archiveReadErr = os.ReadFile(meta.ArchivePath)
if archiveReadErr != nil {
logger.Log().WithError(archiveReadErr).WithField("archive_path", meta.ArchivePath).
Warn("failed to read cached archive before backup")
}
}
Verification
✅ The fix ensures the archive is read into memory before any backup operations modify the file system.
2. Regression Tests
File: hub_pull_apply_test.go
Test Coverage
The new regression tests verify the pull-then-apply workflow:
| Test Name | Purpose | Status |
|---|---|---|
TestPullThenApplyFlow |
End-to-end pull → cache → apply | ✅ PASS |
TestApplyRepullsOnCacheMissAfterCSCLIFailure |
Cache refresh on miss | ✅ PASS |
TestApplyRepullsOnCacheExpired |
Cache refresh on TTL expiry | ✅ PASS |
TestApplyReadsArchiveBeforeBackup |
Archive memory load before backup | ✅ PASS |
TestBackupPathOnlySetAfterSuccessfulBackup |
Backup state integrity | ✅ PASS |
TestApplyWithOpenFileHandles |
File handle safety | ✅ PASS |
Test Execution Output
=== RUN TestPullThenApplyFlow
hub_pull_apply_test.go:90: Step 1: Pulling preset
hub_pull_apply_test.go:110: Step 2: Verifying cache can be loaded
hub_pull_apply_test.go:117: Step 3: Applying preset from cache
--- PASS: TestPullThenApplyFlow (0.00s)
3. Markdownlint Integration
Files Modified
| File | Status | Notes |
|---|---|---|
.markdownlint.json |
✅ Valid | Line length 120, code blocks 150 |
.pre-commit-config.yaml |
✅ Valid | Markdownlint hook added (manual stage) |
.vscode/tasks.json |
✅ Valid | JSONC format with lint tasks |
package.json |
✅ Valid | markdownlint-cli2 devDependency |
Markdownlint Configuration
File: .markdownlint.json
{
"default": true,
"MD013": {
"line_length": 120,
"heading_line_length": 120,
"code_block_line_length": 150,
"tables": false
},
"MD024": { "siblings_only": true },
"MD033": {
"allowed_elements": ["details", "summary", "br", "sup", "sub", "kbd", "img"]
},
"MD041": false,
"MD046": { "style": "fenced" }
}
Pre-commit Integration
File: .pre-commit-config.yaml (Lines 118-124)
- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.43.0
hooks:
- id: markdownlint
args: ["--fix"]
exclude: '^(node_modules|\.venv|test-results|codeql-db|codeql-agent-results)/'
stages: [manual]
VS Code Tasks
File: .vscode/tasks.json
Two new tasks added:
Lint: Markdownlint- Check markdown filesLint: Markdownlint Fix- Auto-fix markdown issues
4. Validation Results
JSON/YAML Syntax Validation
✓ .markdownlint.json is valid JSON
✓ package.json is valid JSON
✓ .vscode/tasks.json is valid JSONC (with comments stripped)
✓ .pre-commit-config.yaml is valid YAML
Backend Build
$ cd /projects/Charon/backend && go build ./...
# No errors
Pre-commit Hooks
Go Build & Test......................................................Passed
Go Vet...............................................................Passed
Check .version matches latest Git tag................................Passed
Prevent large files that are not tracked by LFS......................Passed
Prevent committing CodeQL DB artifacts...............................Passed
Prevent committing data/backups files................................Passed
Frontend TypeScript Check............................................Passed
Frontend Lint (Fix)..................................................Passed
Coverage: 85.1% (minimum required: 85%) ✅
5. Security Notes
- ✅ No secrets or sensitive data exposed
- ✅ File path sanitization in place (
sanitizeSlug,filepath.Clean) - ✅ Archive size limits enforced (25 MiB max)
- ✅ Symlink rejection in tar extraction (path traversal prevention)
- ✅ Graceful error handling with rollback on failure
Conclusion
All verification steps pass. The CrowdSec preset apply bug fix correctly reads the archive into memory before backup operations, preventing file handle invalidation. The new regression tests provide comprehensive coverage for the pull-apply workflow. Markdownlint integration is properly configured for manual linting.
Status: ✅ PASS - Ready for merge