@@ -117,12 +117,12 @@ describe('svg+text utils', function() {
117
117
118
118
it ( 'whitelists http hrefs' , function ( ) {
119
119
var node = mockTextSVGElement (
120
- '<a href="https ://bl.ocks.org/">bl.ocks.org</a>'
120
+ '<a href="http ://bl.ocks.org/">bl.ocks.org</a>'
121
121
) ;
122
122
123
123
expect ( node . text ( ) ) . toEqual ( 'bl.ocks.org' ) ;
124
124
assertAnchorAttrs ( node ) ;
125
- assertAnchorLink ( node , 'https ://bl.ocks.org/' ) ;
125
+ assertAnchorLink ( node , 'http ://bl.ocks.org/' ) ;
126
126
} ) ;
127
127
128
128
it ( 'whitelists https hrefs' , function ( ) {
@@ -512,3 +512,115 @@ describe('svg+text utils', function() {
512
512
} ) ;
513
513
} ) ;
514
514
} ) ;
515
+
516
+ describe ( 'sanitizeHTML' , function ( ) {
517
+ 'use strict' ;
518
+
519
+ describe ( 'convertToTspans' , function ( ) {
520
+ var stringFromCodePoint ;
521
+
522
+ beforeAll ( function ( ) {
523
+ stringFromCodePoint = String . fromCodePoint ;
524
+ } ) ;
525
+
526
+ afterEach ( function ( ) {
527
+ String . fromCodePoint = stringFromCodePoint ;
528
+ } ) ;
529
+
530
+ function mockHTML ( txt ) {
531
+ return util . sanitizeHTML ( txt ) ;
532
+ }
533
+
534
+ afterEach ( function ( ) {
535
+ d3 . selectAll ( '.text-tester' ) . remove ( ) ;
536
+ } ) ;
537
+
538
+ it ( 'checks for XSS attack in href' , function ( ) {
539
+ var innerHTML = mockHTML (
540
+ '<a href="javascript:alert(\'attack\')">XSS</a>'
541
+ ) ;
542
+
543
+ expect ( innerHTML ) . toEqual ( '<a>XSS</a>' ) ;
544
+ } ) ;
545
+
546
+ it ( 'checks for XSS attack in href (with plenty of white spaces)' , function ( ) {
547
+ var innerHTML = mockHTML (
548
+ '<a href = " javascript:alert(\'attack\')">XSS</a>'
549
+ ) ;
550
+
551
+ expect ( innerHTML ) . toEqual ( '<a>XSS</a>' ) ;
552
+ } ) ;
553
+
554
+ it ( 'whitelists relative hrefs (interpreted as http)' , function ( ) {
555
+ var innerHTML = mockHTML (
556
+ '<a href="/mylink">mylink</a>'
557
+ ) ;
558
+
559
+ expect ( innerHTML ) . toEqual ( '<a href="/mylink">mylink</a>' ) ;
560
+ } ) ;
561
+
562
+ it ( 'whitelists http hrefs' , function ( ) {
563
+ var innerHTML = mockHTML (
564
+ '<a href="http://bl.ocks.org/">bl.ocks.org</a>'
565
+ ) ;
566
+
567
+ expect ( innerHTML ) . toEqual ( '<a href="http://bl.ocks.org/">bl.ocks.org</a>' ) ;
568
+ } ) ;
569
+
570
+ it ( 'whitelists https hrefs' , function ( ) {
571
+ var innerHTML = mockHTML (
572
+ '<a href="https://chart-studio.plotly.com">plotly</a>'
573
+ ) ;
574
+
575
+ expect ( innerHTML ) . toEqual ( '<a href="https://chart-studio.plotly.com">plotly</a>' ) ;
576
+ } ) ;
577
+
578
+ it ( 'whitelists mailto hrefs' , function ( ) {
579
+ var innerHTML = mockHTML (
580
+ '<a href="mailto:support@plotly.com">support</a>'
581
+ ) ;
582
+
583
+ expect ( innerHTML ) . toEqual ( '<a href="mailto:support@plotly.com">support</a>' ) ;
584
+ } ) ;
585
+
586
+ it ( 'drops XSS attacks in href' , function ( ) {
587
+ // "XSS" gets interpreted as a relative link (http)
588
+ var textCases = [
589
+ '<a href="XSS\" onmouseover="alert(1)\" style="font-size:300px">Subtitle</a>' ,
590
+ '<a href="XSS" onmouseover="alert(1)" style="font-size:300px">Subtitle</a>'
591
+ ] ;
592
+
593
+ textCases . forEach ( function ( textCase ) {
594
+ var innerHTML = mockHTML ( textCase ) ;
595
+
596
+ expect ( innerHTML ) . toEqual ( '<a style="font-size:300px" href="XSS">Subtitle</a>' ) ;
597
+ } ) ;
598
+ } ) ;
599
+
600
+ it ( 'accepts href and style in <a> in any order and tosses other stuff' , function ( ) {
601
+ var textCases = [
602
+ '<a href="x" style="y">z</a>' ,
603
+ '<a href=\'x\' style="y">z</a>' ,
604
+ '<A HREF="x"StYlE=\'y\'>z</a>' ,
605
+ '<a style=\'y\'href=\'x\'>z</A>' ,
606
+ '<a \t\r\n href="x" \n\r\t style="y" \n \t \r>z</a>' ,
607
+ '<a magic="true" href="x" weather="cloudy" style="y" speed="42">z</a>' ,
608
+ '<a href="x" style="y">z</a href="nope" style="for real?">' ,
609
+ ] ;
610
+
611
+ textCases . forEach ( function ( textCase ) {
612
+ var innerHTML = mockHTML ( textCase ) ;
613
+
614
+ expect ( innerHTML ) . toEqual ( '<a style="y" href="x">z</a>' ) ;
615
+ } ) ;
616
+ } ) ;
617
+
618
+ it ( 'allows encoded URIs in href' , function ( ) {
619
+ var innerHTML = mockHTML (
620
+ '<a href="https://example.com/?q=date%20%3E=%202018-01-01">click</a>'
621
+ ) ;
622
+
623
+ expect ( innerHTML ) . toEqual ( '<a href="https://example.com/?q=date%20%3E=%202018-01-01">click</a>' ) ;
624
+ } ) ;
625
+ } ) ;
626
+ } ) ;
0 commit comments