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

feat: add refinement for transaction notes #2377

Merged
merged 1 commit into from
Feb 24, 2025
Merged

feat: add refinement for transaction notes #2377

merged 1 commit into from
Feb 24, 2025

Conversation

PooyaRaki
Copy link
Contributor

@PooyaRaki PooyaRaki commented Feb 24, 2025

Summary

This PR improves and clarifies transaction notes for better accuracy and readability.

Changes

  • Enhanced transaction note details to ensure clarity and consistency.

Summary by CodeRabbit

  • New Features
    • Enhanced transaction processing by verifying and sanitizing external note content to prevent HTML injection.
  • Tests
    • Expanded test coverage to ensure proper handling of potentially unsafe input in transaction proposals.
  • Chores
    • Updated dependencies to support robust HTML sanitization.

@PooyaRaki PooyaRaki self-assigned this Feb 24, 2025
@PooyaRaki PooyaRaki requested a review from a team as a code owner February 24, 2025 10:36
Copy link

coderabbitai bot commented Feb 24, 2025

Walkthrough

This pull request introduces HTML sanitization by adding the necessary dependency and its type definitions. Changes to the transaction proposal tests include adding an "origin" property with potentially unsafe content and updating the expected output. A new test ensures that the note mapper correctly sanitizes malicious input. The mapper itself is updated to accept multiple transaction types and to sanitize the note content before returning it. Finally, the transactions service now injects the note mapper and includes a method to verify and parse the "origin" property, handling invalid JSON accordingly.

Changes

Files Change Summary
package.json Added "sanitize-html": "^2.14.0" and "@types/sanitize-html": "^2" to dependencies and devDependencies respectively.
src/routes/transactions/__tests__/controllers/propose-transaction.transactions.controller.spec.ts
src/routes/transactions/mappers/multisig-transactions/multisig-transaction-note.mapper.spec.ts
Updated tests: the transaction proposal test now includes an origin property and expected note; a new test case verifies that the note mapper correctly sanitizes HTML with malicious content.
src/routes/transactions/mappers/multisig-transactions/multisig-transaction-note.mapper.ts Modified mapTxNote to accept a union type (`MultisigTransaction
src/routes/transactions/transactions.service.ts Injected MultisigTransactionNoteMapper and added a new private method verifyOrigin to parse and process the origin property in transaction proposals.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant TransactionsService
    participant NoteMapper

    Client->>TransactionsService: proposeTransaction(proposeTransactionDto)
    TransactionsService->>TransactionsService: verifyOrigin(origin)
    alt Valid JSON in origin
        TransactionsService->>NoteMapper: mapTxNote(parsedOrigin)
        NoteMapper-->>TransactionsService: sanitized note
        TransactionsService->>TransactionsService: Append sanitized note to origin
    else Invalid JSON
        TransactionsService->>TransactionsService: Catch error, set origin to null
    end
    TransactionsService-->>Client: Return JSON string (or null) of origin
Loading

Poem

I'm a rabbit, bounding through code's maze,
Hopping over bugs in countless ways.
Sanitizing HTML with a swift, keen glance,
Securing each "origin" with a graceful dance.
In every commit, may our functions prance,
With CodeRabbit's craft, our code shall advance!
🐇💻 Happy hopping!

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/routes/transactions/mappers/multisig-transactions/multisig-transaction-note.mapper.ts (1)

15-15: Consider configuring sanitizeHtml options.

The default sanitizeHtml options might be too permissive. Consider explicitly configuring allowed tags and attributes based on your requirements.

-          return sanitizeHtml(origin.note as string);
+          return sanitizeHtml(origin.note as string, {
+            allowedTags: [], // Disallow all HTML tags
+            allowedAttributes: {}, // Disallow all attributes
+            disallowedTagsMode: 'recursiveEscape'
+          });
src/routes/transactions/transactions.service.ts (1)

439-441: Consider error handling for verifyOrigin.

While the code is functionally correct, it might benefit from explicit error handling to provide better feedback when origin verification fails.

Consider adding error handling:

-    args.proposeTransactionDto.origin = this.verifyOrigin(
-      args.proposeTransactionDto,
-    );
+    try {
+      args.proposeTransactionDto.origin = this.verifyOrigin(
+        args.proposeTransactionDto,
+      );
+    } catch (error) {
+      this.loggingService.warn('Failed to verify transaction origin', {
+        error,
+        chainId: args.chainId,
+        safeAddress: args.safeAddress,
+      });
+    }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 43fc2e9 and 047235a.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (5)
  • package.json (2 hunks)
  • src/routes/transactions/__tests__/controllers/propose-transaction.transactions.controller.spec.ts (2 hunks)
  • src/routes/transactions/mappers/multisig-transactions/multisig-transaction-note.mapper.spec.ts (1 hunks)
  • src/routes/transactions/mappers/multisig-transactions/multisig-transaction-note.mapper.ts (1 hunks)
  • src/routes/transactions/transactions.service.ts (4 hunks)
🔇 Additional comments (7)
package.json (1)

57-57:

✅ Verification successful

Verify the sanitize-html package version.

Let's confirm if version ^2.14.0 is valid and check for any known security advisories.


🌐 Web query:

What is the latest version of sanitize-html package and are there any known security advisories?

💡 Result:

The latest version of sanitize-html is 2.14.0, released in December 2024[1]. This package provides HTML sanitization with customizable rules for allowed tags/attributes and is widely used to clean user-generated HTML content[1][4].

Security Advisories

Several vulnerabilities have been identified in older versions:

Vulnerability Affected Versions Fix Version Details
Information Exposure <2.12.1 2.12.1 Allowed style attribute enumeration of server files when used on backend[3][5]
ReDoS <2.7.1 2.7.1 Regular Expression Denial of Service via HTML comment removal[3]
XSS via Math/SVG N/A (Sanitize library) Sanitize 5.2.1 Related advisory shows risks when allowing certain elements like <math>/<svg>[2]
IDN Bypass All versions Patched Could bypass allowedIframeHostnames with internationalized domain names[3]
Attribute Merging All versions Ongoing Incomplete attributes might merge dangerously (e.g., SRC=)[3]

For secure usage:

  • Upgrade to ≥v2.14.0[1]
  • Avoid allowing risky elements like <math>, <svg>, or <style>[2][6]
  • Use strict configurations:
    sanitizeHtml(dirtyHtml, {
      allowedTags: ['b', 'i', 'a', 'p'],
      allowedAttributes: {a: ['href']},
      allowProtocolRelative: false
    });
  • Consider client-side sanitizers like DOMPurify for additional protection[6][9]

The package remains actively maintained with security updates addressing these issues[1][3][5].

Citations:


Sanitize-html package version is verified as current.

After checking, the sanitize-html version specified in package.json ("^2.14.0") is indeed the latest release (as of December 2024), and the use of the caret (^) ensures that minor security patches are applied automatically. The addition of "@types/sanitize-html" in devDependencies aligns with best practices. No further action is required regarding this dependency.

src/routes/transactions/mappers/multisig-transactions/multisig-transaction-note.mapper.spec.ts (1)

19-34: Great test coverage for XSS prevention!

The test cases effectively cover both direct and encoded XSS attack vectors, ensuring proper sanitization.

src/routes/transactions/mappers/multisig-transactions/multisig-transaction-note.mapper.ts (1)

8-10: LGTM! Good type safety improvement.

The method signature now correctly handles both MultisigTransaction and ProposeTransactionDto types.

src/routes/transactions/__tests__/controllers/propose-transaction.transactions.controller.spec.ts (2)

110-115: LGTM! Good integration test coverage.

The test properly verifies that malicious content in the origin note is sanitized in the response.


180-180: LGTM! Correct assertion for sanitized content.

The test correctly expects an empty string as the result of sanitizing malicious content.

src/routes/transactions/transactions.service.ts (2)

41-41: LGTM! Clean dependency injection setup.

The MultisigTransactionNoteMapper is properly imported and injected as a private readonly dependency.

Also applies to: 55-55


543-558: 🛠️ Refactor suggestion

✅ Verification successful

Enhance error handling in verifyOrigin.

The current implementation silently catches all errors and returns null. This might hide important issues.

Consider these improvements:

   private verifyOrigin(transaction: ProposeTransactionDto): string | null {
     if (transaction.origin) {
       try {
         const note = this.multisigTransactionNoteMapper.mapTxNote(transaction);
 
         const origin = JSON.parse(transaction.origin);
+        if (typeof origin !== 'object' || origin === null) {
+          throw new Error('Origin must be a JSON object');
+        }
         origin.note = note;
 
         return JSON.stringify(origin);
-      } catch {
-        // If the origin is not a valid JSON, we return null
+      } catch (error) {
+        // Log specific error for debugging
+        this.loggingService.debug('Invalid transaction origin', {
+          error,
+          origin: transaction.origin,
+        });
+        return null;
       }
     }
 
     return null;
   }

The improvements:

  1. Validate that parsed JSON is an object
  2. Add specific error logging for debugging

Let's verify the usage of logging service in the class:


🏁 Script executed:

#!/bin/bash
# Verify logging service usage patterns
rg "loggingService\." -A 2

Length of output: 40291


Enhanced error handling in verifyOrigin verified as consistent with logging usage.

The proposed changes correctly validate that the parsed JSON is an object and log detailed debug information when parsing fails. Notably, using this.loggingService.debug for tracking invalid JSON aligns with other parts of the codebase where debug-level logs are used for non-critical issues. The grep output confirms that the logging service is widely used (with debug, info, warn, and error), and using debug here is acceptable.

Changes to be made:

  • Add a check to ensure the parsed JSON is an object and not null.
  • In the catch block, log the error and the raw transaction.origin using this.loggingService.debug.
  • Continue to return null upon failure to parse.
   private verifyOrigin(transaction: ProposeTransactionDto): string | null {
     if (transaction.origin) {
       try {
         const note = this.multisigTransactionNoteMapper.mapTxNote(transaction);
 
         const origin = JSON.parse(transaction.origin);
+        if (typeof origin !== 'object' || origin === null) {
+          throw new Error('Origin must be a JSON object');
+        }
         origin.note = note;
 
         return JSON.stringify(origin);
-      } catch {
-        // If the origin is not a valid JSON, we return null
+      } catch (error) {
+        // Log specific error for debugging
+        this.loggingService.debug('Invalid transaction origin', {
+          error,
+          origin: transaction.origin,
+        });
+        return null;
       }
     }
 
     return null;
   }

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/routes/transactions/mappers/multisig-transactions/multisig-transaction-note.mapper.ts (1)

15-15: Remove redundant type assertion.

The type assertion as string is unnecessary since we already check typeof origin.note === 'string'.

-          return sanitizeHtml(origin.note as string, {
+          return sanitizeHtml(origin.note, {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 047235a and 26f1663.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (5)
  • package.json (2 hunks)
  • src/routes/transactions/__tests__/controllers/propose-transaction.transactions.controller.spec.ts (2 hunks)
  • src/routes/transactions/mappers/multisig-transactions/multisig-transaction-note.mapper.spec.ts (1 hunks)
  • src/routes/transactions/mappers/multisig-transactions/multisig-transaction-note.mapper.ts (1 hunks)
  • src/routes/transactions/transactions.service.ts (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/routes/transactions/mappers/multisig-transactions/multisig-transaction-note.mapper.spec.ts
  • package.json
  • src/routes/transactions/tests/controllers/propose-transaction.transactions.controller.spec.ts
  • src/routes/transactions/transactions.service.ts
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: tests (test:e2e:cov)
  • GitHub Check: tests (test:cov)
🔇 Additional comments (3)
src/routes/transactions/mappers/multisig-transactions/multisig-transaction-note.mapper.ts (3)

3-4: LGTM! Necessary imports added.

The new imports support HTML sanitization and expanded type handling.


15-19: LGTM! Robust HTML sanitization implementation.

The sanitization configuration follows security best practices by:

  • Stripping all HTML tags and attributes
  • Preventing iframe injection
  • Using a restrictive allowlist approach

8-10:

❓ Verification inconclusive

Verify type compatibility of the union type.

The method now accepts both MultisigTransaction and ProposeTransactionDto. Please ensure both types have compatible origin properties to prevent runtime errors.


🏁 Script executed:

#!/bin/bash
# Description: Verify that both types have compatible 'origin' property

# Check MultisigTransaction definition
echo "Checking MultisigTransaction definition:"
ast-grep --pattern 'interface MultisigTransaction {
  $$$
  origin: $_;
  $$$
}'

# Check ProposeTransactionDto definition
echo "Checking ProposeTransactionDto definition:"
ast-grep --pattern 'interface ProposeTransactionDto {
  $$$
  origin: $_;
  $$$
}'

Length of output: 353


Action: Verify ‘origin’ Property Compatibility

Our initial automated AST grep didn’t return explicit definitions for the origin property in either the MultisigTransaction or ProposeTransactionDto types. Please double-check that both types include an origin property of a compatible type (e.g., both as a string, number, etc.) to avoid any runtime issues. In case these definitions are declared differently (for instance, as classes or via type aliases), manually verify their signatures to ensure they align.

  • Confirm that MultisigTransaction defines origin with the intended type.
  • Confirm that ProposeTransactionDto defines origin with a compatible type.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/routes/transactions/mappers/multisig-transactions/multisig-transaction-note.mapper.ts (1)

15-19: Consider adding security logging.

For security monitoring purposes, consider logging attempts to inject malicious content.

 return sanitizeHtml(origin.note as string, {
   allowedAttributes: {},
   allowedTags: [],
   allowedIframeHostnames: [],
+  transformTags: {
+    '*': (tagName, attribs) => {
+      if (Object.keys(attribs).length > 0 || tagName !== '') {
+        this.logger.warn('Attempted HTML injection in transaction note', {
+          tagName,
+          attribs,
+        });
+      }
+      return { tagName: '', attribs: {} };
+    },
+  },
 });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 26f1663 and d1623f2.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (5)
  • package.json (2 hunks)
  • src/routes/transactions/__tests__/controllers/propose-transaction.transactions.controller.spec.ts (2 hunks)
  • src/routes/transactions/mappers/multisig-transactions/multisig-transaction-note.mapper.spec.ts (1 hunks)
  • src/routes/transactions/mappers/multisig-transactions/multisig-transaction-note.mapper.ts (1 hunks)
  • src/routes/transactions/transactions.service.ts (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/routes/transactions/tests/controllers/propose-transaction.transactions.controller.spec.ts
  • src/routes/transactions/mappers/multisig-transactions/multisig-transaction-note.mapper.spec.ts
  • package.json
  • src/routes/transactions/transactions.service.ts
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: tests (test:e2e:cov)
  • GitHub Check: tests (test:cov)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: tests (test:e2e:cov)
  • GitHub Check: tests (test:cov)
🔇 Additional comments (3)
src/routes/transactions/mappers/multisig-transactions/multisig-transaction-note.mapper.ts (3)

8-10: LGTM! Good type safety with union type.

The method signature change to accept both MultisigTransaction and ProposeTransactionDto maintains type safety while providing more flexibility.


15-19: LGTM! Secure sanitization configuration.

The HTML sanitization is implemented with appropriately strict security controls:

  • No HTML tags allowed
  • No attributes allowed
  • No iframes allowed

This configuration effectively prevents XSS attacks.


3-4:

❓ Verification inconclusive

Verify the sanitize-html package version for security.

The addition of sanitize-html for HTML sanitization is a good security practice. Let's ensure we're using a secure version.


🏁 Script executed:

#!/bin/bash
# Check the installed version and latest version of sanitize-html
npm list sanitize-html
npm view sanitize-html versions --json | jq -r '.[-1]'

# Check for known vulnerabilities
npm audit

Length of output: 477


Action Needed: Verify the sanitize-html Dependency Installation and Lockfile Setup

It appears that while the code imports sanitize-html, our initial checks indicate that the package does not seem to be explicitly installed (as shown by the empty output from npm list sanitize-html), and npm audit was unable to run due to a missing lockfile. Please perform the following:

  • Dependency Verification:
    Ensure that sanitize-html is listed in your package.json. If it's missing, add it by running:
    npm install sanitize-html
  • Lockfile Generation:
    Since npm audit failed because no lockfile exists, generate one with:
    npm i --package-lock-only
  • Security Check:
    Confirm that the installed version (currently the latest available is 2.14.0) is secure and free of vulnerabilities.

After addressing these points, please re-run your audit to ensure that all security issues are resolved.

@PooyaRaki PooyaRaki merged commit e9040c1 into main Feb 24, 2025
19 checks passed
@PooyaRaki PooyaRaki deleted the feat/txNote branch February 24, 2025 11:16
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.

2 participants