Hello All,
I am working on using Yahoo Browser Based Authentication into a website. The actual concept is actually fairly simple:
http://developer.yahoo.com/auth/
Here is the code from the entry page (where the user logs in using their Yahoo ID):
<?php
define("APPID", 'Some App Key');
define("SECRET", 'Some Secret Password');
// Include the proper class file
$v = phpversion();
if ($v[0] == '4') {
include("ybrowserauth.class.php4.php");
} elseif ($v[0] == '5') {
include("ybrowserauth.class.php5.php");
} else {
die('Error: could not find the bbauth PHP class file.');
}
function CreateContent() {
$authObj = new YBrowserAuth(APPID, SECRET);
// If Yahoo! isn't sending the token, then we aren't coming back from an
// authentication attempt
if (empty($_GET["token"])) {
// You can send some data along with the authentication request
// In this case, the data is the string 'some_application_data'
echo 'You have not signed on using BBauth yet<br /><br />';
echo '<a href="'.$authObj->getAuthURL('some_application_data', true).'">Click here to authorize</a>';
return;
}
// Validate the sig
if ($authObj->validate_sig()) {
echo '<h2>BBauth authentication Successful</h2>';
echo '<h3>The user hash is: '.$authObj->userhash.'</h3>';
echo '<b>appdata value is:</b> '. $authObj->appdata . '<br />';
} else {
die('<h1>BBauth authentication Failed</h1> Possible error msg is in $sig_validation_error:<br />'. $authObj->sig_validation_error);
}
return;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "[url]http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd[/url]">
<html xmlns="[url]http://www.w3.org/1999/xhtml[/url]">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="look">
<h2>Test BBauth </h2>
<div>
<?php CreateContent(); ?>
</div>
<div id="content">
</div>
</div>
</body>
</html>
And here is the code for the landing page on your site (where the user ends up AFTER they successfully log into yahoo using their username and password):
<?php
$output = array();
$appid = "Some App ID"; // my application ID, obtained at registration
$token = $_GET['token']; // the user's token, obtained at user login
$ts = $_GET['ts']; // seconds since Jan 1, 1970 GMT
$secret = "Some Secret Pass"; // my shared secret, obtained at registration
$sig = md5( "/WSLogin/V1/wspwtoken_login?appid=$appid&token=$token&ts=$ts" . "$secret" );
$url = "[url]https://api.login.yahoo.com/WSLogin/V1/wspwtoken_login?appid=$appid&token=$token&ts=$ts&sig=$sig[/url]";
function get_credentials( $url ) {
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
$store = curl_exec( $ch );
$xml = curl_exec( $ch );
if ( preg_match( "/(Y=.*)/", $xml, $match_array ) == 1 ) {
$COOKIE = $match_array[1];
}
if ( preg_match( "/<WSSID>(.+)<\/WSSID>/", $xml, $match_array ) == 1 ) {
$WSSID = $match_array[1];
}
if ( preg_match( "/<Timeout>(.+)<\/Timeout>/", $xml, $match_array ) == 1 ) {
$timeout = $match_array[1];
}
$rv = array();
$rv["COOKIE"] = $COOKIE;
$rv["WSSID"] = $WSSID;
$rv["timeout"] = $timeout;
$rv["XML"] = $xml;
return $rv;
}
// Use CURL to get response from Yahoo in XML Format and Parse the results -------------------------------------------------------------
$output = get_credentials($url);
echo "Login Results:<BR>";
echo "WSSID: ".$output["WSSID"]."<BR>";
echo "Timeout: ".$output["timeout"]."<BR>";
?>
The above code works well IF the user first goes to the "welcome" page, logs in using Yahoo and gets redirected to the "success" page on your site.
The issue though is that if a malicious user goes to the success page directly and simply enters the AppID correctly (which can easily be found from the welcome page, since the initial login passes it to Yahoo in URL as parameters), the response ALWAYS comes back as Successful!
Of course I didn't set the "some_application_data" parameter in the initial call to yahoo. But even if you do specify it, it is still passed as a parameter to yahoo, so it can easily be obtained.
It CAN NOT be this easy to bypass! I am almost positive I am missing a point here, so I would appreciate any feedback on the above.
Thanks,
Pete