Trying to break the PHP script which processes $_POST form data - php

I can't find any explicit information on this.
I have an HTML5 form...
which outputs to an external PHP script
which saves the variables output by the form as $_SESSION variables
which are then passed on to another page
which displays them
I've not (yet) escaped any of the data from any of the form fields.
Yet, when I enter a ' or a " or a & into the <textarea> of the form, everything continues working smoothly and nothing breaks.
I'm just as happy that it doesn't (since I want my form processing to be as robust as possible), but why doesn't it?
Is there some behind-the-scenes automatic escaping going on that I don't know about?
I am keen to find out if there is an authoritative source which explains what is going on.
The Form Page (HTML5):
<form class="contactform" method="post" action="/form-processing.php">
<fieldset>
<legend>Please Enter your Contact Details</legend>
<ul>
<li><label for="contactName">Contact Name:</label><input type="text" id="contactName" name="contactName" placeholder="Your Full Name" required /></li>
<li><label for="company">Company:</label><input type="text" id="company" name="company" placeholder="Your Company" required /></li>
<li><label for="telephone">Telephone:</label><input type="tel" id="telephone" name="telephone" placeholder="Your Work Telephone" required /></li>
<li><label for="email">Email:</label><input type="email" id="email" name="email" placeholder="Your Work Email" required /></li>
<li><label for="message">Message:</label>
<textarea id="message" name="message" placeholder="Write your message here..." required></textarea></li>
</ul>
</fieldset>
<input type="submit" value="Send your message" />
</form>
The Form Processing Page (PHP)
$Contact_Name = $_POST['contactName'];
$Company = $_POST['company'];
$Telephone = $_POST['telephone'];
$Email = $_POST['email'];
$Message = $_POST['message'];
if (($Contact_Name != '') && ($Company != '') && ($Telephone != '') && ($Email != '') && ($Message != '')) {
[...SCRIPT HERE...]
session_start();
$_SESSION['contactName'] = $Contact_Name;
$_SESSION['company'] = $Company;
$_SESSION['telephone'] = $Telephone;
$_SESSION['email'] = $Email;
$_SESSION['message'] = $Message;
header('Location: http://'.$_SERVER['HTTP_HOST'].'/confirmation-page.php');
}
The Confirmation Page (PHP)
if ((isset($_SESSION['contactName'])) && (isset($_SESSION['company'])) && (isset($_SESSION['telephone'])) && (isset($_SESSION['email'])) && (isset($_SESSION['message']))) {
$Contact_Name = $_SESSION['contactName'];
$Company = $_SESSION['company'];
$Telephone = $_SESSION['telephone'];
$Email = $_SESSION['email'];
$Message = $_SESSION['message'];
echo '<p>Your message has been sent.</p>
<dl>
<dt>Contact Name:</dt>
<dd>'.$Contact_Name.'</dd>
<dt>Company:</dt>
<dd>'.$Company.'<dd>
<dt>Telephone:</dt>
<dd>'.$Telephone.'<dd>
<dt>Email:</dt>
<dd>'.$Email.'</dd>
</dl>
<p>Message:</p>
<pre>'.$Message.'</pre>
<p>Thank you for your message.</p>
<p>We will be in touch.</p>';
I would have expected ' to break the PHP script the form data is passed to... but it doesn't. Any idea why not? I thought that's how XSS attacks were supposed to work?

my comments in answer form:
20 years ago the & and " (rather than & and ") may have broken some browsers when rendering the html, but nowadays they're able to handle it OK (& & " are correct though).
PHP variables may contain any arbitrary string (binary data even).. there's no issue with a var containing ' or ".
When assigning values pragmatically, they need escaped:
$myVar = 'sha\'zam!'; // ' needs escaped as the string is enclosed with '
$myVar = "dblquote -> \"!" // " needs escaped as the string is enclosed with "
As you're not doing any database stuff, there's nothing to "break" on the server side, but since you're not sanitizing stuff.... enter some values like
</form> or
<script>alert('shazam!')</script>
This is how an attacker could end up getting session id (of victim) or other sensitive information.

Related

Php save data to .csv and then redirect

Like the title says, I am trying to make a php script that saves the data to a csv then redirects them to another url on my site. All that is happening is when I hit the submit button I get an error on saying it cannot handle the request.
This is my form
<form action="submit.php" method="post">
<h1 style="text-align: center;">Register</h1><br>
<fieldset>
<legend>Your registration info</legend>
<label for="name">Name:</label>
<input type="text" id="name" name="user_name" required="">
<label for="mail">Email:</label>
<input type="email" id="mail" name="user_email" required="">
<label for="phone">Phone:</label>
<input type="phone" id="phone" name="phone">
<label for="guest">Guest or Spouse:</label>
<input type="text" id="gsname" name="gsname">
<label>Date Attending:</label>
<input type="radio" id="tuesday" value="tuesday" name="date"><label
for="tuesday" class="light">Tuesday, May #, 2018 10 AM - 11:30 AM</label>
<br>
<input type="radio" id="thursday" value="thursday" name="date"><label
for="thursday" class="light">Thursday, May #, 2018 10 AM - 11:30 AM</label>
</fieldset>
<button type="submit" name="submit">Register Now</button>
</form>
This is my php script.
if (isset($_POST['submit'])){
// Fetching variables of the form which travels in URL
$name = $_POST['user_name'];
$email = $_POST['user_email'];
$phone = $_POST['phone'];
$gsname = $_POST['gsname'];
$date = $POST['date'];
$open = fopen("formdata.csv", "a");
$csvData = $name. "," $email. "," $phone. "," $gsname. "," $date. "n";
fwrite($open,$csvData)
fclose($open)
#if($name !=''&& $email !=''&& $phone !=''&& $gsname
// To redirect form on a particular page
header("Location:https://www.google.com/");
}
else (
header("Location:https://www.charter.com");
)
?>
Can anyone give me an idea where I am messing up? I know data validation is important, but if I am using it on the form itself, do I need to validate it here?
A few things that I would try:
Fix the typo $date = $_POST['date'];
Fix the string concatenation $name . "," . $email . "," . $phone . "," . $gsname . "," . $date . "\n";
Check to make sure your script is receiving the POST request. If not double check the path on the form action attribute.
Double check the directory in which you are attempting to create/write formdata.csv is writable. I would suggest using fputcsv() as well.
Although it's not mandatory, it's highly recommended that you do server-side validation. Never assume the data you are receiving is the way you want it.

Passing PHP variable data onto another page after validation

While I found something similar to this question on here it didn't answer my question outright.
I have set up this php script to validate the form data, which works, after its validated I want it to then pass the info onto another script page to let the user then verify their input data and then mail the data. Its at this state that I'm having trouble. I've spent the last few days trying to find a solution to this and unfortunately coming up short.
<?php
$name_error = '';
$email_error = '';
$comments_error = '';
$error = false;
if (!empty($_POST['submitted']))
{ //if submitted, the validate.
$name = trim($_POST['name']);
if (empty($name))
{
$name_error='Name is required';
$error = true;
}
$email = trim($_POST['email']);
/* If e-mail is not valid show error message */
if (!preg_match("/([\w\-]+\#[\w\-]+\.[\w\-]+)/", $email))
{
$email_error='E-mail address not valid';
$error = true;
}
$comments = trim($_POST['comments']);
if (empty($comments))
{
$comments_error='Comments are required';
$error = true;
}
if ($error == false)
{
$name_send = $name;
$email_send = $email;
$comments_send = $comments;
/* Redirect visitor to the thank you page */
header('Location: /mail.php');
exit();
}
}
The form this is attached to:
<form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']);?>" method="post">
<label>Your Name</label><br />
<input type="text" name="name" style="width:95%" class="text" value='<?php echo htmlentities($name) ?>' />
<br/>
<span class='error'><?php echo $name_error ?></span>
<br />
<label>Email</label><br />
<input type="email" name="email" style="width:95%" class="text" value='<?php echo htmlentities($email) ?>' />
<br/>
<span class='error'><?php echo $email_error ?></span>
<br />
<label for="comments" style="font-size:16px;">Feedback Comments</label><br />
<textarea name="comments" style="width:95%;" rows="8" value='<?php echo htmlentities($comments) ?>'></textarea>
<br />
<span class='error'><?php echo $comments_error ?></span>
<br />
<input type="checkbox" name="allowCommentPublish" checked="checked" />
<label for="allowCommentPublish" style="font-size:10px;">Allow these comments to be used on our website</label>
<fieldset class="optional">
<h2>[ OPTIONAL ]</h2>
<label>Company Name</label><br />
<input type="text" name="companyName" style="width:95%" class="text" />
<br/>
<label>Phone</label><br />
<input type="text" name="phone" style="width:95%" class="text" /><br/>
<div style="margin:5px 0px;">
<input type="checkbox" name="incmarketing" />
<label style="font-size:10px;"> Yes, you can email me specials and promotions.</label>
<br/>
</div>
</fieldset>
<fieldset>
<input type="submit" name="submitted" value="Send" />
</fieldset>
I will point out im focusing on the main data inputs: Name E-mail and comments.
I need the info from this form to be sent onward but i dont know exactly how to do this and any help will be appreciated greatly.
For passing the values to next page you will have to use either of the three methods.
1. Set cookies with the data.
2. Use global variable session.
3.Pass the data in the url.
For cookies u can set cookies with the values like
setcookie('name',$name);
in ur next page read those cookie data
For sessions:
$_SESSION['name']= $name;
for reading data from cookies & session:
$name = $_COOKIE['name'];
$name = $_SESSION['name'];
For using sessions you must add the line
session_start();
at the start of both the pages that send or receive(use) the data
and for urls
header('Location: /mail.php?name=$name&email=$email&comment=$comments');
Read more on using session
If you need to pass values from one script to another you can use $_SESSION variables. To start a session use: (at the top of the php script)
session_start();
$_SESSION['somename'] = $somevariable;
To access or get that same variable you can use this:
session_start();
$some_other_variable = $_SESSION['somename'];
or you can use hidden input fields.
You can use hidden fields and javascript to submit the form. However as this is the same php page as the original form you will need an if statement
echo '<form name="newForm" action="newpage.php" method="POST">';
echo '<input type="hidden" name="name2" value"' . $name . '">;
echo '<input type="hidden" name="email2" value"' . $email . '">;
echo '<input type="hidden" name="comments2" value"' . $comments . '"></form>;
echo '<script> if (document.getElementById("name2").value != ""){window.onload = function(){ window.document.newForm.submit(); }} </script>';

How to validate form [duplicate]

This question already has an answer here:
How to validate form in php
(1 answer)
Closed 8 years ago.
Anyone please help me on how to validate a form? I have the code, it is working ok..but I found that after I hit the submit button & php shows the errors, there is an input field, asking the user to answer the math Ques..when I enter the answer, then hit submit button again, it just says mail successfully sent, but other fields are still empty. Any ideas how to fix it. Also, the php value in the answerbox input tags, is not saving the text in box, it disappears. by the way, I got some help from other users, i'm a noob in php, so if you don't mind please explain.
Thanks for your time!
<form name="contact" action="formtest.php" method="post">
<label for="YourName">Your Name:</label>
<input type="text" name="name" class="required" value="<?= isset($_POST['name']) ? $_POST['name'] : '' ?>" />
<label for="YourEmail">Your Email:</label>
<input type="text" name="email" class="required" value="<?= isset($_POST['email']) ? $_POST['email'] : '' ?>"/>
<label for="Subject">Subject:</label>
<input type="text" name="subject" class="required" value="<?= isset($_POST['subject']) ? $_POST['subject'] : '' ?>" />
<label for="YourMessage">Your Message:</label>
<textarea name="message" class="required"><?= isset($_POST['message']) ? $_POST['message'] : '' ?></textarea>
<p class="c3">10 + 5 =<input type="text" name="answerbox" id="answerbox" "<?= isset($_POST['answerbox']) ? $_POST['answerbox'] : '' ?>"/></p>
<fieldset>
<input type="submit" name="submit" id="submit" value="Send" class="required"/>
<input type="reset" id="reset" value="Reset"/>
</fieldset>
<?php
if(isset($_POST['submit'])){
$name = trim($_POST["name"]);
$email = trim($_POST["email"]);
$subject = trim($_POST["subject"]);
$message = trim($_POST["message"]);
$answerbox = trim($_POST["answerbox"]);
if(empty($_POST['name'])){
print "<div class='formerrors'><li>Please type your name.</li></div>";
}
else {
if (ctype_alpha($name) === false) {
print "<div class='formerrors'><li>Your name only should be in letters!</li></div>";
}
}
if(empty($_POST['email'])){
print "<div class='formerrors'><li>You've forgot to type your email address.</li></div>";
} else{
if(filter_var($email, FILTER_VALIDATE_EMAIL) === false){
print "<div class='formerrors'><li>Your email is not valid, please check.</li></div>";
}
}
if(empty($_POST['subject'])){
print "<div class='formerrors'><li>Please type a subject.</li></div>";
}
if(empty($_POST['message'])){
print "<div class='formerrors'><li>You've forgot to type your message.</li></div>";
}
if(empty($_POST['answerbox'])){
print "<div class='formerrors'><li>Please answer the math question.</li></div>";
}
else {
if($answerbox != 15){
print"<div class='formerrors'><li>Answer is not correct.</li></div>";
}
else{
$headers = 'From: '.$email. "\r\n" .
'Reply-To: '.$email . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail('me#mymail.me',$subject,$message,$headers);
print "<div class='formerrors'><li>mail succesuffully sent</li></div>";
}
}
}
?>
</form>
Try placing your php code above the html as it is php setting the values of the variables, and you are calling them before they are set.
It is best practice to have php code at the top of the file, and then html below it, or even have the php on a separate file, but include it at the top.
Also I find it better to create an array of errors, and then if the array count is 0, then perform the action (send email) else call the error of arrays within the html, not the php. Then you can choose where to display it on the page, and style it accordingly.
Change your form action to
<?php $PHP_SELF; ?>
So it has to be
<form name="contact" action="<?php $PHP_SELF; ?>" method="post">
For the other issue you must place your code above the form.

PHP Form, when no text is entered

I'm creating a mobile landing page and I have also created a form that allows me to create more, by duplicating a folder that's host to a template file. The script then takes you to a page where you input the company details one by one and press submit. Then the page is created.
My problem is, when a field is left out (YouTube for instance), the button is created and is blank. I would like there to be a default text for when there is no text. I've tried a few things and have been struggling to make this work for DAYS!
<?php
$company = $_POST["company"];
$phone = $_POST["phone"];
$colour = $_POST["colour"];
$email = $_POST["email"];
$website = $_POST["website"];
$video = $_POST["video"];
?>
<div id="contact-area">
<form method="post" action="generate.php"><br>
<input type="text" name="company" placeholder="Company Name" /><br>
<input type="text" name="slogan" placeholder="Slogan" /><br>
<input class="color {required:false}" name="colour" placeholder="Company Colour"><br>
<input type="text" name="phone" placeholder="Phone Number" /><br>
<input type="text" name="email" placeholder="Email Address" /><br>
<input type="text" name="website" placeholder="Full Website - Include http://" /><br>
<input type="text" name="video" placeholder="Video URL" /><br>
<input type="submit" value="Generate QuickLinks" style="background:url(images/submit.png) repeat-x; color:#FFF"/>
</form>
That's the form. It takes the variables and post's them to the file below.
<?php
$File = "includes/details.php";
$Handle = fopen($File, 'w');
?>
<?php
$File = "includes/details.php";
$Handle = fopen($File, 'w');
$Data = "<div id='logo'>
<h1 style='color:#$_POST[colour]'>$_POST[company]</h1>
<h2>$_POST[slogan]</h2>
</div>
<ul data-role='listview' data-inset='true' data-theme='b'>
<li style='background-color:#$_POST[colour]'><a href='tel:$_POST[phone]'>Phone Us</a></li>
<li style='background-color:#$_POST[colour]'><a href='mailto:$_POST[email]'>Email Us</a></li>
<li style='background-color:#$_POST[colour]'><a href='$_POST[website]'>View Full Website</a></li>
<li style='background-color:#$_POST[colour]'><a href='$_POST[video]'>Watch Us</a></li>
</ul>
\n";
fwrite($Handle, $Data);
fclose($Handle);
?>
and there is what the form turns into. I need there to be a default link put in incase the field is left blank, witch it is sometimes. Thanks in advance guys.
Just use something like this for every element:
$company = trim($_POST["company"]);
if (!isset($company) || empty($company)) {
$company = "Not filled in";
}
I added trim to make sure spaces are ignored
Use following format for each variables:
$company = (isset($_POST["company"]) && !empty($_POST["company"]))? $_POST["company"]:"";
"" at the end of the can assign any default values.
It's usually easier to work with post variables if you wrap the access in a function:
function post($key, $default = '') {
if (!isset($_POST[$key])) return $default;
$value = trim($_POST[$key]);
if ($value == '')
return $default;
else
return $value;
}
You can now assign your variables like this:
$company = post('company');
$phone = post('phone', 'Not provided');
$colour = post('colour', 'blue');
... and so on...
Can you get away with simply wrapping your variable definitions in code like:
if (strlen($_POST["company"]) > 0) {
$company = $_POST["company"];
} else {
$company = "default company";
}
That will let you specify a default value that will be over-written by the user's data if there is any.

Undefined Index PHP issue.Please help

I have the following error:
Notice: Undefined index: submit in C:\wamp\www\registration\register.php on line 6
Can't seem to work out whats wrong??? Here's the code::
<?php
//Create registration form (register.php)
include "../includes/db_connect.php";
if(!$_POST['submit']) ///Line 6
{
?>
<html>
<head><link rel="stylesheet" href="style.css"></head>
<div class="divider">
<strong>Register</strong><br/><br/>
<form method="post" action="register.php">
<div class="formElm">
<label for="first">First Name</label>
<input id="first" type="text" name="first">
</div>
<div class="formElm">
<label for="last">Last Name</label>
<input id="last" type="text" name="last">
</div>
<div class="formElm">
<label for="username">Desired Username</label>
<input id="username" type="text" name="username">
</div>
<div class="formElm">
<label for="password">Password</label>
<input id="password" type="password" name="password">
</div>
<div class="formElm">
<label for="pass_conf">Confirm Password</label>
<input id="pass_conf" type="password" name="pass_conf">
</div>
<div class="formElm">
<label for="email">Email</label>
<input id="email" type="text" name="email">
</div>
<div class="formElm">
<label for="about">About</label>
<textarea id="about" cols="30" rows="5" name="about">Tell us about yourself</textarea>
</div>
<input type="submit" name="submit" value="Register">
</form>
or Login
</div>
</html>
<?php
}
else
{
$first = protect($_POST['first']);
$last = protect($_POST['last']);
$username = protect($_POST['username']);
$password = protect($_POST['password']);
$pass_conf = protect($_POST['pass_conf']);
$email = protect($_POST['email']);
$about = protect($_POST['about']);
$errors = array();
$regex = "/^[a-z0-9]+([_\.-][a-z0-9]+)*#([a-z0-9]+([.-][a-z0-9]+)*)+\.[a-z]{2,}$/i";
if(!preg_match($regex, $email))
{
$errors[] = "E-mail is not in name#domain format!";
}
if(!$first || !$last || !$username || !$password || !$pass_conf || !$email || !$about)
{
$errors[] = "You did not fill out the required fields";
}
$sql = "SELECT * FROM `users` WHERE `username`='{$username}'";
$query = mysql_query($sql) or die(mysql_error());
if(mysql_num_rows($query) == 1)
{
$errors[] = "Username already taken, please try another";
}
if(count($errors) > 0)
{
echo "The following errors occured with your registration";
echo "<font color=\"red\">";
foreach($errors AS $error)
{
echo "<p>" . $error . "\n";
}
echo "</font>";
echo "Try again";
//we use javascript to go back rather than reloading the page
// so the user doesn't have to type in all that info again.
}
else
{
$sql = "INSERT into `users`(`first`,`last`,`username`,`password`,`email`,`about`)
VALUES ('$first','$last','$username','".md5($password)."','$email','$about');";
$query = mysql_query($sql) or die(mysql_error());
echo "Thank You for registering {$first}! Your username is {$username}";
echo " Click here to Login";
}
}
?>
If there is no POST parameter at all or if there is no parameter named submit then you're trying to access an array index that does not exists, hence the warning. You can simply test if there is such an index/element in the _POST array.
if( isset($_POST['submit']) )
It doesn't check the value (like you original script, which tests if the value of _POST['submit'] equals false, see type juggling), but the mere existence of the index/element should suffice in this case.
see http://docs.php.net/isset
To get rid of this error, it should be:
if(!isset($_POST['submit']))
However, your code is already OK.
What you are getting is not an error, it is a warning, which is caused by having strict warnings enabld. PHP is a dynamic language which does not usually require to define variables and array keys, and most documentation and code will skip this part. So you should consider turning this feature off, as it clutters code and has few additional benefits. Or, switch to a statically compiled language (say asp.net) which will really benefit from defined variables and static typing.
Your $_POST does not exist when you first load your page. Change your check to something like:
if(!isset($_POST["submit"]))
Because you did not post anything yet, there will be no "submit" key in your $_POST array. That's what causes the warning.
For those posting use if(isset($_POST['submit'])), you clearly did not read his code. He has put is there is not a submit write the HTML form else use the fields (backwards righting to me!)
If he wants to keep the structure as is, it should be
if(empty($_POST['submit']))

Categories