Skip to content

Commit 650c287

Browse files
committed
Merge branch 'v2.1.0' of git@github.com:datasharingframework/datasharingframework.github.io.git into v2.1.0
2 parents da0d588 + 07ff390 commit 650c287

3 files changed

Lines changed: 96 additions & 75 deletions

File tree

docs/src/.vuepress/data/releases.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ export const releases: Record<string, Release> = {
1818
tag: '2.1.0',
1919
previousTag: '2.0.2',
2020
images: {
21-
fhir: { digest: 'sha256:TODO' },
22-
fhir_proxy: { digest: 'sha256:TODO' },
23-
bpe: { digest: 'sha256:2087a12f2cc8386a019bc9706f8bcfdcd5ee9e12da07ca2bd5f09aaaba8133d7' },
24-
bpe_proxy: { digest: 'sha256:TODO' },
21+
fhir: { digest: 'sha256:71599af143f0262a7265aa2bc4ea5a9660f11de6248a053e060b5667070203fd' },
22+
fhir_proxy: { digest: 'sha256:9f11a3580c970314532f5951808be6fe72f1de7d53348e625d2dd0c95bcf1d96' },
23+
bpe: { digest: 'sha256:3ee7ef0ac201fc3776273fbfc2569bdc4edf724a2bb9f1b4a889eb7e13ff4049' },
24+
bpe_proxy: { digest: 'sha256:c67da4a1720ea75a383764db2bf25619fe70f57773b1069029f5b49588eb1ecc' },
2525
},
2626
},
2727
};

docs/src/operations/v2.1.0/hardening-measures.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,91 @@ icon: safe
55

66
# Defense-in-Depth Hardening Measures
77

8+
For DSF {{release.tag}} we performed a number of IT security hardening measures. The following changes follow security best practices. They reduce risk for non-standard deployments, protect against future code changes that could introduce new attack paths, and align with common security audit expectations.
9+
10+
Each entry describes the change and why we consider it not exploitable in the standard DSF deployment model.
11+
12+
## Deployment Context
13+
14+
The standard DSF deployment uses:
15+
16+
- **Apache2 reverse proxy** with `mod_ssl` performing TLS termination and client certificate validation (`SSLVerifyClient require`, DN checks against trusted CA list)
17+
- **Docker containers** with network isolation (frontend / backend / inter-service networks)
18+
- **Jetty application** on internal port 8080, not directly reachable from outside
19+
- **Status port** on `127.0.0.1:10000` (localhost only), separate Jetty connector
20+
- **Configuration** via Docker environment variables / secrets, only admin-writable
21+
- **PostgreSQL** not exposed to host, only accessible from the application container
22+
23+
The assessments below consider this standard deployment. Non-standard deployments (e.g., Jetty directly exposed, no reverse proxy) may have different risk profiles.
24+
25+
## Improved XML Transformer Configuration
26+
27+
Disabled external entity resolution and enabled secure processing on `TransformerFactory` instances in `ProcessService`, `ThymeleafTemplateServiceImpl`, and `BundleGenerator`. We consider this not exploitable because although external organizations and authorized users can create FHIR resources (e.g., Tasks), the content never reaches the TransformerFactory as raw XML. The data path is: user input is parsed by HAPI FHIR into a Java object model (stripping any XML-level constructs like DOCTYPE/ENTITY declarations), stored as JSONB in PostgreSQL, and then re-serialized to well-formed XML by HAPI's serializer when displayed. The TransformerFactory only pretty-prints HAPI's serialized output, where all text content is properly XML-escaped. `BundleGenerator` is a Maven build-time tool, not a runtime component. Hardening against CWE-611 (XXE).
28+
29+
Commit: [`b89c512dc`](https://github.com/datasharingframework/dsf/commit/b89c512dc)
30+
31+
## Database Username/Group Validation
32+
33+
Added regex validation (`^[a-zA-Z_][a-zA-Z0-9_$]{0,62}$`) for PostgreSQL identifier config parameters used in DDL statements. We consider this not exploitable because these values come exclusively from admin-managed config files and Docker environment variables — an attacker with write access to these already has full system control. Hardening against CWE-89.
34+
35+
Commit: [`7e2de0ed8`](https://github.com/datasharingframework/dsf/commit/7e2de0ed8)
36+
37+
## HTTPS Enforcement for OIDC Endpoints
38+
39+
Added explicit check that OIDC token and JWKS endpoints use HTTPS. We consider this not exploitable because a compromised OIDC provider can already issue arbitrary tokens directly, making HTTP interception redundant. In the MITM scenario (legitimate provider, network attacker), the provider URL is admin-configured as HTTPS and legitimate providers always return HTTPS endpoints in their discovery documents. In both cases, obtained tokens are constrained by the admin-managed `roleConfig` — no privilege escalation beyond configured roles is possible. Hardening against CWE-918 / CWE-319.
40+
41+
Commit: [`bdeddf308`](https://github.com/datasharingframework/dsf/commit/bdeddf308)
42+
43+
## JWKS Minimum Key Size and `use=sig` Filtering
44+
45+
Added 2048-bit minimum RSA key length and `use=sig` check for JWKS keys used in JWT verification. We consider this not exploitable because no mainstream OIDC provider (Keycloak, etc.) publishes RSA keys below 2048 bits. Even if an attacker could forge tokens via weak keys, privileges are constrained by the admin-managed `roleConfig` — the same limitation as with a compromised OIDC provider. Hardening against CWE-326 / CWE-347.
46+
47+
Commit: [`31c2e974d`](https://github.com/datasharingframework/dsf/commit/31c2e974d)
48+
49+
## Removed Access Token Claim Logging
50+
51+
Removed DEBUG-level logging of token claims (groups, roles) in `AbstractIdentityProvider` and `BearerTokenAuthenticator`. We consider this not exploitable because DEBUG logging is disabled in production by default, and the logged data (group memberships, roles) is operational metadata — not secrets like passwords or signing keys. Hardening against CWE-532.
52+
53+
Commit: [`cc0bb71ef`](https://github.com/datasharingframework/dsf/commit/cc0bb71ef)
54+
55+
## Session Cookie Security Attributes
56+
57+
Added `Secure`, `HttpOnly`, and `SameSite=LAX` flags to session cookies. We consider this not exploitable because TLS is terminated at the Apache HTTP Server reverse proxy (clients only communicate over HTTPS), the `HttpOnly` flag is only relevant if an XSS vulnerability exists (none is exploitable, see `th:utext` below), and `SameSite` has limited impact since primary authentication uses mTLS, not cookies. Hardening against CWE-614 / CWE-1004.
58+
59+
Commit: [`5cc00611b`](https://github.com/datasharingframework/dsf/commit/5cc00611b)
60+
61+
## JSON Serialization in JSONB Query Parameters
62+
63+
Replaced string concatenation with Jackson `ObjectMapper` serialization for JSONB query parameters in all DAO classes and search filters. We consider this not exploitable because user-controlled values are bound via `PreparedStatement.setString()`, which transmits query template and parameter values separately to PostgreSQL — the parameter value is never parsed as SQL and there is no way to inject `JOIN`, `UNION`, or subqueries. Within the JSONB domain, the identity filter (access control) operates as a separate `AND` condition with server-side parameters that cannot be influenced by search parameter manipulation, the `@>` containment operator becomes more restrictive with additional injected elements (not less), and result sets are always a subset of authorized resources — no enumeration of unauthorized data is possible. Hardening against CWE-89.
64+
65+
Commit: [`37c0282c6`](https://github.com/datasharingframework/dsf/commit/37c0282c6)
66+
67+
## Client Certificate Expiration Check
68+
69+
Added explicit certificate expiration check and changed auth type from `"RSA"` to `"UNKNOWN"` in `ClientCertificateAuthenticator`. We consider this not exploitable because the Apache HTTP Server reverse proxy performs TLS termination with `SSLVerifyClient require` and validates certificate expiration, chain trust, and revocation before requests reach Jetty. The Jetty-level check is a redundant second validation. Hardening against CWE-295 / CWE-324.
70+
71+
Commit: [`c6d369828`](https://github.com/datasharingframework/dsf/commit/c6d369828)
72+
73+
## Safe YAML Deserialization
74+
75+
Replaced `new Yaml()` with `new Yaml(new SafeConstructor(new LoaderOptions()))` in `RoleConfigReader`. We consider this not exploitable because the YAML content comes exclusively from admin-managed config files (`config.properties`) and Docker environment variables — an attacker with write access to these can already execute arbitrary code through simpler means. Hardening against CWE-502.
76+
77+
Commit: [`e0b6cf00a`](https://github.com/datasharingframework/dsf/commit/e0b6cf00a)
78+
79+
## Thymeleaf `th:utext` Replaced with `th:text`
80+
81+
Replaced `th:utext` (unescaped HTML output) with `th:text` / `th:each` for page headings built from URL segments. We consider this not exploitable because the old code applied `HtmlUtils.htmlEscape()` to all user inputs before concatenation — this escapes `& < > " '`, preventing tag injection (`<` `>` escaped to `&lt;` `&gt;`) and attribute breakout (`"` escaped to `&quot;`, which per HTML spec does not terminate double-quoted attributes). The fix makes XSS structurally impossible and removes reliance on manual escaping — a future developer could have forgotten the `htmlEscape()` call when adding new URL segments. Hardening against CWE-79.
82+
83+
Commit: [`58edc26c5`](https://github.com/datasharingframework/dsf/commit/58edc26c5)
84+
85+
## Error Message Removed from Status Endpoint
86+
87+
Removed database exception messages from the status endpoint error response body. We consider this not exploitable because the status endpoint runs on a separate Jetty connector (port 10000, bound to `127.0.0.1` only) with role-based access control (`STATUS_PORT_ROLE`) — it is not reachable through the Apache HTTP Server reverse proxy or from outside the Docker container. Hardening against CWE-209.
88+
89+
Commit: [`5103d0e9d`](https://github.com/datasharingframework/dsf/commit/5103d0e9d)
90+
91+
## Content Security Policy and Binary Inline Display
92+
93+
Introduced a new inline display mode for `Binary` resources with a strict CSP (`script-src 'none'`), a media type policy, and `ContentTypeSanitizer`. We consider this not a vulnerability fix because the old code served all `Binary` resources with `Content-Disposition: attachment` (forced download, never rendered in browser), so the old `unsafe-inline` CSP was never reachable. This commit implements a new feature with secure defaults. Hardening against CWE-1021.
94+
95+
Commit: [`454c1197b`](https://github.com/datasharingframework/dsf/commit/454c1197b)
Lines changed: 4 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,4 @@
1-
---
2-
title: Release Notes (v2.0.2)
3-
icon: note
4-
---
5-
6-
## [Release Notes for v2.0.2](https://github.com/datasharingframework/dsf/releases/tag/v2.0.2)
7-
8-
::: tip Release Notes
9-
You can access all release notes on our [GitHub](https://github.com/datasharingframework/dsf/releases).
10-
:::
11-
12-
### 2.0.2 - Maintenance Release
13-
General remarks:
14-
15-
- This is an update for DSF 2.0.0 / 2.0.1.
16-
- To Update from an existing 1.x installation, please see the [1.x -> 2.0.2 Upgrade Guide](https://dsf.dev/operations/v2.0.2/upgrade-from-1.html).
17-
- To Update from an existing 2.x installation, please see the [2.x -> 2.0.2 Upgrade Guide](https://dsf.dev/operations/v2.0.2/upgrade-from-2.html).
18-
- For a fresh deployment, follow the [installation instructions](https://dsf.dev/operations/v2.0.2/install.html).
19-
- With this release a number of bugs were fixed.
20-
21-
Bug Fixes:
22-
- The property key `dev.dsf.bpe.fhir.client.connections.config.default.enable.debug.logging` was used for unrelated configuration values to specify the default EnableDebugLogging value for FHIR client connections and the default OidcVerifyAuthorizedParty value for OIDC Client-Credentials-Flow connections. A new property key `dev.dsf.bpe.fhir.client.connections.config.default.oidc.verify.authorized.party` was added.
23-
- A NoClassDefFoundError was throw when executing the [num-process-dashboard-report](https://github.com/medizininformatik-initiative/dsf-plugin-numdashboard) process plugin in Version 1.0.0.0 and 1.1.0.0. Additional packages were added to the API v1 class allow list file.
24-
- A process instance waiting for a timer event crashed on continuation if the process plugin was removed. The crash resulted in Task resources remaining in status `in-progress`. Additional error handling was implemented to update Task to a status `failed`.
25-
- No debug log output was generated for code from the [mii-processes-common](https://github.com/medizininformatik-initiative/mii-processes-common) module used in some medical informatics initiative process plugins. A new config property `dev.dsf.log.min.level.loggers` with default value was added to restore the DSF 1.x behavior.
26-
- The API v2 `setJsonVariable()` mechanism was unable to serialize date/time objects from the `java.time` package. The `ObjectMapper` configuration was fixed and the `JavaTimeModule` added.
27-
28-
Docker images for this release can be accessed via the GitHub Docker registry - ghcr.io:
29-
* **bpe**: [ghcr.io/datasharingframework/bpe:2.0.2](https://github.com/orgs/datasharingframework/packages/container/bpe/679531729?tag=2.0.2)
30-
* **bpe_proxy**: [ghcr.io/datasharingframework/bpe_proxy:2.0.2](https://github.com/orgs/datasharingframework/packages/container/bpe_proxy/679491992?tag=2.0.2)
31-
* **fhir**: [ghcr.io/datasharingframework/fhir:2.0.2](https://github.com/orgs/datasharingframework/packages/container/fhir/679512827?tag=2.0.2)
32-
* **fhir_proxy**: [ghcr.io/datasharingframework/fhir_proxy:2.0.2](https://github.com/orgs/datasharingframework/packages/container/fhir_proxy/679488712?tag=2.0.2)
33-
34-
Process Plugin API v1 on Maven Central:
35-
```xml
36-
<dependency>
37-
<groupId>dev.dsf</groupId>
38-
<artifactId>dsf-bpe-process-api-v1</artifactId>
39-
<version>2.0.2</version>
40-
</dependency>
41-
```
42-
Process Plugin API v2 on Maven Central:
43-
```xml
44-
<dependency>
45-
<groupId>dev.dsf</groupId>
46-
<artifactId>dsf-bpe-process-api-v2</artifactId>
47-
<version>2.0.2</version>
48-
</dependency>
49-
```
50-
DSF Maven Plugin on Maven Central:
51-
```xml
52-
<plugin>
53-
<groupId>dev.dsf</groupId>
54-
<artifactId>dsf-maven-plugin</artifactId>
55-
<version>2.0.2</version>
56-
</plugin>
57-
```
58-
59-
Issues closed:
60-
- API v2 Variables Fails to Serialize java.time Types [#428](https://github.com/datasharingframework/dsf/issues/428)
61-
- Incomplete Debug Logging for MII Process Plugins [#425](https://github.com/datasharingframework/dsf/issues/425)
62-
- Add DFN Community-PKI as Trusted Client CA [#423](https://github.com/datasharingframework/dsf/issues/423)
63-
- Crash on Timer Continuation After Process Plugin Removal Leaves Task In-Progress [#421](https://github.com/datasharingframework/dsf/issues/421)
64-
- Remove Duplicated Thumbprint Calculations [#419](https://github.com/datasharingframework/dsf/issues/419)
65-
- Upgrade Dependencies [#417](https://github.com/datasharingframework/dsf/issues/417)
66-
- NoClassDefFoundError While Executing Plugin num-process-dashboard-report [#415](https://github.com/datasharingframework/dsf/issues/415)
67-
- Start New Development Cycle [#412](https://github.com/datasharingframework/dsf/issues/412)
68-
- Property dev.dsf.bpe.fhir.client.connections.config.default.enable.debug.logging Used for Unrelated Configuration Values [#411](https://github.com/datasharingframework/dsf/issues/411)
69-
70-
This release contains contributions from [@EmteZogaf](https://github.com/EmteZogaf), [@hhund](https://github.com/hhund), [@jaboehri](https://github.com/jaboehri), [@schwzr](https://github.com/schwzr) and [@wetret](https://github.com/wetret).
71-
1+
---
2+
title: Release Notes (v2.1.0)
3+
icon: note
4+
---

0 commit comments

Comments
 (0)