Skip to content

String#escapeHTML() does not encode quotes, allowing XSS in attribute context #370

@knogineer

Description

@knogineer

String#escapeHTML() only encodes &, < and >. It does not encode quote characters, so a value placed inside a quoted HTML attribute can still break out of that attribute, which leads to XSS even after the value has been "escaped".

Current implementation (around line 421 of src/prototype/lang/string.js):

function escapeHTML() {
  return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
}

Reproduction:

var s = 'x" onmouseover="alert(document.domain)';
var html = '<a title="' + s.escapeHTML() + '">hi</a>';
// produces: <a title="x" onmouseover="alert(document.domain)">hi</a>
// the double quote is not encoded, so an event handler gets injected

The method name implies it is safe for HTML, and a lot of code uses it to build attribute values, so this gap is easy to miss.

Suggested fix: also encode " to &quot; and ' to &#39; (encoding / as well does no harm). If the intent is that the method is only ever safe for text node content, that is worth stating clearly in the docs, along with a separate attribute-safe helper.

Refs: CWE-79, CWE-116, OWASP XSS Prevention Cheat Sheet (rule #2), OWASP ASVS V5.3.1 / V5.3.3.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions