Kaynağa Gözat

csp update

CR023
Jason Chuang 16 saat önce
ebeveyn
işleme
e10a788123
4 değiştirilmiş dosya ile 201 ekleme ve 1 silme
  1. +2
    -1
      docs/csp-apache.conf.md
  2. +1
    -0
      docs/csp-report-review-2026-08-03.md
  3. +1
    -0
      docs/csp-report-review-2026-08-14.md
  4. +197
    -0
      docs/csp-report-review-2026-09-22.md

+ 2
- 1
docs/csp-apache.conf.md Dosyayı Görüntüle

@@ -7,7 +7,8 @@ Adjust `report-uri` if your API base path or host differs (UAT example below; PR
See also:

- [permissions-policy-apache.conf.md](./permissions-policy-apache.conf.md) — Permissions-Policy reporting via the same `/api/csp-report` URL
- [csp-report-review-2026-08-14.md](./csp-report-review-2026-08-14.md) — latest PROD + UAT report review and add/remove summary
- [csp-report-review-2026-09-22.md](./csp-report-review-2026-09-22.md) — latest PROD report review (`All_CSP.txt`)
- [csp-report-review-2026-08-14.md](./csp-report-review-2026-08-14.md) — earlier PROD + UAT report review and add/remove summary
- [csp-report-review-2026-08-03.md](./csp-report-review-2026-08-03.md) — earlier PROD report analysis that drove `frame-src` / `media-src` updates

## Enforcing


+ 1
- 0
docs/csp-report-review-2026-08-03.md Dosyayı Görüntüle

@@ -13,6 +13,7 @@ Related app docs:

- [csp-apache.conf.md](./csp-apache.conf.md) — Apache header snippets to deploy
- [csp-report-review-2026-08-14.md](./csp-report-review-2026-08-14.md) — later PROD + UAT review (add/remove summary)
- [csp-report-review-2026-09-22.md](./csp-report-review-2026-09-22.md) — later PROD review (`All_CSP.txt`)

---



+ 1
- 0
docs/csp-report-review-2026-08-14.md Dosyayı Görüntüle

@@ -14,6 +14,7 @@ Related app docs:

- [csp-apache.conf.md](./csp-apache.conf.md) — Apache header snippets to deploy
- [csp-report-review-2026-08-03.md](./csp-report-review-2026-08-03.md) — earlier PROD review
- [csp-report-review-2026-09-22.md](./csp-report-review-2026-09-22.md) — later PROD review (`All_CSP.txt`)

---



+ 197
- 0
docs/csp-report-review-2026-09-22.md Dosyayı Görüntüle

@@ -0,0 +1,197 @@
# CSP Report Review (PROD, 2026-09-22)

Review of Content-Security-Policy-Report-Only violations from PNSPS PROD
(`https://pnsps.gld.gov.hk`).

Source logs (external):

- `All_CSP.txt` — 196 reports, 2026-08-27 to 2026-09-17

Related app docs:

- [csp-apache.conf.md](./csp-apache.conf.md) — Apache header snippets to deploy
- [csp-report-review-2026-08-14.md](./csp-report-review-2026-08-14.md) — earlier PROD + UAT review
- [csp-report-review-2026-08-03.md](./csp-report-review-2026-08-03.md) — earlier PROD review

---

## Verdict

**No app-side CSP concern in this dump.** Almost every line is a browser
extension, not PNSPS code. `/proof/reply/{id}` is just a busy authenticated
page, so the same extension noise shows up there a lot.

CSP is still **Report-Only** (`disposition: report`) — the browser logged these
hits and **did not block the page**.

The 2026-08-14 app-owned issue (proof PDF preview `frame-src`) is **gone** from
this dump. Live PROD now includes `frame-src 'self' data: blob:;`.

---

## Add / remove summary

**PROD — add nothing required. Remove nothing.**

Keep `script-src 'self'`. Do not add `'unsafe-inline'`, `'unsafe-eval'`, or
`'wasm-unsafe-eval'`.

**Optional (low priority, already in [csp-apache.conf.md](./csp-apache.conf.md)):**

```apache
media-src 'self' blob: data:;
```

Live PROD is still `media-src 'self' blob:` (no `data:`). This dump has only
2 matching hits in three weeks.

**Do not add:** `'wasm-unsafe-eval'`, Perplexity CDN, Youdao, NetEase CDN,
Google Fonts.

---

## Confirmed current PROD policy (Report-Only)

This is the live header that generated every report in `All_CSP.txt`. It matches
`original-policy` in all 196 violations.

```apache
Header always set Content-Security-Policy-Report-Only "default-src 'self'; \
base-uri 'self'; \
object-src 'none'; \
frame-ancestors 'none'; \
frame-src 'self' data: blob:; \
form-action 'self'; \
script-src 'self'; \
style-src 'self' 'unsafe-inline'; \
style-src-elem 'self' 'unsafe-inline'; \
img-src 'self' data:; \
media-src 'self' blob:; \
font-src 'self' data:; \
connect-src 'self'; \
upgrade-insecure-requests; \
report-uri https://pnsps.gld.gov.hk/api/csp-report"
```

Changes vs the 2026-08-14 live header:

- `frame-src 'self' data: blob:;` is now present.
- `img-src` no longer allowlists `https://www.w3.org` / `https://w3.org`
(badge is hosted locally).

`style-src 'unsafe-inline'` is expected for MUI and is the only real policy
weakness. These reports do not show a new XSS issue.

---

## Summary of findings

| Count | Directive | Blocked | Verdict |
|---:|---|---|---|
| **192** | `script-src` | `wasm-eval` | Noise — Chrome extension |
| 2 | `media-src` | `data` | Optional leftover — `data:` not in live `media-src` |
| 1 | `font-src` | `frontend-cdn.perplexity.ai` … `FKGroteskNeue.woff2` | Noise — Perplexity sidebar |
| 1 | `img-src` | `ydlunacommon-cdn.nosdn.127.net` … `.svg` | Noise — Youdao / NetEase plugin |

No `frame-src` reports. No app `eval`. No Google Fonts.

---

## Why `wasm-eval` volume is high

192 of 196 reports (98%) are `script-src` / `wasm-eval`.

| Count | `source-file` | Notes |
|---:|---|---|
| 103 | `chrome-extension` | Every one with a location is **line 23, column 39316** — the same injected script |
| 89 | (none) | Chrome often sends a second report for the same violation without `source-file` |

About 46 timestamps have 2+ reports in the same second (paired duplicates).
That is why the log looks twice as large as the number of real events.

Password managers, translators, Grammarly-style tools, and similar extensions
compile WebAssembly into the page. `script-src 'self'` (without
`'wasm-unsafe-eval'`) reports that. Do **not** loosen `script-src` to silence
it.

If quieter logs are needed, filter `blocked-uri=wasm-eval` plus
`source-file=chrome-extension` (and the paired empty-source twin).

---

## Why many `/proof/reply` reports

| Count | Page group |
|---:|---|
| 90 | `/login` |
| **38** | `/proof/reply/{id}` |
| 23 | `/publicNotice/{id}` |
| 15 | `/publicNotice/apply` |
| 10 | `/publicNotice` |
| 10 | `/proof/search` |
| 4 | `/paymentPage/*` |
| 3 | `/user/changePassword` |
| 2 | `/registerFromOrganization` |
| 1 | `/verify/*` |

The 38 Reply Proof hits span **12 proof IDs** (`29518`, `29948`, `30112`,
`30114`, `30134`, `30166`, `30190`, `30266`, `30306`, `30326`, `30484`,
`30958`). They are the same `wasm-eval` + Chrome extension pattern as login,
apply, and notice detail.

Reply Proof is a long, authenticated screen. Anyone with a WASM extension
triggers a report on every visit. **No Reply Proof code change is required.**

---

## Not a PNSPS SPA problem — do not allowlist

| Count | Page | Directive | Blocked | Why ignore |
|---:|---|---|---|---|
| 192 | many (login 90, reply 38, …) | `script-src` | `wasm-eval` | `chrome-extension` (line 23, col 39316) or paired empty source |
| 1 | `/login` | `font-src` | Perplexity `FKGroteskNeue.woff2` | Sidebar / extension |
| 1 | `/login` | `img-src` | NetEase `ydlunacommon-cdn.nosdn.127.net` | Youdao-style translator |
| 2 | `/publicNotice/apply`, `/proof/reply/30166` | `media-src` | `data` | Optional `data:` gap only; 2 hits in three weeks |

`status-code: 404` on 166 reports is typical SPA client-route noise, not a
broken document.

---

## Optional: `media-src` and `data:`

Live policy: `media-src 'self' blob:;`

Captcha audio already uses `blob:` (`CustomFormWizard.js` and similar). Adding
`data:` is low risk and already documented:

```apache
media-src 'self' blob: data:;
```

Not required for this dump.

---

## Recommended actions

1. **No Apache change required** for these reports. `frame-src` deploy from
2026-08-14 looks effective (zero `frame-src` hits here).
2. Keep PROD at `script-src 'self'`. Do not add `'unsafe-eval'` or
`'wasm-unsafe-eval'`.
3. Optional: add `data:` to `media-src` to match
[csp-apache.conf.md](./csp-apache.conf.md).
4. Keep Report-Only until remaining volume is understood as extension noise;
then promote the same policy to enforcing.
5. Optional log hygiene: drop or sample `wasm-eval` + `chrome-extension` so
real app regressions stay visible.

No application code change is required.

---

## Backend reference

- Report endpoint: `POST /csp-report` (context path → `/api/csp-report`)
- Controller: `CspReportController` in PNSPS-backend
- Frontend/Apache CSP above is what browsers apply to the SPA document

Yükleniyor…
İptal
Kaydet