File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 11{
22 "name" : " @decocms/mesh" ,
3- "version" : " 1.0.0-alpha.22 " ,
3+ "version" : " 1.0.0-alpha.23 " ,
44 "description" : " MCP Mesh - Self-hostable MCP Gateway for managing AI connections and tools" ,
55 "license" : " MIT" ,
66 "author" : " Deco team" ,
Original file line number Diff line number Diff line change @@ -63,6 +63,10 @@ export class ConnectionStorage implements ConnectionStoragePort {
6363 const existing = await this . findById ( id ) ;
6464
6565 if ( existing ) {
66+ // Only allow update if same organization - prevent cross-org hijacking
67+ if ( existing . organization_id !== data . organization_id ) {
68+ throw new Error ( "Connection ID already exists" ) ;
69+ }
6670 return this . update ( id , data ) ;
6771 }
6872
Original file line number Diff line number Diff line change 99 createCollectionGetOutputSchema ,
1010} from "@decocms/bindings/collections" ;
1111import { defineTool } from "../../core/define-tool" ;
12+ import { requireOrganization } from "../../core/mesh-context" ;
1213import { ConnectionEntitySchema } from "./schema" ;
1314
1415/**
@@ -26,13 +27,17 @@ export const COLLECTION_CONNECTIONS_GET = defineTool({
2627 outputSchema : ConnectionGetOutputSchema ,
2728
2829 handler : async ( input , ctx ) => {
30+ // Require organization context
31+ const organization = requireOrganization ( ctx ) ;
32+
2933 // Check authorization
3034 await ctx . access . check ( ) ;
3135
3236 // Get connection
3337 const connection = await ctx . storage . connections . findById ( input . id ) ;
3438
35- if ( ! connection ) {
39+ // Verify connection exists and belongs to the current organization
40+ if ( ! connection || connection . organization_id !== organization . id ) {
3641 return { item : null } ;
3742 }
3843
Original file line number Diff line number Diff line change 66
77import { z } from "zod" ;
88import { defineTool } from "../../core/define-tool" ;
9+ import { requireOrganization } from "../../core/mesh-context" ;
910
1011export const CONNECTION_TEST = defineTool ( {
1112 name : "CONNECTION_TEST" ,
@@ -22,9 +23,18 @@ export const CONNECTION_TEST = defineTool({
2223 } ) ,
2324
2425 handler : async ( input , ctx ) => {
26+ // Require organization context
27+ const organization = requireOrganization ( ctx ) ;
28+
2529 // Check authorization
2630 await ctx . access . check ( ) ;
2731
32+ // Fetch connection to verify org ownership before testing
33+ const connection = await ctx . storage . connections . findById ( input . id ) ;
34+ if ( ! connection || connection . organization_id !== organization . id ) {
35+ throw new Error ( "Connection not found" ) ;
36+ }
37+
2838 // Test connection
2939 const result = await ctx . storage . connections . testConnection ( input . id ) ;
3040
Original file line number Diff line number Diff line change @@ -69,20 +69,14 @@ async function validateConfiguration(
6969 if ( refConnectionId === WellKnownMCPId . SELF ) {
7070 continue ;
7171 }
72- // Verify connection exists
72+ // Verify connection exists and belongs to same organization
73+ // Use consistent error message to prevent cross-org information disclosure
7374 const refConnection =
7475 await ctx . storage . connections . findById ( refConnectionId ) ;
75- if ( ! refConnection ) {
76+ if ( ! refConnection || refConnection . organization_id !== organizationId ) {
7677 throw new Error ( `Referenced connection not found: ${ refConnectionId } ` ) ;
7778 }
7879
79- // Verify connection belongs to same organization
80- if ( refConnection . organization_id !== organizationId ) {
81- throw new Error (
82- `Referenced connection ${ refConnectionId } does not belong to organization ${ organizationId } ` ,
83- ) ;
84- }
85-
8680 // Verify user has access to the referenced connection
8781 try {
8882 await ctx . access . check ( refConnectionId ) ;
Original file line number Diff line number Diff line change @@ -121,7 +121,7 @@ export function useBindingSchemaFromRegistry(
121121
122122 // Build query input params using proper WhereExpression format
123123 const toolInputParams = parsedAppName
124- ? { where : { appName : parsedAppName } }
124+ ? { where : { appName : parsedAppName } , includeTools : true }
125125 : { } ;
126126
127127 // Create queries for all registries in parallel
You can’t perform that action at this time.
0 commit comments