0

I need to work with sessions only to maintain form input from edit.php(1) to post.php(2) to edit.php(3) if the input validation failed on save_post, so that my users don't have to re-fill the form at edit.php(3) with their previous entries at edit.php(1) since post.php(2) does not re-post to edit.php(3). There are a number of ways to transient data through this tunnel:

  1. WordPress uses the querystring for its messages - aside from the common cons of querystrings for my purpose, I did not go this way as my $_POST vars may be too much for the querystring
  2. the Transient API - nope, not this one either for (remotely possible) collision reasons
  3. modify edit.php and post.php directly - unsustainable especially over updates. I could look for hooks for this if I can't find anything else
  4. sessions,

among others.

I will not use sessions for login (since I'm using WordPress, I'll let WordPress take care of that.) From scouring the web, I inserted the following in my functions.php:

/*
 * manage sessions
 */
// http://wblinks.com/notes/secure-session-management-tips
// http://devondev.com/2012/02/03/using-the-php-session-in-wordpress/
// http://en.wikipedia.org/wiki/Session_fixation
// http://www.php.net/manual/en/function.session-regenerate-id.php
if (is_admin()) add_action('init', 'empl_sesh_start', 1);
add_action('wp_login', 'empl_sesh_cleanup');
add_action('wp_logout', 'empl_sesh_cleanup');
function empl_sesh_start() {
    session_start();
    // check if loaded session is server-generated
    if (!isset($_SESSION['IS_SERVER_TRUSTED']))
        session_regenerate_id(true); // if not, regenerate id and clean-up previous session files
    // regenerate id for every request
    session_regenerate_id();
    $_SESSION['IS_SERVER_TRUSTED'] = true; // set flag
}
// cleanup
function empl_sesh_cleanup() {
    session_start(); // needed for the rest of this function to work
    $_SESSION = array(); // cleanup session variables
    session_regenerate_id(true); // regenerate id and clean-up previous session files
    session_destroy();
}

I just need to know if I got it right. I'm particularly concerned with

  1. are the order and calls to the session statements correct?
  2. are they necessary (in an effort to make the session less vulnerable as pointed out by the online articles)?

I'm also concerned with what I read about unsetting cookies and their complexities - do I need to do that? I don't use any cookies, I just use two session variables:

// persist form vars to next load
$_SESSION['empl_form_inputs'][] = $_POST['empl_age'];
    // more similar code here...
$_SESSION['empl_form_inputs'][] = $_POST['empl_id'];

// persist message array to next load
$_SESSION['empl_messages'] = $empl_messages;

I posted this here instead of at wordpress.stackexchange.com as (I think) this is not really a WordPress question, but more of a PHP Session best practice.


RESOLUTION: I ended up abandoning the whole session caboodle and implemented collision-addressed (at least for my use case) transients with a 1 second expiration. thanks @Robbie

Ana Ban
  • 1,395
  • 4
  • 21
  • 29
  • "regenerate id for every request" --- for what reason? – zerkms May 18 '12 at 03:32
  • "Remember it's not just for login, any privilege escalation should get a new ID. You could just do it on every request since the user won't care that the session ID changes and it makes any session ID immediately invalid after the next request" - http://wblinks.com/notes/secure-session-management-tips – Ana Ban May 18 '12 at 03:33

1 Answers1

2

You shouldn't need sessions for posting from a form, not even in wordpress.

Your script / plugin should read.

  • Create values with default values
  • Create "empty" error conditions
  • If Post
    • Populate "default" values from POST
    • Sanitize values
    • Validate Values
    • If valid
      • Create action (e.g. put the values in DB)
      • Redirect to another page showing result/scucess message (prevents back button failure)
    • If not valid
      • Poulate error conditions
  • Display form using values and error conditions.

You'd use a session if you were using a wizard (multi-page form) approach. This way the form alsways shows what the user enters and errors.


However, to answer your question, your addactions() are probably what you want, but the functions are agressive.

  • The init looks fine - ish (note comment on regenerating ID below)
  • The cleanup is risky as you will obliterate any other plugins that use sessions. Just delete your entries ( $_SESSION['empl_form_inputs'] = array(); ) and move on
  • If you mess about with the sesson ID like that, you're going to totally screw over any other plugins that use sessions.
  • For "security" keep the same session ID, but track where it comes from and give it a time-out. So if session_id() = "ABC" has not been used for 10 minutes, or comes from a different user agent, then ignore those values you had and start again.

Example of time-out:

if ($_SESSION['empl_form_expires'] > time()) {  // Also add user agent chack or something
    $_SESSION['empl_form_inputs'] = array();  // Clear values
} else {
    $_SESSION['empl_form_expires'] = time() + 600;  // Keep the time running
}
Robbie
  • 17,605
  • 4
  • 35
  • 72
  • hey @Robbie ! thanks for the answer. i edited the question to show why i can't rely on $_POST to transient the data for me. epic effort to keep going and still answer my question, nonetheless. sooo yeap, good point bout other plugins. how could i forget that? will def'ly work on your suggestions and let you know whatever i end up with. might still reconsider the transients api, just need to make sure collision and its impacts to my form are minimized. thanks man! ttyl – Ana Ban May 18 '12 at 04:44
  • Even with the edit I stil have no idea why you can't merge "post.php" into "edit.php" and follow the normal chain of events. So I presume there's something deeper that you're revealing here. Good luck with it. And on another note, the session tim-out you can set as low as 1 minute or less, if you create the session variables in post.php and redirect immediately to edit.php. Very low risk of MITM attacks on the session ID. – Robbie May 18 '12 at 04:56
  • ikr? wish i could just merge those two files and everything would be a lot simpler. but yeap, it's just the way with it with wp, and i'm in too deep taking over this project for a really long-time client, and i can't even switch to another platform for now. maybe in the (really distant) future lol. but yeap, i'm thinking keeping the time-out as small as possible as it's just for transmitting between the 2nd and 3rd steps. thanks again, will keep you `post`ed you on what happens (laaame... lol). – Ana Ban May 18 '12 at 05:07
  • i ended up abandoning the whole session caboodle and implemented collision-addressed transients with a 1 second expiration. thanks @Robbie – Ana Ban May 19 '12 at 06:11