Angular 5 - DomSanitizer and data-attibutes

840 views
Skip to first unread message

Arnaud Deman

unread,
Jan 13, 2018, 2:40:28 PM1/13/18
to Angular and AngularJS discussion
Hi, 
is it possible to keep a specific data attribute with the DomSanitizer ?

For the moment I am doing these steps :
  1.  Extract the data-attribute with a regex from the html string,
  2. Call the DomSanitizer on the html string,
  3. Reinject the data-attribute in the sanitized html.
  4. call DomSanitizer.bypassSecurityTrustHtml on the result of the previous step to obtain a SafeHtml instance.
  5. Inject the result with:  <div  [innerHTML]="mySafeHtml"></div>
It is working but I find this a little bit tricky so I would be interested by a more conventional solution.

Subsidary question: what are the risks of an XSS attack with a data attribute  (quoted and html encoded) ? 

Regards,
Arnaud.

Sander Elias

unread,
Jan 16, 2018, 1:44:09 AM1/16/18
to Angular and AngularJS discussion
Hi Arnaud,

I'm not sure I got it right what you are doing.
Are you reading a data-attribute that comes as a payload inside a template?
Then you are putting it back into a template, just to extract it later on again?


The risk of doing this has little to no bearing in the context of an XSS attack. What has more of an impact, is the way you get the data in the first place. If it's gathered from a user, and not handled properly all along the chain, you might have an exposed attack vector.

Regards
Sander 

Arnaud Deman

unread,
Jan 16, 2018, 8:26:44 AM1/16/18
to Angular and AngularJS discussion
Hi Sander, Hi all,

Some parts of my app are edtable by the user with a wysiwyg editor (quilljs).
This editior is customized to add the possibility to insert dynamically within the html,  some Angular components : button, Card, Collapse, etc.

The defintions of these components are stored in a dedicated data-attribute of an img tag which represents the component during the edition process.
The result of all of this is then processed to generate the view dynamically. You helped me for that few months ago! ;-)

I had to disable the sanitizer of the editor so I would like to keep the angular one for everything except the data-attribute and I wonder if there is a better way than what I did.

Regards,
Arnaud.

Sander Elias

unread,
Jan 16, 2018, 10:21:19 AM1/16/18
to Angular and AngularJS discussion
Hi Arnaud,

I think I need to see some code to be able to decide ;)

Regards
Sander

Arnaud Deman

unread,
Jan 16, 2018, 4:44:02 PM1/16/18
to Angular and AngularJS discussion
Hi Sander,

There is a lot of dependencies so it will be difficult to make a stackblitz but this is the relevant parts of code of one use case. Hope this will be enough to be understandable.

Regards,
Arnaud.


This is the code in the editor component, wich I would like to improve.

 @Input()
    set dlContext(dlContext: DLContextSpec) { 
       
           // Translates the LoadingContext into html with img tags and data attributes to keep.
            let processedData = this.translateDLContextToHtml(dlContext);  // <- HTML entered by user, need to be sanitized.

           // Saves the specific data attributes, sanitizes the html and restores the saved attributes into the sanitized html.
           let dataAttribute: JSONDataAttribute = new JSONDataAttribute(CorpusBlot.CONTEXT_ATTRIBUTE);
           let savedDataAttribute = extractDataAttributes(processedData, dataAttribute);

            let sanitizedData = this._domSanitizer.sanitize(SecurityContext.HTML, processedData);

            // Restores the data attributes.
            let index: number = 0;
            sanitizedData = sanitizedData.replace(new RegExp(`<${CorpusBlot.tagName} [^>]*class="${CorpusBlot.className}" [^>]*>`, "ig"), (matched) => {
                return index < savedDataAttribute.length ? matched.replace('>', ' ' + savedDataAttribute[index++] + '>') : "";
            })
            
            this.initialData =  this._domSanitizer.bypassSecurityTrustHtml(sanitizedData);
           
        }
    }


The editor, QuillJs is then initialized from a div in the template where the resulting SafeHtml of the method above is injected :

<div *ngIf="render" id="{{containerId}}" [innerHTML]="initialData"></div>

Sander Elias

unread,
Jan 16, 2018, 10:21:07 PM1/16/18
to Angular and AngularJS discussion
Hi Arnoud,

I don't think there is a way around this little dance, without exposing yourself to even bigger XSS concerns. The angular sanitizer does a reasonably good job, but don't expect it to be flawless. Quill does some work to prevent this too, but again.. trusting user input is dangerous no matter what.
Have a look at this. (Go read, I'll still be here when you return.) ...

(Ah, there you are again, welcome back). Feeling slightly depressed now? Worst part yet has to come: The chance that that list is complete is about 0(ZERO!)% New attack vectors are found often. At least you need to inspect your new data on your server too.
But not all is lost, here are some things you can do.

Regards
Sander
Message has been deleted

Arnaud Deman

unread,
Jan 17, 2018, 1:03:13 AM1/17/18
to Angular and AngularJS discussion
Hi Sander,

Thanks for your answer. 
I will have a look at yours pointer. I have browsed the first one... and yes I feel sligthly depressed ;-)
I will pay special attention on server side. 

Regards,
Arnaud.
Reply all
Reply to author
Forward
0 new messages