mschroeder 251 Bestower of Knowledge Team Colleague

For starters, Zend Guard is a product for encoding your php in opcode *I believe the term is opcode*, it has nothing to do with securing a form or validating logins.

Second, I'm going to make a big assumption here, and say that you're using javascript validation to verify that 95% of the form submissions *should* be valid prior to them getting to a PHP form processor which then AGAIN should verify the data that was submitted.

The reason this is key, is because i can just as easily create a form that mimics your form fields and posts the submission to your php script without ever passing through the javascript validation. This is the real problem with relying strictly on javascript.

Generally speaking these kinds of validations are best handled by regular expressions. Where when the user submits their username and it should be between 8 and 16 characters in length, and only contain upper and lower case letters and numbers, or whatever your specifications are.

You would use a php function like preg_match and then write a regular expression to match your requirements for example /([a-zA-Z0-9]{8,16})/ -- I didnt test this, but it should be valid.

Now onto the php

if (!preg_match( '/([a-zA-Z0-9]{8,16})/', $sUsername )) {
    echo 'Your username must contain only numbers and letters and be between 8 and 16 characters in length.';
}

Hopefully this gives your the basics of how this works.
There are a ton of different ways …

mschroeder 251 Bestower of Knowledge Team Colleague

indeed i believe that was referenced recently on slashdot, but I might be mistaken.

Some how though, I don't think "hacking my school's proxy server" falls into the national interest of science.

btw in case the op is still hanging around this thread, if your proxy is highly monitored, then what makes you think your network admin isn't noticing your 650 failed logins/second on their admin account?

mschroeder 251 Bestower of Knowledge Team Colleague

Or 62^8, or 218,340,105,584,896 possibilities...

Actually the math is 8^62 8 positions with 62 possibilities in each, special characters excluded 62 positions where each will only be 1 of 8 options yields significantly less possibilities.

Not to nitpick your math, because ultimately, our points were the same as the one you made, it would take to long to generate them all.

Funny side tangent, I was reading about security somewhere and there was a discussion on how frequently if ever a password should be changed and the usual answers showed up. Then someone pointed the thread to a url regarding where changing passwords originated from.

Turns out in the days of the first "super computers" some mathematicians determined if a "hacker" could have full access of the computer, every 30 days or so, they probability wise would generate a successful login attempt.

Hence they set forward to make users change their passwords every 30 days...

alright back on topic.

mschroeder 251 Bestower of Knowledge Team Colleague

php simply isn't meant for this kind of thing, regardless of its intention, albeit yours is a pretty useless one. On the basis of an 8 character password, where each letter can be 1 of 62 possibilities (a-zA-Z0-9) that is 9.807971461541689e+55 possibilities.

Good luck with that.

mschroeder 251 Bestower of Knowledge Team Colleague

just did a quick run of these on my local machine:

truehash_a() takes 0.00002598762512207 seconds to execute.
salthash_a() takes 0.000015020370483398 seconds to execute.
salthash_b() takes 0.000015974044799805 seconds to execute.
salthash_c() takes 0.000015974044799805 seconds to execute.
salthash_d() takes 0.000015974044799805 seconds to execute.
salthash_e() takes 0.00002598762512207 seconds to execute. (mschroeder's hasher)

**** These results are from php 5.3.0 the rest of the results will be from 5.2.8 installs

I did have to make one small change though:

function salthash_e($hashzzz) {
$sPossible = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()-+=[]{}|';
$iPossibleCount = strlen( $sPossible );

$sSalt = '';
for( $i=0; $i<10; $i++ )
{
$sSalt .= $sPossible[mt_rand(0, $iPossibleCount)];
}

$sHash = hash('whirlpool', $hashzzz . $sSalt);
}

the for loop wasn't getting a length to check against so i just hardcoded it to 10.
However I get the same results with the speedup when adding static salts. That is very unexpected. I'll post additional test results from other machines tomorrow.

mschroeder 251 Bestower of Knowledge Team Colleague

the thing with hashes, is that they SHOULD NOT be able to be reversed. If the intention was to reverse it then it would be encryption.

Generally when i read about weak hashes being cracked its because of a design flaw in the algorithm, which contains math way above my head. Or someone has created a lookup table of common dictionary words, which is where salting the hashed string comes into play because even common words and combinations are no longer common.

I'd also be curious to see some comparative benchmarks regarding hashing a string once using a randomly generated salt as i provided, where the cpu intensity will be in the salt generation vs using a static salt(s) and then double hashing the string or any of the other methods cwarn provided.

If someone posts their test code and results, i'd be happy to run them on a handful of drastically different servers and post those results as well.

mschroeder 251 Bestower of Knowledge Team Colleague

the registered number of algorithms will vary by system, although in my experience most of them are commonly available. As far as execution time, that would vary drastically depending on the type of hardware your site/system is hosted on.

I would suggest running a quick benchmark on the hash_algos() output.

<?php

$aAlgos = hash_algos();
$sStringToHash = 'This is a test string';
$sSaltString = 'This is the salt';

foreach( $aAlgos as $sAlgoName)
{
	echo 'Algorithm: ' . $sAlgoName . '<br />';
	
	$iStart = microtime(true); //Only valid with PHP5
	$sHashed = hash( $sAlgoName, $sStringToHash . $sSaltString );
	$iEnd = microtime(true);
	
	
	echo 'String Length: ' . strlen( $sHashed ) . '<br />';
	echo 'Hash: ' . $sHashed . '<br />';
	echo 'Total Hashing Time: ' . number_format( ($iEnd - $iStart), 8) . ' seconds';
	echo '<hr />';

}

It is crude but should give you a fairly accurate idea of how long its taking your system to run a single hash. I'm not certain if there are other factors that would skew this benchmark or not as I'm not familiar with the internals behind the hash() function.

nav33n commented: Thanks for the info! +10
mschroeder 251 Bestower of Knowledge Team Colleague

They're two different things that both have different purposes. as I indicated in my first post and as ShawnC again emphasized, encryption and hashing are two different things. You can't compare them on a security level.

mschroeder 251 Bestower of Knowledge Team Colleague

The hash function is a function that allows you to utilize numerous kinds of algorithms. if you run print_r(hash_algos()); it will give you an array of the hash algorithms available on your system. Whirlpool is just one type of hash, like MD5, SHA1 and CRN32

A salt is basically adding a random string(s) to whatever you are encrypting or hashing:

<?php

$sSalt = '8*S&AsEc4qUs';
$sHash = hash( 'whirlpool', $sString . $sSalt );

echo $sHash;

so if the user decided to make their password "password" the hashed password would actually be for the value of "password8*S&AsEc4qUs" which would prevent someone from using a hash lookup database as it ensures that the users password has some form of complexity to it. This is assuming that someone was looking at the actual hash stored in the database and not trying to forge logins from a from.

I *believe* phpBB3 uses the random salt for every password option i mentioned in my previous post. It would be something like this:

<?php

function getSalt( $iLength = 10 )
{
	$sPossible = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()-+=[]{}|';
	$iPossibleCount = strlen( $sPossible );
	
	$sSalt = '';
	for( $i=0; $i<$iLength; $i++ )
	{
		$sSalt .= $sPossible[mt_rand(0, $iPossibleCount)];
	}
	
	return $sSalt;
}

$sPassword  = 'password';
$sSalt = getSalt();

$sHash = hash('whirlpool', $sPassword . $sSalt );

//Store  $sHash and $sSalt in the database.

Although I imagine when you get into generating random salts, you are going to be just as comparable to double hashing the same string, in terms of cpu usage …

OmniX commented: Thankyou for the Informative Post +2
Will Gresham commented: Good info +1
Atli commented: Good post. +3
mschroeder 251 Bestower of Knowledge Team Colleague

hashing and encryption are two different things.
hashes like MD5, SHA1, Whirlpool etc. are one way. There *should* NOT be a way to reverse them.

Encryption however is two way. you can encrypt a string and when decrypted returns the same string.

For hashes I agree with cwarn in the use of whirlpool, but i would have to argue that salting the string to be hashed prior to running it through whirlpool, would be just as strong as double hashing the string, but would require less cpu work. You could also make it infinitely harder by generating a random salt for every password and then storing the salt along with the hashed string in the database.

If the op is interested in encryption I would suggest taking a look at this post in the php documentation using the mcrypt library. http://us2.php.net/manual/en/function.mcrypt-encrypt.php

There are also a few different mysql methods for dealing with encryption:
aes_encrypt/aes_decrypt
encode/decode
des_decrypt/des_encrypt

I've worked on projects where for example, passwords needed to be hashed to prevent their snooping by people with access to the database, and also where passwords needed to be encrypted so that support staff could view the password if the user had forgotten it, without having to reset it to a random string or a default password.

mschroeder 251 Bestower of Knowledge Team Colleague
<?php

$xYahooXML = '
<ysearchresponse responsecode="200">
	<prevpage> /ysearch/web/v1/sunflower%20seeds?appid=e4j0dGfIkY0.VnPaj_m8JivWDmAdWAV50uTRuIaqvA--&amp;format=xml&amp;count=1&amp;start=0 </prevpage>
	<nextpage> /ysearch/web/v1/sunflower%20seeds?appid=e4j0dGfIkY0.VnPaj_m8JivWDmAdWAV50uTRuIaqvA--&amp;format=xml&amp;count=1&amp;start=2 </nextpage>
	<resultset_web count="1" start="1" totalhits="376055" deephits="11600000">
		<result>
			<abstract> Home to the <b>seed</b> brand featuring products, nutrition facts, and more. </abstract>
			<clickurl> http://lrd.yahooapis.com/_ylc=X3oDMTRrYzhoc210BF9TAzIwMjMxNTI3MDIEYXBwaWQDZTRqMGRHZklrWTAuVm5QYWpfbThKaXZXRG1BZFdBVjUwdVRSdUlhcXZBLS0EcG9zAzEEc2VydmljZQNZU2VhcmNoV2ViBHNsawN0aXRsZQRzcmNwdmlkA2ZIUnh2RVBEQjJHQjIxOF9zZjhLc3dsa1RNTzJsa21qWS5FQUE2WkI-/SIG=10v00dabm/**http%3A//www.davidseeds.com/ </clickurl>
			<date>2008/12/12</date>
			<dispurl>www.<b>davidseeds.com</b></dispurl>
			<size>7122</size>
			<title>David <b>Sunflower</b> <b>Seeds</b></title>
			<url>http://www.davidseeds.com/</url>
		</result>
	</resultset_web>
</ysearchresponse>';

$oSimpleXML = new SimpleXMLElement( $xYahooXML );
echo $oSimpleXML->resultset_web->attributes()->totalhits;

First, I used SimpleXML as it is generally easier to parse this kind of xml with.

Second, I don't know if the DOM will complain about this, but to my knowledge for XML to be valid a node can not contain an html entity that is not in entity format aka & => &amp; Also, besides 5 entities quot, amp, apos, lt, gt any other element has to be numerically defined. http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
I had to change the &'s to &amp; in the url's in your code to get SimpleXML to not complain about it being invalid xml etc.

Let me know if you have any additional questions.

nav33n commented: nice info! +10
lonestar23 commented: Fast problem solver! Cheers! +1
mschroeder 251 Bestower of Knowledge Team Colleague

Why does the page value need to be passed in the url?
Will it always be the same as the hidden field view?

I ask because i see $_GET & $_POST being set to the same value.

Here is a quick example of moving the value of "page" to a hidden field and setting it and view to the value:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
	$('#go').submit( function() {
		var page = $('#where').val();
		alert(page);
		//Set view to value of where
		$('#view').val(page);
		//Set page to value of where
		$('#page').val(page);
	});
});
</script>
</head>
<body>
<!-- Added ID to the form for easier reference -->
<form name="go" id="go" action="post.php" method="post">
    <input type="hidden" name="action" value="view" />
    <input type="hidden" name="view" id="view" value="" />
    <input type="hidden" name="page" id="page" value="" />
    
    
    <!-- Added input field for illustrative purposes -->
    <input type="text" name="where" id="where" value="" />
    <!-- Added submit button for illustrative purposes -->
    <input name="submit" type="submit" value="Go!" />
</form>
</body>
</html>

I added a where field and a submit button to illustrate how the change happens and post.php in the action of the form, was simply print_r($_POST) Does this kind of workaround work?
BTW, this uses jQuery for the javscript library.

mschroeder 251 Bestower of Knowledge Team Colleague

Well, if you can execute commands against the server, you could try this:

GRANT ALL PRIVILEGES ON {database}.* TO '{username}'@'{ip address}' IDENTIFIED BY '{password}' WITH GRANT OPTION;

The options are pretty straight forward but just in case:

{database} = db name
{username} = login
{ip address} = YOUR ip address (http;//www.whatismyip.com) (Can use a % to indicate a wildcard aka 192.168.1.%)
{password} = the password

If that doesn't work it can also be achieved by using an INSERT if the user you are connecting to the server with has the appropriate permissions. Its all in the mysql docs with examples and such. Its a long shot but it might get you somewhere.

mschroeder 251 Bestower of Knowledge Team Colleague

If the server is configured to allow access from the outside world, then just use the ip of the machine to connect to it.

At least in terms of cPanel you need to add external hosts to the permissions for connections outside of localhost.
I *believe* DirectAdmin was/is the same way.

diafol commented: Thanks for the help - above and beyond the call of duty +3
mschroeder 251 Bestower of Knowledge Team Colleague

Glad to be of assistance. Please mark the thread as solved if we've resolved your issue

mschroeder 251 Bestower of Knowledge Team Colleague
<td width=""><p><?php echo nl2br(wordwrap($message, 75, PHP_EOL, true)); ?></p></td>

The wordwrap function breaks your content down with PHP_EOL which is a constant that is defined to match the proper end of line charachter for your operating system.

Then uses nl2br to convert them to <br>'s including any ones the user entered.

the only thing i caution is against using the last parameter of "true" as this will allow php to cut words in half instead of breaking at the nearest word break

mschroeder 251 Bestower of Knowledge Team Colleague

You could use the wordwrap function and break the string at however long you would like.

Although there are some shortcomings, as it will treat Mr. Smith as two words and would break between the prefix and last name. I also do not believe it to be utf-8 capable, but there are some good examples on the manual page on php.net.

I've also seen some functions in the past that alleviate the breaking between parts of a name (prefix and suffix) etc, just cant think of one at the moment.

mschroeder 251 Bestower of Knowledge Team Colleague

if you mean when typing in the textarea the text just continues on one long line, add wrap="physical" to the textarea markup. <textarea name="" cols="" rows="" wrap="physical" class="" id=""></textarea> This will make the textarea wrap at word breaks [spaces] that are close to the end of the line. If it is one large line of non broken text then it will cause the text area to scroll horizontally.

mschroeder 251 Bestower of Knowledge Team Colleague

Could you post an export of your table structure?

mschroeder 251 Bestower of Knowledge Team Colleague

You're positive you have a column named status in your table?

mschroeder 251 Bestower of Knowledge Team Colleague
$query = 'INSERT INTO user_notifications (`username`, `status` ) VALUES ("'.$username.'", "new to the site!" )';

mysql_query( $query ) or die( mysql_error() );

That is how I would handle the query, although the column names are not reserved words so they really dont need the backticks around them.

Here is the list of mysql 5.0 reserved keywords

mschroeder 251 Bestower of Knowledge Team Colleague

Try this example out. This uses jQuery to grab the css properties you want. Even on elements that do not have inline styles.

This is what matters, it serves the jquery library from googles cdn, but this could be from a local copy too. jQuery CSS Documentation
Sends two alerts to the browser the first with the padding-left value and the second with the margin-left value.

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
   alert( $("#someTable").css('padding-left') );
   alert( $("#someTable").css('margin-left') );
 });
</script>

This is the full example, but i gave my table and id of "someTable"
You could use whatever you wanted.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
   alert( $("#someTable").css('padding-left') );
   alert( $("#someTable").css('margin-left') );
 });
</script>
<style>
table {
	padding-left: 10px;
	margin-left: 50px;
}
</style>
</head>

<body>
<table width="200" border="0" cellpadding="2" id="someTable" >
  <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
</table>
</body>
</html>
mschroeder 251 Bestower of Knowledge Team Colleague

Check out PHPMailer or Swift Mailer.
I prefer the prior, but u simply set the FROM address(es) or name(s), REPLY-TO etc...

Then when the user receives the email it looks like it came from whatever email or user you have specified.

Both libraries make sending complex emails a lot easier too.

http://www.swiftmailer.org/
http://phpmailer.codeworxtech.com/index.php?pg=examples

mschroeder 251 Bestower of Knowledge Team Colleague

Excellent glad i could be of assistance.
Don't forget to mark the thread as solved.

mschroeder 251 Bestower of Knowledge Team Colleague

What you're describing sounds like you're looking for something like the __call() magic method

mschroeder 251 Bestower of Knowledge Team Colleague

Lets see if i understand what you're trying to attempt.

You have a physical xml file somewhere on your server, we'll call it file.xml and you have a php form. That should load the contents of file.xml and allow the user to add/subtract from it, and then a save button that takes whats in the text box and then overwrites the file?

For starters the editing part does not require you to parse the xml.
user file_get_contents('file.xml') to load the contents of the file into a variable and into the textarea, or use something like this:

$handle = @fopen("/tmp/inputfile.txt", "r");
if ($handle) {
    while (!feof($handle)) {
        $buffer = fgets($handle, 4096);
        echo $buffer;
    }
    fclose($handle);
}

That code will read the file line by line and only display one line at a time until it has reached the end of the file. It's much more efficient if you're trying to display a large file then loading the entire file into memory with file_get_contents and then displaying it.

When you go to save it, you dont need to convert the newlines to <br> in the xml. If the xml looks correct in the textarea it will save just like that into the text file. Now, if the content in your xml has <br /> tags thats a different story, as to be valid XML that node would need to be enclosed in a CDATA structure or would need the < & >'s encoded.

Displaying text from the …

mschroeder 251 Bestower of Knowledge Team Colleague

in your parameter_check function
$_SESSION[] = $error_list;

mschroeder 251 Bestower of Knowledge Team Colleague

that is because in the mysql_data_check function you are doing this:

$_SESSION[] = &$error_list;

which i believe is setting and entry of $_SESSION equal to an array. you don't need the []'s there

Produces:

$_SESSION = array(
1 => array (
1=> 'Error #1';
),
2 => array (
1 => 'Error #1',
2 => 'Error #2'
)
);

The only place you need the []'s is when you do $_SESSION[] = $error_data; This way you end up with one array that contains each error message.

Produces:
$_SESSION = array (
1 => 'Error #1',
2 => 'Error #2'
);

mschroeder 251 Bestower of Knowledge Team Colleague

I wasn't sure what you were doing on line 101 I assumed you were basically looking to see if there was an error and if so you were redirecting to page1 to handle the errors.

In which case you would want to do something like if (!empty( $_SESSION )){ //redirect code }

if you do a print_r($_SESSION); what is the structure that is being returned.

mschroeder 251 Bestower of Knowledge Team Colleague

in you functions you add string data to $_SESSION instead of actually making $_SESSION an array of multiple errors.

Then when you call foreach it is not finding an array because one does not exist.

Try adding [] after each place where you add error data to the error_list session value. This will create a numerically indexed array of multiple errors. $_SESSION[] = $error_data;

mschroeder 251 Bestower of Knowledge Team Colleague

I would generally caution against fckEditor for its lack of MS-Word support. Other than that it runs pretty neck and neck with tinyMCE.

tinyMCE however has a wonderful paste from word feature that really does an excellent job of stripping all of the crap markup from the input. If you know you won't be taking input from a user who writes first in word than either one should perform exceptionally.