views:

424

answers:

6

How can I let a user access a WordPress protected page with a URL that will submit the password in the form below?

I want to be able to let a user get to a password protected WordPress page without needing to type the password, so when they go to the page, the password is submitted by a POST URL on page load.

This not intended to be secure in any respect; I'll need to hardcode the password in the URL and the PHP. It's just for simplicity for the user.

Edit 4/19/10: As per answers below, it's possible to set a cookie directly to allow users to not have to enter a password. Letting search bots in is best done by detecting the user agent and redirecting, as bots aren't going to deal with cookies.

This is the form (which is WordPress core code):

<form action="http://mydomain.com/wp-pass.php" method="post">

Password: <input name="post_password" type="password" size="20" />

<input type="submit" name="Submit" value="Submit" /></form>

This is wp-pass.php (which is WordPress core code):

<?php
require( dirname(__FILE__) . '/wp-load.php');

if ( get_magic_quotes_gpc() )
    $_POST['post_password'] = stripslashes($_POST['post_password']);

setcookie('wp-postpass_' . COOKIEHASH, $_POST['post_password'], time() + 864000, COOKIEPATH);

wp_safe_redirect(wp_get_referer());
?>
+1  A: 

Change $_POST to $_REQUEST everywhere in wp-pass.php.

That code is only looking at the POST variables, not the GET variables in the URL. The REQUEST global contains both the POST, and the GET variables, which is what you want.

There's probably a better way, but I don't know WordPress.

EDIT

The problem is those parameters are in the GET array, not the POST array. So using a regular link with parameters isn't going to work. You can use a form with a hidden field. You can style the submit button to look like a link, if you want.

<form action="http://mydomain.com/wp-pass.php" method="post">
<input name="post_password" type="hidden" value="totally insecure password here" />
<input type="submit" name="Submit" value="Click here to enter your account" />
</form>
Matt
Not a good idea to hack core Wordpress files for both functionality and upgrade reasons. Besides, if I changed wp-pass.php, than all password functions in Wordpress would break. And I'd rather work with the built in wp-pass function than replace it with another file or version.
songdogtech
Actually, you _probably_ won't break anything. REQUEST contains POST and GET variables, and POST variables overwrite GET variables (unless you changed `variables_order` in PHP.ini). I will update my post to explain another solution.
Matt
+1  A: 

If you want to do this without editing WP's core, you can use cURL to simulate POST variables like this:

$ch = curl_init("http://mydomain.com/wp-pass.php");
curl_setopt($ch, CURLOPT_POSTFIELDS,  "post_password=mypassword&Submit=Submit");  
curl_setopt($ch, CURLOPT_HEADER, 0);  
curl_setopt($ch, CURLOPT_POST, 1);  
curl_exec($ch);  
curl_close($ch);
Arda Xi
Good idea to work around the form with curl, but still no luck. I wonder if my query string is wrong, or if I need a referrer in it?
songdogtech
Well, looking at the code again, I think you simply need to access the original page (not `wp-pass.php`) with a cookie.
Arda Xi
Hmm... If I access the original page, the curl function reloads the page without submitting the password string. I don't need the cookie set by wp-pass.php, and can ignore it.
songdogtech
You need the cookie set by `wp-pass.php`, you can't ignore it. All `wp-pass.php` does is set the cookie and redirect to the original page. No more, no less. So, if you would just set the cookie with whatever page you use, you can bypass `wp-pass.php`. Use `setcookie('wp-postpass_' . COOKIEHASH, "mypassword", time() + 864000, COOKIEPATH);`
Arda Xi
Good idea to bypass wp-pass, but I get the dreaded "Headers already sent" error when I try to directly set the cookie. Would Javascript set the cookie? But my ultimate aim is allowing search bots into passworded pages so the content can be indexed, and I assume bots don't accept cookies.
songdogtech
Headers already sent means that you're outputting data (like HTML) before the cookie. Make sure it's at the top.Also, why would you want to allow search-engines access to passworded data? Why not just remove the password on them? Anyone using Google could read anything you'd passworded then.
Arda Xi
+2  A: 

Rather than keep appending in the previous answer, I'll try to explain the problem a bit further here.

The way Wordpress passwording works, is:

  1. The original page has a form, which is sent to wp-pass.php.
  2. wp-pass.php takes the provided password, puts it in a cookie and redirects the user back ot the original page.
  3. The original page checks the cookie and if the password is correct, it will show the page.

The problem here is that search engines don't accept cookies. So, you have two options:

  1. Change the code Wordpress uses for passworded content to something that also accepts $_GET variables.
  2. Use cURL to send the cookie using headers, having a separate page search engines can use.

I'd love to expand on the latter answer if you want, but I do wonder; if you're going to give search engines access to passworded content, anyone will have access. Why not just remove the password?

Arda Xi
Thanks for all your help. I'm looking into now simply redirecting the search engines to a different page. But then that page will be indexed, so I need to figure out a way to block or redirect non-search engine traffic away from it and back to the original page. Yes, it's a strange way to do things, but something I'd like to get to work.
songdogtech
May I still ask why you want this, though? By having it indexed, the content will be available for anyone to see through that search engine. What's the point of having a password then?
Arda Xi
Actually, now I think I want search engines to index the page, but then non-googlebot traffic from that search link gets redirected to an introductory page, not a password protected page. I could use php to select googlebot traffic to see the page (and index it), but non-googlebot traffic could get an http redirect to an intro page where the content is user toggled by ajax after they see the intro?
songdogtech
This should work then: `if(strpos($_SERVER['HTTP_USER_AGENT'], "Googlebot") === false) header("Location: http://mydomain.com/intro.php");`This'll check for Googlebot in the UA string, if it isn't found redirected to http://mydomain.com/intro.php.
Arda Xi
I was working with a redirect, but your code is better. I think that's the way to go. Be nice if I could check for an array of google, bing and yahoo and forget about the other bots. Thanks for all your help. The cURL and cookie idea is also workable for other things.
songdogtech
A: 

I think the previous answers are rather more convoluted than they need to be.

If everyone can read the page, do not password protect it. That is by far the most neat solution. What is the password for if everyone and his dog can read the page?

If you really feel the need to make a link that uses POST though, here is the way to do it:

(Sorry if this background is redundant, but it seems like from your question like it is worth mentioning: HTTP supports various methods on URLs; POST is on, GET is another. When you normal-fetch a url, like with an <a> element, you are using the GET method.)

I agree that modifying core files to replace $_POST with $_REQUEST is unnecessary. What you want is a link element that uses the POST method. To do that, make a simple form like so:

<form action="your url" method="POST">
    <input type="hidden" value="my_password" name="password"/>
    <input type="submit" value="Submit" name="submit">
</form>

You can add style="border: 0; background: transparent;" and so on to the second input to make it look like a normal link if you want. It is a bit cumbersome, but works fine whenever you need to send a link using the POST method.

PS. Using Wireshark to inspect POST variables is a big waste of time. Install the Firebug FF extension and use the net panel. It will massively speed up working these sorts of things out.

Nicholas Wilson
This, however, will not solve the problem of search engines being able to access them.Without modifying core files you will not get around needing cookies. Therefore, it's impossible without something like cURL, which is just going overboard. Also, this is exactly what Matt said.
Arda Xi
A: 

Hi,

First I don't know how search engines react to javascript, but could something like this work?

Call mydomain.com/wp-pass.php?post_password=mypassword&Submit=Submit

Add these 2 js function:

function gup( name ){  
 name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");  
 var regexS = "[\\?&]"+name+"=([^&#]*)";  var regex = new RegExp( regexS );  
 var results = regex.exec( window.location.href );  
 if( results == null )    
  return "";  
 else    
  return results[1];
}

function setPassword()
{

 var password = gup('post_password');
 var passField = document.getElementByName('post_password');
 var buttonSubmit = document.getElementByName('Submit');

 if(password != "")
 {
  passField.value = password;
  buttonSubmit.Click();
 }

}

Add to the body tag, OnLoad="setPassword();"

I dont know how robots react to this...

Enriquev
+1  A: 

In your comment in this answer:

Actually, now I think I want search engines to index the page, but then non-googlebot traffic from that search link gets redirected to an introductory page, not a password protected page. I could use php to select googlebot traffic to see the page (and index it), but non-googlebot traffic could get an http redirect to an intro page where the content is user toggled by ajax after they see the intro?

Beware about this practice. Search engines could interpret this as Cloaking.

Cloaking is a black hat search engine optimization (SEO) technique in which the content presented to the search engine spider is different to that presented to the user's browser.

I'm not saying they are automatically going to know you're doing this, maybe they'll never will. But it's interesting to know the risks involved.

I would like to know your intents about this practice to know if there are other alternatives that fit your needs.

GmonC