apache / apache/fineract-backoffice-ui

The production CSP blocks Angular's critical-CSS onload and the federation blob: module, so the main stylesheet never applies in the container

Open
#360 0 comments 0 reactions 0 assignees View on GitHub
angular bug ci typescript
Dominant language
TypeScript
Stars
15
Forks
60
Avg merge
10h 15m
Merged PRs (30d)
108

Description

Found while verifying the removal of the Google Fonts dependency. **Neither defect is caused by that work** — both reproduce on `main` @ `82e9a209`. Filing separately so the font change stays scoped.

Both are the same class of problem: `deploy/nginx.conf` sets a strict `script-src 'self'`, and Angular's production output depends on script execution that the policy correctly refuses. The CSP is right; the build output is what does not fit it.

## 1. The main stylesheet never applies — `media` stays `print`

Angular's `inlineCritical` optimisation emits a deferred stylesheet:

```html

```

`script-src 'self'` carries no `'unsafe-inline'` and no `'unsafe-hashes'`, so the inline `onload` handler is blocked and `media` never flips to `all`:

```
[error] Executing inline event handler violates the following Content Security Policy
directive 'script-src 'self''. Either the 'unsafe-inline' keyword, a hash
('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution.
... The action has been blocked.
```

Measured in Chrome against a container built from `deploy/Dockerfile`, and against the same build served without the CSP header:

| | behind the production CSP | same build, no CSP |
| --- | --- | --- |
| `link[rel=stylesheet].media` | `print` | `all` |

With JavaScript enabled the `` fallback does not apply either, so only the inlined critical CSS takes effect on screen — the Ionic bundle and the compiled component styles do not.

## 2. The federation `blob:` module is blocked

```
[error] Loading the script 'blob:http://.../' violates the following Content Security
Policy directive: "script-src 'self'". Note that 'script-src-elem' was not explicitly
set, so 'script-src' is used as a fallback. The action has been blocked.
[error] Uncaught TypeError: Failed to fetch dynamically imported module: blob:http://.../
```

`es-module-shims` / `@angular-architects/native-federation` builds a module as a `blob:` URL and imports it. `script-src 'self'` does not cover `blob:`, so the dynamic import fails.

## Reproduce

```bash
docker build -f deploy/Dockerfile -t fbui:csp-check .
docker run --rm -d --name fbui-csp -p 8080:80 fbui:csp-check
# open http://127.0.0.1:8080/ and read the browser console
```

On `82e9a209` the console shows 39 errors. 35 of them were blocked Google Fonts requests and are gone once the webfont is removed; **these 4 remain**.

## Possible directions

Deliberately not proposing a fix — each option trades away part of a CSP the project configured on purpose, so the choice deserves its own discussion:

1. `"optimization": { "styles": { "inlineCritical": false } }` in the production configuration of `angular.json`. Removes the `onload` pattern entirely at the cost of a small first-paint regression. Addresses defect 1 only, and is the smallest change.
2. Admitting `blob:` to `script-src` for defect 2. This widens the policy, and is worth weighing against whether native federation needs to be active in the shipped artifact at all.
3. A nonce-based CSP via `ngCspNonce`, which requires the static nginx server to inject a per-response nonce. Largest change, and the only one that keeps both the strict policy and the current build output.

Whichever is chosen, `scripts/ga-check.mjs` is the natural place to gate it, alongside the existing `headers` gate — a rendering defect that only appears behind the production CSP is exactly the kind that survives review otherwise.

## References

- `security.md` §4 — the trust boundary the CSP sits on
- `deploy/nginx.conf` — the policy in question
- `DOCS/FONTS.md` — the font change during which this surfaced

Contributor guide

Open the contributing guide

Research direction

Start by building and running deploy/Dockerfile as described, then compare the browser console and stylesheet media behavior behind the CSP. Read angular.json, deploy/nginx.conf, scripts/ga-check.mjs, and security.md §4 before choosing among the listed directions. Done means the production container no longer exhibits the four remaining CSP-related failures and the regression is covered by the existing gate.

Written by the indexing model from the issue text.

Assessment

Tech stack
angular, docker, nginx, typescript
Domain
devops, frontend, security
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.