From bc7d6cd1d6b90f0f52e888830e1f764d673a0dc8 Mon Sep 17 00:00:00 2001 From: Dimitri van Hees Date: Wed, 30 Sep 2026 14:09:58 +0200 Subject: [PATCH] Beheer: beperk servers-use-https tot plekken waar servers mag voorkomen De selector `$.paths..servers[*]` zocht recursief onder `paths` en nam daardoor ook (via $ref opgeloste) schema's mee met een property genaamd `servers`. Beperk de regel tot servers op hoofd-, pad-, operatie- en callbackniveau en voeg een testcase toe voor deze regel. Co-Authored-By: Claude Opus 5.5 --- .../servers-https/expected-output.txt | 9 + linter/testcases/servers-https/openapi.json | 251 ++++++++++++++++++ media/linter.yaml | 5 +- 3 files changed, 264 insertions(+), 1 deletion(-) create mode 100644 linter/testcases/servers-https/expected-output.txt create mode 100644 linter/testcases/servers-https/openapi.json diff --git a/linter/testcases/servers-https/expected-output.txt b/linter/testcases/servers-https/expected-output.txt new file mode 100644 index 0000000..73d4663 --- /dev/null +++ b/linter/testcases/servers-https/expected-output.txt @@ -0,0 +1,9 @@ + +/testcases/servers-https/openapi.json + 15:20 error nlgov:servers-use-https Server URL http://example.com/api/v1 "http://example.com/api/v1" must not match the pattern "^http://.*". servers[0].url + 64:32 error nlgov:servers-use-https Server URL http://example.com/api/v1 "http://example.com/api/v1" must not match the pattern "^http://.*". paths./openapi.json.get.servers[0].url + 70:28 error nlgov:servers-use-https Server URL http://example.com/api/v1 "http://example.com/api/v1" must not match the pattern "^http://.*". paths./openapi.json.servers[0].url + 119:44 error nlgov:servers-use-https Server URL http://example.com/callback "http://example.com/callback" must not match the pattern "^http://.*". paths./apis.get.callbacks.apiGewijzigd.{$request.query.callbackUrl}.servers[0].url + 127:48 error nlgov:servers-use-https Server URL http://example.com/callback "http://example.com/callback" must not match the pattern "^http://.*". paths./apis.get.callbacks.apiGewijzigd.{$request.query.callbackUrl}.post.servers[0].url + +✖ 5 problems (5 errors, 0 warnings, 0 infos, 0 hints) diff --git a/linter/testcases/servers-https/openapi.json b/linter/testcases/servers-https/openapi.json new file mode 100644 index 0000000..2c61ebe --- /dev/null +++ b/linter/testcases/servers-https/openapi.json @@ -0,0 +1,251 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "Servers HTTPS", + "description": "Deze OpenAPI specification bevat servers zonder https op hoofd-, pad-, operatie- en callbackniveau, en een schema met een property genaamd servers die niet gevalideerd mag worden.", + "contact": { + "name": "Beheerder", + "url": "https://www.example.com", + "email": "mail@example.com" + }, + "version": "1.0.0" + }, + "servers": [ + { + "url": "http://example.com/api/v1" + } + ], + "security": [ + { + "default": [] + } + ], + "tags": [ + { + "name": "openapi" + } + ], + "paths": { + "/openapi.json": { + "get": { + "tags": [ + "openapi" + ], + "description": "OpenAPI document", + "operationId": "getOpenapiJSON", + "parameters": [], + "responses": { + "200": { + "description": "OK", + "headers": { + "API-Version": { + "description": "De huidige versie van de applicatie", + "style": "simple", + "schema": { + "type": "string" + } + }, + "access-control-allow-origin": { + "description": "Alle origins mogen bij deze resource", + "schema": { + "type": "string" + } + } + } + } + }, + "security": [ + { + "default": [] + } + ], + "servers": [ + { + "url": "http://example.com/api/v1" + } + ] + }, + "servers": [ + { + "url": "http://example.com/api/v1" + } + ] + }, + "/apis": { + "get": { + "tags": [ + "openapi" + ], + "description": "Lijst van API's", + "operationId": "getApis", + "parameters": [], + "responses": { + "200": { + "description": "OK", + "headers": { + "API-Version": { + "description": "De huidige versie van de applicatie", + "style": "simple", + "schema": { + "type": "string" + } + }, + "access-control-allow-origin": { + "description": "Alle origins mogen bij deze resource", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Api" + } + } + } + } + }, + "security": [ + { + "default": [] + } + ], + "callbacks": { + "apiGewijzigd": { + "{$request.query.callbackUrl}": { + "servers": [ + { + "url": "http://example.com/callback" + } + ], + "post": { + "description": "Notificatie van een gewijzigde API", + "operationId": "postApiGewijzigd", + "servers": [ + { + "url": "http://example.com/callback" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Api" + } + } + } + }, + "responses": { + "204": { + "description": "No Content", + "headers": { + "API-Version": { + "description": "De huidige versie van de applicatie", + "style": "simple", + "schema": { + "type": "string" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/problem+json": { + "schema": { + "type": "object", + "properties": { + "status": { + "type": "integer" + }, + "title": { + "type": "string" + }, + "detail": { + "type": "string" + }, + "errors": { + "type": "object", + "properties": { + "in": { + "type": "string" + }, + "location": { + "type": "object", + "properties": { + "pointer": { + "type": "string" + }, + "name": { + "type": "string" + }, + "index": { + "type": "integer" + } + } + }, + "code": { + "type": "string" + }, + "detail": { + "type": "string" + } + } + } + }, + "required": [ + "status", + "title", + "detail", + "errors" + ], + "additionalProperties": false + } + } + } + } + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Api": { + "type": "object", + "properties": { + "servers": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "example": { + "url": "http://example.com/api/v1", + "description": "Voorbeeld van een server van een andere API" + } + } + } + } + }, + "securitySchemes": { + "default": { + "type": "oauth2", + "flows": { + "implicit": { + "authorizationUrl": "https://test.com", + "scopes": {} + } + } + } + } + } +} \ No newline at end of file diff --git a/media/linter.yaml b/media/linter.yaml index a36ba4d..54abab2 100644 --- a/media/linter.yaml +++ b/media/linter.yaml @@ -177,7 +177,10 @@ rules: message: "Server URL {{value}} {{error}}." given: - $.servers[*] - - $.paths..servers[*] + - $.paths[*].servers[*] + - $.paths[*][*].servers[*] + - $.paths[*][*].callbacks[*][*].servers[*] + - $.paths[*][*].callbacks[*][*][*].servers[*] then: field: url function: pattern