Problem/Motivation

Currently, Attribute sanitizes strings using htmlspecialchars() to filter for HTML-based XSS attacks. However, there is no check for potentially executable attribute name/values such as onload="javascript:alert('XSS')".

Xss::filter() sanitizes attributes for dangerous protocols, but is heavy-handed: it also strips valid metadata attributes such as rel="schema:author". There's a related issue for this: #2544110: XSS attribute filtering is inconsistent and strips valid attributes

Proposed resolution

Unsure.

Remaining tasks

Write beta evaluation
Determine an approach

User interface changes

None, probably

API changes

Possibly

Data model changes

None, probably

Comments

joelpittet’s picture

Issue tags: +D8 Security Bounty

Could be a security bounty issue for you @Les Lim, so tagging in-case.

Anyways thoughts on resolution. Possibly stripping out attribute values from unsafe attributes. like javascript:, but we'd need a method like SafeMarkup/SafeString to override that in use-cases where those are practical.

Thanks for reporting this though!

Les Lim’s picture

I don't think there's any way to exploit this maliciously given what's in core. But as a contrib author, I could see someone writing a module that runs user input through Attribute and not Xss::filter(), thinking that the class would take care of all attack vectors.

larowlan’s picture

Is there a proof of concept here?

pwolanin’s picture

Duplicate to the on Wim is working on to filter attributes?

Wim Leers’s picture

#4: no, this is the theme/render system, not the filter system.

Wim Leers’s picture

Which is exactly why there's no protection here: you should never ever pass user-created data to Attribute.

pwolanin’s picture

Ok, so I think we should mark this as "as designed"? The attributes class is not supposed to be checking attribute names.

Les Lim’s picture

That makes sense, but will contrib authors know not to use Attribute in this way? The comments on the class say that it handles sanitization, which can reasonably be interpreted to mean its safe to use with user-entered input.

pwolanin’s picture

Well, in this case you need a dangerous attribute name. So, possibly the code doc should be updated to make it clear that this doesn't check the actual names, just sanitizes HTML

droplet’s picture

I must be missed something, I have same comment to this issue

Why Why ? I don't understand. Danger strings in safe area, this is safe.

#2544110: XSS attribute filtering is inconsistent and strips valid attributes

onload="javascript:alert('XSS')"
This is the example in Summary. This is totally wrong.

#1. If you write custom code (in theme or PHP backend coding) and use onload and apply value. You expected THIS IS "JAVASCRIPT" and can be executed. (if Drupal stripped, it's bug)
#2. If you use javascript:alert('XSS') in non on* evetns, what's wrong ?

joelpittet’s picture

Here's a POC.

// test.php
// drush scr test.php
use Drupal\Core\Template\Attribute;

$render = \Drupal::service('renderer');
$attributes = new Attribute(['href' => 'javascript:alert(String.fromCharCode(88,83,83))']);
$xss = [
  '#type' => 'inline_template',
  '#template' => '<a{{ attributes }}>click me</a>',
  '#context' => ['attributes' => $attributes],
];
print $render->renderPlain($xss);

Yields:
<a href="javascript:alert(String.fromCharCode(88,83,83))">click me</a>

We are looking into hardening this but we have to try to avoid breaking mailto:

// Test
$mailto = 'mailto:me@example.com';
$result = UrlHelper::stripDangerousProtocols($mailto);
$this->assertEquals($mailto, $result);
droplet’s picture

Personally, I don't think it's an issue.

@see #6
@see #10: Point #1

Here's what developers should do:

$attributes = new Attribute(['href' => 

APPLY_XSS_FILTER_HERE('javascript:alert(String.fromCharCode(88,83,83))')

]);

If we do introduce it into Drupal, it should NOT enabled by default IMO.

dawehner’s picture

This issue sounds like a duplicate of #2567743: Add protocol filtering to Attribute isn't it?

Wim Leers’s picture

Status: Active » Closed (duplicate)

#13++

It is extremely confusing to see so many issues that are so heavily overlapping. Tentatively closing this one as a duplicate.