1

I have a page with a few buttons. When people click on the buttons they issue AJAX requests and update various parts of the page. The AJAX requests make use of nonces for security purposes.

I noticed that if someone leaves the page open for longer than the time it takes for a nonce to expire, then the AJAX requests will stop working as expected. However, I would want a bit more of a robust behavior.

What I'd want to do is - detect when a nonce has expired / failed, and then at that point somehow generate a new nonce.

So this is a two part question:

  1. How can I detect that the nonce has expired?
  2. Is the best thing to do on expired nonce a full page refresh, or something else? I'm not super versed in security considerations. I would want to carry over the current page status though (so any of the selected options in the various ajax requesting parts of the page) after the page refresh.
0

Nonces are not magic bullet that by simply applying it everywhere your site get more secure. Talking broadly, nonce should be applied only to logged in users, and serve little purpose when applied to non logged in. Even for logged in users, there might be situations in which nonces are just not needed (like when reading publicly available information).

.... but when coding, it is truly easier to apply nonces everywhere instead of having repetitive checks whether a user is logged in. Still, if it is important for you that a page can stay open for more than a day and still retain all its functionality, that is the way to go - remove nonces where they are not needed.

The nonce issue you describe is the result of WordPress not implementing nonce as the definition implies. Nonces are supposed to be unique per page load, while WordPress reuses them for 24 hours. This has a huge performance and architectural advantage as it removes the requirement to store them somewhere, but leads to problems like the one you describe which are hard to eliminate without resorting to a "forced" reload of the page every 24 hours. therefor the other solution to your problem is to override the nonce api with your own logic to generate a one time nonce, or use different time interval for non logged in users.

Why not to detect the expiry somehow in JS? because nonce are generate by using secret "SALT" keys, and the only way to reconstruct the calculation is to expose them in your JS, at which point they will not be secret any longer.

  • I'm not sure i follow this entirely (mostly due to my lack of security knowledge) but if I'm sending AJAX requests through somethign like JQuery then the nonce will be exposed to the JS right? A user will always be able to get their generated nonce by just opening up the console. Are you suggesting that I shouldn't issue AJAX requests for anything secure via javascript? – CHP Dec 30 '17 at 16:46
  • The problem is not that the nonce is exposed, the problem is that it is time constrained. It is just easier to not set the nonce in the first place when it is not truly needed than doing a refresh of the nonce (which is probably why such a refresh do not happen even on admin side). The only proper way to do the refresh without exposing the salts (which have to remain secret) is to send an ajax request to get a new nonce, but that request has to not be protected with a nonce which leads us back to the need to evaluate what needs to be protected and what not. – Mark Kaplun Dec 30 '17 at 18:24
  • Didn't find a good resource for understanding the why of nonce, but basically it is used from doing a CSRF attack in which for example you can be made to create a new user by clicking on a link sent by email to you. In this case the nonce adds a "random" factor to the link which is hard for the attacker to anticipate. The way wordpress implements it, it is based also on the user id which should be impossible for the attacker to guess, and therefor (even without salting) be able to generate the nonce by himself.. – Mark Kaplun Dec 30 '17 at 18:36
  • So the concise answer to the second part of my question is that basically page reload is the only thing? – CHP Dec 31 '17 at 16:29
  • 1
    Thanks for helping me think through this. In the end there's no real need to overthink or overengineer this, given the long expiry time of the nonce, it's just simplest to auto-refresh the page every 12 hours, saving its necessary values in a sessionStorage on refresh, then reloading them and clearing out sessionStorage. – CHP Dec 31 '17 at 18:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.