Why do I always get 'Invalid token' message?

234 views
Skip to first unread message

PGS

unread,
Feb 9, 2016, 3:59:16 AM2/9/16
to Joomla! General Development
It's about a custom component of mine.

In my layout, I have:
JHtml::_('behavior.keepalive');

and
<?php echo JHtml::_('form.token'); ?>

I submit the form.

In my controller I check the token:
JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));

But I ALWAYS get the 'Invalid Token' message.

I log out, loggin again, and the same thing happens, always 'Invalid Token' message.

What am I doing wrong?

Viper

unread,
Feb 9, 2016, 6:59:24 AM2/9/16
to Joomla! General Development
var_dump($_REQUEST);
echo JSession::getFormToken();
compare session token from request and session.

checkToken look variable from $_POST by default, if you send form via $_GET you need to pass additional parameter into this method.

PGS

unread,
Feb 9, 2016, 11:21:40 AM2/9/16
to Joomla! General Development
You 're right, this:
var_dump($_REQUEST);
does not give me a token (in the view I'm talking about).
I don't understand why...:(.

seraphim

unread,
Feb 9, 2016, 11:45:44 AM2/9/16
to joomla-de...@googlegroups.com
Maybe it's not inside your form.

Op 09-02-16 om 17:21 schreef PGS:
--
You received this message because you are subscribed to the Google Groups "Joomla! General Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to joomla-dev-gene...@googlegroups.com.
To post to this group, send email to joomla-de...@googlegroups.com.
Visit this group at https://groups.google.com/group/joomla-dev-general.
For more options, visit https://groups.google.com/d/optout.

PGS

unread,
Feb 9, 2016, 11:59:30 AM2/9/16
to Joomla! General Development, sera...@glockenbach.net
I checked the page 's source code, the token is in the form.
5 lines before the form 's closing tag (</form>).

Maybe the form does not get submited?
I open the next view with a click on a link:
href="<?php echo JRoute::_('index.php?option=com_pgclassifieds&view=newad&layout=start'); ?>"

I suppose that when we open a new view, the current form gets submited, or am I wrong?

seraphim

unread,
Feb 9, 2016, 12:04:07 PM2/9/16
to joomla-de...@googlegroups.com, panagiot...@gmail.com
The form gets submitted if your link is in the forms action or if you submit it by javascript.

Op 09-02-16 om 17:59 schreef PGS:

PGS

unread,
Feb 9, 2016, 12:49:28 PM2/9/16
to Joomla! General Development, panagiot...@gmail.com, sera...@glockenbach.net
Well, yes that was the problem.
The form was not submited.
I did it with js (Joomla.submitform), it now gets submited and works fine!
Seraphim thank you very much my friend!

seraphim

unread,
Feb 9, 2016, 1:21:57 PM2/9/16
to joomla-de...@googlegroups.com, panagiot...@gmail.com
You are Welcome!

Καλησπέρα :-)

Op 09-02-16 om 18:49 schreef PGS:

PGS

unread,
Feb 10, 2016, 4:55:13 AM2/10/16
to Joomla! General Development, panagiot...@gmail.com, sera...@glockenbach.net
Ελληνας είσαι;!!
Να 'σαι καλά  σ' ευχαριστώ πολύ!

Patrick Mutwiri

unread,
Feb 12, 2016, 12:49:31 AM2/12/16
to Joomla! General Development
probably because you 'go back' instead of 'refreshing' the page. I've such issues during support. Another cause is a short-lived session period. 


On Tuesday, February 9, 2016 at 11:59:16 AM UTC+3, PGS wrote:

PGS

unread,
Feb 15, 2016, 1:21:25 PM2/15/16
to Joomla! General Development
I 'm trying to include the token in a URL, like this:
<a href=<?php echo JRoute::_('index.php?option=com_mycomponent&view=myview&' .  JSession::getFormToken() .'=1'); ?>
It fails the JSession::checkToken() in my controller.

In the controller, I echo the input:
var_dump($app->input->post);

But, no token exists in the input. (but exists in the $_REQUEST).

What am I doing wrong?

(In session.php, in function checkToken, the token is read from the $app->input->post)

seraphim

unread,
Feb 15, 2016, 1:27:32 PM2/15/16
to joomla-de...@googlegroups.com
If you send it by the url it's in the php $_GET variables and not in the $_POST variables.
So you should use $app->input->get instead.

Op 15-02-16 om 19:21 schreef PGS:

PGS

unread,
Feb 15, 2016, 1:44:25 PM2/15/16
to Joomla! General Development, sera...@glockenbach.net
The reason why I 'm using the '$app->input->post' is because I 'm trying to see why it fails in session.php function checkToken().

In this function it checks the post ($app->input->post), not the get ($_GET variables)...

PGS

unread,
Feb 15, 2016, 1:49:32 PM2/15/16
to Joomla! General Development, sera...@glockenbach.net
I tried JSession::checkToken('get'), it works, but I'm not sure what should  do now.
Should I check for both post and get?
That is:
JSession::checkToken();
 
JSession::checkToken('get');


Michael Babker

unread,
Feb 15, 2016, 1:57:14 PM2/15/16
to joomla-de...@googlegroups.com
If the request you're sending the token in is expecting it from the GET variables, then call `JSession::checkToken('get')`.  Otherwise it's going to use the default POST.  You need to tell Joomla where you're expecting the token to be found if it isn't using the default behavior (and the default's coded for the more typical use case of a form's CSRF token and forms are more often than not submitted via POST).

Chris Davenport

unread,
Feb 15, 2016, 2:10:14 PM2/15/16
to joomla-de...@googlegroups.com
There is a section on Securing Forms towards the end of this page https://docs.joomla.org/Secure_coding_guidelines that describes what you need to do, although I notice it needs updating to use JSession instead of JRequest.  Anyone have a minute to update it?

Chris.
--
Chris Davenport
Joomla Production Leadership Team

Viper

unread,
Feb 15, 2016, 3:46:39 PM2/15/16
to Joomla! General Development
Updated information on the page.


On Monday, February 15, 2016 at 10:10:14 PM UTC+3, Chris Davenport wrote:
There is a section on Securing Forms towards the end of this page https://docs.joomla.org/Secure_coding_guidelines that describes what you need to do, although I notice it needs updating to use JSession instead of JRequest.  Anyone have a minute to update it?

Chris.

Chris Davenport

unread,
Feb 15, 2016, 3:56:41 PM2/15/16
to joomla-de...@googlegroups.com
Thank you. :-)

Chris.

--
You received this message because you are subscribed to the Google Groups "Joomla! General Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to joomla-dev-gene...@googlegroups.com.
To post to this group, send email to joomla-de...@googlegroups.com.
Visit this group at https://groups.google.com/group/joomla-dev-general.
For more options, visit https://groups.google.com/d/optout.

PGS

unread,
Feb 16, 2016, 2:30:06 AM2/16/16
to Joomla! General Development
How can I check this? (if it's expected from the GET variables)

seraphim

unread,
Feb 16, 2016, 3:57:00 AM2/16/16
to joomla-de...@googlegroups.com
If the variables are sent by the url you have GET variables if you submit a form you have POST variables. Or you use the REQUEST variables which is a merge of GET, POST and COOKIE variables.
Have a look at: http://php.net/manual/en/reserved.variables.php

Op 16-02-16 om 08:30 schreef PGS:
How can I check this? (if it's expected from the GET variables)

Τη Δευτέρα, 15 Φεβρουαρίου 2016 - 6:57:14 μ.μ. UTC, ο χρήστης Michael Babker έγραψε:
If the request you're sending the token in is expecting it from the GET variables, then call `JSession::checkToken('get')`.  Otherwise it's going to use the default POST.  You need to tell Joomla where you're expecting the token to be found if it isn't using the default behavior (and the default's coded for the more typical use case of a form's CSRF token and forms are more often than not submitted via POST).


PGS

unread,
Feb 16, 2016, 5:49:19 AM2/16/16
to Joomla! General Development, sera...@glockenbach.net
I made a custom checkToken function in my controller.   
    function checkToken() {        
        $app
= JFactory::getApplication();
        $token
= JSession::getFormToken();

       
if (!$_REQUEST[$token]) {
            $session
= JFactory::getSession();

           
if ($session->isNew()) {
               
// Redirect to login screen.
                $app
->enqueueMessage(JText::_('JLIB_ENVIRONMENT_SESSION_EXPIRED'), 'warning');
                $app
->redirect(JRoute::_('index.php'));
           
} else {
               
return false;
           
}
       
} else {
           
return true;
       
}
   
}
I 'll use this, if there are any objections please let me know.

seraphim

unread,
Feb 16, 2016, 6:00:34 AM2/16/16
to joomla-de...@googlegroups.com
I think this is the same with JSession::checkToken('request'); no need for custom function in your controller.


Op 16-02-16 om 11:49 schreef PGS:

PGS

unread,
Feb 16, 2016, 6:21:39 AM2/16/16
to Joomla! General Development, sera...@glockenbach.net
Yes, it is the same with a major difference, instead of using input 's post or get, it uses the $_REQUEST to get the token.

Niels Braczek

unread,
Feb 16, 2016, 7:09:49 AM2/16/16
to joomla-de...@googlegroups.com
Am 16.02.2016 um 12:21 schrieb PGS:

> Yes, it is the same with a *major* difference, instead of using input 's
> post or get, it uses the $_REQUEST to get the token.

The token is a security feature. You should be aware, if you expect it
sent through POST (recommended) or GET, and check it on exactly that.
Everything else is a step backward.

Regards,
Niels

--
| New Stars on the Horizon: GreenCape · nibralab · laJoom |
| http://www.bsds.de · BSDS Braczek Software- und DatenSysteme |
| Webdesign · Webhosting · e-Commerce · Joomla! Content Management |
------------------------------------------------------------------

PGS

unread,
Feb 16, 2016, 8:01:59 AM2/16/16
to Joomla! General Development, nbra...@bsds.de
Then I think I 'll do it somehow like this:

function checkToken(){
  $result
= JSession::checkToken();
 
if(!$result){$result = JSession::checkToken('get');}
}

So that both post and get are checked.
Isn't it better?

Niels Braczek

unread,
Feb 16, 2016, 9:00:44 AM2/16/16
to joomla-de...@googlegroups.com
No.
You're using

<a href=<?php echo
JRoute::_('index.php?option=com_mycomponentview=myview&'
. JSession::getFormToken() .'=1'); ?>

so the right check is

$result = JSession::checkToken('get');

Hannes Papenberg

unread,
Feb 16, 2016, 9:26:34 AM2/16/16
to joomla-de...@googlegroups.com
You want to protect your form from someone who maliciously injects data.
That means, that you want to make it hard for an attacker to do that. By
allowing both POST and GET data, you are already doubling your attack
surface. So, no, your proposal is not better. Either use GET _or_ POST,
but not both. If it didn't matter, we would already be using $_REQUEST
in the original code.

Hannes

Am 16.02.2016 um 14:01 schrieb PGS:
> Then I think I 'll do it somehow like this:
> |
>
> functioncheckToken(){
> $result =JSession::checkToken();
> if(!$result){$result =JSession::checkToken('get');}
> }
> |
>
> So that both post and get are checked.
> Isn't it better?
> --
> You received this message because you are subscribed to the Google
> Groups "Joomla! General Development" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to joomla-dev-gene...@googlegroups.com
> <mailto:joomla-dev-gene...@googlegroups.com>.
> To post to this group, send email to
> joomla-de...@googlegroups.com
> <mailto:joomla-de...@googlegroups.com>.

PGS

unread,
Feb 16, 2016, 9:37:43 AM2/16/16
to Joomla! General Development
My problem is that I don't always use a URL
<a href=<?php echo JRoute::_('index.php?option=com_mycomponentview=myview&' .  JSession::getFormToken() .'=1'); ?>
 to open this view.

I also use a form's action:
<form action = '<?php echo JRoute::_('index.php?option=com_mycomponentview=myview'>.

So, in the first case it's a 'get' and in the second it 's a 'post'.

Viper

unread,
Feb 16, 2016, 12:42:02 PM2/16/16
to Joomla! General Development
You have wrong architecture of you component. You should not to use same URL for POST and GET because it' a bit overhead. Just use controller for custom actions.
E.g.
index.php?option=com_blabla&view=see to display some content to user and index.php?option=com_blabla&task=form.see to send POST to this URL.
Reply all
Reply to author
Forward
0 new messages