security: fix all LOW priority items from TODO.SECURITY.md

Item 13 — Remove deprecated X-XSS-Protection header
- nginx/posterg.conf: header removed (was '1; mode=block')
- nginx/SECURITY_HEADERS.md: new file documenting header decisions
  and explaining why X-XSS-Protection is counterproductive

Item 14 — Add rel="noreferrer" to external target="_blank" link
- public/admin/thanks.php: rel="noopener" → rel="noopener noreferrer"

Item 15 — Explicit (int) casts on all integer HTML outputs
- public/index.php: (int) on item id, page numbers
- public/search.php: (int) on totalItems, year options, item id, pagination

Item 16 — Remove unused DATABASE_PATH constant
- config/bootstrap.php: define('DATABASE_PATH', ...) removed

docs/TODO.SECURITY.md updated: items 13-16 marked resolved and
moved to the  Resolved section.
This commit is contained in:
Théophile Gervreau-Mercier
2026-02-08 11:58:51 +01:00
parent 94d110438f
commit f5d3281c43
8 changed files with 490 additions and 221 deletions

30
nginx/SECURITY_HEADERS.md Normal file
View File

@@ -0,0 +1,30 @@
# Security Headers — nginx/posterg.conf
## Headers in use
| Header | Value | Purpose |
|--------|-------|---------|
| `X-Frame-Options` | `SAMEORIGIN` | Prevent clickjacking |
| `X-Content-Type-Options` | `nosniff` | Prevent MIME-type sniffing |
| `Referrer-Policy` | `strict-origin-when-cross-origin` | Limit referrer leakage |
| `Permissions-Policy` | `geolocation=(), microphone=(), camera=()` | Disable unused browser APIs |
## Intentionally omitted headers
### `X-XSS-Protection`
This header was **removed** (was `"1; mode=block"`).
**Why:** `X-XSS-Protection` is deprecated and removed from all modern browsers
(Chrome 78+, Firefox never implemented it, Edge dropped it). Worse, the
`mode=block` behaviour can be [actively exploited](https://portswigger.net/daily-swig/xss-protection-header-is-no-longer-supported-in-any-major-browser)
to expose response bodies that would otherwise be blocked. Sending it provides
no protection and may introduce risk.
**Correct mitigation:** a proper `Content-Security-Policy` header (todo item #11).
## Pending headers
| Header | Status |
|--------|--------|
| `Content-Security-Policy` | ⏳ todo item #11 |

View File

@@ -22,7 +22,8 @@ server {
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# X-XSS-Protection intentionally omitted — deprecated and counterproductive in modern browsers.
# CSP (Content-Security-Policy) is the correct mitigation (see item #11).
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;