User tests: Successful: Unsuccessful:
The session token validation implementation in various controller methods currently gives an empty white screen with "Invalid token" text. This is total uninformative to a normal user.
This update implicitly redirects to the previous page if the token is not valid. To prevent implicit redirect pass false
as the second argument to JSession::validateToken()
$this->checkToken()
from the JControllerLegacy
controller instance.
To make use of this method we need to replace any occurrence of JSession::checkToken('post') or jexit(JText::_('JINVALID_TOKEN'));
with JSession::validateToken('post');
$this->checkToken();
JSession
class and put it in the closer context of its application viz. JControllerLegacy
.$this->checkToken()
and the redirection shall be handled implicitly. Implicit redirection is done to the referrer (calling) page always.$this->checkToken
like:if (!$this->checkToken('post', false))
{
// ...
}
or even directly call the current JSession::checkToken
(without the die part) like:
if (!JSession::checkToken('post'))
{
// ...
}
This will skip the implicit redirection and return false if the token does not match. Then the necessary if - else
may be implemented as needed.
To see the effect the respective forms should be submitted after manipulating the token input in the form so as to trigger invalid token situation. This can usually be done by selecting in the browser "inspect element" (or similar) and modify the DOM.
If the token is valid (not manipulated or expired), everything should be working as usual without any difference.
The necessary changes are made in the front-end which should be tested:
com_users
component try to register a new user, login, logout, remind username, reset password, save user profile.com_contact
submit the contact form to send an email.com_content
submit a vote.EDIT June 26, 2016:
Added Summary of changes and Test Instructions based on the new changes.
Status | New | ⇒ | Pending |
Labels |
Added:
?
?
|
Another idea is to allow passing the second argument to JSession::validateToken($method, $redirect)
as:
Value of $redirect
|
Behaviour |
---|---|
true |
Redirect to the referrer page (default value) |
false |
No redirect, just return false if token is invalid |
Custom URL String | redirect to this specific url if token is invalid |
Category | ⇒ | UI/UX |
Labels | |||
Easy | No | ⇒ | Yes |
I was recently thinking about this method getting influenced by
... it is the wrong way and against design principles: JSession is a specialised class for sessionhandling and not about redirection handling ... #8416 (comment)
I see most of these checks are done in controllers and all (almost) are inherited from JControllerLegacy
. Would that be an appropriate location to move this method validateToken
, however I like the name checkToken
more.
So that we can do the check like:
$this->checkToken('post', true); // checkToken($method, $redirect)
Then gradually update the core components to use this test by test.
Better.
But you don't have to move your new method, just use the allready existing ones from JControllerLegacy instead:
You just have to change
JSession::checkToken('post') or jexit(JText::_('JINVALID_TOKEN'));
to
JSession::checkToken('post') or $this->setRedirect($url, JText::_('JINVALID_TOKEN'), 'error')->redirect();
with the right url and your improved message.
Your solution is still a code- (and thus test-) duplication.
@peterpeter I almost agree. But to me the code does not appear to be any duplication. It internally uses the already existing method. The extra method introduced is just to provide the ability to auto calculate the REFERER page url for redirection. If that is not needed then of course we can follow what you suggested. But I think it could be useful.
I agree this is a real problem, but in current state untestable (we do not have a solution). Please elaborate, because it is a good idea to solve this.
Category | UI/UX | ⇒ | Language & Strings UI/UX |
Labels |
Hello @izharaazmi
Thank you for your contribution.
The last comment here was on April 15th. Can you update this PR so it is testable?
If no reply is received within 4 weeks we will close this issue.
Thanks for understanding!
Status | Pending | ⇒ | Information Required |
I have made the necessary changes in the front-end components. Please see #8445 (comment) for updated notes.
I hope it is now testable for the front-end. I'll preferably do backend implementation as a separate PR if this is approved.
I have tested this item
I found issue, after applying patch and I modified token of login form presented on sidebar. It redirects to blank screen, Network tab shows "500 Internal Server Error". Before applying patch "The most recent request was denied because it contained an invalid security token. Please refresh the page and try again." message was appearing on screen.
For the other inner pages warning message "The security token did not match. The request was aborted to prevent any security breach. Please try again." appears after applying the patch.
Check the warning message after patch applied(All pages except login form problem mentioned above):
Before applying patch (for all screens):
@hardiktailored I tested it again and it worked fine. I may be missing something... can you please explain the issue a little more?
Status | Information Required | ⇒ | Pending |
Labels |
I have tested this item
I have also found the issue after applying this patch (using the patchtester component) same as @hardiktailored, when I login (after modifying the token from DOM), I get the following error "
Fatal error: Call to undefined method JSession::validateToken() in components/com_users/controllers/user.php on line 30".
Before applying the patch login function has JSession::checkToken('post') or jexit(JText::_('JINVALID_TOKEN')); instead of JSession::validateToken('post');
I have checked for other forms (registration, reset password, remind username, edit profile etc.), they are working fine.
@AnishaTailored Thanks for explaining the issue in detail. I found that in my previous commit I had missed changing one occurrence of validateToken
that was causing failures.
I've fixed it now, please test this again.
I have tested this item
Now it works fine.
@hardiktailored Can you test this again please.
I have tested this item
I have tested this item
Tested with modification of the token through Firebug. After patch installation better message in a alert.
I was resolving the conflict, then I saw the missing register
method the controller. Little investigation led me to bae1d43#diff-f820ef502f338b5be5a00aac838e756fL287. I could not find the exact PR which actually made this change. On 3.7.x branch this method still exists. Somebody guide me at this please!
This is removed in 3.6.4 to avoid registations over the wrong way. 3.7.0-dev branch is not updated with this change as staging is now 3.7.-dev
Won't it break b/c for components redirecting/submitting to that task for registration?
Yes. But it was the decision of the JSST to remove that method as it is not used anymore and was never correctly implemented.
Category | UI/UX Language & Strings | ⇒ | Administration Language & Strings Front End Components Libraries UI/UX |
Milestone |
Added: |
Status | Pending | ⇒ | Fixed in Code Base |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2016-11-05 10:12:00 |
Closed_By | ⇒ | rdeutz |
Thanks everybody for making this to this point
I think this should followed up by some documentation update. Please advise where can I do that.
@izharaazmi can you do the same for all other token dies (where applies) so we have a consistent core?
There a lot of JSession::checkToken('xxxxx') or die(JText::_('JINVALID_TOKEN'));
egrep -R "JSession::checkToken" /path/to/joomla-staging/ | awk '{print $1}'
@andrepereiradasilva Sure, hope to see it this Monday! Btw, I'm having 152 occurrences. Please do let me know if you find more.
This is also the kind of function that would benefit from some UnitTests so that it can be tested with different sessions and referers...
@andrepereiradasilva I have made the required changes. Please test the other PR at your convenience.
I was making changes in the
checkToken
method itself. But made this a separate method for clarity.The other similar discussion on this topic is ongoing in the PR #8416.