@produtype/core 0.90.0 → 0.91.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -196,7 +196,45 @@ async function detectSecurity(ctx) {
196
196
  /^\s*SECURE_CROSS_ORIGIN_OPENER_POLICY\s*=/m,
197
197
  /^\s*CSP_DEFAULT_SRC\s*=/m,
198
198
  ], 20);
199
- const helmet = helmetDep || headerSignals.length > 0;
199
+ /**
200
+ * Spring Security, which writes the headers without being asked.
201
+ *
202
+ * Adding `spring-boot-starter-security` and configuring an `HttpSecurity` chain
203
+ * gives every response `X-Content-Type-Options: nosniff`, `X-Frame-Options: DENY`
204
+ * and a no-store `Cache-Control` — the framework's defaults, applied whether or not
205
+ * anybody writes a line about headers. shopizer does exactly that and was told it
206
+ * has none.
207
+ *
208
+ * Unlike Django's `SecurityMiddleware`, which is deliberately not counted a few
209
+ * lines down: `django-admin startproject` writes that into every new project, so it
210
+ * distinguishes nothing, and its HSTS and nosniff behaviour still waits on
211
+ * `SECURE_*` settings. This starter is not in every Spring project — petclinic has
212
+ * no security at all — and its defaults need no settings.
213
+ *
214
+ * The chain is what is required. A project can pull the starter for method-level
215
+ * authorization in something that serves no requests, and then there is no filter
216
+ * chain and no headers — which is what the second fixture holds.
217
+ *
218
+ * The dependency check in front of it is a pre-filter and nothing more: it keeps
219
+ * this search off every file of every non-Spring repository. Removing it fails no
220
+ * test, and the comment says so rather than implying a safety it does not provide.
221
+ */
222
+ const springSecurity = (0, detectContext_1.hasAnyGradleDep)(ctx, ['spring-boot-starter-security', 'spring-security-config']);
223
+ const springFilterChain = springSecurity.length > 0
224
+ ? await (0, textSearch_1.searchInFiles)(ctx.root, source, [/HttpSecurity\s+\w+|\bhttp\s*\n?\s*\.\s*(?:authorizeHttpRequests|authorizeRequests|securityMatcher|antMatcher)/], 2)
225
+ : [];
226
+ if (springFilterChain.length > 0) {
227
+ for (const dep of springSecurity)
228
+ evidence.push({ type: 'dependency', value: dep, claim: 'headers' });
229
+ evidence.push({
230
+ type: 'snippet',
231
+ value: springFilterChain[0].snippet,
232
+ file: springFilterChain[0].file,
233
+ line: springFilterChain[0].line,
234
+ claim: 'headers',
235
+ });
236
+ }
237
+ const helmet = helmetDep || headerSignals.length > 0 || springFilterChain.length > 0;
200
238
  /**
201
239
  * The packages the ecosystem names, as distinct from the variables authors do.
202
240
  * Shared between the dependency check below and the binding walk further down.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@produtype/core",
3
- "version": "0.90.0",
3
+ "version": "0.91.0",
4
4
  "description": "Deterministic CLI and library that analyzes a web application repository and reports how far it is from production-ready for the kind of product it is meant to be.",
5
5
  "license": "MIT",
6
6
  "bin": {