1
- <?php if ( ! defined ('BASEPATH ' )) exit ('No direct script access allowed ' );
1
+ <?php if ( ! defined ('BASEPATH ' )) exit ('No direct script access allowed ' );
2
2
/**
3
3
* CodeIgniter
4
4
*
@@ -69,16 +69,16 @@ class CI_Security {
69
69
* @access protected
70
70
*/
71
71
protected $ _never_allowed_str = array (
72
- 'document.cookie ' => '[removed] ' ,
73
- 'document.write ' => '[removed] ' ,
74
- '.parentNode ' => '[removed] ' ,
75
- '.innerHTML ' => '[removed] ' ,
76
- 'window.location ' => '[removed] ' ,
77
- '-moz-binding ' => '[removed] ' ,
78
- '<!-- ' => '<!-- ' ,
79
- '--> ' => '--> ' ,
80
- '<![CDATA[ ' => '<![CDATA[ ' ,
81
- '<comment> ' => '<comment> '
72
+ 'document.cookie ' => '[removed] ' ,
73
+ 'document.write ' => '[removed] ' ,
74
+ '.parentNode ' => '[removed] ' ,
75
+ '.innerHTML ' => '[removed] ' ,
76
+ 'window.location ' => '[removed] ' ,
77
+ '-moz-binding ' => '[removed] ' ,
78
+ '<!-- ' => '<!-- ' ,
79
+ '--> ' => '--> ' ,
80
+ '<![CDATA[ ' => '<![CDATA[ ' ,
81
+ '<comment> ' => '<comment> '
82
82
);
83
83
84
84
/* never allowed, regex replacement */
@@ -89,10 +89,11 @@ class CI_Security {
89
89
* @access protected
90
90
*/
91
91
protected $ _never_allowed_regex = array (
92
- "javascript\s*: " => '[removed] ' ,
93
- "expression\s*(\(|&\#40;) " => '[removed] ' , // CSS and IE
94
- "vbscript\s*: " => '[removed] ' , // IE, surprise!
95
- "Redirect\s+302 " => '[removed] '
92
+ 'javascript\s*: ' ,
93
+ 'expression\s*(\(|&\#40;) ' , // CSS and IE
94
+ 'vbscript\s*: ' , // IE, surprise!
95
+ 'Redirect\s+302 ' ,
96
+ "([ \"'])?data\s*:[^ \\1]*?base64[^ \\1]*?,[^ \\1]*? \\1? "
96
97
);
97
98
98
99
/**
@@ -364,9 +365,9 @@ public function xss_clean($str, $is_image = FALSE)
364
365
* These words are compacted back to their correct state.
365
366
*/
366
367
$ words = array (
367
- 'javascript ' , 'expression ' , 'vbscript ' , 'script ' ,
368
- 'applet ' , 'alert ' , 'document ' , 'write ' , 'cookie ' , 'window '
369
- );
368
+ 'javascript ' , 'expression ' , 'vbscript ' , 'script ' , ' base64 ' ,
369
+ 'applet ' , 'alert ' , 'document ' , 'write ' , 'cookie ' , 'window '
370
+ );
370
371
371
372
foreach ($ words as $ word )
372
373
{
@@ -524,38 +525,38 @@ public function entity_decode($str, $charset='UTF-8')
524
525
public function sanitize_filename ($ str , $ relative_path = FALSE )
525
526
{
526
527
$ bad = array (
527
- "../ " ,
528
- "<!-- " ,
529
- "--> " ,
530
- "< " ,
531
- "> " ,
532
- "' " ,
533
- '" ' ,
534
- '& ' ,
535
- '$ ' ,
536
- '# ' ,
537
- '{ ' ,
538
- '} ' ,
539
- '[ ' ,
540
- '] ' ,
541
- '= ' ,
542
- '; ' ,
543
- '? ' ,
544
- "%20 " ,
545
- "%22 " ,
546
- "%3c " , // <
547
- "%253c " , // <
548
- "%3e " , // >
549
- "%0e " , // >
550
- "%28 " , // (
551
- "%29 " , // )
552
- "%2528 " , // (
553
- "%26 " , // &
554
- "%24 " , // $
555
- "%3f " , // ?
556
- "%3b " , // ;
557
- "%3d " // =
558
- );
528
+ "../ " ,
529
+ "<!-- " ,
530
+ "--> " ,
531
+ "< " ,
532
+ "> " ,
533
+ "' " ,
534
+ '" ' ,
535
+ '& ' ,
536
+ '$ ' ,
537
+ '# ' ,
538
+ '{ ' ,
539
+ '} ' ,
540
+ '[ ' ,
541
+ '] ' ,
542
+ '= ' ,
543
+ '; ' ,
544
+ '? ' ,
545
+ "%20 " ,
546
+ "%22 " ,
547
+ "%3c " , // <
548
+ "%253c " , // <
549
+ "%3e " , // >
550
+ "%0e " , // >
551
+ "%28 " , // (
552
+ "%29 " , // )
553
+ "%2528 " , // (
554
+ "%26 " , // &
555
+ "%24 " , // $
556
+ "%3f " , // ?
557
+ "%3b " , // ;
558
+ "%3d " // =
559
+ );
559
560
560
561
if ( ! $ relative_path )
561
562
{
@@ -613,19 +614,20 @@ protected function _remove_evil_attributes($str, $is_image)
613
614
*/
614
615
unset($ evil_attributes [array_search ('xmlns ' , $ evil_attributes )]);
615
616
}
616
-
617
+
617
618
do {
618
619
$ count = 0 ;
619
620
$ attribs = array ();
620
-
621
+
621
622
// find occurrences of illegal attribute strings without quotes
622
- preg_match_all (" /( " .implode ('| ' , $ evil_attributes )." )\s*=\s*([^\s]*)/is " , $ str , $ matches , PREG_SET_ORDER );
623
-
623
+ preg_match_all (' /( ' .implode ('| ' , $ evil_attributes ).' )\s*=\s*([^\s> ]*)/is ' , $ str , $ matches , PREG_SET_ORDER );
624
+
624
625
foreach ($ matches as $ attr )
625
626
{
627
+
626
628
$ attribs [] = preg_quote ($ attr [0 ], '/ ' );
627
629
}
628
-
630
+
629
631
// find occurrences of illegal attribute strings with quotes (042 and 047 are octal quotes)
630
632
preg_match_all ("/( " .implode ('| ' , $ evil_attributes ).")\s*=\s*( \042| \047)([^ \\2]*?)( \\2)/is " , $ str , $ matches , PREG_SET_ORDER );
631
633
@@ -637,11 +639,11 @@ protected function _remove_evil_attributes($str, $is_image)
637
639
// replace illegal attribute strings that are inside an html tag
638
640
if (count ($ attribs ) > 0 )
639
641
{
640
- $ str = preg_replace ("/<(\/?[^><]+?)([^A-Za-z\-])( " .implode ('| ' , $ attribs ).")([\s><])([><]*)/i " , '<$1$2$4$5 ' , $ str , -1 , $ count );
642
+ $ str = preg_replace ("/<(\/?[^><]+?)([^A-Za-z<> \-])(.*?)( " .implode ('| ' , $ attribs ).")(.*?)( [\s><])([><]*)/i " , '<$1 $3$5$6$7 ' , $ str , -1 , $ count );
641
643
}
642
-
644
+
643
645
} while ($ count );
644
-
646
+
645
647
return $ str ;
646
648
}
647
649
@@ -682,9 +684,15 @@ protected function _sanitize_naughty_html($matches)
682
684
*/
683
685
protected function _js_link_removal ($ match )
684
686
{
685
- $ attributes = $ this ->_filter_attributes (str_replace (array ('< ' , '> ' ), '' , $ match [1 ]));
686
-
687
- return str_replace ($ match [1 ], preg_replace ("#href=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si " , "" , $ attributes ), $ match [0 ]);
687
+ return str_replace (
688
+ $ match [1 ],
689
+ preg_replace (
690
+ '#href=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|data\s*:)#si ' ,
691
+ '' ,
692
+ $ this ->_filter_attributes (str_replace (array ('< ' , '> ' ), '' , $ match [1 ]))
693
+ ),
694
+ $ match [0 ]
695
+ );
688
696
}
689
697
690
698
// --------------------------------------------------------------------
@@ -702,9 +710,15 @@ protected function _js_link_removal($match)
702
710
*/
703
711
protected function _js_img_removal ($ match )
704
712
{
705
- $ attributes = $ this ->_filter_attributes (str_replace (array ('< ' , '> ' ), '' , $ match [1 ]));
706
-
707
- return str_replace ($ match [1 ], preg_replace ("#src=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si " , "" , $ attributes ), $ match [0 ]);
713
+ return str_replace (
714
+ $ match [1 ],
715
+ preg_replace (
716
+ '#src=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si ' ,
717
+ '' ,
718
+ $ this ->_filter_attributes (str_replace (array ('< ' , '> ' ), '' , $ match [1 ]))
719
+ ),
720
+ $ match [0 ]
721
+ );
708
722
}
709
723
710
724
// --------------------------------------------------------------------
@@ -819,14 +833,11 @@ protected function _validate_entities($str)
819
833
*/
820
834
protected function _do_never_allowed ($ str )
821
835
{
822
- foreach ($ this ->_never_allowed_str as $ key => $ val )
823
- {
824
- $ str = str_replace ($ key , $ val , $ str );
825
- }
836
+ $ str = str_replace (array_keys ($ this ->_never_allowed_str ), $ this ->_never_allowed_str , $ str );
826
837
827
- foreach ($ this ->_never_allowed_regex as $ key => $ val )
838
+ foreach ($ this ->_never_allowed_regex as $ regex )
828
839
{
829
- $ str = preg_replace (" # " . $ key . " #i " , $ val , $ str );
840
+ $ str = preg_replace (' # ' . $ regex . ' #is ' , ' [removed] ' , $ str );
830
841
}
831
842
832
843
return $ str ;
0 commit comments