Cross Site Form Submission - khalilhimura - 11-18-2014
Hi guys,
General Question: How to do Form submission between 2 CI application.
CI1 : http://www.example.com
CI2 : http://sub.example.com
Form is on CI1 & it is submitted to CI2.
Both apps are configured with CSRF & XSS enabled.
Any way to "whitelist" CI1 in CI2 so that it does not generate an error & allow CI2 controller to process CI1 post request.
Thanks!
-- Khalil
RE: Cross Site Form Submission - kilishan - 11-18-2014
I did this on CI 2 before. You basically have to extend the Security library and provide a list of controllers for it not to check CSRF for. This means that you'll need to be extremely careful about all the methods available, yada, yada...
Code: class MY_Security extends CI_Security
{
/**
* @var array Controllers to ignore during the CSRF cycle.
*
* If part of a module, the controller should be listed as:
* {module}/{controller}
*/
protected $ignored_controllers = array();
/**
* The constructor
*
* @return void
*/
public function __construct()
{
parent::__construct();
$this->ignored_controllers = config_item('csrf_ignored_controllers');
}
/**
* Show CSRF Error
*
* Override the csrf_show_error method to improve the error message
*
* @return void
*/
public function csrf_show_error()
{
show_error('The action you have requested is not allowed. You either do not have access, or your login session has expired and you need to sign in again.');
}
/**
* Verify Cross Site Request Forgery Protection
*
* Override the csrf_verify method to allow us to set controllers and
* modules to override.
*
* @return object Returns $this to allow method chaining
*/
public function csrf_verify()
{
if ( ! empty($this->ignored_controllers)) {
global $RTR;
$module = $RTR->fetch_module();
$controller = $RTR->fetch_class();
$path = empty($module) ? $controller : "{$module}/{$controller}";
if (in_array($path, $this->ignored_controllers)) {
return $this;
}
}
return parent::csrf_verify();
}
}
That's older code, too, that won't work on newer versions of PHP since it's using the $RTR global, so you'll need to rework that a bit but it should give you an idea to get you started with.
RE: Cross Site Form Submission - Narf - 11-19-2014
Just configure your cookie to match the .example.com domain.
RE: Cross Site Form Submission - khalilhimura - 11-23-2014
(11-19-2014, 04:44 AM)Narf Wrote: Just configure your cookie to match the .example.com domain.
Yeah, I had that done already but it didn't work.
RE: Cross Site Form Submission - khalilhimura - 11-23-2014
Thanks kilishan!
It took some time but manage to make it work with your code
Code: class MY_Security extends CI_Security
{
/**
* @var array Controllers to ignore during the CSRF cycle.
*
* If part of a module, the controller should be listed as:
* {module}/{controller}
*/
protected $ignored_controllers = array('authorization/signin');
/**
* The constructor
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Show CSRF Error
*
* Override the csrf_show_error method to improve the error message
*
* @return void
*/
public function csrf_show_error()
{
show_error('[Moru.my] The action you have requested is not allowed. You either do not have access, or your login session has expired and you need to sign in again.');
}
/**
* Verify Cross Site Request Forgery Protection
*
* Override the csrf_verify method to allow us to set controllers and
* modules to override.
*
* @return object Returns $this to allow method chaining
*/
public function csrf_verify()
{
$uri = $_SERVER['REQUEST_URI'];
$uri = explode("/", $uri);
$module = empty($uri[1]) ? "" : $uri[1];
$controller = empty($uri[2]) ? "" : $uri[2];
if ( ! empty($this->ignored_controllers)) {
$path = empty($module) ? $controller : "{$module}/{$controller}";
if (in_array($path, $this->ignored_controllers)) {
return $this;
}
}
return parent::csrf_verify();
}
}
Do let me know if there's any issue with the above code. For now its working!
|