Summary
3 of 8 ScriptRoute methods skip assertUserCanReadCollection() that all adjacent methods require. Any authenticated user can create/delete/take-ownership of scripts in collections they don't have access to.
Details
File: server/src/main/kotlin/com/espero/yaade/server/routes/ScriptRoute.kt
Vulnerable methods:
- createScript (lines 41-56): Takes
collectionId from body, creates script without checking access
- deleteScript (lines 82-89): Deletes any script by ID without checking collection access
- takeOwnership (lines 91-100): Any user can take ownership of any script
Secure comparison (same file):
getScript (line 37): assertUserCanReadCollection(ctx, collection.id)
updateScript (line 62): assertUserCanReadCollection(ctx, collectionId)
moveScript (lines 284, 287): checks both old and new collection
tokenRunScript (line 156): assertUserCanReadCollection(ctx, collection.id)
runScript (line 205): assertUserCanReadCollection(ctx, collection.id)
Remediation
Add assertUserCanReadCollection(ctx, collectionId) before the operation in all 3 methods. For deleteScript and takeOwnership, fetch the script first, then check its collectionId.
Summary
3 of 8
ScriptRoutemethods skipassertUserCanReadCollection()that all adjacent methods require. Any authenticated user can create/delete/take-ownership of scripts in collections they don't have access to.Details
File:
server/src/main/kotlin/com/espero/yaade/server/routes/ScriptRoute.ktVulnerable methods:
collectionIdfrom body, creates script without checking accessSecure comparison (same file):
getScript(line 37):assertUserCanReadCollection(ctx, collection.id)updateScript(line 62):assertUserCanReadCollection(ctx, collectionId)moveScript(lines 284, 287): checks both old and new collectiontokenRunScript(line 156):assertUserCanReadCollection(ctx, collection.id)runScript(line 205):assertUserCanReadCollection(ctx, collection.id)Remediation
Add
assertUserCanReadCollection(ctx, collectionId)before the operation in all 3 methods. FordeleteScriptandtakeOwnership, fetch the script first, then check itscollectionId.