in_array not working

I am currently writing an email form with PHP and this is the first time I have attempted to write all the security necessary to keep it from being used for not intended purposes.

Currently, I am having an issue with trying to verify whether or not a value is in an array called $tokens using the in_array command.

I have verified that the string $_POST[‘token’] is in the array, but it always drops down and executes the statements under else instead of sending out the email.

I am not sure what I am missing…

Here is the code:


<?php
$tokens = file('./tokens.txt');
if (in_array($_POST['token'], $tokens))
	{
		$name = $_POST['name'];
		if (!preg_match("/^[a-zA-Z]+(\\s+)?$/", $name)) //verify $name contains only letters and spaces
			{
				echo htmlspecialchars('Name field is invalid, letters and spaces only please correct and re-submit.');
				exit();
			}
		$email = $_POST['email'];
		if (!preg_match('/^[^@]+@[a-zA-Z0-9._-]+\\.[a-zA-Z]+$/', $email)) //verifies that $email syntax is correct
			{
				echo htmlspecialchars('Email field is invalid, please correct and re-submit.');
				exit();
			}							
		$reason = $_POST['reason'];
		if (!preg_match("/[A-Z|a-z]/", $reason)) //verfies that $reason contains only letters
			{
				echo htmlspecialchars('Reason field is invalid, letters only please correct and re-submit.');
				exit();
			}			
		$comment = $_POST['comment'];
		$comment = strip_tags($comment, ENT_QUOTES); //strips out all html tags
		$comment = wordwrap($comment, 70, "\\r\
"); ///wraps text to new line after seventy characters
		$headers = "Reply-To: $email" . "\\r\
" . "Reason: $reason" . "\\r\
" . "$comment"; //defines headers to be passed to browser
		mail( "name@doamain.com", "A Message has been received", "$headers"); //sends out the email 
	}
else  //executed if  $_POST['token'] is not in the array $tokens
	{
		echo htmlspecialchars("Invalid Submission Method", ENT_QUOTES, 'utf-8');
	}
?>

and here is the form code if needed


<?php
$token = md5(time());

$fp = fopen('./tokens.txt', 'a');
	  fwrite($fp, "$token\
");
	  fclose($fp);	  
?>

All fields are required<BR/>
<form action="secure.php" method="post">
<input type="hidden" name="token" id="token" value="<?php echo $token; ?>" />
	<TABLE>
		<TR>
    		<TD><label for="name">Name:</label></TD><TD></TD>
    		<TD><input type="text" name="name" id="name" /><br/><br/></TD>
    	</TR>
   		<TR>
 	   		<TD><label for="email">Email Address:</label></TD><TD></TD>
 	    	<TD><input type="text" name="email" id="email" /><br/><br/></TD>
 		</TR>
	 	<TR>
 	    	<TD><label for="reaason">Reason for Contact:</label></TD><TD></TD>
        	<TD><select name="reason" id="reason" size="1">
				  	<option value="Default">Please Choose</option>
  	 			  	<option value="comment">Comment</option>
       			  	<option value="Prayer Request">Prayer Request</option>
          		  	<option value="question">Question</option>
		  			<option value="other">Other</option>
  		    	</select><br/><br/>
        	</TD>
    	</TR>
	    <TR>
        	<TD> <label for="comment">Enter Message Below:</label></TD><TD></TD><TD></TD>
    	</TR>
	</TABLE>
	<TABLE>
	     <TR>
   	    	 <TD><textarea cols="50" rows="4" name="comment" id="comment"></textarea></TD><TD></TD>
    	 </TR>
	     <TR>
   	    	 <TD><input type="submit" value="Send" id="submit"/></TD>
    	 </TR>    
	</TABLE>
</form>

Thanks in advance for any help

Plus if anyone notices any security issues that I have missed that would be worthwhile to address… That is appreciated as well

Quite alright, can’t quite see what I did, but if var_dump() helped shine a light into why the strings needed trimming then I’m gratified it helped.

By default, file’s lines will include the line break (in your case \r
) at the end of each line: this is documented behaviour, maybe you skipped over it when reading the docs (you did read the docs, right?).

If you file to ignore those line breaks then you can feed a special flag to file instructing it to do so, rather than using trim on each line manually.

$tokens = file('./tokens.txt', FILE_IGNORE_NEW_LINES);

I didn’t think about using var dump until you suggested it. Once I saw that the array had 2 characters more than the string. I figured it had to be the extra spaces.

Got it fixed… Thank You Cups for your help. I imploded the array $tokens and then trimmed the whitespace characters from the ends and then compared the two strings.

Thanks again Cups.

post a couple of line from tokens.txt

The only thing that is stored in the tokens file is the randomly generated hash that is used for comparison purposes.

Here is an example

0a2739a353d252a5ec745c12ef44f851

so a different hash on separate lines, thats what I’m getting after, or are they separated by a character, or are they in a php array already?

string(32) “7800c9cc033ee76932289aca0a675423” array(1) { [0]=> string(34) "0a2739a353d252a5ec745c12ef44f851 " }

Hmm… so what does this give you?

$tokens = file('./tokens.txt');
if (in_array($_POST['token'], $tokens)){
echo 'success' ;
}else{
var_dump( $_POST['token'])'
var_dump( $tokens );
}

I went ahead and outputted the variable and the array…

1c4b6c76e6be3728fc3d5c72b5bcf209
Array ( [0] => 1c4b6c76e6be3728fc3d5c72b5bcf209 )

It’s just one per line, no special characters…

Here are a couple of more lines from it

0a2739a353d252a5ec745c12ef44f851
2daa0ca4c2255b3791256ed62608fbdd
57151bc9fc59eb5d7ef0dfe658c5a8c3