Merge pull request #291 from kenjis/html_escape

add html_escape() function to escape HTML.
diff --git a/application/config/config.php b/application/config/config.php
index 7554f99..880393c 100644
--- a/application/config/config.php
+++ b/application/config/config.php
@@ -296,11 +296,13 @@
 | 'csrf_token_name' = The token name
 | 'csrf_cookie_name' = The cookie name
 | 'csrf_expire' = The number in seconds the token should expire.
+| 'csrf_exclude_uris' = Array of URIs which ignore CSRF checks
 */
 $config['csrf_protection'] = FALSE;
 $config['csrf_token_name'] = 'csrf_test_name';
 $config['csrf_cookie_name'] = 'csrf_cookie_name';
 $config['csrf_expire'] = 7200;
+$config['csrf_exclude_uris'] = array();
 
 /*
 |--------------------------------------------------------------------------
diff --git a/readme.md b/readme.md
index dfcf856..be807db 100644
--- a/readme.md
+++ b/readme.md
@@ -6,5 +6,6 @@
 
  * [User Guide](http://codeigniter.com/user_guide/)
  * [Community Forums](http://codeigniter.com/forums/)
+ * [User Voice](http://codeigniter.uservoice.com/forums/40508-codeigniter-reactor)
  * [Community Wiki](http://codeigniter.com/wiki/)
  * [Community IRC](http://webchat.freenode.net/?channels=codeigniter&uio=d4)
\ No newline at end of file
diff --git a/system/core/Security.php b/system/core/Security.php
index dcc680a..342455f 100755
--- a/system/core/Security.php
+++ b/system/core/Security.php
@@ -33,6 +33,7 @@
 	 * @access protected
 	 */
 	protected $_xss_hash			= '';
+	
 	/**
 	 * Random Hash for Cross Site Request Forgery Protection Cookie
 	 *
@@ -40,6 +41,7 @@
 	 * @access protected
 	 */
 	protected $_csrf_hash			= '';
+	
 	/**
 	 * Expiration time for Cross Site Request Forgery Protection Cookie
 	 * Defaults to two hours (in seconds)
@@ -48,6 +50,7 @@
 	 * @access protected
 	 */
 	protected $_csrf_expire			= 7200;
+	
 	/**
 	 * Token name for Cross Site Request Forgery Protection Cookie
 	 *
@@ -55,6 +58,7 @@
 	 * @access protected
 	 */
 	protected $_csrf_token_name		= 'ci_csrf_token';
+	
 	/**
 	 * Cookie name for Cross Site Request Forgery Protection Cookie
 	 *
@@ -62,12 +66,14 @@
 	 * @access protected
 	 */
 	protected $_csrf_cookie_name	= 'ci_csrf_token';
+	
 	/**
 	 * List of never allowed strings
 	 *
 	 * @var array
 	 * @access protected
 	 */
+	
 	protected $_never_allowed_str = array(
 					'document.cookie'	=> '[removed]',
 					'document.write'	=> '[removed]',
@@ -80,7 +86,6 @@
 					'<![CDATA['			=> '&lt;![CDATA['
 	);
 
-	/* never allowed, regex replacement */
 	/**
 	 * List of never allowed regex replacement
 	 *
@@ -134,6 +139,16 @@
 		{
 			return $this->csrf_set_cookie();
 		}
+		
+		// Check if URI has been whitelisted from CSRF checks
+		if ($exclude_uris = config_item('csrf_exclude_uris'))
+		{
+			$uri = load_class('URI', 'core');
+			if (in_array($uri->uri_string(), $exclude_uris))
+			{
+				return $this;
+			}
+		}
 
 		// Do the tokens exist in both the _POST and _COOKIE arrays?
 		if ( ! isset($_POST[$this->_csrf_token_name]) OR
@@ -156,9 +171,9 @@
 		unset($_COOKIE[$this->_csrf_cookie_name]);
 		$this->_csrf_set_hash();
 		$this->csrf_set_cookie();
-
-		log_message('debug', "CSRF token verified ");
-
+		
+		log_message('debug', "CSRF token verified");
+		
 		return $this;
 	}
 
@@ -869,7 +884,6 @@
 	}
 
 }
-// END Security Class
 
 /* End of file Security.php */
-/* Location: ./system/libraries/Security.php */
+/* Location: ./system/libraries/Security.php */
\ No newline at end of file
diff --git a/user_guide/changelog.html b/user_guide/changelog.html
index c22bebd..e1a134d 100644
--- a/user_guide/changelog.html
+++ b/user_guide/changelog.html
@@ -78,7 +78,7 @@
 	</li>
 	<li>Database
 		<ul>
-			<li class="reactor">Added a <a href="http://www.cubrid.org/" target="_blank">CUBRID</a> driver to the <a href="libraries/database.html">Database Driver</a>. Thanks to the CUBRID team for supplying this patch.</li>
+			<li class="reactor">Added a <a href="http://www.cubrid.org/" target="_blank">CUBRID</a> driver to the <a href="database/index.html">Database Driver</a>. Thanks to the CUBRID team for supplying this patch.</li>
 			<li class="reactor">Typecast limit and offset in the <a href="database/queries.html">Database Driver</a> to integers to avoid possible injection.</li>
 			<li class="reactor">
 				Added additional option 'none' for the optional third argument for  <kbd>$this->db->like()</kbd> in the <a href="database/active_record.html">Database Driver</a>.
@@ -127,6 +127,7 @@
 			<li>Visual updates to the welcome_message view file and default error templates. Thanks to <a href="https://bitbucket.org/danijelb">danijelb</a> for the pull request.</li>
 			<li class="reactor">Added <samp>insert_batch()</samp> function to the PostgreSQL database driver.  Thanks to epallerols for the patch.</li>
 			<li class="reactor">Added "application/x-csv" to mimes.php.</li>
+			<li class="reactor">Added CSRF protection URI whitelisting.</li>
 			<li>Fixed a bug where <a href="libraries/email.html">Email library</a> attachments with a "." in the name would using invalid MIME-types.</li>
             <li>Added support for pem,p10,p12,p7a,p7c,p7m,p7r,p7s,crt,crl,der,kdb,rsa,cer,sst,csr Certs to mimes.php.</li>
             <li>Added support pgp,gpg to mimes.php.</li>
diff --git a/user_guide/libraries/security.html b/user_guide/libraries/security.html
index dd62a43..cbe12d8 100644
--- a/user_guide/libraries/security.html
+++ b/user_guide/libraries/security.html
@@ -116,6 +116,9 @@
 
 <p>If you use the <a href="../helpers/form_helper.html">form helper</a> the <var>form_open()</var> function will automatically insert a hidden csrf field in your forms.</p>
 
+<p>Select URIs can be whitelisted from csrf protection (for example API endpoints expecting externally POSTed content). You can add these URIs by editing the 'csrf_exclude_uris' config parameter:</p>
+<code>$config['csrf_exclude_uris'] = array('api/person/add');</code>
+
 </div>
 <!-- END CONTENT -->