Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add version check for firstnode in restore network #62

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from

Conversation

tanuj-shardeum
Copy link
Contributor

No description provided.

Copy link

PR Reviewer Guide 🔍

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Key issues to review

Error Handling
The error handling for the version check in 'registerRoutes' does not account for the scenario where 'networkAccount' is a string. This could lead to misleading error messages or incorrect error responses.

Security Concern
The use of '~~' for parsing integers in 'isEqualOrNewerVersion' is unconventional and may lead to unexpected behavior if not properly validated.

src/API.ts Fixed Show fixed Hide fixed
src/API.ts Fixed Show fixed Hide fixed
src/API.ts Fixed Show fixed Hide fixed
if (!isSignatureValid) {
Logger.mainLogger.error('Invalid signature', signedFirstNodeInfo)
Logger.mainLogger.error('Invalid signature', requestBody)

Check warning

Code scanning / CodeQL

Log injection Medium

Log entry depends on a
user-provided value
.

Copilot Autofix AI about 2 months ago

To fix the log injection issue, we need to sanitize the user-provided input before logging it. Specifically, we should remove any newline characters from the requestBody to prevent log injection. This can be done using String.prototype.replace to ensure no line endings are present in the user input.

Suggested changeset 1
src/API.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/API.ts b/src/API.ts
--- a/src/API.ts
+++ b/src/API.ts
@@ -90,3 +90,5 @@
     nestedCountersInstance.countEvent('consensor', 'POST_nodelist', 1)
-    const requestBody = request.body
+    let requestBody = request.body
+    // Sanitize requestBody to remove newline characters
+    requestBody = JSON.parse(JSON.stringify(requestBody).replace(/\n|\r/g, ""))
     // eslint-disable-next-line no-constant-condition
EOF
@@ -90,3 +90,5 @@
nestedCountersInstance.countEvent('consensor', 'POST_nodelist', 1)
const requestBody = request.body
let requestBody = request.body
// Sanitize requestBody to remove newline characters
requestBody = JSON.parse(JSON.stringify(requestBody).replace(/\n|\r/g, ""))
// eslint-disable-next-line no-constant-condition
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
reply.send({ success: false, error: 'Invalid signature' })
return
}
} catch (e) {
Logger.mainLogger.error(e)
Logger.mainLogger.error('Signature verification failed', requestBody)

Check warning

Code scanning / CodeQL

Log injection Medium

Log entry depends on a
user-provided value
.

Copilot Autofix AI 3 months ago

To fix the log injection issue, we need to sanitize the user-provided input before logging it. Specifically, we should remove any newline characters from the requestBody to prevent log injection. This can be done using String.prototype.replace to ensure no line endings are present in the user input.

Suggested changeset 1
src/API.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/API.ts b/src/API.ts
--- a/src/API.ts
+++ b/src/API.ts
@@ -90,3 +90,4 @@
     nestedCountersInstance.countEvent('consensor', 'POST_nodelist', 1)
-    const requestBody = request.body
+    let requestBody = request.body
+    requestBody = JSON.parse(JSON.stringify(requestBody).replace(/\n|\r/g, ""))
     // eslint-disable-next-line no-constant-condition
@@ -105,3 +106,3 @@
       } catch (e) {
-        Logger.mainLogger.error(e)
+        Logger.mainLogger.error(e.message.replace(/\n|\r/g, ""))
         Logger.mainLogger.error('Signature verification failed', requestBody)
EOF
@@ -90,3 +90,4 @@
nestedCountersInstance.countEvent('consensor', 'POST_nodelist', 1)
const requestBody = request.body
let requestBody = request.body
requestBody = JSON.parse(JSON.stringify(requestBody).replace(/\n|\r/g, ""))
// eslint-disable-next-line no-constant-condition
@@ -105,3 +106,3 @@
} catch (e) {
Logger.mainLogger.error(e)
Logger.mainLogger.error(e.message.replace(/\n|\r/g, ""))
Logger.mainLogger.error('Signature verification failed', requestBody)
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
// eslint-disable-next-line no-constant-condition
if (true) {
Logger.mainLogger.debug('POST /nodelist firstNode:', firstNode)
Logger.mainLogger.debug('POST /nodelist appJoinData:', appJoinData)

Check warning

Code scanning / CodeQL

Log injection Medium

Log entry depends on a
user-provided value
.

Copilot Autofix AI about 2 months ago

To fix the log injection issue, we need to sanitize the appJoinData before logging it. Specifically, we should remove any newline characters from the user input to prevent log injection. This can be done using the String.prototype.replace method to replace newline characters with an empty string.

Suggested changeset 1
src/API.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/API.ts b/src/API.ts
--- a/src/API.ts
+++ b/src/API.ts
@@ -133,3 +133,4 @@
         Logger.mainLogger.debug('POST /nodelist firstNode:', firstNode)
-        Logger.mainLogger.debug('POST /nodelist appJoinData:', appJoinData)
+        const sanitizedAppJoinData = JSON.parse(JSON.stringify(appJoinData).replace(/\\n|\\r/g, ""))
+        Logger.mainLogger.debug('POST /nodelist appJoinData:', sanitizedAppJoinData)
       }
EOF
@@ -133,3 +133,4 @@
Logger.mainLogger.debug('POST /nodelist firstNode:', firstNode)
Logger.mainLogger.debug('POST /nodelist appJoinData:', appJoinData)
const sanitizedAppJoinData = JSON.parse(JSON.stringify(appJoinData).replace(/\\n|\\r/g, ""))
Logger.mainLogger.debug('POST /nodelist appJoinData:', sanitizedAppJoinData)
}
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
src/API.ts Fixed Show fixed Hide fixed
}, based on ${receiptLoadTraker} receipts received.`
)
receiptLoadTraker = 0 // Reset the count
}, config.receiptLoadTrakerInterval)

Check failure

Code scanning / CodeQL

Resource exhaustion High

This creates a timer with a user-controlled duration from a
user-provided value
.

Copilot Autofix AI 3 months ago

To fix the problem, we need to validate the receiptLoadTrakerInterval value before it is used in the setInterval function. This can be done by adding a check to ensure the interval is within an acceptable range. If the value is outside this range, we should set it to a default safe value.

  1. Add validation for receiptLoadTrakerInterval in src/API.ts when updating the configuration.
  2. Ensure that the validated value is used in src/primary-process/index.ts.
Suggested changeset 1
src/API.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/API.ts b/src/API.ts
--- a/src/API.ts
+++ b/src/API.ts
@@ -1005,2 +1005,9 @@
         const { sign, ...newConfig } = _request.body
+        if (newConfig.receiptLoadTrakerInterval !== undefined) {
+          const interval = parseInt(newConfig.receiptLoadTrakerInterval, 10);
+          if (isNaN(interval) || interval < 1000 || interval > 60000) { // Set acceptable range between 1 second and 1 minute
+            throw new Error('Invalid receiptLoadTrakerInterval value. Must be between 1000 and 60000 milliseconds.');
+          }
+          newConfig.receiptLoadTrakerInterval = interval;
+        }
         const validKeys = new Set(Object.keys(config))
EOF
@@ -1005,2 +1005,9 @@
const { sign, ...newConfig } = _request.body
if (newConfig.receiptLoadTrakerInterval !== undefined) {
const interval = parseInt(newConfig.receiptLoadTrakerInterval, 10);
if (isNaN(interval) || interval < 1000 || interval > 60000) { // Set acceptable range between 1 second and 1 minute
throw new Error('Invalid receiptLoadTrakerInterval value. Must be between 1000 and 60000 milliseconds.');
}
newConfig.receiptLoadTrakerInterval = interval;
}
const validKeys = new Set(Object.keys(config))
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
host: '0.0.0.0',
},
(err) => {
Logger.mainLogger.debug('TXDigestAPI Listening', config.txDigest.apiServerPort)

Check warning

Code scanning / CodeQL

Log injection Medium

Log entry depends on a
user-provided value
.

Copilot Autofix AI 3 months ago

To fix the log injection issue, we need to sanitize the config.txDigest.apiServerPort value before logging it. This can be done by ensuring that any potentially harmful characters are removed or escaped. Specifically, we should remove any newline characters from the user input before logging it.

  1. Identify the line where the logging occurs: Logger.mainLogger.debug('TXDigestAPI Listening', config.txDigest.apiServerPort).
  2. Sanitize the config.txDigest.apiServerPort value by removing newline characters before logging it.
  3. Ensure that the sanitization does not alter the functionality of the code.
Suggested changeset 1
src/txDigestAPIserver.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/txDigestAPIserver.ts b/src/txDigestAPIserver.ts
--- a/src/txDigestAPIserver.ts
+++ b/src/txDigestAPIserver.ts
@@ -79,3 +79,4 @@
     (err) => {
-      Logger.mainLogger.debug('TXDigestAPI Listening', config.txDigest.apiServerPort)
+      const sanitizedPort = config.txDigest.apiServerPort.toString().replace(/\n|\r/g, "");
+      Logger.mainLogger.debug('TXDigestAPI Listening', sanitizedPort)
       if (err) {
EOF
@@ -79,3 +79,4 @@
(err) => {
Logger.mainLogger.debug('TXDigestAPI Listening', config.txDigest.apiServerPort)
const sanitizedPort = config.txDigest.apiServerPort.toString().replace(/\n|\r/g, "");
Logger.mainLogger.debug('TXDigestAPI Listening', sanitizedPort)
if (err) {
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
cron.schedule(config.txDigest.txCronSchedule, async () => {
console.log('Running cron task....')
console.log('Checking archiver status....')
const archiverStatusResp = await axios.get(ARCHIVER_STATUS_CHECK_URL)

Check failure

Code scanning / CodeQL

Server-side request forgery Critical

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

Copilot Autofix AI 3 months ago

To fix the SSRF vulnerability, we need to ensure that the ARCHIVER_IP and ARCHIVER_PORT values are validated and restricted to a safe set of values. This can be achieved by implementing an allow-list of acceptable IP addresses and ports. Additionally, we should ensure that the URL is constructed safely.

  1. Implement an allow-list for ARCHIVER_IP and ARCHIVER_PORT.
  2. Validate the user input against the allow-list before updating the configuration.
  3. Update the /set-config endpoint to include this validation.
Suggested changeset 1
src/API.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/API.ts b/src/API.ts
--- a/src/API.ts
+++ b/src/API.ts
@@ -1014,2 +1014,12 @@
 
+        // Validate ARCHIVER_IP and ARCHIVER_PORT
+        const allowedIPs = ['127.0.0.1', '192.168.1.1'] // Example allow-list
+        const allowedPorts = [8080, 9090] // Example allow-list
+        if (newConfig.ARCHIVER_IP && !allowedIPs.includes(newConfig.ARCHIVER_IP)) {
+          throw new Error(`Invalid ARCHIVER_IP provided: ${newConfig.ARCHIVER_IP}`)
+        }
+        if (newConfig.ARCHIVER_PORT && !allowedPorts.includes(newConfig.ARCHIVER_PORT)) {
+          throw new Error(`Invalid ARCHIVER_PORT provided: ${newConfig.ARCHIVER_PORT}`)
+        }
+
         if (config.VERBOSE)
EOF
@@ -1014,2 +1014,12 @@

// Validate ARCHIVER_IP and ARCHIVER_PORT
const allowedIPs = ['127.0.0.1', '192.168.1.1'] // Example allow-list
const allowedPorts = [8080, 9090] // Example allow-list
if (newConfig.ARCHIVER_IP && !allowedIPs.includes(newConfig.ARCHIVER_IP)) {
throw new Error(`Invalid ARCHIVER_IP provided: ${newConfig.ARCHIVER_IP}`)
}
if (newConfig.ARCHIVER_PORT && !allowedPorts.includes(newConfig.ARCHIVER_PORT)) {
throw new Error(`Invalid ARCHIVER_PORT provided: ${newConfig.ARCHIVER_PORT}`)
}

if (config.VERBOSE)
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
src/worker-process/index.ts Fixed Show fixed Hide fixed
console.log(`Worker ${process.pid} is idle for more than 1 minute`)
process.send({ type: 'child_close' })
}
}, config.lastActivityCheckInterval)

Check failure

Code scanning / CodeQL

Resource exhaustion High

This creates a timer with a user-controlled duration from a
user-provided value
.

Copilot Autofix AI 3 months ago

To fix the problem, we need to ensure that the lastActivityCheckInterval value is validated and restricted to a safe range before it is used in the setInterval function. This can be done by adding a validation check in the src/API.ts file where the configuration is updated.

  1. Add a validation check for lastActivityCheckInterval in the src/API.ts file to ensure it is within an acceptable range.
  2. If the value is outside the acceptable range, return an error response and do not update the configuration.
Suggested changeset 1
src/API.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/API.ts b/src/API.ts
--- a/src/API.ts
+++ b/src/API.ts
@@ -1014,2 +1014,6 @@
 
+        if (newConfig.lastActivityCheckInterval && (newConfig.lastActivityCheckInterval < 1000 || newConfig.lastActivityCheckInterval > 60000)) {
+          throw new Error('Invalid value for lastActivityCheckInterval. It must be between 1000 and 60000 milliseconds.')
+        }
+
         if (config.VERBOSE)
EOF
@@ -1014,2 +1014,6 @@

if (newConfig.lastActivityCheckInterval && (newConfig.lastActivityCheckInterval < 1000 || newConfig.lastActivityCheckInterval > 60000)) {
throw new Error('Invalid value for lastActivityCheckInterval. It must be between 1000 and 60000 milliseconds.')
}

if (config.VERBOSE)
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
src/API.ts Dismissed Show dismissed Hide dismissed
)
) {
Logger.mainLogger.debug(
`Invalid version of the node: ${appJoinData.shardeumVersion}, required minVersion: ${networkAccount?.data?.current?.minVersion}, required latestVersion: ${networkAccount?.data?.current?.latestVersion}`

Check warning

Code scanning / CodeQL

Log injection Medium

Log entry depends on a
user-provided value
.

Copilot Autofix AI 3 months ago

To fix the log injection issue, we need to sanitize the user input before logging it. Specifically, we should remove any newline characters from the appJoinData.shardeumVersion value to prevent log injection. This can be done using the String.prototype.replace method to strip out newline characters.

Suggested changeset 1
src/API.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/API.ts b/src/API.ts
--- a/src/API.ts
+++ b/src/API.ts
@@ -150,3 +150,3 @@
           Logger.mainLogger.debug(
-            `Invalid version of the node: ${appJoinData.shardeumVersion}, required minVersion: ${networkAccount?.data?.current?.minVersion}, required latestVersion: ${networkAccount?.data?.current?.latestVersion}`
+            `Invalid version of the node: ${appJoinData.shardeumVersion.replace(/\n|\r/g, '')}, required minVersion: ${networkAccount?.data?.current?.minVersion}, required latestVersion: ${networkAccount?.data?.current?.latestVersion}`
           )
EOF
@@ -150,3 +150,3 @@
Logger.mainLogger.debug(
`Invalid version of the node: ${appJoinData.shardeumVersion}, required minVersion: ${networkAccount?.data?.current?.minVersion}, required latestVersion: ${networkAccount?.data?.current?.latestVersion}`
`Invalid version of the node: ${appJoinData.shardeumVersion.replace(/\n|\r/g, '')}, required minVersion: ${networkAccount?.data?.current?.minVersion}, required latestVersion: ${networkAccount?.data?.current?.latestVersion}`
)
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
}

export function isValidVersion(minimumVersion: string, latestVersion: string, nodeVersion: string): boolean {
if(config.VERBOSE) Logger.mainLogger.debug('isValidVersion: ', minimumVersion, latestVersion, nodeVersion)

Check warning

Code scanning / CodeQL

Log injection Medium

Log entry depends on a
user-provided value
.

Copilot Autofix AI about 2 months ago

To fix the log injection issue, we need to sanitize the nodeVersion before logging it. Specifically, we should remove any newline characters from the nodeVersion string to prevent log injection attacks. This can be done using String.prototype.replace to remove newline characters.

Suggested changeset 1
src/NodeList.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/NodeList.ts b/src/NodeList.ts
--- a/src/NodeList.ts
+++ b/src/NodeList.ts
@@ -443,3 +443,4 @@
 export function isValidVersion(minimumVersion: string, latestVersion: string, nodeVersion: string): boolean {
-  if(config.VERBOSE) Logger.mainLogger.debug('isValidVersion: ', minimumVersion, latestVersion, nodeVersion)
+  const sanitizedNodeVersion = nodeVersion.replace(/\n|\r/g, "");
+  if(config.VERBOSE) Logger.mainLogger.debug('isValidVersion: ', minimumVersion, latestVersion, sanitizedNodeVersion)
   
EOF
@@ -443,3 +443,4 @@
export function isValidVersion(minimumVersion: string, latestVersion: string, nodeVersion: string): boolean {
if(config.VERBOSE) Logger.mainLogger.debug('isValidVersion: ', minimumVersion, latestVersion, nodeVersion)
const sanitizedNodeVersion = nodeVersion.replace(/\n|\r/g, "");
if(config.VERBOSE) Logger.mainLogger.debug('isValidVersion: ', minimumVersion, latestVersion, sanitizedNodeVersion)

Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
@tanuj-shardeum tanuj-shardeum marked this pull request as ready for review September 24, 2024 13:23
if (
typeof networkAccount != 'string' &&
!NodeList.isValidVersion(
networkAccount?.data?.current?.minVersion,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How will the archiver knows the data type and format of the global/network account from the Shardeum? For instance, if archiver is used other app layers (other than Shardeum) that use different format for network account, this will fail.

Logger.mainLogger.debug('networkAccount', networkAccount)

if (networkAccount) {
if (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good if this if check can be simplified for better readability

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants