|
@@ -0,0 +1,90 @@
|
|
|
|
|
+{
|
|
|
|
|
+ "name": "verify-system-collections-refused",
|
|
|
|
|
+ "comment": "A workflow gets nowhere near the collections SmartBotic runs on, even with defaultAccess read-write. This is the setting that matters: a blanket yes to every unlisted name. Reading projects exposes who may do what; writing it is a grant of access somebody gave themselves. Writing workflows edits another workflow's graph without passing a single permission check.\n\nThis was open. The runner and the webserver each kept their own list of protected collections and the two had drifted - the runner named five, the webserver ten, and \"projects\" was in neither. The list is one list now, in storage/system_collections.hpp, so a name added there is protected in both places at once.\n\nThe control is an ordinary collection written under the same defaultAccess, which must still succeed: this test is about protecting the system's own data, not about turning defaultAccess off.",
|
|
|
|
|
+ "settings": {
|
|
|
|
|
+ "storagePermissions": {
|
|
|
|
|
+ "defaultAccess": "read-write"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ "nodes": [
|
|
|
|
|
+ {
|
|
|
|
|
+ "id": "n1",
|
|
|
|
|
+ "name": "Trigger",
|
|
|
|
|
+ "type": "click-trigger",
|
|
|
|
|
+ "position": { "x": 0, "y": 0 },
|
|
|
|
|
+ "config": {}
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "id": "projects",
|
|
|
|
|
+ "name": "Read who may do what",
|
|
|
|
|
+ "type": "storage-query",
|
|
|
|
|
+ "position": { "x": 0, "y": 100 },
|
|
|
|
|
+ "config": { "collectionSource": "manual", "collectionManual": "projects" }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "id": "workflows",
|
|
|
|
|
+ "name": "Read every workflow",
|
|
|
|
|
+ "type": "storage-query",
|
|
|
|
|
+ "position": { "x": 0, "y": 200 },
|
|
|
|
|
+ "config": { "collectionSource": "manual", "collectionManual": "workflows" }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "id": "users",
|
|
|
|
|
+ "name": "Read the password hashes",
|
|
|
|
|
+ "type": "storage-query",
|
|
|
|
|
+ "position": { "x": 0, "y": 300 },
|
|
|
|
|
+ "config": { "collectionSource": "manual", "collectionManual": "users" }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "id": "escalate",
|
|
|
|
|
+ "name": "Grant itself a project role",
|
|
|
|
|
+ "type": "storage-insert",
|
|
|
|
|
+ "position": { "x": 0, "y": 400 },
|
|
|
|
|
+ "config": {
|
|
|
|
|
+ "collectionSource": "manual",
|
|
|
|
|
+ "collectionManual": "projects",
|
|
|
|
|
+ "documentData": "{\"name\": \"trespass\"}"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "id": "control",
|
|
|
|
|
+ "name": "An ordinary collection still works",
|
|
|
|
|
+ "type": "storage-insert",
|
|
|
|
|
+ "position": { "x": 0, "y": 500 },
|
|
|
|
|
+ "config": {
|
|
|
|
|
+ "collectionSource": "manual",
|
|
|
|
|
+ "collectionManual": "wfprobe_control_collection",
|
|
|
|
|
+ "documentData": "{\"probe\": \"control\"}"
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ ],
|
|
|
|
|
+ "connections": [
|
|
|
|
|
+ { "sourceNodeId": "n1", "sourceOutput": "main", "targetNodeId": "projects", "targetInput": "data" },
|
|
|
|
|
+ { "sourceNodeId": "projects", "sourceOutput": "main", "targetNodeId": "workflows", "targetInput": "data" },
|
|
|
|
|
+ { "sourceNodeId": "workflows", "sourceOutput": "main", "targetNodeId": "users", "targetInput": "data" },
|
|
|
|
|
+ { "sourceNodeId": "users", "sourceOutput": "main", "targetNodeId": "escalate", "targetInput": "data" },
|
|
|
|
|
+ { "sourceNodeId": "escalate", "sourceOutput": "main", "targetNodeId": "control", "targetInput": "data" }
|
|
|
|
|
+ ],
|
|
|
|
|
+ "expect": {
|
|
|
|
|
+ "projects": {
|
|
|
|
|
+ "status": "completed",
|
|
|
|
|
+ "output": { "error": "No read access to collection: projects" }
|
|
|
|
|
+ },
|
|
|
|
|
+ "workflows": {
|
|
|
|
|
+ "status": "completed",
|
|
|
|
|
+ "output": { "error": "No read access to collection: workflows" }
|
|
|
|
|
+ },
|
|
|
|
|
+ "users": {
|
|
|
|
|
+ "status": "completed",
|
|
|
|
|
+ "output": { "error": "No read access to collection: users" }
|
|
|
|
|
+ },
|
|
|
|
|
+ "escalate": {
|
|
|
|
|
+ "status": "completed",
|
|
|
|
|
+ "output": { "success": false, "error": "No write access to collection: projects" }
|
|
|
|
|
+ },
|
|
|
|
|
+ "control": {
|
|
|
|
|
+ "status": "completed",
|
|
|
|
|
+ "output": { "success": true }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|