Conversation
📝 WalkthroughWalkthroughThese changes implement a multi-layered security hardening and optimization framework for the Docker environment. HTTP security headers are added to nginx configuration, a dynamic Content-Security-Policy system generates policies from environment variables, and a post-build script extracts and externalizes inline JavaScript from Next.js output. Changes
Sequence Diagram(s)sequenceDiagram
participant Build as Build System
participant NextJS as Next.js Export
participant HTML as HTML Files
participant PostBuild as postbuild.js
participant Assets as Assets Directory
Build->>NextJS: Run build & export
NextJS->>HTML: Generate HTML with inline scripts
Build->>PostBuild: Execute postbuild script
PostBuild->>HTML: Find all HTML files recursively
PostBuild->>HTML: Extract inline script contents
PostBuild->>PostBuild: Aggregate & clean script contents
PostBuild->>PostBuild: Generate MD5 hash
PostBuild->>Assets: Write chunk.<hash>.js
PostBuild->>HTML: Replace inline scripts with<br/>external script references
PostBuild->>Build: Script execution complete
sequenceDiagram
participant Env as Environment Variables
participant InitScript as init_react_envs.sh
participant CSPBuilder as CSP Assembly Logic
participant Nginx as Nginx Config
participant Server as Nginx Server
Env->>InitScript: Provide CSP/auth/domain vars
InitScript->>InitScript: Check NETBIRD_DISABLE_CSP
alt CSP Enabled
InitScript->>CSPBuilder: Extract policy sources
CSPBuilder->>CSPBuilder: Assemble from multiple sources
CSPBuilder->>CSPBuilder: Deduplicate & format<br/>CONNECT_SRC, FRAME_SRC, SCRIPT_SRC
CSPBuilder->>Nginx: Generate & replace<br/>add_header Content-Security-Policy
else CSP Disabled
InitScript->>Nginx: Remove CSP header
end
InitScript->>Server: Reload nginx
Server->>Server: Apply new configuration
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~28 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@docker/default.conf`:
- Line 21: Replace the permissive placeholder Content-Security-Policy header set
by add_header Content-Security-Policy (the current value including
'unsafe-inline' and 'unsafe-eval') with a fail-closed restrictive default such
as "default-src 'none'; base-uri 'self'; frame-ancestors 'none';" (or similarly
strict minimal policy) for both occurrences where add_header
Content-Security-Policy is used, and ensure init_react_envs.sh still performs
its runtime replacement; update any test or comment referencing the old
permissive value so the script can safely overwrite a restrictive baseline
rather than leaving an insecure fallback.
In `@docker/init_react_envs.sh`:
- Around line 146-150: The current sed invocation that replaces the CSP header
uses "|| { echo ... }" which swallows failures; change it so a failed
replacement becomes fatal: run the sed replacement for the CSP_HEADER into
/etc/nginx/http.d/default.conf without the trailing "||" fallback and
immediately verify the replacement succeeded (e.g., grep or string check that
$CSP_HEADER is present in /etc/nginx/http.d/default.conf) and if the check
fails, write a clear error and exit 1; update the block surrounding the sed call
(the line containing sed -i "s|add_header Content-Security-Policy \"[^\"]*\"
always;|$CSP_HEADER|g") to perform this verification and exit on failure.
🧹 Nitpick comments (6)
postbuild.js (3)
50-56: Redundantsrc=guard, but the regex lookahead is actually overly broad.The negative lookahead
(?![^>]*src)rejects any<script>tag containing the substringsrcanywhere in its attributes — not just thesrc=attribute. This means a tag like<script data-src="...">inline code</script>would be silently skipped. The line 54 guard (attributes.includes("src=")) is more precise but unreachable for such cases because the regex already filters them out.If Next.js ever emits inline scripts with attributes containing "src" as a substring (e.g.,
data-src), they won't be extracted.Consider tightening the lookahead to match only the
srcattribute:Proposed fix
- /<script(?![^>]*src)([^>]*)>(.+?)<\/script>/gs, + /<script(?![^>]*\ssrc[\s=])([^>]*)>(.+?)<\/script>/gs,
71-74: Log message missing the filename being processed.When no inline scripts are found, the log doesn't indicate which file was skipped. With many HTML files, this makes debugging harder.
Proposed fix
- console.log(`No inline scripts found`); + console.log(`No inline scripts found in ${file}`);
44-94: Each HTML file writes its own chunk — consider deduplicating writes.Every HTML file independently hashes its extracted scripts and writes a chunk file. When many pages share identical inline scripts (common in Next.js static exports), the same file is written repeatedly. This isn't a correctness bug, but a single-pass approach (collect all unique chunks first, then rewrite HTML files) would be cleaner and avoid redundant I/O.
docker/init_react_envs.sh (1)
128-138:default.confhas a permissive fallback CSP — document the intent.The static CSP in
default.confis"default-src 'self' 'unsafe-inline' 'unsafe-eval' data: blob: ws: wss: https:;"(essentially allows everything over HTTPS), while the dynamically generated policy here is properly restrictive (default-src 'none', explicit allowlists). This works because the script replaces it at runtime, but if the replacement fails silently (see prior comment), the permissive policy is served. Consider adding a comment indefault.confto make this intentional fallback/placeholder relationship clear.docker/default.conf (2)
15-24: Security headers look good. Consider addingReferrer-PolicyandPermissions-Policy.The set of headers is solid. Two commonly recommended headers that are absent:
Referrer-Policy: strict-origin-when-cross-origin— limits referrer leakage to third parties.Permissions-Policy: camera=(), microphone=(), geolocation=()— explicitly disables browser features the dashboard likely doesn't need.Neither is critical, but they complement the existing hardening nicely.
Also applies to: 27-36
6-13: Wasm location blocks don't inherit the security headers.In nginx,
add_headerin alocationblock replaces — not supplements — directives from the parent. Since there are noadd_headerdirectives at theserverlevel, the wasm locations have zero security response headers. The wasm files themselves aren't a direct risk, but responses withoutX-Content-Type-Options: nosniffcould theoretically be MIME-sniffed.If adding headers to these blocks, be careful not to add
Cache-Control: no-storesince wasm files should be cacheable.
|
Hi! Just wanted to flag that the Without the This PR fixes it correctly by adding Would love to see this merged — the |
Summary by CodeRabbit
Release Notes