PluginProbe
ShiftController Employee Shift Scheduling / 2.1.0
ShiftController Employee Shift Scheduling v2.1.0
4.9.97 4.9.96 4.9.95 4.9.74 4.9.75 4.9.76 4.9.77 4.9.78 4.9.84 4.9.85 4.9.87 4.9.91 4.9.92 trunk 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 3.2.4 All 38 releases
shiftcontroller / happ / system / core / Security.php

Security.php in ShiftController Employee Shift Scheduling 2.1.0, at happ/system/core/Security.php

876 lines 21.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2 /**
3 * CodeIgniter
4 *
5 * An open source application development framework for PHP 5.1.6 or newer
6 *
7 * @package CodeIgniter
8 * @author ExpressionEngine Dev Team
9 * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
10 * @license http://codeigniter.com/user_guide/license.html
11 * @link http://codeigniter.com
12 * @since Version 1.0
13 * @filesource
14 */
15
16 // ------------------------------------------------------------------------
17
18 /**
19 * Security Class
20 *
21 * @package CodeIgniter
22 * @subpackage Libraries
23 * @category Security
24 * @author ExpressionEngine Dev Team
25 * @link http://codeigniter.com/user_guide/libraries/security.html
26 */
27 class CI_Security {
28
29 /**
30 * Random Hash for protecting URLs
31 *
32 * @var string
33 * @access protected
34 */
35 protected $_xss_hash = '';
36 /**
37 * Random Hash for Cross Site Request Forgery Protection Cookie
38 *
39 * @var string
40 * @access protected
41 */
42 protected $_csrf_hash = '';
43 /**
44 * Expiration time for Cross Site Request Forgery Protection Cookie
45 * Defaults to two hours (in seconds)
46 *
47 * @var int
48 * @access protected
49 */
50 protected $_csrf_expire = 7200;
51 /**
52 * Token name for Cross Site Request Forgery Protection Cookie
53 *
54 * @var string
55 * @access protected
56 */
57 protected $_csrf_token_name = 'ci_csrf_token';
58 /**
59 * Cookie name for Cross Site Request Forgery Protection Cookie
60 *
61 * @var string
62 * @access protected
63 */
64 protected $_csrf_cookie_name = 'ci_csrf_token';
65 /**
66 * List of never allowed strings
67 *
68 * @var array
69 * @access protected
70 */
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 '<!--' => '&lt;!--',
79 '-->' => '--&gt;',
80 '<![CDATA[' => '&lt;![CDATA[',
81 '<comment>' => '&lt;comment&gt;'
82 );
83
84 /* never allowed, regex replacement */
85 /**
86 * List of never allowed regex replacement
87 *
88 * @var array
89 * @access protected
90 */
91 protected $_never_allowed_regex = array(
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?"
97 );
98
99 /**
100 * Constructor
101 *
102 * @return void
103 */
104 public function __construct()
105 {
106 // Is CSRF protection enabled?
107 if (config_item('csrf_protection') === TRUE)
108 {
109 // CSRF config
110 foreach (array('csrf_expire', 'csrf_token_name', 'csrf_cookie_name') as $key)
111 {
112 if (FALSE !== ($val = config_item($key)))
113 {
114 $this->{'_'.$key} = $val;
115 }
116 }
117
118 // Append application specific cookie prefix
119 if (config_item('cookie_prefix'))
120 {
121 $this->_csrf_cookie_name = config_item('cookie_prefix').$this->_csrf_cookie_name;
122 }
123
124 // Set the CSRF hash
125 $this->_csrf_set_hash();
126 }
127
128 log_message('debug', "Security Class Initialized");
129 }
130
131 // --------------------------------------------------------------------
132
133 /**
134 * Verify Cross Site Request Forgery Protection
135 *
136 * @return object
137 */
138 public function csrf_verify()
139 {
140 // If it's not a POST request we will set the CSRF cookie
141 if (strtoupper($_SERVER['REQUEST_METHOD']) !== 'POST')
142 {
143 return $this->csrf_set_cookie();
144 }
145
146 // Do the tokens exist in both the _POST and _COOKIE arrays?
147 if ( ! isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name]))
148 {
149 $this->csrf_show_error();
150 }
151
152 // Do the tokens match?
153 if ($_POST[$this->_csrf_token_name] != $_COOKIE[$this->_csrf_cookie_name])
154 {
155 $this->csrf_show_error();
156 }
157
158 // We kill this since we're done and we don't want to
159 // polute the _POST array
160 unset($_POST[$this->_csrf_token_name]);
161
162 // Nothing should last forever
163 unset($_COOKIE[$this->_csrf_cookie_name]);
164 $this->_csrf_set_hash();
165 $this->csrf_set_cookie();
166
167 log_message('debug', 'CSRF token verified');
168
169 return $this;
170 }
171
172 // --------------------------------------------------------------------
173
174 /**
175 * Set Cross Site Request Forgery Protection Cookie
176 *
177 * @return object
178 */
179 public function csrf_set_cookie()
180 {
181 $expire = time() + $this->_csrf_expire;
182 $secure_cookie = (config_item('cookie_secure') === TRUE) ? 1 : 0;
183
184 if ($secure_cookie && (empty($_SERVER['HTTPS']) OR strtolower($_SERVER['HTTPS']) === 'off'))
185 {
186 return FALSE;
187 }
188
189 setcookie($this->_csrf_cookie_name, $this->_csrf_hash, $expire, config_item('cookie_path'), config_item('cookie_domain'), $secure_cookie);
190
191 log_message('debug', "CRSF cookie Set");
192
193 return $this;
194 }
195
196 // --------------------------------------------------------------------
197
198 /**
199 * Show CSRF Error
200 *
201 * @return void
202 */
203 public function csrf_show_error()
204 {
205 show_error('The action you have requested is not allowed.');
206 }
207
208 // --------------------------------------------------------------------
209
210 /**
211 * Get CSRF Hash
212 *
213 * Getter Method
214 *
215 * @return string self::_csrf_hash
216 */
217 public function get_csrf_hash()
218 {
219 return $this->_csrf_hash;
220 }
221
222 // --------------------------------------------------------------------
223
224 /**
225 * Get CSRF Token Name
226 *
227 * Getter Method
228 *
229 * @return string self::csrf_token_name
230 */
231 public function get_csrf_token_name()
232 {
233 return $this->_csrf_token_name;
234 }
235
236 // --------------------------------------------------------------------
237
238 /**
239 * XSS Clean
240 *
241 * Sanitizes data so that Cross Site Scripting Hacks can be
242 * prevented. This function does a fair amount of work but
243 * it is extremely thorough, designed to prevent even the
244 * most obscure XSS attempts. Nothing is ever 100% foolproof,
245 * of course, but I haven't been able to get anything passed
246 * the filter.
247 *
248 * Note: This function should only be used to deal with data
249 * upon submission. It's not something that should
250 * be used for general runtime processing.
251 *
252 * This function was based in part on some code and ideas I
253 * got from Bitflux: http://channel.bitflux.ch/wiki/XSS_Prevention
254 *
255 * To help develop this script I used this great list of
256 * vulnerabilities along with a few other hacks I've
257 * harvested from examining vulnerabilities in other programs:
258 * http://ha.ckers.org/xss.html
259 *
260 * @param mixed string or array
261 * @param bool
262 * @return string
263 */
264 public function xss_clean($str, $is_image = FALSE)
265 {
266 /*
267 * Is the string an array?
268 *
269 */
270 if (is_array($str))
271 {
272 while (list($key) = each($str))
273 {
274 $str[$key] = $this->xss_clean($str[$key]);
275 }
276
277 return $str;
278 }
279
280 /*
281 * Remove Invisible Characters
282 */
283 $str = remove_invisible_characters($str);
284
285 // Validate Entities in URLs
286 $str = $this->_validate_entities($str);
287
288 /*
289 * URL Decode
290 *
291 * Just in case stuff like this is submitted:
292 *
293 * <a href="http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D">Google</a>
294 *
295 * Note: Use rawurldecode() so it does not remove plus signs
296 *
297 */
298 $str = rawurldecode($str);
299
300 /*
301 * Convert character entities to ASCII
302 *
303 * This permits our tests below to work reliably.
304 * We only convert entities that are within tags since
305 * these are the ones that will pose security problems.
306 *
307 */
308
309 $str = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, '_convert_attribute'), $str);
310
311 $str = preg_replace_callback("/<\w+.*?(?=>|<|$)/si", array($this, '_decode_entity'), $str);
312
313 /*
314 * Remove Invisible Characters Again!
315 */
316 $str = remove_invisible_characters($str);
317
318 /*
319 * Convert all tabs to spaces
320 *
321 * This prevents strings like this: ja vascript
322 * NOTE: we deal with spaces between characters later.
323 * NOTE: preg_replace was found to be amazingly slow here on
324 * large blocks of data, so we use str_replace.
325 */
326
327 if (strpos($str, "\t") !== FALSE)
328 {
329 $str = str_replace("\t", ' ', $str);
330 }
331
332 /*
333 * Capture converted string for later comparison
334 */
335 $converted_string = $str;
336
337 // Remove Strings that are never allowed
338 $str = $this->_do_never_allowed($str);
339
340 /*
341 * Makes PHP tags safe
342 *
343 * Note: XML tags are inadvertently replaced too:
344 *
345 * <?xml
346 *
347 * But it doesn't seem to pose a problem.
348 */
349 if ($is_image === TRUE)
350 {
351 // Images have a tendency to have the PHP short opening and
352 // closing tags every so often so we skip those and only
353 // do the long opening tags.
354 $str = preg_replace('/<\?(php)/i', "&lt;?\\1", $str);
355 }
356 else
357 {
358 $str = str_replace(array('<?', '?'.'>'), array('&lt;?', '?&gt;'), $str);
359 }
360
361 /*
362 * Compact any exploded words
363 *
364 * This corrects words like: j a v a s c r i p t
365 * These words are compacted back to their correct state.
366 */
367 $words = array(
368 'javascript', 'expression', 'vbscript', 'script', 'base64',
369 'applet', 'alert', 'document', 'write', 'cookie', 'window'
370 );
371
372 foreach ($words as $word)
373 {
374 $temp = '';
375
376 for ($i = 0, $wordlen = strlen($word); $i < $wordlen; $i++)
377 {
378 $temp .= substr($word, $i, 1)."\s*";
379 }
380
381 // We only want to do this when it is followed by a non-word character
382 // That way valid stuff like "dealer to" does not become "dealerto"
383 $str = preg_replace_callback('#('.substr($temp, 0, -3).')(\W)#is', array($this, '_compact_exploded_words'), $str);
384 }
385
386 /*
387 * Remove disallowed Javascript in links or img tags
388 * We used to do some version comparisons and use of stripos for PHP5,
389 * but it is dog slow compared to these simplified non-capturing
390 * preg_match(), especially if the pattern exists in the string
391 */
392 do
393 {
394 $original = $str;
395
396 if (preg_match("/<a/i", $str))
397 {
398 $str = preg_replace_callback("#<a\s+([^>]*?)(>|$)#si", array($this, '_js_link_removal'), $str);
399 }
400
401 if (preg_match("/<img/i", $str))
402 {
403 $str = preg_replace_callback("#<img\s+([^>]*?)(\s?/?>|$)#si", array($this, '_js_img_removal'), $str);
404 }
405
406 if (preg_match("/script/i", $str) OR preg_match("/xss/i", $str))
407 {
408 $str = preg_replace("#<(/*)(script|xss)(.*?)\>#si", '[removed]', $str);
409 }
410 }
411 while($original != $str);
412
413 unset($original);
414
415 // Remove evil attributes such as style, onclick and xmlns
416 $str = $this->_remove_evil_attributes($str, $is_image);
417
418 /*
419 * Sanitize naughty HTML elements
420 *
421 * If a tag containing any of the words in the list
422 * below is found, the tag gets converted to entities.
423 *
424 * So this: <blink>
425 * Becomes: &lt;blink&gt;
426 */
427 $naughty = 'alert|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|isindex|layer|link|meta|object|plaintext|style|script|textarea|title|video|xml|xss';
428 $str = preg_replace_callback('#<(/*\s*)('.$naughty.')([^><]*)([><]*)#is', array($this, '_sanitize_naughty_html'), $str);
429
430 /*
431 * Sanitize naughty scripting elements
432 *
433 * Similar to above, only instead of looking for
434 * tags it looks for PHP and JavaScript commands
435 * that are disallowed. Rather than removing the
436 * code, it simply converts the parenthesis to entities
437 * rendering the code un-executable.
438 *
439 * For example: eval('some code')
440 * Becomes: eval&#40;'some code'&#41;
441 */
442 $str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2&#40;\\3&#41;", $str);
443
444
445 // Final clean up
446 // This adds a bit of extra precaution in case
447 // something got through the above filters
448 $str = $this->_do_never_allowed($str);
449
450 /*
451 * Images are Handled in a Special Way
452 * - Essentially, we want to know that after all of the character
453 * conversion is done whether any unwanted, likely XSS, code was found.
454 * If not, we return TRUE, as the image is clean.
455 * However, if the string post-conversion does not matched the
456 * string post-removal of XSS, then it fails, as there was unwanted XSS
457 * code found and removed/changed during processing.
458 */
459
460 if ($is_image === TRUE)
461 {
462 return ($str == $converted_string) ? TRUE: FALSE;
463 }
464
465 log_message('debug', "XSS Filtering completed");
466 return $str;
467 }
468
469 // --------------------------------------------------------------------
470
471 /**
472 * Random Hash for protecting URLs
473 *
474 * @return string
475 */
476 public function xss_hash()
477 {
478 if ($this->_xss_hash == '')
479 {
480 mt_srand();
481 $this->_xss_hash = md5(time() + mt_rand(0, 1999999999));
482 }
483
484 return $this->_xss_hash;
485 }
486
487 // --------------------------------------------------------------------
488
489 /**
490 * HTML Entities Decode
491 *
492 * This function is a replacement for html_entity_decode()
493 *
494 * The reason we are not using html_entity_decode() by itself is because
495 * while it is not technically correct to leave out the semicolon
496 * at the end of an entity most browsers will still interpret the entity
497 * correctly. html_entity_decode() does not convert entities without
498 * semicolons, so we are left with our own little solution here. Bummer.
499 *
500 * @param string
501 * @param string
502 * @return string
503 */
504 public function entity_decode($str, $charset='UTF-8')
505 {
506 if (stristr($str, '&') === FALSE)
507 {
508 return $str;
509 }
510
511 $str = html_entity_decode($str, ENT_COMPAT, $charset);
512 $str = preg_replace('~&#x(0*[0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str);
513 return preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str);
514 }
515
516 // --------------------------------------------------------------------
517
518 /**
519 * Filename Security
520 *
521 * @param string
522 * @param bool
523 * @return string
524 */
525 public function sanitize_filename($str, $relative_path = FALSE)
526 {
527 $bad = array(
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 );
560
561 if ( ! $relative_path)
562 {
563 $bad[] = './';
564 $bad[] = '/';
565 }
566
567 $str = remove_invisible_characters($str, FALSE);
568 return stripslashes(str_replace($bad, '', $str));
569 }
570
571 // ----------------------------------------------------------------
572
573 /**
574 * Compact Exploded Words
575 *
576 * Callback function for xss_clean() to remove whitespace from
577 * things like j a v a s c r i p t
578 *
579 * @param type
580 * @return type
581 */
582 protected function _compact_exploded_words($matches)
583 {
584 return preg_replace('/\s+/s', '', $matches[1]).$matches[2];
585 }
586
587 // --------------------------------------------------------------------
588
589 /*
590 * Remove Evil HTML Attributes (like evenhandlers and style)
591 *
592 * It removes the evil attribute and either:
593 * - Everything up until a space
594 * For example, everything between the pipes:
595 * <a |style=document.write('hello');alert('world');| class=link>
596 * - Everything inside the quotes
597 * For example, everything between the pipes:
598 * <a |style="document.write('hello'); alert('world');"| class="link">
599 *
600 * @param string $str The string to check
601 * @param boolean $is_image TRUE if this is an image
602 * @return string The string with the evil attributes removed
603 */
604 protected function _remove_evil_attributes($str, $is_image)
605 {
606 // All javascript event handlers (e.g. onload, onclick, onmouseover), style, and xmlns
607 $evil_attributes = array('on\w*', 'style', 'xmlns', 'formaction');
608
609 if ($is_image === TRUE)
610 {
611 /*
612 * Adobe Photoshop puts XML metadata into JFIF images,
613 * including namespacing, so we have to allow this for images.
614 */
615 unset($evil_attributes[array_search('xmlns', $evil_attributes)]);
616 }
617
618 do {
619 $count = 0;
620 $attribs = array();
621
622 // find occurrences of illegal attribute strings with quotes (042 and 047 are octal quotes)
623 preg_match_all('/('.implode('|', $evil_attributes).')\s*=\s*(\042|\047)([^\\2]*?)(\\2)/is', $str, $matches, PREG_SET_ORDER);
624
625 foreach ($matches as $attr)
626 {
627 $attribs[] = preg_quote($attr[0], '/');
628 }
629
630 // find occurrences of illegal attribute strings without quotes
631 preg_match_all('/('.implode('|', $evil_attributes).')\s*=\s*([^\s>]*)/is', $str, $matches, PREG_SET_ORDER);
632
633 foreach ($matches as $attr)
634 {
635 $attribs[] = preg_quote($attr[0], '/');
636 }
637
638 // replace illegal attribute strings that are inside an html tag
639 if (count($attribs) > 0)
640 {
641 $str = preg_replace('/(<?)(\/?[^><]+?)([^A-Za-z<>\-])(.*?)('.implode('|', $attribs).')(.*?)([\s><]?)([><]*)/i', '$1$2 $4$6$7$8', $str, -1, $count);
642 }
643
644 } while ($count);
645
646 return $str;
647 }
648
649 // --------------------------------------------------------------------
650
651 /**
652 * Sanitize Naughty HTML
653 *
654 * Callback function for xss_clean() to remove naughty HTML elements
655 *
656 * @param array
657 * @return string
658 */
659 protected function _sanitize_naughty_html($matches)
660 {
661 // encode opening brace
662 $str = '&lt;'.$matches[1].$matches[2].$matches[3];
663
664 // encode captured opening or closing brace to prevent recursive vectors
665 $str .= str_replace(array('>', '<'), array('&gt;', '&lt;'),
666 $matches[4]);
667
668 return $str;
669 }
670
671 // --------------------------------------------------------------------
672
673 /**
674 * JS Link Removal
675 *
676 * Callback function for xss_clean() to sanitize links
677 * This limits the PCRE backtracks, making it more performance friendly
678 * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in
679 * PHP 5.2+ on link-heavy strings
680 *
681 * @param array
682 * @return string
683 */
684 protected function _js_link_removal($match)
685 {
686 return str_replace(
687 $match[1],
688 preg_replace(
689 '#href=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|data\s*:)#si',
690 '',
691 $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]))
692 ),
693 $match[0]
694 );
695 }
696
697 // --------------------------------------------------------------------
698
699 /**
700 * JS Image Removal
701 *
702 * Callback function for xss_clean() to sanitize image tags
703 * This limits the PCRE backtracks, making it more performance friendly
704 * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in
705 * PHP 5.2+ on image tag heavy strings
706 *
707 * @param array
708 * @return string
709 */
710 protected function _js_img_removal($match)
711 {
712 return str_replace(
713 $match[1],
714 preg_replace(
715 '#src=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si',
716 '',
717 $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]))
718 ),
719 $match[0]
720 );
721 }
722
723 // --------------------------------------------------------------------
724
725 /**
726 * Attribute Conversion
727 *
728 * Used as a callback for XSS Clean
729 *
730 * @param array
731 * @return string
732 */
733 protected function _convert_attribute($match)
734 {
735 return str_replace(array('>', '<', '\\'), array('&gt;', '&lt;', '\\\\'), $match[0]);
736 }
737
738 // --------------------------------------------------------------------
739
740 /**
741 * Filter Attributes
742 *
743 * Filters tag attributes for consistency and safety
744 *
745 * @param string
746 * @return string
747 */
748 protected function _filter_attributes($str)
749 {
750 $out = '';
751
752 if (preg_match_all('#\s*[a-z\-]+\s*=\s*(\042|\047)([^\\1]*?)\\1#is', $str, $matches))
753 {
754 foreach ($matches[0] as $match)
755 {
756 $out .= preg_replace("#/\*.*?\*/#s", '', $match);
757 }
758 }
759
760 return $out;
761 }
762
763 // --------------------------------------------------------------------
764
765 /**
766 * HTML Entity Decode Callback
767 *
768 * Used as a callback for XSS Clean
769 *
770 * @param array
771 * @return string
772 */
773 protected function _decode_entity($match)
774 {
775 return $this->entity_decode($match[0], strtoupper(config_item('charset')));
776 }
777
778 // --------------------------------------------------------------------
779
780 /**
781 * Validate URL entities
782 *
783 * Called by xss_clean()
784 *
785 * @param string
786 * @return string
787 */
788 protected function _validate_entities($str)
789 {
790 /*
791 * Protect GET variables in URLs
792 */
793
794 // 901119URL5918AMP18930PROTECT8198
795
796 $str = preg_replace('|\&([a-z\_0-9\-]+)\=([a-z\_0-9\-]+)|i', $this->xss_hash()."\\1=\\2", $str);
797
798 /*
799 * Validate standard character entities
800 *
801 * Add a semicolon if missing. We do this to enable
802 * the conversion of entities to ASCII later.
803 *
804 */
805 $str = preg_replace('#(&\#?[0-9a-z]{2,})([\x00-\x20])*;?#i', "\\1;\\2", $str);
806
807 /*
808 * Validate UTF16 two byte encoding (x00)
809 *
810 * Just as above, adds a semicolon if missing.
811 *
812 */
813 $str = preg_replace('#(&\#x?)([0-9A-F]+);?#i',"\\1\\2;",$str);
814
815 /*
816 * Un-Protect GET variables in URLs
817 */
818 $str = str_replace($this->xss_hash(), '&', $str);
819
820 return $str;
821 }
822
823 // ----------------------------------------------------------------------
824
825 /**
826 * Do Never Allowed
827 *
828 * A utility function for xss_clean()
829 *
830 * @param string
831 * @return string
832 */
833 protected function _do_never_allowed($str)
834 {
835 $str = str_replace(array_keys($this->_never_allowed_str), $this->_never_allowed_str, $str);
836
837 foreach ($this->_never_allowed_regex as $regex)
838 {
839 $str = preg_replace('#'.$regex.'#is', '[removed]', $str);
840 }
841
842 return $str;
843 }
844
845 // --------------------------------------------------------------------
846
847 /**
848 * Set Cross Site Request Forgery Protection Cookie
849 *
850 * @return string
851 */
852 protected function _csrf_set_hash()
853 {
854 if ($this->_csrf_hash == '')
855 {
856 // If the cookie exists we will use it's value.
857 // We don't necessarily want to regenerate it with
858 // each page load since a page could contain embedded
859 // sub-pages causing this feature to fail
860 if (isset($_COOKIE[$this->_csrf_cookie_name]) &&
861 preg_match('#^[0-9a-f]{32}$#iS', $_COOKIE[$this->_csrf_cookie_name]) === 1)
862 {
863 return $this->_csrf_hash = $_COOKIE[$this->_csrf_cookie_name];
864 }
865
866 return $this->_csrf_hash = md5(uniqid(rand(), TRUE));
867 }
868
869 return $this->_csrf_hash;
870 }
871
872 }
873
874 /* End of file Security.php */
875 /* Location: ./system/libraries/Security.php */
876