Welcome Guest, Not a member yet? Register   Sign In
Cross Site Form Submission
#1

(This post was last modified: 11-18-2014, 06:19 PM by khalilhimura.)

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
Reply
#2

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.
Reply
#3

Just configure your cookie to match the .example.com domain.
Reply
#4

(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.
Reply
#5

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!  Big Grin
Reply




Theme © iAndrew 2016 - Forum software by © MyBB