Closed Thread Icon

Topic awaiting preservation: find the security flaw.... Pages that link to <a href="https://ozoneasylum.com/backlink?for=13059" title="Pages that link to Topic awaiting preservation: find the security flaw...." rel="nofollow" >Topic awaiting preservation: find the security flaw....\

 
Author Thread
norm
Paranoid (IV) Inmate

From: [s]underwater[/s] under-snow in Juneau
Insane since: Sep 2002

posted posted 02-21-2004 22:38

I'm making a remote authentication script that runs a PHP ldap look-up on my server. No one outside our network has access to the ldap server, so I'm making this application available to others by having them use clientside includes(hidden iframe/ilayer).

The hidden PHP script accepts username and password via Post from the parent document, then if they match the ldap info, assigns a 'True' value to its own form/hiddenfield element. Then the parent document can grab this value via Javascript and do whatever it needs to do.....

Anyone see any security risks/holes in this?

/* Sure, go ahead and code in your fancy IDE. Just remember: it's all fun and games until someone puts an $i out */

WarMage
Maniac (V) Mad Scientist

From: Rochester, New York, USA
Insane since: May 2000

posted posted 02-22-2004 02:47

Other than that I can simply look at the code and get the hidden form value, and from that create my own GET or even spoof a POST query? or the fact that web pages are cached to the harddisk, so any user could potentially see the result page with the included hidden form field?

Nope, I think it is safe.

-Dan-

norm
Paranoid (IV) Inmate

From: [s]underwater[/s] under-snow in Juneau
Insane since: Sep 2002

posted posted 02-22-2004 04:20

Thanks for the response....

I'm not quite dumb enough to pass anything confidential using Get. So this means the password & name will go TO the iframe/ilayer Post.

The php script contained in the iframe/ilayer does not send anything back. It just assigns a value to the hidden field in it's own HTML form, which I have not been able to see by 'view-source'.The iframe/ilayer also doesn't appear in the browser history, but I suppose that the information it contained in cache and viewable someway that I don't know of. But I should be able to prevent caching with http headers, which I would not have thought of doing if you had not brought this up.

I was puzzled by how to keep someone from looking to see what the "TRUE" value needs to be, after all they will be able to view the javascript on the parent document. So I thought that the javascript function should check for a change in the value of the iframe/ilayer hidden field and then Post it back to $_SERVER['PHP_SELF], where the client would be cookied and allowed access if approved or scolded sent away if not.

But then I guess someone could just tweak the javascript function to spit out my variable with an alert(), instead of submitting. But in order for the "True" value to be there in the first place, they would have to be an authenticated user....

Still being hack-able by registered users isn't appealing either, so back to the drawing board for me.

BTW-
as I have mentioned in this forum before, I'm not the sharpest crayon in the box. So if you want to be sure that I actually notice the sarcasm in a reply, you may want to use more than three sentences, just to be on the safe side.



/* Sure, go ahead and code in your fancy IDE. Just remember: it's all fun and games until someone puts an $i out */

WarMage
Maniac (V) Mad Scientist

From: Rochester, New York, USA
Insane since: May 2000

posted posted 02-22-2004 07:54

Real security is hard for something like a website.

A good way to do it is using session variables which are kept on the server, this way you can check and recheck the information from the session for everypage.

The next things you might want to do are to store the IP address of the user for the session. If the IP address's do not match then someone has hijacked the session. This isn't fool proof but it is good. Anything stored in HTML format can be broken, so it is really not a good idea to output any critical data to the HTML page.

One thing that you might want to send to the page if you want to keep things secure is a random password which you md5 encode. This password then needs to be kept by the server, away from the user's access (say a database table or a flat text file). For each page access you generate a different MD5 hash and send it to the page. When the page data is returned via a post you then take the password on the server send it through the MD5 function and then check it against the value that was returned. There is really no good way that a session can be hijacked easily using this method. The person who wishes to take control must know the temporary password, which they do not have access to.

The reason that I say not to have a piece of code for data validation saved in the HTML is because you can come across the following:

userA: does some meaningful secret work.
userB: logs in, and decides that he wants to mess with user A, user B check the HTML code and finds that she can get access to user A's data by sending the following url to the browser: secret.php?user=userA&secretValue=true and in this method bypassing your password check.

What I am presenting is pure speculation. I can not say that you idea is not secure because I can not see your code, but I can only present hypothetical methods of breaking the system.

For most users a simple password would suffice in keeping people out, but someone who really wants in might find a way given enough time especially if they have some knowledge.

-Dan-

Tyberius Prime
Paranoid (IV) Mad Scientist with Finglongers

From: Germany
Insane since: Sep 2001

posted posted 02-22-2004 10:31

authentication the user via setting 'a hidden form element that isn't in the source'/cookies/whatever is not secure. All I need is a half way decent http sniffer, and voila.
I use one regularly for difficult problems. It's called httplook, has a trial version, and works quite nice, though you require adminstrator privileges under windows.

Now, personally, for something close to your needs, I'd use Apache Basic Authentication (you know, the one that pops up the 'insert username/password' box in your browser (you could see http://ozoneasylum.com/stats for an example ('lunatic','asylum' is the combo there, I believe), plus SSL encryption. That way the password can not be spoofed, it can't be simply grabbed from the browser via some javascript trickery, can be done via a php script if you don't want to use .htaccess... you catch my drift.

so long,
Tyberius Prime

norm
Paranoid (IV) Inmate

From: [s]underwater[/s] under-snow in Juneau
Insane since: Sep 2002

posted posted 02-23-2004 03:03

The advice is much appreciated. The problem here stems from the fact that our LDAP sever will not accept connections from outside our local network.

My boss wants to set up another LDAP that has some of the info from the first and have me supply a few code samples on how outside vendors could access the new server. This is no problem, I will include a sample .htaccess file (that's the way I handle it for my internal sites) that checks LDAP, an example of how to use PHP's LDAP functions for a lookup, and the same functionality in .Net. My Java is not up to speed yet but I work with some pretty sharp Java coders, so I'll get an example of that too.

But I don't like the idea of setting up a second server when we already have one. Needless redundency. After all, it means spending money on hardware, someone to set it up and someone to maintain it. That money could be spent on much better things, like a raise for me or that 23 inch LCD display I need.... So I'm going to show them a way to do this without a second LDAP server.

After some more thought, and carefull consideration of the points you both brought up, I'm leaning towards doing this with sockets and leaving the browser out of the picture. Then the vendor's serverside program can do what it wants with the results. Besides, all my PHP programing so far has been the standard database and content management type stuff, so this will be a great opportunity to delve into the networking power of PHP.

Sockets are gonna be fun. I like 'em already.......

/* Sure, go ahead and code in your fancy IDE. Just remember: it's all fun and games until someone puts an $i out */

Tyberius Prime
Paranoid (IV) Mad Scientist with Finglongers

From: Germany
Insane since: Sep 2001

posted posted 02-23-2004 11:49

five things tyberius never wants to have to do:
number 1: PHP Socket Programing for a Server. Or any PHP program than needs to run longer than 2 minutes, actually.
(Python and twisted would be a much more powerful and easier choice in my opinion)

... tbc.

Tyberius Prime

trib
Paranoid (IV) Inmate

From: Den Haag, Netherlands
Insane since: Sep 2002

posted posted 03-03-2004 17:34

An interesting little alternative would be to write a pseudo_browser object in php to run server_side and do your authentication query as though it was a browser ... passing the login details in and getting the authentication back before the page is rendered ... I use that method to access read-only (public-domain) documents from within our document repository (password protected). You can even handle cookies, keeping them in an array between accesses if you like .. stops them being written to the users PC in the event of the sort of access I described above ....

I'm not proud of my recoding - it's often scruffy - but a quick read through will probably show you how it's done ... its actually a readically stripped-down version of Snoopy - a full PHP browser simulator which I didn't get to work - too complicated for what I wanted - but if you're interested in looking at the original its at http://sourceforge.net/projects/snoopy/

Here's the class file
<BLOCKQUOTE><FONT face="Verdana, Arial">code:</font><HR><pre><?php

class snooper
{

var $host = "target.host.name"; // host name we are connecting to
var $port = 80; // port we are connecting to
var $agent = "(compatible; MSIE 4.01; MSN 2.5; AOL 4.0; Windows 98)"; // agent we masquerade as
var $cookies = array(); // array of cookies to pass

// http accept types
var $results = ""; // where the content is put
var $response_code = ""; // response code returned from server
var $headers = array(); // headers returned from server sent here
var $maxlength = 2000000; // max return data length (body)
var $read_timeout = 0; // timeout on read operations, in seconds
// set to 0 to disallow timeouts
var $timed_out = false; // if a read operation timed out
var $status = 0; // http request status

/**** Private variables ****/
var $_maxlinelen = 4096; // max line length (headers)
var $_httpmethod = "GET"; // default http request method
var $_httpversion = "HTTP/1.0"; // default http request version
var $_fp_timeout = 30; // timeout for socket connection


/*======================================================================*\
Function: fetch
Purpose: the only public function
input: $URI - the uri to submit to the server
Output:
/*======================================================================*\

function fetch($URI) {
$fp = fsockopen($this->host, 80, $errno, $errstr, 0 );
$this->_httprequest($URI,$fp,$URI,"GET");
$this->_close($fp);
}

/*======================================================================*\
Function: _close
Purpose: tidy up before you go home
input: $fp - the current open file pointer
Output:
/*======================================================================*\

function _close($fp) {
fclose($fp);
}

/*======================================================================*\
Function: _httprequest
Purpose: go get the http data from the server
Input: $url - the url to fetch
$fp - the current open file pointer
$URI - the full URI
$body - body contents to send if any (POST)
Output:
\*======================================================================*/

function _httprequest($url,$fp,$URI,$http_method,$content_type="",$body="") {
$cookie_headers = "";
$URI_PARTS = parse_url($URI);
if(empty($url))
$url = "/";
$headers = $http_method." ".$url." ".$this->_httpversion."\r\n";
if(!empty($this->agent)) $headers .= "User-Agent: ".$this->agent."\r\n";
if(!empty($this->host)) $headers .= "Host: ".$this->host."\r\n";
if(!empty($this->cookies)) {
reset($this->cookies);
if ( count($this->cookies) > 0 ) {
$cookie_headers .= 'Cookie: ';
foreach ( $this->cookies as $cookieKey => $cookieVal ) {
$cookie_headers .= $cookieKey."=".urlencode($cookieVal)."; ";
}
$headers .= substr($cookie_headers,0,-2) . "\r\n";
}
}
if(!empty($content_type)) {
$headers .= "Content-type: $content_type";
$headers .= "\r\n";
}
$headers .= "\r\n";
// set the read timeout if needed
if ($this->read_timeout > 0) socket_set_timeout($fp, $this->read_timeout);

$this->timed_out = false;
fwrite($fp,$headers,strlen($headers));
unset($this->headers);
while($currentHeader = fgets($fp,$this->_maxlinelen)){
if ($this->read_timeout > 0 && $this->_check_timeout($fp)){
$this->status=-100;
return false;
}
if($currentHeader == "\r\n") break;
if(preg_match("

« BackwardsOnwards »

Show Forum Drop Down Menu