Skip to content

Conversation

@AdriGeorge
Copy link

enterprise node

mariacarmina and others added 30 commits April 17, 2025 14:35
* Import v0.0.3 of ddo.js.

* Update workflow.

* avoid loop run env

* Use ddomanager

* update node version

* update ci node

* cast previousddo to instance

* fix ddoclass null

* lint fix

* Refactor metadataevents processor

* use ddo instance in rest of methods

* lint fix

* fix short format

* assign short version ddo

* remove old keys

* refactor saving short version

* skip test

* Run indexer test only

* revert to integration testing

* remove skip test

* wait for EVENTS.METADATA_STATE

* use manager methods in metadata processing

* less strict isUpdateable check

* update orderstartedevent processor and generic did function

* use updatefiels in processevents

* Use same checks for short version

* revert to computing did with event

* use ddomanager in compute initialize

* revert to getddodata short version

* increase timeout tests and refactor waittoindex

* ensure no ddo found in waitforindexrefactor

* update startcompute

* refactor testutils

* add new type to compute test

* ddomanager in fees and db

* increase timeout

* update asset and downloadhandler

* use saveddo

* recreate if deprecated

* use assetfields

* Set manually ddo

* refactor use ddo in helpers

* fix wrong methods

* revert to default ddo

* Use versioned ddo

* use ddo js credentials

* credentials test

* use ddo fields instead of manager

* Use VersionedDDO from ddo-js

* use ddo instead of record string

* revert to database record validate

* remove bad validation

* keep version field in short format ddo and update ddo-js

* fix tests package json

* revert increase test timeout

* revert indexer tests

* remove database clear in test

* fix missing types

---------

Co-authored-by: Razvan Giurgiu <[email protected]>
…ncoding+contentleght

Fix/ Use safe headers for Arweave storage type
* use mappings instead of if checking

* split in separate files

* use get did
…zeCompute and startCompute handlers. Added tests.
@@ -26,7 +27,10 @@
return res.status(400).send('Invalid expiryTimestamp')
}

const isValid = validateAdminSignature(expiryTimestamp, signature)
const isValid: CommonValidation = await validateAdminSignature(
expiryTimestamp,

Check failure

Code scanning / CodeQL

Reflected cross-site scripting High

Cross-site scripting vulnerability due to a
user-provided value
.

Copilot Autofix

AI 22 days ago

To fix this issue, we must sanitize any user-controlled string before incorporating it into an HTTP response. The most reliable approach for Node.js/Express is output encoding for HTML using a well-tested library such as escape-html. This prevents browser interpretation of injected JavaScript or HTML if the response is rendered as HTML. We should import escape-html and use it on isValid.error inside the response, so attackers cannot inject code via manipulated request parameters (e.g., signature).
Specifically:

  • In src/components/httpRoutes/logs.ts, import escape-html near the top.
  • Wrap isValid.error with escape() in the response on line 35:
    return res.status(403).send(`Invalid signature: ${escape(isValid.error)}`)
  • Add the import for escape-html if not present.

Only these changes are required; no other lines or files shown need modification.

Suggested changeset 2
src/components/httpRoutes/logs.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/components/httpRoutes/logs.ts b/src/components/httpRoutes/logs.ts
--- a/src/components/httpRoutes/logs.ts
+++ b/src/components/httpRoutes/logs.ts
@@ -1,4 +1,5 @@
 import express from 'express'
+import escape from 'escape-html'
 import { validateAdminSignature } from '../../utils/auth.js'
 import { HTTP_LOGGER } from '../../utils/logging/common.js'
 import { CommonValidation } from '../../utils/validators.js'
@@ -32,7 +33,7 @@
     signature
   )
   if (!isValid.valid) {
-    return res.status(403).send(`Invalid signature: ${isValid.error}`)
+    return res.status(403).send(`Invalid signature: ${escape(isValid.error)}`)
   }
 
   next() // Proceed to the next middleware/function if validation is successful
EOF
@@ -1,4 +1,5 @@
import express from 'express'
import escape from 'escape-html'
import { validateAdminSignature } from '../../utils/auth.js'
import { HTTP_LOGGER } from '../../utils/logging/common.js'
import { CommonValidation } from '../../utils/validators.js'
@@ -32,7 +33,7 @@
signature
)
if (!isValid.valid) {
return res.status(403).send(`Invalid signature: ${isValid.error}`)
return res.status(403).send(`Invalid signature: ${escape(isValid.error)}`)
}

next() // Proceed to the next middleware/function if validation is successful
package.json
Outside changed files

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/package.json b/package.json
--- a/package.json
+++ b/package.json
@@ -100,7 +100,8 @@
     "winston": "^3.11.0",
     "winston-daily-rotate-file": "^4.7.1",
     "winston-transport": "^4.6.0",
-    "zod": "^3.25.76"
+    "zod": "^3.25.76",
+    "escape-html": "^1.0.3"
   },
   "devDependencies": {
     "@types/chai": "^4.3.10",
EOF
@@ -100,7 +100,8 @@
"winston": "^3.11.0",
"winston-daily-rotate-file": "^4.7.1",
"winston-transport": "^4.6.0",
"zod": "^3.25.76"
"zod": "^3.25.76",
"escape-html": "^1.0.3"
},
"devDependencies": {
"@types/chai": "^4.3.10",
This fix introduces these dependencies
Package Version Security advisories
escape-html (npm) 1.0.3 None
Copilot is powered by AI and may make mistakes. Always verify output.
)
if (authValidationResponse.status.httpStatus !== 200) {
return authValidationResponse
}

Check failure

Code scanning / CodeQL

Type confusion through parameter tampering Critical

Potential type confusion as
this HTTP request parameter
may be either an array or a string.

Copilot Autofix

AI 22 days ago

To fix the problem, ensure that the jobId parameter is a string before any string methods (indexOf, slice) are used on it. The best place to enforce this is the validate method of ComputeStopHandler. This should reject non-string jobId values as early as possible, returning an invalid message if jobId is not a string. In addition, for extra robustness, add a runtime type check at the start of the handle method, ideally throwing or replying with a proper error if the type is not as expected.

Steps/changes:

  • In ComputeStopHandler.validate, after validating required fields, check that command.jobId is a string. If not, return an invalid request message.
  • (Optional but recommended) At the top of the handle function, check typeof task.jobId === 'string'; if not, return a 400 error.
  • No need to change the query handler in compute.ts, since the check in the handler will now enforce correctness.
  • No new imports are needed.

Suggested changeset 1
src/components/core/compute/stopCompute.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/components/core/compute/stopCompute.ts b/src/components/core/compute/stopCompute.ts
--- a/src/components/core/compute/stopCompute.ts
+++ b/src/components/core/compute/stopCompute.ts
@@ -14,6 +14,11 @@
   validate(command: ComputeStopCommand): ValidateParams {
     const validation = validateCommandParameters(command, ['jobId'])
     if (validation.valid) {
+      if (typeof command.jobId !== 'string') {
+        return buildInvalidRequestMessage(
+          'Parameter: "jobId" must be a string'
+        )
+      }
       if (!isAddress(command.consumerAddress)) {
         return buildInvalidRequestMessage(
           'Parameter : "consumerAddress" is not a valid web3 address'
@@ -24,6 +29,16 @@
   }
 
   async handle(task: ComputeStopCommand): Promise<P2PCommandResponse> {
+    // Defensive runtime check for jobId type confusion
+    if (typeof task.jobId !== 'string') {
+      return {
+        stream: null,
+        status: {
+          httpStatus: 400,
+          error: 'Parameter: "jobId" must be a string'
+        }
+      }
+    }
     const validationResponse = await this.verifyParamsAndRateLimits(task)
     if (this.shouldDenyTaskHandling(validationResponse)) {
       return validationResponse
EOF
@@ -14,6 +14,11 @@
validate(command: ComputeStopCommand): ValidateParams {
const validation = validateCommandParameters(command, ['jobId'])
if (validation.valid) {
if (typeof command.jobId !== 'string') {
return buildInvalidRequestMessage(
'Parameter: "jobId" must be a string'
)
}
if (!isAddress(command.consumerAddress)) {
return buildInvalidRequestMessage(
'Parameter : "consumerAddress" is not a valid web3 address'
@@ -24,6 +29,16 @@
}

async handle(task: ComputeStopCommand): Promise<P2PCommandResponse> {
// Defensive runtime check for jobId type confusion
if (typeof task.jobId !== 'string') {
return {
stream: null,
status: {
httpStatus: 400,
error: 'Parameter: "jobId" must be a string'
}
}
}
const validationResponse = await this.verifyParamsAndRateLimits(task)
if (this.shouldDenyTaskHandling(validationResponse)) {
return validationResponse
Copilot is powered by AI and may make mistakes. Always verify output.
String(task.consumerAddress + (task.jobId || ''))
)
if (authValidationResponse.status.httpStatus !== 200) {
return authValidationResponse

Check failure

Code scanning / CodeQL

Type confusion through parameter tampering Critical

Potential type confusion as
this HTTP request parameter
may be either an array or a string.

Copilot Autofix

AI 22 days ago

The best way to fix this problem is to ensure that the untrusted input (req.query.jobId) is of the expected type (string) before using it, both at the point where it's assigned to the command object and before any string methods are called on it.

  • First, in the route handler (in compute.ts), ensure that jobId is assigned as typeof req.query.jobId === "string" ? req.query.jobId : null. This will safely guard against type confusion caused by arrays.
  • Optionally (but recommended), add an explicit type check in the saferizer/validation path, to future-proof against other bug sources.
  • In stopCompute.ts, before using task.jobId as a string (e.g., calling .indexOf, .slice), check that it is a string, and gracefully handle (reject) if not.

These targeted changes are easy to apply within the code snippets shown, only require well-known JS/TS language constructs, and do not change the application’s intended behavior.


Suggested changeset 2
src/components/core/compute/stopCompute.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/components/core/compute/stopCompute.ts b/src/components/core/compute/stopCompute.ts
--- a/src/components/core/compute/stopCompute.ts
+++ b/src/components/core/compute/stopCompute.ts
@@ -43,6 +43,16 @@
     try {
       // split jobId (which is already in hash-jobId format) and get the hash
       // then get jobId which might contain dashes as well
+      if (typeof task.jobId !== 'string') {
+        CORE_LOGGER.error('Invalid type for jobId; expected a string.')
+        return {
+          stream: null,
+          status: {
+            httpStatus: 400,
+            error: 'Parameter "jobId" must be a string'
+          }
+        }
+      }
       const index = task.jobId.indexOf('-')
       const hash = task.jobId.slice(0, index)
       const jobId = task.jobId.slice(index + 1)
EOF
@@ -43,6 +43,16 @@
try {
// split jobId (which is already in hash-jobId format) and get the hash
// then get jobId which might contain dashes as well
if (typeof task.jobId !== 'string') {
CORE_LOGGER.error('Invalid type for jobId; expected a string.')
return {
stream: null,
status: {
httpStatus: 400,
error: 'Parameter "jobId" must be a string'
}
}
}
const index = task.jobId.indexOf('-')
const hash = task.jobId.slice(0, index)
const jobId = task.jobId.slice(index + 1)
src/components/httpRoutes/compute.ts
Outside changed files

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/components/httpRoutes/compute.ts b/src/components/httpRoutes/compute.ts
--- a/src/components/httpRoutes/compute.ts
+++ b/src/components/httpRoutes/compute.ts
@@ -165,7 +165,7 @@
       consumerAddress: (req.query.consumerAddress as string) || null,
       signature: (req.query.signature as string) || null,
       nonce: (req.query.nonce as string) || null,
-      jobId: (req.query.jobId as string) || null,
+      jobId: typeof req.query.jobId === "string" ? req.query.jobId : null,
       agreementId: (req.query.agreementId as string) || null,
       authorization: req.headers?.authorization || null
     }
EOF
@@ -165,7 +165,7 @@
consumerAddress: (req.query.consumerAddress as string) || null,
signature: (req.query.signature as string) || null,
nonce: (req.query.nonce as string) || null,
jobId: (req.query.jobId as string) || null,
jobId: typeof req.query.jobId === "string" ? req.query.jobId : null,
agreementId: (req.query.agreementId as string) || null,
authorization: req.headers?.authorization || null
}
Copilot is powered by AI and may make mistakes. Always verify output.
task.signature,
String(task.consumerAddress + (task.jobId || ''))
)
if (authValidationResponse.status.httpStatus !== 200) {

Check failure

Code scanning / CodeQL

Type confusion through parameter tampering Critical

Potential type confusion as
this HTTP request parameter
may be either an array or a string.

Copilot Autofix

AI 22 days ago

To fix the type confusion in this code, we need to ensure that jobId is always a string before it is used further down the chain—especially before using string-specific methods like .indexOf('-'), .slice(), etc. The best approach is to add a runtime check in the router/controller (file: src/components/httpRoutes/compute.ts, where the tainted parameter is first used), which explicitly validates req.query.jobId. If it is not a string, the request should be rejected with an appropriate error response (bad request), and execution should not proceed to the handler. This prevents arrays (or other non-string types) from reaching the business logic and eliminates the risk.

We should insert a check immediately before constructing the stopComputeTask object in the PUT /compute handler (so after line 161, before line 162). If req.query.jobId is not a string, send a 400 Bad Request response and return. This also provides a clear message to the client about what went wrong.

No new imports or dependencies are required, as this is achieved with native JS type checking.


Suggested changeset 1
src/components/httpRoutes/compute.ts
Outside changed files

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/components/httpRoutes/compute.ts b/src/components/httpRoutes/compute.ts
--- a/src/components/httpRoutes/compute.ts
+++ b/src/components/httpRoutes/compute.ts
@@ -159,13 +159,22 @@
       true
     )
 
+    // Ensure jobId is a string and not an array (type confusion protection)
+    if (
+      typeof req.query.jobId !== 'string' ||
+      req.query.jobId.trim() === ''
+    ) {
+      res.status(400).send('Bad Request: jobId must be a non-empty string.')
+      return
+    }
+
     const stopComputeTask: ComputeStopCommand = {
       command: PROTOCOL_COMMANDS.COMPUTE_STOP,
       node: (req.query.node as string) || null,
       consumerAddress: (req.query.consumerAddress as string) || null,
       signature: (req.query.signature as string) || null,
       nonce: (req.query.nonce as string) || null,
-      jobId: (req.query.jobId as string) || null,
+      jobId: req.query.jobId,
       agreementId: (req.query.agreementId as string) || null,
       authorization: req.headers?.authorization || null
     }
EOF
@@ -159,13 +159,22 @@
true
)

// Ensure jobId is a string and not an array (type confusion protection)
if (
typeof req.query.jobId !== 'string' ||
req.query.jobId.trim() === ''
) {
res.status(400).send('Bad Request: jobId must be a non-empty string.')
return
}

const stopComputeTask: ComputeStopCommand = {
command: PROTOCOL_COMMANDS.COMPUTE_STOP,
node: (req.query.node as string) || null,
consumerAddress: (req.query.consumerAddress as string) || null,
signature: (req.query.signature as string) || null,
nonce: (req.query.nonce as string) || null,
jobId: (req.query.jobId as string) || null,
jobId: req.query.jobId,
agreementId: (req.query.agreementId as string) || null,
authorization: req.headers?.authorization || null
}
Copilot is powered by AI and may make mistakes. Always verify output.
Accept:
'application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json, application/vnd.docker.distribution.manifest.list.v2+json, application/vnd.oci.image.index.v1+json'
}
let response = await fetch(url, { headers })

Check failure

Code scanning / CodeQL

Server-side request forgery Critical

The
URL
of this request depends on a
user-provided value
.

Copilot Autofix

AI 22 days ago

To fix this SSRF vulnerability, you need to restrict the set of Docker registries (domains/hosts) to an explicit server-side allowlist before making any outgoing requests. That is, when parsing the Docker image reference, you should check if the resolved registry URL (namely, registry host) is one of your expected/trusted registry domains (such as "docker.io", "registry-1.docker.io", or domains configured in your environment). If the registry or domain is not trusted, reject the request early and do not perform the fetch.

Implement this by:

  • Adding an allowlist of trusted registry hosts either as a constant array in compute_engine_docker.ts or loaded from config.
  • Updating the parseImage method, or immediately after it in getDockerManifest, to check whether the registry host is in this allowlist.
  • If not, throw a clear error or return a validation object indicating a failed check.
  • Also, ensure that the path (name) and reference (ref) parts are not allowing traversal or malformed values (this can be simple, e.g., by using regular expressions to restrict characters, but the most crucial aspect is hostname restriction).
  • Changes are limited to the handling and validation of registry domains just before the fetch in getDockerManifest in src/components/c2d/compute_engine_docker.ts.
Suggested changeset 1
src/components/c2d/compute_engine_docker.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/components/c2d/compute_engine_docker.ts b/src/components/c2d/compute_engine_docker.ts
--- a/src/components/c2d/compute_engine_docker.ts
+++ b/src/components/c2d/compute_engine_docker.ts
@@ -51,6 +51,17 @@
 import { Service } from '@oceanprotocol/ddo-js'
 import { getOceanTokenAddressForChain } from '../../utils/address.js'
 
+// Allowlist of trusted Docker registries
+const TRUSTED_DOCKER_REGISTRIES = [
+  'docker.io',
+  'registry-1.docker.io',
+  'ghcr.io',
+  'quay.io',
+  'registry.gitlab.com',
+  'mcr.microsoft.com'
+  // Add more trusted registries if your business accepts them
+];
+
 export class C2DEngineDocker extends C2DEngine {
   private envs: ComputeEnvironment[] = []
 
@@ -366,6 +377,27 @@
 
   public static async getDockerManifest(image: string): Promise<any> {
     const { registry, name, ref } = C2DEngineDocker.parseImage(image)
+    // Extract hostname from registry URL
+    let registryHost = '';
+    try {
+      registryHost = new URL(registry).hostname;
+    } catch (err) {
+      // not a valid URL
+      throw new Error(`Malformed registry URL: ${registry}`);
+    }
+    // Check allowlist
+    if (!TRUSTED_DOCKER_REGISTRIES.includes(registryHost)) {
+      throw new Error(
+        `Registry host '${registryHost}' is not in the trusted allowlist`
+      );
+    }
+    // Optionally: check for path traversal and other invalid values in 'name' and 'ref'
+    if (name.includes('..') || name.includes('\\')) {
+      throw new Error(`Docker image name contains invalid path segments`);
+    }
+    if (ref.includes('..') || ref.includes('\\')) {
+      throw new Error(`Docker image reference contains invalid path segments`);
+    }
     const url = `${registry}/v2/${name}/manifests/${ref}`
     let headers: Record<string, string> = {
       Accept:
EOF
@@ -51,6 +51,17 @@
import { Service } from '@oceanprotocol/ddo-js'
import { getOceanTokenAddressForChain } from '../../utils/address.js'

// Allowlist of trusted Docker registries
const TRUSTED_DOCKER_REGISTRIES = [
'docker.io',
'registry-1.docker.io',
'ghcr.io',
'quay.io',
'registry.gitlab.com',
'mcr.microsoft.com'
// Add more trusted registries if your business accepts them
];

export class C2DEngineDocker extends C2DEngine {
private envs: ComputeEnvironment[] = []

@@ -366,6 +377,27 @@

public static async getDockerManifest(image: string): Promise<any> {
const { registry, name, ref } = C2DEngineDocker.parseImage(image)
// Extract hostname from registry URL
let registryHost = '';
try {
registryHost = new URL(registry).hostname;
} catch (err) {
// not a valid URL
throw new Error(`Malformed registry URL: ${registry}`);
}
// Check allowlist
if (!TRUSTED_DOCKER_REGISTRIES.includes(registryHost)) {
throw new Error(
`Registry host '${registryHost}' is not in the trusted allowlist`
);
}
// Optionally: check for path traversal and other invalid values in 'name' and 'ref'
if (name.includes('..') || name.includes('\\')) {
throw new Error(`Docker image name contains invalid path segments`);
}
if (ref.includes('..') || ref.includes('\\')) {
throw new Error(`Docker image reference contains invalid path segments`);
}
const url = `${registry}/v2/${name}/manifests/${ref}`
let headers: Record<string, string> = {
Accept:
Copilot is powered by AI and may make mistakes. Always verify output.
// split jobId (which is already in hash-jobId format) and get the hash
// then get jobId which might contain dashes as well
const index = task.jobId.indexOf('-')
const hash = task.jobId.slice(0, index)

Check failure

Code scanning / CodeQL

Type confusion through parameter tampering Critical

Potential type confusion as
this HTTP request parameter
may be either an array or a string.

Copilot Autofix

AI 22 days ago

The fix is to ensure that task.jobId is a string before doing any string operations like indexOf and slice. If it is not a string (e.g., it is an array because of a multi-parameter attack), the code should reject the request with an appropriate error message instead of proceeding. The fix should be applied before any string operations, ideally at the start of the handle method of ComputeGetStreamableLogsHandler in src/components/core/compute/getStreamableLogs.ts. You can use typeof task.jobId !== 'string' or !task.jobId || typeof task.jobId !== 'string' to catch null/undefined as well. Optionally, you may want to validate the format to match expected patterns, but at minimum, you must prevent non-string types.

Only edits to src/components/core/compute/getStreamableLogs.ts are required, and the change should be made at the start of the handle() method, before any usage of task.jobId. No additional packages are required.

Suggested changeset 1
src/components/core/compute/getStreamableLogs.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/components/core/compute/getStreamableLogs.ts b/src/components/core/compute/getStreamableLogs.ts
--- a/src/components/core/compute/getStreamableLogs.ts
+++ b/src/components/core/compute/getStreamableLogs.ts
@@ -26,6 +26,17 @@
   async handle(task: ComputeGetStreamableLogsCommand): Promise<P2PCommandResponse> {
     const oceanNode = this.getOceanNode()
 
+    // Type guard for jobId: must be a string (not array, not null/undefined)
+    if (typeof task.jobId !== 'string') {
+      return {
+        stream: null,
+        status: {
+          httpStatus: 400,
+          error: 'Invalid jobId: must be a string.'
+        }
+      }
+    }
+
     const validationResponse = await this.verifyParamsAndRateLimits(task)
     if (this.shouldDenyTaskHandling(validationResponse)) {
       return validationResponse
EOF
@@ -26,6 +26,17 @@
async handle(task: ComputeGetStreamableLogsCommand): Promise<P2PCommandResponse> {
const oceanNode = this.getOceanNode()

// Type guard for jobId: must be a string (not array, not null/undefined)
if (typeof task.jobId !== 'string') {
return {
stream: null,
status: {
httpStatus: 400,
error: 'Invalid jobId: must be a string.'
}
}
}

const validationResponse = await this.verifyParamsAndRateLimits(task)
if (this.shouldDenyTaskHandling(validationResponse)) {
return validationResponse
Copilot is powered by AI and may make mistakes. Always verify output.
// then get jobId which might contain dashes as well
const index = task.jobId.indexOf('-')
const hash = task.jobId.slice(0, index)
const jobId = task.jobId.slice(index + 1)

Check failure

Code scanning / CodeQL

Type confusion through parameter tampering Critical

Potential type confusion as
this HTTP request parameter
may be either an array or a string.

Copilot Autofix

AI 22 days ago

To fix this problem, we must ensure that the handler in getStreamableLogs.ts only processes a string-type jobId value, rejecting requests where jobId is an array or any other unexpected type. The best way to address this is to add a runtime type check for jobId before using string methods on it (e.g., indexOf, slice). The most sensible place for this check is in the validate method or at the head of the handle method. Since the command is validated by a dedicated validate method, we should update this validator to return an error if command.jobId is anything other than a string (and non-empty). This avoids type confusion in all downstream code.

Specific changes:

  • In validate(command: ComputeGetStreamableLogsCommand): ValidateParams (in src/components/core/compute/getStreamableLogs.ts):
    • Add a check: If command.jobId is not a string, return buildInvalidRequestMessage indicating the wrong type.
  • Optionally, for defense-in-depth, a check can also be added in the route handler in src/components/httpRoutes/compute.ts after reading req.query.jobId, but strictly, the validator catch suffices.

No additional methods or imports are needed; just a runtime type check and an error return.


Suggested changeset 1
src/components/core/compute/getStreamableLogs.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/components/core/compute/getStreamableLogs.ts b/src/components/core/compute/getStreamableLogs.ts
--- a/src/components/core/compute/getStreamableLogs.ts
+++ b/src/components/core/compute/getStreamableLogs.ts
@@ -14,6 +14,12 @@
   validate(command: ComputeGetStreamableLogsCommand): ValidateParams {
     const validation = validateCommandParameters(command, ['jobId'])
     if (validation.valid) {
+      // Type confusion prevention: ensure jobId is a string
+      if (typeof command.jobId !== 'string') {
+        return buildInvalidRequestMessage(
+          'Parameter : "jobId" must be a string.'
+        )
+      }
       if (command.consumerAddress && !isAddress(command.consumerAddress)) {
         return buildInvalidRequestMessage(
           'Parameter : "consumerAddress" is not a valid web3 address'
EOF
@@ -14,6 +14,12 @@
validate(command: ComputeGetStreamableLogsCommand): ValidateParams {
const validation = validateCommandParameters(command, ['jobId'])
if (validation.valid) {
// Type confusion prevention: ensure jobId is a string
if (typeof command.jobId !== 'string') {
return buildInvalidRequestMessage(
'Parameter : "jobId" must be a string.'
)
}
if (command.consumerAddress && !isAddress(command.consumerAddress)) {
return buildInvalidRequestMessage(
'Parameter : "consumerAddress" is not a valid web3 address'
Copilot is powered by AI and may make mistakes. Always verify output.
}
} catch (error) {
console.error('Error processing request:', error)
res.status(400).send(error)

Check warning

Code scanning / CodeQL

Exception text reinterpreted as HTML Medium

Exception text
is reinterpreted as HTML without escaping meta-characters.

Copilot Autofix

AI 22 days ago

To fix the problem, the app should avoid sending unsanitized error text containing possible user input directly in the response body. The safest way is to not expose raw error text at all—instead, return a generic error message, or if details are required for debugging, sanitize them before sending. Ideally, also ensure the response content-type is set to application/json, so meta-characters will not be interpreted as HTML (though escaping is still important for JSON).

In src/components/httpRoutes/dids.ts, within the catch block of the POST /getProvidersForStrings route handler, replace the line res.status(400).send(error) with a generic error message such as:

res.status(400).json({ error: 'Error processing request.' })

Optionally, if the error message is useful for development but must be sanitized, use a escaping library (e.g., lodash.escape or he) to encode meta-characters, and return as a property in the JSON. However, for production, it is best to avoid including details that can contain user-supplied strings.

Only the specified code block needs to be changed; no imports or extra logic is needed since a generic error message (or sanitized message) suffices.


Suggested changeset 1
src/components/httpRoutes/dids.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/components/httpRoutes/dids.ts b/src/components/httpRoutes/dids.ts
--- a/src/components/httpRoutes/dids.ts
+++ b/src/components/httpRoutes/dids.ts
@@ -51,7 +51,7 @@
       }
     } catch (error) {
       console.error('Error processing request:', error)
-      res.status(400).send(error)
+      res.status(400).json({ error: 'Error processing request.' })
     }
   }
 )
EOF
@@ -51,7 +51,7 @@
}
} catch (error) {
console.error('Error processing request:', error)
res.status(400).send(error)
res.status(400).json({ error: 'Error processing request.' })
}
}
)
Copilot is powered by AI and may make mistakes. Always verify output.
}
} catch (error) {
console.error('Error processing request:', error)
res.status(400).send(error)

Check warning

Code scanning / CodeQL

Information exposure through a stack trace Medium

This information exposed to the user depends on
stack trace information
.

Copilot Autofix

AI 22 days ago

To fix this issue, we need to avoid exposing potentially sensitive error information to the user. Instead of sending the error object to the client, we should send a generic, non-descriptive error message (such as "An error occurred while processing your request." or "Bad request."). The internal details should still be logged to the server using console.error.

Detailed steps:

  • In src/components/httpRoutes/dids.ts, in the catch block at line 54, replace res.status(400).send(error) with res.status(400).send('An error occurred while processing your request.') or similar.
  • No new imports or method definitions are required.
  • Only the catch block needs to change; logging remains as is.

Suggested changeset 1
src/components/httpRoutes/dids.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/components/httpRoutes/dids.ts b/src/components/httpRoutes/dids.ts
--- a/src/components/httpRoutes/dids.ts
+++ b/src/components/httpRoutes/dids.ts
@@ -51,7 +51,7 @@
       }
     } catch (error) {
       console.error('Error processing request:', error)
-      res.status(400).send(error)
+      res.status(400).send('An error occurred while processing your request.')
     }
   }
 )
EOF
@@ -51,7 +51,7 @@
}
} catch (error) {
console.error('Error processing request:', error)
res.status(400).send(error)
res.status(400).send('An error occurred while processing your request.')
}
}
)
Copilot is powered by AI and may make mistakes. Always verify output.
policyServer: req.query.policyServer || null
policyServer: (req.query.policyServer as any) || null,
authorization: authorization as string,
userData: parsedUserData

Check warning

Code scanning / CodeQL

Information exposure through a stack trace Medium

This information exposed to the user depends on
stack trace information
.

Copilot Autofix

AI 22 days ago

The best way to fix this problem is to ensure that received errors are never sent directly to the user. Instead, a generic error message should be sent, while the full details are logged server-side for debugging or audit purposes. Specifically, in providerRoutes.get(${SERVICES_API_BASE_PATH}/download, ...), the catch block should be modified so that after logging the error with HTTP_LOGGER.logMessage, the HTTP response uses a generic message like "Internal Server Error" instead of error. Do not change any other functionality, request/response behavior, nor logging. Only the response body to the client should be generalized.

Change:

res.status(500).send(error)

To:

res.status(500).send('Internal Server Error')

No new imports or helper functions are needed; only this line needs to be edited.


Suggested changeset 1
src/components/httpRoutes/provider.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/components/httpRoutes/provider.ts b/src/components/httpRoutes/provider.ts
--- a/src/components/httpRoutes/provider.ts
+++ b/src/components/httpRoutes/provider.ts
@@ -254,7 +254,7 @@
       }
     } catch (error) {
       HTTP_LOGGER.logMessage(`Error: ${error}`, true)
-      res.status(500).send(error)
+      res.status(500).send('Internal Server Error')
     }
     // res.sendStatus(200)
   }
EOF
@@ -254,7 +254,7 @@
}
} catch (error) {
HTTP_LOGGER.logMessage(`Error: ${error}`, true)
res.status(500).send(error)
res.status(500).send('Internal Server Error')
}
// res.sendStatus(200)
}
Copilot is powered by AI and may make mistakes. Always verify output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants