BACK TO SEARCH
monoes/monomindcritical

Enterprise AI agent orchestration platform — 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code

Monomind is an autonomous AI agent orchestration platform that extends Claude Code with multi-agent coordination, self-learning capabilities, vector m...

purpose: Monomind is an autonomous AI agent orchestration pthreat: network exposed
TypeScript · 6 · Jun 9, 2026 · Jun 10, 2026 · GITHUB ↗
RISK SCORE
0/ 100 risk
high findings+100
medium findings+45
capped at100
Indicators — descriptive signals, not vulnerabilities
pastebin-ipfspackages/@monomind/cli/cloud-functions/publish-registry/index.js:152 `https://gateway.pinata.cloud/ipfs/${result.IpfsHash}`,
pastebin-ipfspackages/@monomind/cli/cloud-functions/publish-registry/index.js:153 `https://ipfs.io/ipfs/${result.IpfsHash}`,
pastebin-ipfspackages/@monomind/cli/cloud-functions/publish-registry/index.js:164 'https://ipfs.io',
pastebin-ipfspackages/@monomind/cli/cloud-functions/publish-registry/index.js:170 const response = await fetch(`${gateway}/ipfs/${cid}`, {
pastebin-ipfspackages/@monomind/cli/cloud-functions/publish-registry/index.js:256 `https://gateway.pinata.cloud/ipfs/${pinResult.IpfsHash}`,
pastebin-ipfspackages/@monomind/cli/cloud-functions/publish-registry/index.js:257 `https://ipfs.io/ipfs/${pinResult.IpfsHash}`,
pastebin-ipfspackages/@monomind/cli/cloud-functions/publish-registry/index.js:258 `https://dweb.link/ipfs/${pinResult.IpfsHash}`,
pastebin-ipfspackages/@monomind/cli/cloud-functions/publish-registry/index.js:351 `https://gateway.pinata.cloud/ipfs/${cid}`,
pastebin-ipfspackages/@monomind/cli/cloud-functions/publish-registry/index.js:352 `https://ipfs.io/ipfs/${cid}`,
These are automated indicators of code characteristics detected by regex pattern matching. They are informational, not security verdicts. Some patterns (e.g. telegram, crypto-wallet) may reflect legitimate functionality.
VULNERABILITY ANALYSIS · 7 findings in 7 blocks4 HIGH · 3 MEDIUM
HIGH1 finding
packages/@monomind/cli/cloud-functions/publish-registry/index.js:456
456case 'bulk-ratings': {
457  // Get ratings for multiple items at once
458  const { itemIds, itemType = 'plugin' } = req.body || req.query;
459
460  if (!itemIds || !Array.isArray(itemIds)) {
461    return res.status(400).json({ error: 'itemIds array required' });
462  }
463
464  const results = {};
465
466  for (const itemId of itemIds.slice(0, 50)) { // Limit to 50 items
467    try {
468      const ratingsFile = bucket.file(`ratings/${itemType}/${itemId}.json`);
469      const [exists] = await ratingsFile.exists();
470
471      if (exists) {
472        const [content] = await ratingsFile.download();
473        const ratings = JSON.parse(content.toString());

// Network-exposed Cloud Function with no authentication

EXPLAINSimilar to 'get-ratings', the 'bulk-ratings' action reads arbitrary files from GCS based on user-supplied `itemType` and `itemIds`. Path traversal in `itemId` allows reading any JSON file in the bucket. The 50-item limit does not prevent traversal.
IMPACTAn attacker can read multiple arbitrary files from the GCS bucket, including the registry and analytics data, by providing traversed paths in the `itemIds` array.
FIXSame as 'get-ratings': validate `itemType` against a whitelist and sanitize `itemId` to prevent path traversal.
HIGH1 finding
packages/@monomind/cli/cloud-functions/publish-registry/index.js:363
363case 'rate': {
364  // Rate a plugin or model (stored in GCS, no SQL)
365  const { itemId, itemType = 'plugin', rating, userId } = req.body || {};
366
367  if (!itemId || !rating || rating < 1 || rating > 5) {
368    return res.status(400).json({ error: 'itemId and rating (1-5) required' });
369  }
370
371  // Generate anonymous user ID if not provided
372  const finalUserId = userId || `anon-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
373
374  // Store rating in GCS (JSON file per item)
375  const ratingsFile = bucket.file(`ratings/${itemType}/${itemId}.json`);

// Network-exposed Cloud Function with no authentication

EXPLAINThe 'rate' action writes to GCS at a path constructed from user-supplied `itemType` and `itemId` without validation. An attacker can write arbitrary JSON files to any GCS path by using path traversal characters (e.g., `../`) in `itemId` or `itemType`. This allows overwriting registry files or injecting malicious data.
IMPACTAn attacker can overwrite the registry.json file, inject malicious plugin metadata, or write arbitrary files to the GCS bucket, potentially leading to supply chain attacks or data corruption.
FIXValidate `itemType` against a whitelist (e.g., 'plugin', 'model'). Sanitize `itemId` to prevent path traversal (e.g., reject slashes, dots, or use a hash). Use a fixed directory structure and avoid user-controlled path segments.
HIGH1 finding
packages/@monomind/cli/cloud-functions/publish-registry/index.js:426
426case 'get-ratings': {
427  // Get ratings for a plugin or model
428  const { itemId, itemType = 'plugin' } = req.query;
429
430  if (!itemId) {
431    return res.status(400).json({ error: 'itemId required' });
432  }
433
434  const ratingsFile = bucket.file(`ratings/${itemType}/${itemId}.json`);
435
436  try {
437    const [exists] = await ratingsFile.exists();
438    if (!exists) {
439      return res.json({ itemId, average: 0, count: 0, ratings: [] });
440    }
441
442    const [content] = await ratingsFile.download();
443    const ratings = JSON.parse(content.toString());

// Network-exposed Cloud Function with no authentication

EXPLAINThe 'get-ratings' action reads a file from GCS at a path constructed from user-supplied `itemType` and `itemId` without validation. An attacker can read arbitrary JSON files from the GCS bucket by using path traversal (e.g., `../registry.json`). This allows reading sensitive data like the registry itself or analytics files.
IMPACTAn attacker can read the entire plugin registry, analytics data, or any other JSON file in the bucket, leading to information disclosure of plugin metadata, download statistics, and potentially secrets if stored in the bucket.
FIXValidate `itemType` against a whitelist. Sanitize `itemId` to prevent path traversal. Restrict file reads to the `ratings/` directory only.
HIGH1 finding
packages/@monomind/cli/cloud-functions/publish-registry/index.js:193
193export async function publishRegistry(req, res) {
194  // CORS headers
195  res.set('Access-Control-Allow-Origin', '*');
196  res.set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
197  res.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
198
199  if (req.method === 'OPTIONS') {
200    return res.status(204).send('');
201  }
202
203  try {
204    const { action = 'publish' } = req.query;

// Network-exposed Cloud Function with no authentication

EXPLAINThe Cloud Function is deployed with `--allow-unauthenticated` (line 13) and has no authentication checks. The `analytics` and `get-ratings` actions expose internal data (download counts, ratings) without any access control. An attacker can query analytics and ratings for any plugin or model without authentication.
IMPACTAn attacker can enumerate all plugins and models, retrieve download statistics, and read rating data. This leaks business intelligence and user activity patterns.
FIXAdd authentication middleware (e.g., verify API key or Firebase Auth token) for non-publish actions. Restrict analytics and ratings endpoints to authenticated users or remove them from the public endpoint.
MEDIUM1 finding
packages/@monomind/cli/cloud-functions/publish-registry/index.js:264
264case 'export-model': {
265  const pinataJwt = await getSecret('pinata-jwt');
266  const modelData = req.body;
267
268  if (!modelData) {
269    return res.status(400).json({ error: 'Model data required' });
270  }
271
272  const result = await exportModel(modelData, pinataJwt);
273  await trackEvent(bucket, 'model-export', modelData.id || 'unknown');
274
275  return res.json({
276    success: true,
277    ...result,
278  });
279}

// Network-exposed Cloud Function with no authentication

EXPLAINThe 'export-model' action accepts arbitrary JSON from the request body and pins it to IPFS via Pinata. There is no validation of the model data structure or size limits. An attacker could upload arbitrary content (e.g., malicious data, copyrighted material) to IPFS using the function's Pinata JWT, potentially incurring costs or legal liability.
IMPACTAn attacker can upload arbitrary content to IPFS using the project's Pinata account, leading to financial costs for pinning, potential abuse of IPFS resources, and legal exposure if illegal content is uploaded.
FIXValidate the model data structure against a schema. Implement size limits. Require authentication for export operations. Consider rate limiting.
MEDIUM1 finding
packages/@monomind/cli/cloud-functions/publish-registry/index.js:281
281case 'import-model': {
282  const { cid } = req.query;
283
284  if (!cid) {
285    return res.status(400).json({ error: 'CID required' });
286  }
287
288  const result = await importModel(cid);
289  await trackEvent(bucket, 'model-import', cid);
290
291  return res.json(result);
292}

// Network-exposed Cloud Function with no authentication

EXPLAINThe 'import-model' action accepts a `cid` parameter from the query string and passes it directly to `importModel`, which fetches from IPFS gateways. There is no validation that the CID is a valid IPFS hash or that the content is safe. An attacker could provide a CID pointing to malicious content, or use the function as a proxy to fetch arbitrary content from IPFS.
IMPACTAn attacker can use the function as an open proxy to fetch arbitrary content from IPFS, potentially bypassing network restrictions. The function could also be used to import malicious models into the system.
FIXValidate that the `cid` matches the expected format (e.g., base58 encoded hash). Consider adding a whitelist of allowed CIDs or requiring authentication for import operations.
MEDIUM1 finding
packages/@monomind/cli/cloud-functions/publish-registry/index.js:294
294case 'track-download': {
295  const { pluginId } = req.body || req.query;
296
297  if (!pluginId) {
298    return res.status(400).json({ error: 'Plugin ID required' });
299  }
300
301  await trackEvent(bucket, 'download', pluginId);
302  return res.json({ success: true });
303}

// Network-exposed Cloud Function with no authentication

EXPLAINThe 'track-download' action accepts a `pluginId` from the request body or query string without validation. The `trackEvent` function writes to a file named with the current date, but the `pluginId` is embedded in the JSON event. An attacker could inject arbitrary data into the analytics files, potentially corrupting analytics or injecting malicious JSON.
IMPACTAn attacker can inject arbitrary data into analytics files, potentially corrupting analytics or causing issues when the files are parsed. This could also be used to inject malicious content if the analytics files are later processed unsafely.
FIXValidate `pluginId` against a whitelist of known plugin IDs. Sanitize the input to prevent injection of special characters. Consider using a structured logging format that escapes user input.
6/10/2026
Findings are produced by automated LLM analysis and may include false positives or miss issues. Verify independently before acting.