Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix improper state handling #417

Merged
merged 2 commits into from
Mar 28, 2018
Merged

Conversation

joshcanhelp
Copy link
Contributor

State generation, specifically cookie storage, needs to happen before
any output. The previous arch was ok for login page generation but
failed with a "headers already set" error if used in the shortcode.
This addresses the issue by storing state earlier and getting the
value later.

@joshcanhelp joshcanhelp added this to the v3-Next milestone Mar 26, 2018
@joshcanhelp joshcanhelp self-assigned this Mar 26, 2018
@joshcanhelp joshcanhelp force-pushed the fix-state-handling-for-shortcode branch from 81a4456 to b0f3707 Compare March 26, 2018 18:59
@lbalmaceda lbalmaceda self-requested a review March 26, 2018 19:25
WP_Auth0.php Outdated
@@ -120,6 +120,9 @@ public function init() {

$this->check_signup_status();

// Store nonce value before headers are sent
new WP_Auth0_State_Handler();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why isn't this being assigned anywhere? If this is some kind of "static helper" maybe you'd want to have a singleton to access it instead of creating new instances.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔

*
* @return string
*/
public function issue() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this a breaking change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has not gone out yet

@@ -72,7 +77,7 @@ public static function reset() {
*
* @return string
*/
public static function generateNonce() {
protected function generateNonce() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this a breaking change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has not gone out yet

@@ -40,6 +44,7 @@ public function issue() {
* @return bool
*/
protected function store() {
$_COOKIE[ self::COOKIE_NAME ] = $this->uniqid;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

who was setting this value to $_COOKIE previously?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setcookie() (PHP core) does the work sending the header but it doesn't set the global for use later. I need to check for that cookie later on during processing

@joshcanhelp joshcanhelp force-pushed the fix-state-handling-for-shortcode branch 4 times, most recently from 32df76e to 6d05e0a Compare March 27, 2018 18:56
State generation, specifically cookie storage, needs to happen before
any output. The previous arch was ok for login page generation but
failed with a "headers already set" error if used in the shortcode.
This addresses the issue by storing state earlier and getting the
value later.
@joshcanhelp joshcanhelp force-pushed the fix-state-handling-for-shortcode branch from 6d05e0a to 1b344ea Compare March 27, 2018 19:00
@joshcanhelp joshcanhelp changed the title Fix state handling for shortcode Fix improper state handling Mar 27, 2018
@joshcanhelp joshcanhelp force-pushed the fix-state-handling-for-shortcode branch 2 times, most recently from 7713d2b to bcb9eac Compare March 27, 2018 21:46
* @return bool
*/
protected function validate_state() {
$valid = isset( $_COOKIE[ WPA0_STATE_COOKIE_NAME ] )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we going to force people to set the state then? Or better put.. is this library setting a new state on every request?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting a new state when initializing Lock, yes

*
* @var string
*/
const COOKIE_NAME = 'auth0_uniqid';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe you want to use "auth0_nonce" here?

final class WP_Auth0_Nonce_Handler {

/**
* Cookie name used to store unique state value
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"unique state value" shouldn't be "nonce"?

private $_uniqid;

/**
* WP_Auth0_State_Handler constructor
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nonce handler

// Have a state cookie, don't want to generate a new one
$this->_uniqid = $_COOKIE[ self::COOKIE_NAME ];
} else {
// No state cookie, need to create one
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nonce

}

/**
* Return the unique ID used for state validation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nonce>

}

/**
* Check if the stored state matches a specific value
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nonce

/**
* Check if the stored state matches a specific value
*
* @param $state
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nonce

*
* @return bool
*/
public function validate( $state ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nonce

*/
protected function get_state() {
protected function get_state( $decoded = FALSE ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why would I need the "encoded" state? URL encoding a state shouldn't be responsibility of this class, but the class who constructs the requests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

References base64 encoded, not URL. URL decoding has to happen, this is just basically "do you want the raw value or the object"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would I need it to be base64 encoded? The form of the nonce or state values should be obscure. I don't care how you generate it internally as long as it's "safe and secure". (guarantying that it's too hard to repeat itself in a short period of time, etc).

And TBH, the server doesn't care either. It's a plain text string that it needs to put somewhere so the client can later obtain it and validate it with the one it sent before. So unless you have a reason why to have a method supporting both encoded/decoded scenarios, I think it's useless.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's base64 encoded when it's created in WP_Auth0_Lock10_Options->get_state_obj() ... more specifically, it's a JSON encoded object that's then base64 encoded. That's what I store in a cookie then validate during the login process, still base64 encoded. Once someone is logged in, then I need that object I created before to get a redirect URL.

If you look for where get_state is used in this class, you'll see what I mean

Originally was generating and setting a nonce value in a state object,
then checking that nonce on return from Auth0 instead of checking the
entire state parameter.
@joshcanhelp joshcanhelp force-pushed the fix-state-handling-for-shortcode branch from bcb9eac to fdcd069 Compare March 28, 2018 17:22
Copy link
Contributor

@lbalmaceda lbalmaceda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

@joshcanhelp joshcanhelp merged commit 8e81a74 into dev Mar 28, 2018
@joshcanhelp joshcanhelp deleted the fix-state-handling-for-shortcode branch March 28, 2018 17:51
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 19, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants