Security + performance hardening from production/enterprise audit#70
Closed
ibuilder wants to merge 7 commits into
Closed
Security + performance hardening from production/enterprise audit#70ibuilder wants to merge 7 commits into
ibuilder wants to merge 7 commits into
Conversation
The Vite build already emits .gz/.br siblings but nginx served neither and had no gzip on, so the ~7 MB thatopen chunk shipped raw. Enable gzip_static (serves the precompressed .gz for hashed JS/CSS/wasm) and gzip on with gzip_types so proxied /api/ JSON is compressed too. brotli_static is intentionally omitted: the stock nginx:alpine image has no ngx_brotli module. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add a shared content_disposition() helper that strips path components and CR/LF, emits a quoted ASCII fallback plus an RFC 5987 filename*=UTF-8'' form for non-ASCII names, and route range_response() (attachment + model downloads) through it. A caller-controlled filename can no longer inject header fields or crash latin-1 header encoding. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Sanitize the attacker-controlled UploadFile.filename before joining it to the temp dir so a crafted name can't traverse outside it (path traversal). - Log the converter subprocess stderr server-side and return a generic 502 so internal APS/converter detail no longer leaks to the caller. - Build the .frag / .xyz download Content-Disposition via the shared helper. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…vent loop - Attach a BackgroundTask(os.unlink) to the subset.ifc FileResponse so the server-chosen throwaway file no longer leaks in /tmp. - Wrap the blocking storage.put / zip+XML importers (add_attachment, bcf_import, coordination import xlsx/xml, import_bundle) in run_in_threadpool, mirroring the existing pattern in authoring.py so a big upload can't stall the loop. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The raw upload is capped by AEC_MAX_UPLOAD_MB, but a tiny .bcfzip can still expand to gigabytes in RAM. Add _open_bcfzip() to check each entry's declared uncompressed size and the cumulative total against AEC_MAX_UNZIP_MB (default 512), rejecting oversized archives with 413. defusedxml parsing is unchanged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Every publish spawned a raw daemon Thread, so a burst of uploads could launch N heavy ifcopenshell converts at once and exhaust CPU/RAM. Submit run_publish to a module-level ThreadPoolExecutor sized by AEC_PUBLISH_WORKERS (default 2); excess publishes queue. All 13 call sites funnel through _publish_bg, so this single pool governs the whole app. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
ibuilder
added a commit
that referenced
this pull request
Jul 23, 2026
ibuilder
added a commit
that referenced
this pull request
Jul 23, 2026
Owner
Author
|
Landed in v0.3.586 (merged into main with the full suite re-verified — 313/313 green). Thanks! |
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.
Implements the safe, low-risk hardening items from the production/enterprise audit. All changes are source-local; no architectural rewrites. Each item cites
file:lineevidence from the audit.Performance
Security
Tests
Deferred (separate PRs)
`/metrics` auth (breaks Prometheus scrapers; needs opt-in path), compose CPU/mem limits (OOM risk for legitimate conversion), Dockerfile digest pinning (needs exact platform digests), `npm audit fix` dev/docs chain (lockfile churn), and the architectural items (Alembic migrations, OpenTelemetry tracing, Sentry alerting, on-demand rendering, warm converter worker, chunk splitting, point-cloud worker, streaming uploads/downloads, batch portfolio aggregates, and product gaps: clash detection, IFC version-compare, public API, SOC 2).
```task
file:apps/web/nginx.conf
file:services/api/src/aec_api/bcf_io.py
file:services/api/src/aec_api/routers/authoring.py
file:services/api/src/aec_api/routers/bim.py
file:services/api/src/aec_api/routers/convert.py
file:services/api/src/aec_api/serving.py
```