PHP Server Side Validation - php

Using various tutorials namely here and here I've managed to put together the following PHP script which performs server side validation on the form being submitted. (I already have script which is dealing with the 'client side' validation.
<?php
//email signup ajax call
if($_GET['action'] == 'signup'){
//sanitize data
$email = mysql_real_escape_string($_POST['signup-email']);
//validate email address - check if input was empty
if(empty($email)){
$status = "error";
$message = "You did not enter an email address!";
}
else if(!preg_match('/^[^\W][a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*\#[a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*\.[a-zA-Z]{2,4}$/', $email)){ //validate email address - check if is a valid email address
$status = "error";
$message = "You have entered an invalid email address!";
}
else {
$insertSignup = mysql_query("INSERT INTO signups (signup_email_address) VALUES ('$email')");
if($insertSignup){ //if insert is successful
$status = "success";
$message = "You have been signed up!";
}
else { //if insert fails
$status = "error";
$message = "Ooops, Theres been a technical error!";
}
}
//return json response
$data = array(
'status' => $status,
'message' => $message
);
echo json_encode($data);
exit;
}
?>
What I'm now trying to do is to add another field, in this case 'name' which I'd like to also validate.
The problem I'm having is that I'm not sure how to add another field into the above code. Again, I've been trying to find an example which I could use to study from, but I haven't found any that I can use.
I just wondered whether someone could possibly look at this please, and perhaps point me in the right direction.
Many thanks and kind regards

PHP has a Filter extension to validate and sanitize input.
The function you are looking for is
filter_var_array — Gets multiple variables and optionally filters them
There is also filter_input_array but since there is no easy way to unit-test that properly, it is easier to use the above one instead and pass it the superglobals as needed.
Example:
$userInput = array(
'signup-email' => 'foo at example.com',
'name' => 'ArthurDent42'
);
$validatedInput = filter_var_array(
$userInput,
array(
'signup-email' => FILTER_VALIDATE_EMAIL,
'name' => array(
'filter' => FILTER_VALIDATE_REGEXP,
'options' => array(
'regexp' => "/^[a-z ]{5,10}$/i"
)
)
)
);
var_dump($validatedInput);
Output (demo):
array(2) {
["signup-email"]=> bool(false)
["name"]=> bool(false)
}
Once you have the input validated and sanitized put some guard clauses for each of the values in the array and return early when they are false:
if (!$validatedInput['signup-email']) {
return json_encode(array(
'status' => 'error',
'message' => 'The eMail was invalid'
));
}
if (!$validatedInput['name']) {
return json_encode(array(
'status' => 'error',
'message' => 'Name must be 5 to 10 letters from A to Z only'
));
}
// everything's validated at this point. Insert stuff to database now.
Note that you want to use either PDO or mysqli instead of ext/mysql.

In your HTML add a field:
<input type="text" name="name" value="" />
In your PHP:
$name = trim($_POST['name']);
To validate:
if ($name === '') {
$status = 'error';
$message = 'need a name!';
}
Now add name to your insert statement (it would be better to use PDO prepared statements):
$nameSql = mysql_real_escape_string($name);
$insertSignup = mysql_query("INSERT INTO signups (signup_email_address, name) VALUES ('$email', '$nameSql')");

$rule['email']= '/^[^\W][a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*\#[a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*\.[a-zA-Z]{2,4}$`/'
$rule['name']= 'bla bla';
$rule['address']= 'bla bla';
$data = sanitize($_POST,$rule);
function sanitize($input_array,$rule){
$message = array();
foreach($input_array as $key=> $value){
$input_array[$key]= mysql_real_escape_string($value);
if(isset($rule[$key])){
if(!preg_match($rule[$key],$input_array[$key]){
$message[$key] = 'error';
unset($input_array[$key]);//optional
}
}
}
return array('data'=>$input_array,'message'=>$message);
}

Related

Secure a contact form from scratch in Wordpress

I am currently creating a website with Wordpress, I am creating my theme and I am not using jQuery. I need to introduce a simple contact form, which sends an email on submission and all plugins need jquery to work.
Is it safe to create a contact form that sends an email? Is there a risk of SQL injection since I do not query the database on submission?
I have very little security skill, any information or clarification will be welcome
So for example something like:
$name = "{$_POST['message_name']} {$_POST['message_lastname']}"; // I like to combine first and lastname in to 1 variable.
$email = $_POST['message_email'];
$website = $_POST['message_url'];
$message = $_POST['message_description'];
if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
$response = form_validation_response( 'error', $email_invalid );
} else {
if ( empty( $name ) || empty( $message) ) {
$response = form_validation_response( 'error', $missing_content );
}
}
// The most simple check you can do is make sre that the fields are NOT empty.
The form_validation_response method is a simple function which you can use to return error message:
$not_human = "Human verification incorrect.";
$missing_content = "Please supply all information.";
$email_invalid = "Email Address Invalid.";
$message_unsent = "Message was not sent. Try Again.";
$message_sent = "Thanks! Your message has been sent.";
function form_validation_response( $type, $message ) {
$class = 'px-2 py-1 mb-6 rounded-md' // These are tailwind classes, but it could be bootstrap
if ( $type == 'success' ) {
$class .= "border border-green-800 text-green-700";
} else {
$class .= "border border-redish text-redish";
}
return "<div class='{$class}'>{$message}</div>";
}
The example above is used to validate the email, but you can also make sure that the fields are actually submitted, before even starting the validation process:
If you're not familiar with creating a "secure" php form I would advice you to use a plugin for this.
If your "allowed" to install plugins, then have a look "form plugins" like:
WPForms (https://wpforms.com/)
Gravity Forms (https://www.wpbeginner.com/refer/gravityforms/)
Contact Form 7 (https://wordpress.org/plugins/contact-form-7/)
This is just a few of the form plugins that are available. Depending on your need/budget you should then make a decision which plugin fits the best (some are free, freemium, premium etc.).

MailGun Check if an email already is subscribing

I have been trying to solve this in all ways I can figure out, but have surely missed something. I've tried to access the fields using for-loops, just calling it, arrays, objects etc. I just can't get it to work.
What I'm talking about is to check if a provided email in a form already is subscribing to my maillist at MailGun. I don't know how to check this and I've been searching the web for answer for about 1-2 hours now and I'm finally asking here aswell.
My code so far:
<?php
session_start();
ini_set('display_errors', 1);
require_once 'init.php';
if (!isset($_POST['email']) && isset($_POST['name'])) {
echo 'You have to provide an email!';
} else if (!isset($_POST['name']) && isset($_POST['email'])) {
echo 'You have to provide a name!';
} else if (isset($_POST['name'], $_POST['email'])) {
$name = $_POST['name'];
$email = $_POST['email'];
// This is temporary to test and only works if an email existing is provided.
// If an invalid email is provided, an error is cast
// See below for the error
if (!$mailgun->get('lists/' . MAILGUN_LIST . '/members' . $email)) {
echo "Email doesnt exist";
die();
$validate = $mailgunValidate->get('address/validate', [
'address' => $email
])->http_response_body;
if ($validate->is_valid) {
$hash = $mailgunOptIn->generateHash(MAILGUN_LIST, MAILGUN_SECRET, $email);
$mailgun->sendMessage(MAILGUN_DOMAIN, [
'from' => 'noreply#adamastmar.se',
'to' => $email,
'subject' => 'Please confirm your subscription to the mailing list',
'html' => "
Hello {$name},<br><br>
You signed up to our mailing list. Please confirm your subscription below.<br><br>
<a href='http://www.adamastmar.se/confirm.php?hash={$hash}'>Click here to confirm</a>"
]);
$mailgun->post('lists/' . MAILGUN_LIST . '/members', [
'name' => $name,
'address' => $email,
'subscribed' => 'no'
]);
$_SESSION['joined'] = "A message has been sent to the provided email. Please confirm the subscription by clicking the link in the mail.";
header('Location: ./');
}
} else {
$_SESSION['alreadysub'] = "You are already a subscriber to this list!";
header('Location: ./');
}
}
?>
The error I get if I use the code above:
Uncaught exception 'Mailgun\Connection\Exceptions\MissingEndpoint' with message 'The endpoint you've tried to access does not exist.
Check your URL.' in /home/jivusmc/domains/adamastmar.se/public_html/vendor/mailgun/mailgun-php/src/Mailgun/Connection/RestClient.php:258
Stack trace: #0 /home/jivusmc/domains/adamastmar.se/public_html/vendor/mailgun/mailgun-php/src/Mailgun/Connection/RestClient.php(110):
Mailgun\Connection\RestClient->responseHandler(Object(GuzzleHttp\Psr7\Response))
#1 /home/jivusmc/domains/adamastmar.se/public_html/vendor/mailgun/mailgun-php/src/Mailgun/Connection/RestClient.php(195):
Mailgun\Connection\RestClient->send('GET', 'lists/news#mail...') #2 /home/jivusmc/domains/adamastmar.se/public_html/vendor/mailgun/mailgun-php/src/Mailgun/Mailgun.php(215):
Mailgun\Connection\RestClient->get('lists/news#mail...', Array) #3 /home/jivusmc/domains/adamastmar.se/public_html/mailinglist.php(16):
Mailgun\Mailgun->get('lists/news#mail...') #4 {main} thrown in /home/jivusmc/domains/adamastmar.se/public_html/vendor/mailgun/mailgun-php/src/Mailgun/Connection/RestClient.php on line 258
Any help & tips/tricks is appreciated!
I found a solution to the issue I had. Instead of doing everything in an if-statement, I instead surrounded it in a try-catch. I try to check if the email can be fetched from the mailgun list and if it fails, it catches the error and instead adds the mail to the list. (I'm posting it here since it's nearly impossible to find a solution to this in a better way)
$name = $_POST['name'];
$email = $_POST['email'];
try {
$mailgun->get('lists/' . MAILGUN_LIST . '/members/' . $email);
$_SESSION['alreadysub'] = "You are already a subscriber to this list!";
header('Location: ./');
} catch (Exception $e) {
$validate = $mailgunValidate->get('address/validate', [
'address' => $email
])->http_response_body;
if ($validate->is_valid) {
$hash = $mailgunOptIn->generateHash(MAILGUN_LIST, MAILGUN_SECRET, $email);
$mailgun->sendMessage(MAILGUN_DOMAIN, [
'from' => 'noreply#adamastmar.se',
'to' => $email,
'subject' => 'Please confirm your subscription to the mailing list',
'html' => "
Hello {$name},<br><br>
You signed up to our mailing list. Please confirm your subscription below.<br><br>
<a href='http://www.adamastmar.se/confirm.php?hash={$hash}'>Click here to confirm</a>"
]);
$mailgun->post('lists/' . MAILGUN_LIST . '/members', [
'name' => $name,
'address' => $email,
'subscribed' => 'no'
]);
$_SESSION['joined'] = "A message has been sent to the provided email. Please confirm the subscription by clicking the link in the mail.";
header('Location: ./');
}
}
I know this problem and the answer are in PHP. But I just figured out a way in NodeJS and wish I've found a solution for it earlier. Maybe it helps someone.
FYI: I'm checking if an email exists in mailing list from Mailgun.
var DOMAIN = 'YOUR_DOMAIN_NAME';
var mailgun = require('mailgun-js')({ apiKey: "YOUR_API_KEY", domain: DOMAIN});
const array = await mailgun.getList().catch(console.error);
if(checkIfEmailExcistInMailinglist(array.items, dbUser.email)){
// if then do something
}
checkIfEmailExcistInMailinglist(array, email) {
for (var i = 0; i < array.length; i++) {
if (array[i].address === email) {
return true;
}
}
return false;
}

Form Post Data As Array Value

I'm trying to integrate an API builder to my control panel through a form or post data. I can't figure out how to put the post data as the value for the array.
I tried using print_r($_POST['VALUE']) with and without quotes.
I tried using just $_POST['VALUE'] with and without quotes.
I also tried to set $value = $_POST['VALUE'] then using $value with and without quotes but that caused an error 500.
Here is the code I am trying to use:
$res = $api->remoteCall('requestLogin', array(
'type' => 'external',
'domain' => 'print_r($_POST['domain'])',
'lang' => 'en',
'username' => 'print_r($_POST['uname'])',
'password' => 'print_r($_POST['pass'])',
'apiUrl' => '127.0.0.1',
'uploadDir' => '/web/'.print_r($_POST['domain']).'/public_html',
I apologize as I am new to PHP, but thank you in advance.
I'm not sure what other logic is being done there, how the post variables are being sent to the script your sample code is running on, or any of the other details which might point towards a more complete solution but here are some basic tips to help you troubleshoot.
The post variables should be formatted like this:
$res = $api->remoteCall('requestLogin', array(
'domain' => $_POST['domain'],
You can dump the entire post array to the screen by doing
print_r($_POST);
This should output your array to the screen so you can verify that you're receiving the post data in the code and should help you fix any typos or misnamed post variables. If the array has the key as $_POST['domainName'] and you're echoing $_POST['domain']
You're calling code (the "form or post data") should have the post fields in place and named correctly in order for them to be sent to the script
<input type="text" name="domain">
You should be performing some basic validation on your post fields before adding them to something that's going to be stored anywhere or sent off to a third-party. At the most minimal you'll want to check that there is a value being set for the essential fields (required fields) and I'd look to make sure the values are matching requirements of the API you're passing them off to.
Several things may go wrong when using api. POST values, input values, API call or connection or maybe api response. So not only at the time of implementation and coding but also when integrating api call script with the application there should be some sort of testing and error handling in place. A simple script can be like this
$error = array();
$request = array();
$request['type'] = 'external';
if (isset($_POST['domain']) && !empty($_POST['domain'])) {
$request['domain'] = $_POST['domain'];
$request['uploadDir'] = "/web/{$_POST['domain']}/public_html";
} else {
$error[] = "Domain is empty";
}
if (isset($_POST['uname']) && !empty($_POST['uname'])) {
$request['username'] = $_POST['uname'];
} else {
$error[] = "Username is empty";
}
if (isset($_POST['pass']) && !empty($_POST['pass'])) {
$request['password'] = $_POST['pass'];
} else {
$error[] = "Username is empty";
}
$request['lang'] = 'en';
$request['apiUrl'] = '127.0.0.1';
if (count($error) > 0) {
echo implode( "<br>" , $error );
} else {
try{
$res = $api->remoteCall('requestLogin',$request);
} catch ( Exception $e ) {
print_r($e);
exit();
}
}

Check if session data isset and apply error to each item

I have to do the following for a large amount of session variables, is there a way I can shorten this code to apply to all the variables rather than repeatedly writing out if(!isset($_SESSION['whatever'])) and adding the apropriate error to the errors array.
if(!isset($_SESSION['fiat'])) {
$errors[fiat] = 'Please enter valid amount';
}
if(!isset($_SESSION['contact'])) {
$errors[contact] = 'Please enter valid contact';
}
if(!isset($_SESSION['name'])) {
$errors[name] = 'Please enter valid name';
}
I have tried some things with for loops and arrays but am really struggling even after some serious googling, so any help much appreciated.
Thanks!
I have now made the following array but am unsure how to use it:
$errors = array(
$_SESSION['fiat'] => 'Please enter valid amount',
$_SESSION['contact'] => 'Please enter valid contact',
$_SESSION['name'] => 'Please enter valid name',
);
Do i do something like the following? Not sure what goes inbetween.
for(!isset($errors)){
}
What you can do is the following:
$errors = array();
// List all session parameters and error messages you want to check here
$valuesToCheck = array(
'fiat' => 'Please enter valid amount',
'contact' => 'Please enter valid contact'
// and so on...
);
// Loop through all values you want to check and validate it. if validation doesn't pass add error message to $errors array.
foreach ($valuesToCheck as $k => $v) {
if(!isset($_SESSION[$k])) {
$errors[$k] = $v;
}
}
// Check if after the validation array with errors is not empty then deal with it.
if (!empty($errors)) {
// Do something with errors here
}
PS: I think you should learn more about software development basics before start writing a code. This will be useful in your further career.

php json return creating syntax error on responce

I have looked at many posts here and elswhere on this error without success of resolving my error. In console the form data is being sent via json as expected to my php processing page, the php process is not returning any errors so I'm confident the process is completing. I have checked the way the result is formatted and cannot see anything wrong there, although I'm no expert at ajax/json so I could be wrong, Here is my code
Jquery code
<script type="text/javascript">
$(document).ready(function() {
$("#admin_login_but").click(function() {
if($("#admin_name").val()=="" || $("#admin_password").val()=="" || $("#admin_email").val()=="") {
$(".adminloginError").html("Please enter Admin Name, Admin Email and Admin Password");
return false;
}else{
$(".adminloginError").html('<img src="image/ajax-loader.gif" width="16" height="16" alt=""/>');
var adminName=$("#admin_name").val();
var adminPassword=$("#admin_password").val();
var adminEmail=$("#admin_email").val();
$.post("includes/admin_login.inc.php",{admin_name:adminName,admin_password:adminPassword, admin_email:adminEmail},function(json) {
if(json.result === "success") {
$(".adminloginError").html( "Welcome "+adminName+"!");
setTimeout(function(){
window.location= "admin_secure.php";
},2000);
}else{
$(".adminloginError").html(json.message);
}
});
}
Here is my php processing code
<?php
include_once 'functions.php';
include_once 'db_connect.php';
header("Content-Type: application/json"); //this will tell the browser to send a json object back to client not text/html (as default)
//convert variable (array) into a JSON object
function result($var){
echo json_encode($var);
exit();
}
sec_session_start();
error_reporting(E_ALL); ini_set('display_errors', 1);
//check if surname is empty
if (isset($_POST["admin_login_but"])) {
//check if first_name is empty
if (empty($_POST["admin_name"])) {
$response = array('result'=>'fail', 'message' => 'Missing Admin Name');
result($response);
}else{
// if not empty sanitize first_name input
$admin_name = filter_input(INPUT_POST, 'admin_name', FILTER_SANITIZE_STRING);
}
//Check if email is empty and santize and validate email
if (empty($_POST['admin_email'])) {
$response = array('result'=>'fail', 'message' => 'Missing Admin Email');
result($response);
}else{
$admin_email = filter_var($_POST['admin_email'], FILTER_SANITIZE_EMAIL);
}
if (!filter_var($admin_email, FILTER_VALIDATE_EMAIL)) {
$response = array('result'=>'fail', 'message' => 'The Email is not in a Valid Email Format!');
result($response);
}
//check if register password input is empty
if (empty($_POST["admin_password"])) {
$response = array('result'=>'fail', 'message' => 'Missing Admin Password');
result($response);
} else {
//Sanitize the data passed in 'password'
$admin_password = filter_input(INPUT_POST, 'admin_password', FILTER_SANITIZE_STRING);
}
//validate the data passed in 'password'
if (!preg_match("/^.*(?=.{8,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$/", $admin_password)) {
$response = array('result'=>'fail', 'message' => 'Password is in the Wrong Format!');
result($response);
}
//query database
$results = mysqli_query($mysqli, "SELECT * FROM admin WHERE name = '$admin_name' AND email = '$admin_email' AND hash = '$admin_password'");
// Check if SQL query had erors
if(!$results){
$response = array('result'=>'fail', 'message' => 'sql error: ' . mysqli_error($mysqli));
result($response);
}
// If query was successfull and there are rows do this:
if (mysqli_num_rows($results)>0){
$_GET['name'] = $admin_name;
$response = array('result'=>'success', 'message' => 'User is Authenticated');
result($response);
} else {
$response = array('result'=>'fail', 'message' => 'User Authentication Failed');
result($response);
}
}
?>
I cannot figure out how to resolve this. Can anyone help please
I just figured it out, I hadn't put an else option at the end of my php for the initial post check
if(!isset($_POST)) {
//all the processing code
}else{
$response = array('result'=>'success', 'message' => 'Post is Empty');
result($response);
}

Categories