need help with PHP (and preventing XSS vuln)
I'm new to programming and decided to make a simple Cryptogram decrypter for learning purposes. I'm stuck on part of it though and was wondering if you guys could give me any suggestions.
The part I'm stuck on is "<?php echo strtr ( $cipherString, $input1, $input2 ); ?>"
I want it to also say something like "but if $input2 equals a character in $cipherString, do not echo strtr ( $cipherString, $input1, $input2 );
<?php $cipherString = $_POST['string']; $input1 = $_POST['input1']; $input2 = $_POST['input2']; ?> <form action="phpcryptogram.php" method="post"> Cipher text: (Example: CND FZJNDV JTPPLHVM ZP MVHJ)<br> <input type="text" name="string" id="string" style="width: 100%;" value="<?php echo strtr ( $cipherString, $input1, $input2 ); ?>" /> <p></p> Change character:<br> From: <input type="text" name="input1" maxlength="1" style="width: 10%;" /> To: <input type="text" name="input2" maxlength="1"style="width: 10%;" /> <p></p> <input type="submit" name="submitEntry" value="Submit" /> <p></p> <?php if ( strpbrk( $input1, $cipherString ) ) { echo "Character " . $input1 . " has been changed to " . $input2 . "."; } ?>
"Are you wanting to make it so that if any character in $input2 matches any character in $cipherString, don't print?" exactly
oops about the XSS vuln. lol Mind giving me any info on how I can exploit my own vuln?
thanks for any help
After googling…
So I should probably use input filtering? such as….
$clean = array();
if (ctype_alnum($_POST['input1'])) { $clean['input1'] = $_POST['input1']; }
and do the same with $cipherString and $input2?
and also escape output…
$html = array();
$html['input1'] = htmlentities($input1, ENT_QUOTES, 'UTF-8');
I'm really new to this :D
prox wrote: "Are you wanting to make it so that if any character in $input2 matches any character in $cipherString, don't print?" exactly
An easy way to do this would be to use str_split to break $input2 into an array of characters, then use a foreach loop to iterate through them and use strpos to check for each character in $cipherString. If strpos returns anything other than False during the foreach loop, don't print the string.
If that's complicated, I can write some code that might show it better to you.
oops about the XSS vuln. lol Mind giving me any info on how I can exploit my own vuln?
If you enter something like this:
markup"> <script type="text/javascript">alert("XSS");</script> <br
into the "Cipher text" field, and leave the other two fields blank, it will trigger an XSS exploit under the viewers browser (unless it's Chrome).
So I should probably use input filtering? such as….
$clean = array();
if (ctype_alnum($_POST['input1'])) { $clean['input1'] = $_POST['input1']; }
and do the same with $cipherString and $input2?
and also escape output…
$html = array();
$html['input1'] = htmlentities($input1, ENT_QUOTES, 'UTF-8');
I'm really new to this :D
ctype_alnum isn't really necessary, htmlentities itself will solve the problem and protect you from XSS.
http://php.net/manual/en/function.str-split.php
Code from example:
$str = "Hello Friend";
$arr1 = str_split($str);
$arr2 = str_split($str, 3);
print_r($arr1);
print_r($arr2);
?>
Result:
Array ( [0] => H [1] => e [2] => l [3] => l [4] => o [5] => [6] => F [7] => r [8] => i [9] => e [10] => n [11] => d )
Array ( [0] => Hel [1] => lo [2] => Fri [3] => end )
Thanks for the help guys. While reading about str_split and strpos today, I ran across strtok which seems easier. I don't have to set up an array. Any reason str_split and strpos would have an advantage over strtok?
Here is my code now…
<?php $cipherString = $_POST['string']; $input1 = $_POST['input1']; $input2 = $_POST['input2']; ?> <form action="phpcryptogram.php" method="post"> Cipher text: (Example: CND FZJNDV JTPPLHVM ZP MVHJ)<br> <input type="text" name="string" id="string" style="width: 100%;" value="<?php if ( strtok( $input2, $cipherString ) === $input2 ) { echo strtr ( $cipherString, $input1, $input2 ); } else { echo $cipherString; } ?>" /> <p></p> Change character:<br> From: <input type="text" name="input1" maxlength="1" style="width: 10%;" /> To: <input type="text" name="input2" maxlength="1"style="width: 10%;" /> <p></p> <input type="submit" name="submitEntry" value="Submit" /> <p></p> <?php if ( strtok( $input2, $cipherString ) === $input2 ) { echo "Character " . $input1 . " has been changed to " . $input2 . "."; } else { echo " "; } ?>
Here is what it looks like so far… http://i.imgur.com/nx0fH.jpg
Now for setting escape output… example:
$html['cipherString'] = htmlentities($input1, ENT_QUOTES, 'UTF-8');```
I'm still confused about this. Should I do this for all three variables? (cipherString, input1, and input2)
If so, can I do something like...
$html['cipherString', 'input1', 'input2'] ?
Can someone give me an example of the best way to go about securing the XSS vuln?
Sorry if this is stupid, this is the first program I have written.
markuphtmlentities($input1, ENT_QUOTES, 'UTF-8');
It isn't necessary to specify ENT_QUOTES, unless you have a specific reason to want that special behaviour. The encoding specification is not necessary either, unless you also happen to need that.
Also, you could set the entire array easily like this:
$html = array( 'input1' => htmlentities($_POST['input1']),
'input2' => htmlentities($_POST['input2']),
'cipherString' => htmlentities($_POST['string']) );
That would set every value into $html, filtered, in one step.
For strtok, that is typically not how the function is meant to be used, but irregardless it is a pretty clever method and it should work.
Also, for more information on preventing XSS:
https://www.owasp.org/index.php/XSS_%28Cross_Site_**S**cripting%29_Prevention_Cheat_Sheet
Looking forward to HBH Redux - hopefully links will work properly then.