VYPR
Medium severity5.4OSV Advisory· Published May 7, 2024· Updated Apr 15, 2026

CVE-2024-34341

CVE-2024-34341

Description

Trix is a rich text editor. The Trix editor, versions prior to 2.1.1, is vulnerable to arbitrary code execution when copying and pasting content from the web or other documents with markup into the editor. The vulnerability stems from improper sanitization of pasted content, allowing an attacker to embed malicious scripts which are executed within the context of the application. Users should upgrade to Trix editor version 2.1.1 or later, which incorporates proper sanitization of input from copied content.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Trix editor prior to 2.1.1 is vulnerable to arbitrary code execution via crafted pasted content due to insufficient sanitization.

Trix, a rich text editor, contains a vulnerability in versions prior to 2.1.1 where insufficient sanitization of pasted content allows execution of arbitrary scripts [4]. The bug originates from the editor's handling of markup from external sources during copy-paste operations, failing to properly escape or strip malicious HTML elements.

An attacker can exploit this flaw by crafting a document with embedded JavaScript and inducing a user to copy and paste it into a Trix editor [2]. No special privileges are required, as the attack vector relies on the user's action. The pasted content is processed by Trix's document model, which prior to the fix did not adequately sanitize attributes like data-trix-* [3].

Successful exploitation leads to arbitrary code execution within the context of the application, potentially enabling data theft, session hijacking, or further compromise of the user's session [4].

Users should upgrade to Trix version 2.1.1 or later, which includes proper input sanitization [2][3]. No workarounds are mentioned, but the fix is straightforward and incorporated into Rails via commit 260cb39 [2].

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
trixnpm
>= 2.0.0, < 2.1.12.1.1
trixnpm
>= 0.9.0, < 1.3.21.3.2
actiontextRubyGems
>= 7.0.0.alpha1, < 7.0.8.37.0.8.3
actiontextRubyGems
>= 7.1.0.beta1, < 7.1.3.37.1.3.3

Affected products

5

Patches

6
1a5c68a14d48

Merge pull request #1149 from basecamp/paste-html-sanitize

https://github.com/basecamp/trixAlberto Fernández-CapelMay 1, 2024via ghsa
2 files changed · +22 1
  • src/test/system/pasting_test.js+15 0 modified
    @@ -104,6 +104,21 @@ testGroup("Pasting", { template: "editor_empty" }, () => {
         delete window.unsanitized
       })
     
    +  test("paste data-trix-attachment unsafe html", async () => {
    +    window.unsanitized = []
    +    const pasteData = {
    +      "text/plain": "x",
    +      "text/html": `\
    +      copy<div data-trix-attachment="{&quot;contentType&quot;:&quot;text/html&quot;,&quot;content&quot;:&quot;&lt;img src=1 onerror=window.unsanitized.push(1)&gt;HELLO123&quot;}"></div>me
    +      `,
    +    }
    +
    +    await pasteContent(pasteData)
    +    await delay(20)
    +    assert.deepEqual(window.unsanitized, [])
    +    delete window.unsanitized
    +  })
    +
       test("prefers plain text when html lacks formatting", async () => {
         const pasteData = {
           "text/html": "<meta charset='utf-8'>a\nb",
    
  • src/trix/models/html_parser.js+7 1 modified
    @@ -40,7 +40,13 @@ const blockForAttributes = (attributes = {}, htmlAttributes = {}) => {
     
     const parseTrixDataAttribute = (element, name) => {
       try {
    -    return JSON.parse(element.getAttribute(`data-trix-${name}`))
    +    const data = JSON.parse(element.getAttribute(`data-trix-${name}`))
    +
    +    if (data.contentType === "text/html" && data.content) {
    +      data.content = HTMLSanitizer.sanitize(data.content).getHTML()
    +    }
    +
    +    return data
       } catch (error) {
         return {}
       }
    
841ff19b53f3

Merge pull request #1147 from basecamp/sanitize-noscript

https://github.com/basecamp/trixAlberto Fernández-CapelApr 26, 2024via ghsa
2 files changed · +16 1
  • src/test/system/pasting_test.js+15 0 modified
    @@ -89,6 +89,21 @@ testGroup("Pasting", { template: "editor_empty" }, () => {
         delete window.unsanitized
       })
     
    +  test("paste unsafe html with noscript", async () => {
    +    window.unsanitized = []
    +    const pasteData = {
    +      "text/plain": "x",
    +      "text/html": `\
    +        <div><noscript><div class="123</noscript>456<img src=1 onerror=window.unsanitized.push(1)//"></div></noscript></div>
    +      `
    +    }
    +
    +    await pasteContent(pasteData)
    +    await delay(20)
    +    assert.deepEqual(window.unsanitized, [])
    +    delete window.unsanitized
    +  })
    +
       test("prefers plain text when html lacks formatting", async () => {
         const pasteData = {
           "text/html": "<meta charset='utf-8'>a\nb",
    
  • src/trix/models/html_sanitizer.js+1 1 modified
    @@ -4,7 +4,7 @@ import { nodeIsAttachmentElement, removeNode, tagName, walkTree } from "trix/cor
     
     const DEFAULT_ALLOWED_ATTRIBUTES = "style href src width height language class".split(" ")
     const DEFAULT_FORBIDDEN_PROTOCOLS = "javascript:".split(" ")
    -const DEFAULT_FORBIDDEN_ELEMENTS = "script iframe form".split(" ")
    +const DEFAULT_FORBIDDEN_ELEMENTS = "script iframe form noscript".split(" ")
     
     export default class HTMLSanitizer extends BasicObject {
       static sanitize(html, options) {
    
73fac32511ee

Keep actiontext depending on trix 1.3.1

https://github.com/rails/railsRafael Mendonça FrançaMay 17, 2024via ghsa
2 files changed · +7 7
  • actiontext/package.json+3 3 modified
    @@ -1,6 +1,6 @@
     {
       "name": "@rails/actiontext",
    -  "version": "7.0.8-2",
    +  "version": "7.0.8-3",
       "description": "Edit and display rich text in Rails applications",
       "main": "app/assets/javascripts/actiontext.js",
       "type": "module",
    @@ -25,13 +25,13 @@
         "@rails/activestorage": ">= 7.0.0-alpha1"
       },
       "peerDependencies": {
    -    "trix": "^2.0.0"
    +    "trix": "^1.3.1"
       },
       "devDependencies": {
         "@rollup/plugin-node-resolve": "^11.0.1",
         "@rollup/plugin-commonjs": "^19.0.1",
         "rollup": "^2.35.1",
    -    "trix": "^2.0.0"
    +    "trix": "^1.3.1"
       },
       "scripts": {
         "build": "rollup --config rollup.config.js"
    
  • yarn.lock+4 4 modified
    @@ -4974,10 +4974,10 @@ tough-cookie@~2.4.3:
         psl "^1.1.24"
         punycode "^1.4.1"
     
    -trix@^2.0.0:
    -  version "2.1.1"
    -  resolved "https://registry.yarnpkg.com/trix/-/trix-2.1.1.tgz#688f1213601316cf8b92c5e625d2f562c118c780"
    -  integrity sha512-IljOMGOlRUPg1i5Pk/+x/Ia65ZY7Gw5JxxKCh/4caxG5ZaKuFJCKdn1+TF0efUYfdg+bqWenB/mAYCHjZu0zpQ==
    +trix@^1.3.1:
    +  version "1.3.2"
    +  resolved "https://registry.yarnpkg.com/trix/-/trix-1.3.2.tgz#9568c3bbda1085b9fcf2619ac41363011493d57f"
    +  integrity sha512-nV8IL6eS/czlaOu9TVIEcblQuPHeuuFpeoO7jFKII5q1pMUXCUGalJtEstS70HSkBSfUXU2vGJUfYXvSItcRCA==
     
     tsconfig-paths@^3.14.1:
       version "3.14.1"
    
07e6c88cc4de

Upgrade Trix to 1.3.2 to fix [CVE-2024-34341][1]

https://github.com/rails/railsRafael Mendonça FrançaMay 13, 2024via ghsa
8 files changed · +5228 10876
  • actiontext/app/assets/javascripts/trix.js+18 5275 modified
  • actiontext/app/assets/stylesheets/trix.css+20 374 modified
  • actiontext/CHANGELOG.md+5 0 modified
    @@ -1,3 +1,8 @@
    +*   Upgrade Trix to 1.3.2 to fix [CVE-2024-34341](https://github.com/basecamp/trix/security/advisories/GHSA-qjqp-xr96-cj99).
    +
    +    *Rafael Mendonça França*
    +
    +
     ## Rails 7.0.8.1 (February 21, 2024) ##
     
     *   No changes.
    
  • actiontext/package.json+2 2 modified
    @@ -25,13 +25,13 @@
         "@rails/activestorage": ">= 7.0.0-alpha1"
       },
       "peerDependencies": {
    -    "trix": "^1.3.1"
    +    "trix": "^2.0.0"
       },
       "devDependencies": {
         "@rollup/plugin-node-resolve": "^11.0.1",
         "@rollup/plugin-commonjs": "^19.0.1",
         "rollup": "^2.35.1",
    -    "trix": "^1.3.1"
    +    "trix": "^2.0.0"
       },
       "scripts": {
         "build": "rollup --config rollup.config.js"
    
  • actiontext/Rakefile+23 0 modified
    @@ -18,4 +18,27 @@ Rake::TestTask.new "test:system" do |t|
       t.verbose = true
     end
     
    +task :vendor_trix do
    +  require "importmap-rails"
    +  require "importmap/packager"
    +
    +  packager = Importmap::Packager.new(vendor_path: "app/assets/javascripts")
    +  imports = packager.import("trix@^1.3.2", from: "unpkg")
    +  imports.each do |package, url|
    +    url.gsub!("esm.min.js", "umd.js")
    +    puts %(Vendoring "#{package}" to #{packager.vendor_path}/#{package}.js via download from #{url})
    +    packager.download(package, url)
    +
    +    css_url = url.gsub("umd.js", "css")
    +    puts %(Vendoring "#{package}" to #{packager.vendor_path}/#{package}.css via download from #{css_url})
    +
    +    response = Net::HTTP.get_response(URI(css_url))
    +    if response.code == "200"
    +      File.open(Pathname.new("app/assets/stylesheets/trix.css"), "w+") do |file|
    +        file.write response.body
    +      end
    +    end
    +  end
    +end
    +
     task default: :test
    
  • Gemfile+1 1 modified
    @@ -29,7 +29,7 @@ gem "stimulus-rails"
     gem "turbo-rails"
     gem "jsbundling-rails"
     gem "cssbundling-rails"
    -gem "importmap-rails"
    +gem "importmap-rails", ">= 1.2.3"
     gem "tailwindcss-rails"
     # require: false so bcrypt is loaded only when has_secure_password is used.
     # This is to avoid Active Model (and by extension the entire framework)
    
  • Gemfile.lock+7 2 modified
    @@ -314,8 +314,9 @@ GEM
         image_processing (1.12.2)
           mini_magick (>= 4.9.5, < 5)
           ruby-vips (>= 2.0.17, < 3)
    -    importmap-rails (1.1.5)
    +    importmap-rails (2.0.1)
           actionpack (>= 6.0.0)
    +      activesupport (>= 6.0.0)
           railties (>= 6.0.0)
         io-console (0.6.0)
         irb (1.6.3)
    @@ -526,6 +527,10 @@ GEM
           concurrent-ruby (~> 1.0)
         tailwindcss-rails (2.0.21)
           railties (>= 6.0.0)
    +    tailwindcss-rails (2.0.21-x86_64-darwin)
    +      railties (>= 6.0.0)
    +    tailwindcss-rails (2.0.21-x86_64-linux)
    +      railties (>= 6.0.0)
         terser (1.1.13)
           execjs (>= 0.3.0, < 3)
         thin (1.8.1)
    @@ -592,7 +597,7 @@ DEPENDENCIES
       google-cloud-storage (~> 1.11)
       hiredis
       image_processing (~> 1.2)
    -  importmap-rails
    +  importmap-rails (>= 1.2.3)
       jsbundling-rails
       json (>= 2.0.0)
       libxml-ruby
    
  • yarn.lock+5152 5222 modified
260cb392fc1e

Upgrade Trix to 2.1.1 to fix [CVE-2024-34341][1]

https://github.com/rails/railsRafael Mendonça FrançaMay 13, 2024via ghsa
3 files changed · +100 31
  • actiontext/app/assets/javascripts/trix.js+92 30 modified
    @@ -1,6 +1,6 @@
     /*
    -Trix 2.0.7
    -Copyright © 2023 37signals, LLC
    +Trix 2.1.1
    +Copyright © 2024 37signals, LLC
      */
     (function (global, factory) {
       typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    @@ -9,14 +9,15 @@ Copyright © 2023 37signals, LLC
     })(this, (function () { 'use strict';
     
       var name = "trix";
    -  var version = "2.0.7";
    +  var version = "2.1.1";
       var description = "A rich text editor for everyday writing";
       var main = "dist/trix.umd.min.js";
       var module = "dist/trix.esm.min.js";
       var style = "dist/trix.css";
       var files = [
       	"dist/*.css",
       	"dist/*.js",
    +  	"dist/*.map",
       	"src/{inspector,trix}/*.js"
       ];
       var repository = {
    @@ -130,6 +131,7 @@ Copyright © 2023 37signals, LLC
         code: {
           tagName: "pre",
           terminal: true,
    +      htmlAttributes: ["language"],
           text: {
             plaintext: true
           }
    @@ -1215,7 +1217,7 @@ $\
           no-useless-escape,
       */
       const normalizeSpaces = string => string.replace(new RegExp("".concat(ZERO_WIDTH_SPACE), "g"), "").replace(new RegExp("".concat(NON_BREAKING_SPACE), "g"), " ");
    -  const normalizeNewlines = string => string.replace(/\r\n/g, "\n");
    +  const normalizeNewlines = string => string.replace(/\r\n?/g, "\n");
       const breakableWhitespacePattern = new RegExp("[^\\S".concat(NON_BREAKING_SPACE, "]"));
       const squishBreakableWhitespace = string => string
       // Replace all breakable whitespace characters with a space
    @@ -2144,20 +2146,28 @@ $\
           }
         }
         createContainerElement(depth) {
    -      let attributes, className;
    +      const attributes = {};
    +      let className;
           const attributeName = this.attributes[depth];
           const {
    -        tagName
    +        tagName,
    +        htmlAttributes = []
           } = getBlockConfig(attributeName);
           if (depth === 0 && this.block.isRTL()) {
    -        attributes = {
    +        Object.assign(attributes, {
               dir: "rtl"
    -        };
    +        });
           }
           if (attributeName === "attachmentGallery") {
             const size = this.block.getBlockBreakPosition();
             className = "".concat(css$1.attachmentGallery, " ").concat(css$1.attachmentGallery, "--").concat(size);
           }
    +      Object.entries(this.block.htmlAttributes).forEach(_ref => {
    +        let [name, value] = _ref;
    +        if (htmlAttributes.includes(name)) {
    +          attributes[name] = value;
    +        }
    +      });
           return makeElement({
             tagName,
             className,
    @@ -5828,28 +5838,29 @@ $\
       class Block extends TrixObject {
         static fromJSON(blockJSON) {
           const text = Text.fromJSON(blockJSON.text);
    -      return new this(text, blockJSON.attributes);
    +      return new this(text, blockJSON.attributes, blockJSON.htmlAttributes);
         }
    -    constructor(text, attributes) {
    +    constructor(text, attributes, htmlAttributes) {
           super(...arguments);
           this.text = applyBlockBreakToText(text || new Text());
           this.attributes = attributes || [];
    +      this.htmlAttributes = htmlAttributes || {};
         }
         isEmpty() {
           return this.text.isBlockBreak();
         }
         isEqualTo(block) {
           if (super.isEqualTo(block)) return true;
    -      return this.text.isEqualTo(block === null || block === void 0 ? void 0 : block.text) && arraysAreEqual(this.attributes, block === null || block === void 0 ? void 0 : block.attributes);
    +      return this.text.isEqualTo(block === null || block === void 0 ? void 0 : block.text) && arraysAreEqual(this.attributes, block === null || block === void 0 ? void 0 : block.attributes) && objectsAreEqual(this.htmlAttributes, block === null || block === void 0 ? void 0 : block.htmlAttributes);
         }
         copyWithText(text) {
    -      return new Block(text, this.attributes);
    +      return new Block(text, this.attributes, this.htmlAttributes);
         }
         copyWithoutText() {
           return this.copyWithText(null);
         }
         copyWithAttributes(attributes) {
    -      return new Block(this.text, attributes);
    +      return new Block(this.text, attributes, this.htmlAttributes);
         }
         copyWithoutAttributes() {
           return this.copyWithAttributes(null);
    @@ -5866,6 +5877,12 @@ $\
           const attributes = this.attributes.concat(expandAttribute(attribute));
           return this.copyWithAttributes(attributes);
         }
    +    addHTMLAttribute(attribute, value) {
    +      const htmlAttributes = Object.assign({}, this.htmlAttributes, {
    +        [attribute]: value
    +      });
    +      return new Block(this.text, this.attributes, htmlAttributes);
    +    }
         removeAttribute(attribute) {
           const {
             listAttribute
    @@ -5962,7 +5979,8 @@ $\
         toJSON() {
           return {
             text: this.text,
    -        attributes: this.attributes
    +        attributes: this.attributes,
    +        htmlAttributes: this.htmlAttributes
           };
         }
     
    @@ -6325,6 +6343,11 @@ $\
           const range = this.getRangeOfAttachment(attachment);
           return this.removeAttributeAtRange(attribute, range);
         }
    +    setHTMLAttributeAtPosition(position, name, value) {
    +      const block = this.getBlockAtPosition(position);
    +      const updatedBlock = block.addHTMLAttribute(name, value);
    +      return this.replaceBlock(block, updatedBlock);
    +    }
         insertBlockBreakAtRange(range) {
           let blocks;
           range = normalizeRange(range);
    @@ -6793,9 +6816,9 @@ $\
         return attributes;
       };
     
    -  const DEFAULT_ALLOWED_ATTRIBUTES = "style href src width height class".split(" ");
    +  const DEFAULT_ALLOWED_ATTRIBUTES = "style href src width height language class".split(" ");
       const DEFAULT_FORBIDDEN_PROTOCOLS = "javascript:".split(" ");
    -  const DEFAULT_FORBIDDEN_ELEMENTS = "script iframe form".split(" ");
    +  const DEFAULT_FORBIDDEN_ELEMENTS = "script iframe form noscript".split(" ");
       class HTMLSanitizer extends BasicObject {
         static sanitize(html, options) {
           const sanitizer = new this(html, options);
    @@ -6923,15 +6946,21 @@ $\
       };
       const blockForAttributes = function () {
         let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    +    let htmlAttributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
         const text = [];
         return {
           text,
    -      attributes
    +      attributes,
    +      htmlAttributes
         };
       };
       const parseTrixDataAttribute = (element, name) => {
         try {
    -      return JSON.parse(element.getAttribute("data-trix-".concat(name)));
    +      const data = JSON.parse(element.getAttribute("data-trix-".concat(name)));
    +      if (data.contentType === "text/html" && data.content) {
    +        data.content = HTMLSanitizer.sanitize(data.content).getHTML();
    +      }
    +      return data;
         } catch (error) {
           return {};
         }
    @@ -7027,8 +7056,9 @@ $\
           } else if (element === this.containerElement || this.isBlockElement(element)) {
             var _this$currentBlock;
             const attributes = this.getBlockAttributes(element);
    +        const htmlAttributes = this.getBlockHTMLAttributes(element);
             if (!arraysAreEqual(attributes, (_this$currentBlock = this.currentBlock) === null || _this$currentBlock === void 0 ? void 0 : _this$currentBlock.attributes)) {
    -          this.currentBlock = this.appendBlockForAttributesWithElement(attributes, element);
    +          this.currentBlock = this.appendBlockForAttributesWithElement(attributes, element, htmlAttributes);
               this.currentBlockElement = element;
             }
           }
    @@ -7039,9 +7069,10 @@ $\
           if (elementIsBlockElement && !this.isBlockElement(element.firstChild)) {
             if (!this.isInsignificantTextNode(element.firstChild) || !this.isBlockElement(element.firstElementChild)) {
               const attributes = this.getBlockAttributes(element);
    +          const htmlAttributes = this.getBlockHTMLAttributes(element);
               if (element.firstChild) {
                 if (!(currentBlockContainsElement && arraysAreEqual(attributes, this.currentBlock.attributes))) {
    -              this.currentBlock = this.appendBlockForAttributesWithElement(attributes, element);
    +              this.currentBlock = this.appendBlockForAttributesWithElement(attributes, element, htmlAttributes);
                   this.currentBlockElement = element;
                 } else {
                   return this.appendStringWithAttributes("\n");
    @@ -7129,8 +7160,9 @@ $\
         // Document construction
     
         appendBlockForAttributesWithElement(attributes, element) {
    +      let htmlAttributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
           this.blockElements.push(element);
    -      const block = blockForAttributes(attributes);
    +      const block = blockForAttributes(attributes, htmlAttributes);
           this.blocks.push(block);
           return block;
         }
    @@ -7235,6 +7267,17 @@ $\
           }
           return attributes$1.reverse();
         }
    +    getBlockHTMLAttributes(element) {
    +      const attributes$1 = {};
    +      const blockConfig = Object.values(attributes).find(settings => settings.tagName === tagName(element));
    +      const allowedAttributes = (blockConfig === null || blockConfig === void 0 ? void 0 : blockConfig.htmlAttributes) || [];
    +      allowedAttributes.forEach(attribute => {
    +        if (element.hasAttribute(attribute)) {
    +          attributes$1[attribute] = element.getAttribute(attribute);
    +        }
    +      });
    +      return attributes$1;
    +    }
         findBlockElementAncestors(element) {
           const ancestors = [];
           while (element && element !== this.containerElement) {
    @@ -7830,6 +7873,15 @@ $\
             return this.notifyDelegateOfCurrentAttributesChange();
           }
         }
    +    setHTMLAtributeAtPosition(position, attributeName, value) {
    +      var _getBlockConfig;
    +      const block = this.document.getBlockAtPosition(position);
    +      const allowedHTMLAttributes = (_getBlockConfig = getBlockConfig(block.getLastAttribute())) === null || _getBlockConfig === void 0 ? void 0 : _getBlockConfig.htmlAttributes;
    +      if (block && allowedHTMLAttributes !== null && allowedHTMLAttributes !== void 0 && allowedHTMLAttributes.includes(attributeName)) {
    +        const newDocument = this.document.setHTMLAttributeAtPosition(position, attributeName, value);
    +        this.setDocument(newDocument);
    +      }
    +    }
         setTextAttribute(attributeName, value) {
           const selectedRange = this.getSelectedRange();
           if (!selectedRange) return;
    @@ -7877,10 +7929,10 @@ $\
           return ((_this$getBlock = this.getBlock()) === null || _this$getBlock === void 0 ? void 0 : _this$getBlock.getNestingLevel()) > 0;
         }
         canIncreaseNestingLevel() {
    -      var _getBlockConfig;
    +      var _getBlockConfig2;
           const block = this.getBlock();
           if (!block) return;
    -      if ((_getBlockConfig = getBlockConfig(block.getLastNestableAttribute())) !== null && _getBlockConfig !== void 0 && _getBlockConfig.listAttribute) {
    +      if ((_getBlockConfig2 = getBlockConfig(block.getLastNestableAttribute())) !== null && _getBlockConfig2 !== void 0 && _getBlockConfig2.listAttribute) {
             const previousBlock = this.getPreviousBlock();
             if (previousBlock) {
               return arrayStartsWith(previousBlock.getListItemAttributes(), block.getListItemAttributes());
    @@ -8521,6 +8573,11 @@ $\
           return this.composition.removeCurrentAttribute(name);
         }
     
    +    // HTML attributes
    +    setHTMLAtributeAtPosition(position, name, value) {
    +      this.composition.setHTMLAtributeAtPosition(position, name, value);
    +    }
    +
         // Nesting level
     
         canDecreaseNestingLevel() {
    @@ -10941,8 +10998,12 @@ $\
           });
         },
         insertReplacementText() {
    -      return this.insertString(this.event.dataTransfer.getData("text/plain"), {
    -        updatePosition: false
    +      const replacement = this.event.dataTransfer.getData("text/plain");
    +      const domRange = this.event.getTargetRanges()[0];
    +      this.withTargetDOMRange(domRange, () => {
    +        this.insertString(replacement, {
    +          updatePosition: false
    +        });
           });
         },
         insertText() {
    @@ -11064,7 +11125,7 @@ $\
             return this.toggleDialog(actionName);
           } else {
             var _this$delegate2;
    -        return (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 ? void 0 : _this$delegate2.toolbarDidInvokeAction(actionName);
    +        return (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 ? void 0 : _this$delegate2.toolbarDidInvokeAction(actionName, element);
           }
         }
         didClickAttributeButton(event, element) {
    @@ -11509,8 +11570,8 @@ $\
             });
           }
         }
    -    toolbarDidInvokeAction(actionName) {
    -      return this.invokeAction(actionName);
    +    toolbarDidInvokeAction(actionName, invokingElement) {
    +      return this.invokeAction(actionName, invokingElement);
         }
         toolbarDidToggleAttribute(attributeName) {
           this.recordFormattingUndoEntry(attributeName);
    @@ -11579,10 +11640,11 @@ $\
             return !!((_this$actions$actionN = this.actions[actionName]) !== null && _this$actions$actionN !== void 0 && (_this$actions$actionN = _this$actions$actionN.test) !== null && _this$actions$actionN !== void 0 && _this$actions$actionN.call(this));
           }
         }
    -    invokeAction(actionName) {
    +    invokeAction(actionName, invokingElement) {
           if (this.actionIsExternal(actionName)) {
             return this.notifyEditorElement("action-invoke", {
    -          actionName
    +          actionName,
    +          invokingElement
             });
           } else {
             var _this$actions$actionN2;
    
  • actiontext/app/assets/stylesheets/trix.css+3 1 modified
    @@ -334,7 +334,9 @@ trix-editor .attachment__metadata {
         white-space: nowrap; }
     
     .trix-content {
    -  line-height: 1.5; }
    +  line-height: 1.5;
    +  overflow-wrap: break-word;
    +  word-break: break-word; }
       .trix-content * {
         box-sizing: border-box;
         margin: 0;
    
  • actiontext/CHANGELOG.md+5 0 modified
    @@ -1,3 +1,8 @@
    +*   Upgrade Trix to 1.3.2 to fix [CVE-2024-34341](https://github.com/basecamp/trix/security/advisories/GHSA-qjqp-xr96-cj99).
    +
    +    *Rafael Mendonça França*
    +
    +
     ## Rails 7.1.3.2 (February 21, 2024) ##
     
     *   No changes.
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

15

News mentions

0

No linked articles in our index yet.