Opened 12 years ago

Closed 8 years ago

#685 closed defect (fixed)

Patch to make javascript safe (not execute) in Xinha

Reported by: mharrisonline Owned by: gogo
Priority: normal Milestone: 2.0
Component: Xinha Core Version:
Severity: normal Keywords: javascript execute write freezescript
Cc:

Description

In htmlarea.js, just below the line that says:

  // external stylesheets to load (REFERENCE THESE ABSOLUTELY)
  this.pageStyleSheets = ["this.css"];

add:

  // external js file to link content to (REFERENCE THIS ABSOLUTELY)
  // example:   utilityjs = "flashobject.js";
  utilityjs = "";

Replace:

  // Set up event listeners for saving the iframe content to the textarea
  if (textarea.form)
  {
    // onsubmit get the HTMLArea content and update original textarea.
    HTMLArea.prependDom0Event
    (
      this._textArea.form,
      'submit',
      function() {editor._textArea.value = editor.outwardHtml(editor.getHTML()); return true;}
    );

with:

  // Set up event listeners for saving the iframe content to the textarea
  if (textarea.form)
  {
    // onsubmit get the HTMLArea content and update original textarea.
    HTMLArea.prependDom0Event
    (
      this._textArea.form,
      'submit',
      function() {editor._textArea.value = editor.outwardHtml(editor.getHTML()).replace(/freezescript/ig, "javascript"); return true;}
    );

Replace:

      html += "</head>\n";
      html += "<body>\n";
      html +=   editor.inwardHtml(editor._textArea.value);
      html += "</body>\n";
      html += "</html>";
    } else {
      var html = editor.inwardHtml(editor._textArea.value);
      if (html.match(HTMLArea.RE_doctype)) {
        editor.setDoctype(RegExp.$1);
        html = html.replace(HTMLArea.RE_doctype, "");
      }
    }
    doc.write(html);
    doc.close();

with:

      html += "</head>\n";
      html += "<body>\n";
      html +=   editor.inwardHtml(editor._textArea.value);
      html += "</body>\n";
      html += "</html>";
    } else {
      var html = editor.inwardHtml(editor._textArea.value);
	  if(utilityjs){
	  html = "<script type=\"text/javascript\" src=\""+utilityjs+"\"></script>\n" + html;
	  }
	  html = html.replace(/<script>/ig, "<script type=\"text/freezescript\">");
	  html = html.replace(/javascript/ig, "freezescript");
      if (html.match(HTMLArea.RE_doctype)) {
        editor.setDoctype(RegExp.$1);
        html = html.replace(HTMLArea.RE_doctype, "");
      }
    }
    doc.write(html);
    doc.close();

This provides the config option of creating a link to an external js file such as flashobject.js, and also allows javascript document.writes to be in the content without executing.

Please add this capability to core Xinha so the Flash plugin can be used by any Xinha user.

Attachments (2)

htmlarea.js (191.1 KB) - added by mharrisonline 11 years ago.
htmlarea.js with patch applied to make Xinha safe to use with content containing JavaScript?
simple_example.html (2.5 KB) - added by mharrisonline 11 years ago.
place in the examples folder in xinha instance with the patched htmlare.js patch, this will demonstrate preloaded js with document.write statements being prevented from executing in the editor.

Download all attachments as: .zip

Change History (12)

comment:1 Changed 12 years ago by mharrisonline

  • Keywords execute write freezescript added
  • Milestone set to 2.0

comment:2 Changed 12 years ago by mharrisonline

If this capability was added to Xinha, it would make possible a powerful new type of plugin which could insert Javascript to write in dynamic content, such as RSS feeds.

comment:3 Changed 12 years ago by mharrisonline

So, after this patch is added, if you want to insert new JavaScript? while using the editor, just replace the word javascript with freezescript, and the script language will revert to javascript upon save.

comment:4 Changed 11 years ago by mharrisonline

I updated the patch, and will attach a revised htmlarea.js and a simplified example page to demonstrate this.

Add to line 291, or after the config "this.pageStyleSheets = [];"

  // external js file to link content to (REFERENCE THIS ABSOLUTELY)
  // example:   utilityjs = "flashobject.js";
  utilityjs = "";

line 1603 changes from:

editor._textArea.value = editor.outwardHtml(editor.getHTML());

to:

editor._textArea.value = editor.outwardHtml(editor.getHTML()).replace(/freezescript/ig, "javascript");

Replace the function HTMLArea.prototype.initIframe

with:

HTMLArea.prototype.initIframe = function()
{
  this.setLoadingMessage('Init IFrame');
  this.disableToolbar();
  var doc = null;
  var editor = this;
  try
  {
    if ( editor._iframe.contentDocument )
    {
      this._doc = editor._iframe.contentDocument;        
    }
    else
    {
      this._doc = editor._iframe.contentWindow.document;
    }
    doc = this._doc;
    // try later
    if ( !doc )
    {
      if ( HTMLArea.is_gecko )
      {
        setTimeout(function() { editor.initIframe(); }, 50);
        return false;
      }
      else
      {
        alert("ERROR: IFRAME can't be initialized.");
      }
    }
  }
  catch(ex)
  { // try later
    setTimeout(function() { editor.initIframe(); }, 50);
  }
  
  HTMLArea.freeLater(this, '_doc');
  
  doc.open();
  var html = '';
  if ( !editor.config.fullPage )
  {
    html = "<html>\n";
    html += "<head>\n";
    html += "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=" + editor.config.charSet + "\">\n";
    if ( typeof editor.config.baseHref != 'undefined' && editor.config.baseHref !== null )
    {
      html += "<base href=\"" + editor.config.baseHref + "\"/>\n";
    }
    html += "<style title=\"table borders\">";
    html += ".htmtableborders, .htmtableborders td, .htmtableborders th {border : 1px dashed lightgrey ! important;} \n";
    html += "</style>\n";
    html += "<style type=\"text/css\">";
    html += "html, body { border: 0px;  background-color: #ffffff; } \n";
    html += "span.macro, span.macro ul, span.macro div, span.macro p {background : #CCCCCC;}\n";
    html += "</style>\n";

    if ( editor.config.pageStyle )
    {
      html += "<style type=\"text/css\">\n" + editor.config.pageStyle + "\n</style>";
    }

    if ( typeof editor.config.pageStyleSheets !== 'undefined' )
    {
      for ( var i = 0; i < editor.config.pageStyleSheets.length; i++ )
      {
        if ( editor.config.pageStyleSheets[i].length > 0 )
        {
          html += "<link rel=\"stylesheet\" type=\"text/css\" href=\"" + editor.config.pageStyleSheets[i] + "\">";
          //html += "<style> @import url('" + editor.config.pageStyleSheets[i] + "'); </style>\n";
        }
      }
    }
if(utilityjs){
	  html = "<script type=\"text/freezescript\" src=\""+utilityjs+"\"></script>\n" + html;
}
    html += "</head>\n";
    html += "<body>\n";
    html +=   editor.inwardHtml(editor._textArea.value);
    html += "</body>\n";
    html += "</html>";
  }
  else
  {
    html = editor.inwardHtml(editor._textArea.value);
	  if(utilityjs){
	  html = "<script type=\"text/freezescript\" src=\""+utilityjs+"\"></script>\n" + html;
	  }
    if ( html.match(HTMLArea.RE_doctype) )
    {
      editor.setDoctype(RegExp.$1);
      html = html.replace(HTMLArea.RE_doctype, "");
    }
  }
  	html = html.replace(/<script>/ig, "<script type=\"text/freezescript\">");
	html = html.replace(/javascript/ig, "freezescript");
  doc.write(html);
  doc.close();

  this.setEditorEvents();
};

Changed 11 years ago by mharrisonline

htmlarea.js with patch applied to make Xinha safe to use with content containing JavaScript?

Changed 11 years ago by mharrisonline

place in the examples folder in xinha instance with the patched htmlare.js patch, this will demonstrate preloaded js with document.write statements being prevented from executing in the editor.

comment:5 Changed 11 years ago by Geoffrey

This is very useful. Could it perhaps be implemented (initially) as a FreezeScript? plugin, a bit like the GetHTML plugin, which replaces core functions without actually meddling with Xinha's internal code?

comment:6 Changed 11 years ago by mharrisonline

On our Website numerous pages have javascript functions to load Flash videos using a modified SWFObject script. All the JavaScript? gets entered through Xinha with the FreezeSccript? fix. There are even AJAX tabs that are left intact by Xinha.

http://www.jiu.edu/

comment:7 Changed 11 years ago by koto

Is there anything against commiting this to Xinha? Seems very useful, especially for Flash-related plugins described in http://xinha.python-hosting.com/ticket/669

comment:8 follow-up: Changed 11 years ago by ray

Hello,
in rev [620] I have added the freezescript functionality with some differences:

  • using HTMLArea.prototype.outwardHtml()/HTMLArea.prototype.inwardHtml() it works transparently in the background in all relevant places, also you don't have to use "freezescript" in text mode
  • I have not yet taken over the changes in HTMLArea.prototype.initIframe(), because I didn't quite understand them:
    • in non-FullPage? mode it brings just about nothing. It isn't executed because of freezescript, neither is it saved with the document as it's in the head section
    • in FullPage? mode I found it a bit strange to enter content through a config variable. What if you open the document once again? I think the utilityjs is added once again and again... Also it is placed before the <head>

Pls comment if I got something wrong

Furthermore this changeset enables the use of script tags with the "old" getHTML() and introduces a new config option to control whether you want to allow or deny <script>s in the editor

  • xinha_config.stripScripts = true;
    • default; strip <script> tags from the source
  • xinha_config.stripScripts = false;
    • leave <script> tags intact

comment:9 in reply to: ↑ 8 Changed 8 years ago by gogo

Replying to ray:

Hello,
in rev [620] I have added the freezescript functionality with some differences:

Ray, does this mean this patch is no longer required? Can you close the ticket if so please, save me digging through it.

comment:10 Changed 8 years ago by gogo

  • Resolution set to fixed
  • Status changed from new to closed

Hmm, actually I think this is old enough without any further comments that I will say ray's commit in changeset:620 is deemed to resolve this ticket.

Closing.

Note: See TracTickets for help on using tickets.