I would like to make a user registration form which only accepts email addresses from my university.
e.g
me#gmail.com, me#yahoo.com, me#live.com = INVALID
me#university.ac.uk = VALID
what types of terms and queries should I start researching to achieve this? I am new to PHP, but from the homework, I've done so far can only find tutorials on how to validate emails based on rejecting invalid inputs, rather than only accepting valid domain extensions such as #university.ac.uk
Hope this makes sense, not trying to get code written for me (although visual explanations are helpful), just asking for a few pointers to help get in the right direction.
i will suggest you regex for email that your requirements.
/^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#\buniversity.ac.uk/
Please visits here https://regex101.com/r/KkJeho/9
If you first make sure the address is an email, and then explode() the email, you can check if the server matches:
<?php
$email = "foo#university.ac.uk";
$allowed_servers = array("university.ac.uk", "other_server.maybe");
if (filter_var($email, "FILTER_VALIDATE_EMAIL")) {
$check = explode("#", $email);
if (in_array($check[1], $allowed_servers)) {
// server checks out
} else {
// server doesn't check out
}
} else {
// invalid email address
}
To begin with, requiring domain specific email addresses in a form means you need to utilize it at least server side (the mail addresses submitted needs to be checked againist non conforming user input). In simple words, if someone wants to "play" with your site he could send "bad" requests so that you store the wrong information in your database.
Moreover it's not compulsory but if you want to aid the user you can add client side verification.
As far as server side code is concerned you can use regular expressions to validate input. See here and here
Additionally, client side code can be used to assist the user in order to submit the form properly. You have more choices for this:
HTML5 regex
Javascript regex
Related
What else is needed to:
make this php script send an auto-response back?
sanitize and check the phone number and email that is not junk as my current formmail from dbmasters I get junk like dasawewdjz89)$%&*_sasa779%7fmsdls in almost every field including the input areas.
It is mentioned to take out the bcc and cc code, yet, I had code to sent to a different recipient based on the state, so is there a way to keep the bcc and cc fields too without compromising security?
Maybe this is 3 questions in 1, but this is essentially building upon the answer here
Replacing deprecated eregi() with stristr(). Is this php mail script secure from header injections? since it is a deprecated form and I get error logs each day now.
I believe I only need validation on input fields NOT select or radio fields, right?
I am an html/css guy so would this actual code go into the php page or as a separate contact.php page.
EDIT: The script I cannot post for some reason here with the code given (like in other forums). so I made a link to it in BOLD
..Validate without Javascript
To answer your questions:
Question 1: Don't quite understand what you mean here. Once you are in your script you can send output to the screen, generate and email, etc. This question is very vague.
Question 2: You can use regular expressions to validate various pieces of information. For example this will check a phone number in the format of XXX-XXX-XXXX and tell you if it is valid.
function validatePhone($number)
{
$test = "/^\d{3}-\d{3}-\d{4}$/";
return (preg_match($test, $number) != 0) ? true : false;
}
var_dump(validatePhone("815-555-1234"));
var_dump(validatePhone("8158791359"));
var_dump(validatePhone("blah blah 209#&$#)(##1;llkajsdf"));
This will produce:
bool(true)
bool(false)
bool(false)
Keep in mind this function is far from robust. Valid phone numbers in different formats will fail (e.g. 815 555-8846), so you will need to adjust the regexp or craft multiple regexps to meet your needs. But that should be enough to illustrate the process.
Question 3: For email, I don't really see how the BCC and CC fields are going to compromise security. What you need to focus on in that area is preventing email header injections.
Spammers have recently been using mail header injection to send spam e-mail from contact forms that have in the past viewed as secure.
If you are a webmaster you can edit your forums to ensure they are secure and safe from spammers
Anyway, I have several websites that all use a common contact form. Every contact form posts to the same script.
This is how I defend against header injections. (I typically use this script as an include file)
This script requires your html form to use action="post". Make sure this is only used on the script that the html form will be posted to. If you use this script on a regular page request, it will die().
More error checking should be done when testing posted values for bad strings. Possibly a regular expression.
<?php
// First, make sure the form was posted from a browser.
// For basic web-forms, we don't care about anything
// other than requests from a browser:
if(!isset($_SERVER['HTTP_USER_AGENT'])){
die("Forbidden - You are not authorized to view this page");
exit;
}
// Make sure the form was indeed POST'ed:
// (requires your html form to use: action="post")
if(!$_SERVER['REQUEST_METHOD'] == "POST"){
die("Forbidden - You are not authorized to view this page");
exit;
}
// Host names from where the form is authorized
// to be posted from:
$authHosts = array("domain.com", "domain2.com", "domain3.com");
// Where have we been posted from?
$fromArray = parse_url(strtolower($_SERVER['HTTP_REFERER']));
// Test to see if the $fromArray used www to get here.
$wwwUsed = strpos($fromArray['host'], "www.");
// Make sure the form was posted from an approved host name.
if(!in_array(($wwwUsed === false ? $fromArray['host'] : substr(stristr($fromArray['host'], '.'), 1)), $authHosts)){
logBadRequest();
header("HTTP/1.0 403 Forbidden");
exit;
}
// Attempt to defend against header injections:
$badStrings = array("Content-Type:",
"MIME-Version:",
"Content-Transfer-Encoding:",
"bcc:",
"cc:");
// Loop through each POST'ed value and test if it contains
// one of the $badStrings:
foreach($_POST as $k => $v){
foreach($badStrings as $v2){
if(strpos($v, $v2) !== false){
logBadRequest();
header("HTTP/1.0 403 Forbidden");
exit;
}
}
}
// Made it past spammer test, free up some memory
// and continue rest of script:
unset($k, $v, $v2, $badStrings, $authHosts, $fromArray, $wwwUsed);
?>
I need to check if the email the user enters during registration is valid/real, meaning they can't just enter whatever they want as long as it meets the proper email format, I need to actually be able to send mail to it.
I also don't want to do email confirmation, though, where the user would have to click a link from an email to register. I just want it to verify on the spot.
You can do all the validation you want, but in the end the best and only way is to send an email with a verification link.
Also, because there is a huge amount of valid and odd emails that you would think aren't, the idea is generally to have fairly loose validation. Take a look here for all sorts of interesting emails.
You will need to do a DNS lookup on the MX record for the domain, then make sure that mx domain is contactable. I think that is about as close as you can get.
You might also consider letting a 3rd party do the validation for you - e.g. implement Google OAuth as a method of registration for your site.
In case of Laravel (you've mentioned it as a tag for the question) I suggest you to use such a Laravel's native feature as Validation: Laravel 3 / Laravel 4.
Below is how I use it in POST controller:
// Rules for form validation
$rules = array(
'email' => array('required', 'email', 'unique:users,email'), // Email is required and should satisfy E-mail format and it should be unique for table users.
);
// Form validation
$validation = Validator::make(Input::all(), $rules);
if($validation->fails()) {
// Flash validator with input values and errors to some controller
Former::withErrors($validation);
return Redirect::to_action('some.controller')
->with_input()
->with_errors($validation);
}
}
In general PHP usage case you can check it using PHP's native function like this:
filter_var($email, FILTER_VALIDATE_EMAIL)
I have used RS form form for user Registration on my joomla site. There i want to make registration from only company email address for internal users. How can i do this ? Please advice. Is there any way of configure custom email domain for RS Form email validation field?
You can use a Regular Expression as field validation (instead of email).
While on the RS Form, edit the field and go to Validations.
Change the Validation Rule to Regex.
Set the Regex Syntax to /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+#yourdomain.com$/
Note: be sure to change "yourdomain.com" to your own domain.
Validating emails using regular expressions is not perfect. See Using a regular expression to validate an email address. The first part of the regex I suggested here is taken from w3.
If you need a workaround and hardcode it, you can try the following approach in code:
// Domain to check
$email_domain = "#mydomain.com";
// Email to check
$co_email = "joefoobar#mydomain.com"; // returns true => valid
//$co_email = "joefoobar#gmail.com"; // returns false => invalid (uncomment to test)
if(!substr_count($co_email, $email_domain) > 0){
// Set the error
echo "Invalid!";
} else {
// No error, proceed with code
echo "Valid!";
}
I'm using the Zend_Mail_Message class to display emails inside of my PHP app, and am able to output the subject, content, date and even the NAME of the sender (using $message->from) but I can't figure out how to get the email address of the person who sent the message. The documentation is no help and googling finds a million results for how to send messages with Zend, but nothing about getting the address that sent the message.
EDIT:
This is how I ended up doing it. After some more digging, I found the sender's email in a field called 'return-path'. Unfortunately, this field has a dash in the name (WTF??) so to access it, I had to do this:
$return_path = 'return-path';
$message->reply_to = $zendMessage->$return_path;
Using the return-path caused some problems with some emails, specifically messages from no-reply accounts (mail-noreply#gmail.com, member#linkedin.com etc). These addresses would end up looking something like this:
m-9xpfkzulthmad8z9lls0s6ehupvordjdcor30geppm12kbvyropj1zs5#bounce.linkedin.com
...which obviously doesn't work for display in a 'from' field on the front-end. Email clients like Apple Mail and Gmail show mail-noreply#gmail.com or member#linkedin.com, so that's what I was going for too.
Anyways, after some more research, I discovered that the 'from' field in a Zend Mail Message object always looks something like this:
"user account name" <user#email.com>
The part in < > is what I was after, but simply doing $from = $zend_message->from only gave me the user's account name (hence my original question). After some more playing around, this is how I finally got it working:
$from = $zendMessage->from;
$start = strpos($from, '<');
$email = substr($from, $start, -1);
$result = str_replace('<', '', $email);
Hopefully this will save someone some frustration. If anyone knows of a simpler way of doing this, please let me know.
This works well..
$senderMailAddress = null;
foreach ( $message->getHeader('from')->getAddressList() as $address ) {
if ( $senderMailAddress === null) {
$senderMailAddress = $address->getEmail();
}
}
The main problem here is that many email programs, relay agents and virus scanner along the way do funny stuff to an actually simple and well defined email standard.
Zend_Mail_Message extends to Zend_Mail_Part which has a method called getHeaders(). This will have all the data from an email stored in the head versus the body which is accessed with getContent() and the actual email message.
With this method you'll get an array of all the key/value pairs in the header and while developing you should be able to determine which header field you will actually want. Once you know that you can then get the actual field with getHeader('field_name') or with its actual name directly.
However, if you have to many different email senders you may want to stick with the complete header array though and evaluate multiple fields for the best result like if there's an "reply-to" address. Again there are many uncertainties because the standard isn't always obeyed.
Does anybody have a good function for validating email addresses by SMTP in PHP?
Also, is it worth it? Will it slow down my server?
--> EDIT: I am referring to something like this:
http://onwebdevelopment.blogspot.com/2008/08/php-email-address-validation-through.html
which is meant to complement validation of the syntax of the email address.
It looks complicated though, and I was hoping there was a simpler way of doing this.
If you want to check if there is a mail exchanger at the domain, you can use something like this:
/*checks if email is well formed and optionally the existence of a MX at that domain*/
function checkEmail($email, $domainCheck = false)
{
if (preg_match('/^[a-zA-Z0-9\._-]+\#(\[?)[a-zA-Z0-9\-\.]+'.
'\.([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/', $email)) {
if ($domainCheck && function_exists('checkdnsrr')) {
list (, $domain) = explode('#', $email);
if (checkdnsrr($domain, 'MX') || checkdnsrr($domain, 'A')) {
return true;
}
return false;
}
return true;
}
return false;
}
Usage:
$validated = checkEmail('foo#gmail.com', true);
Here is what I believe you are looking for. It does a validation with the SMTP server. It shows PHP code. http://www.webdigi.co.uk/blog/2009/how-to-check-if-an-email-address-exists-without-sending-an-email/.
Here's such a code, taken from the drupal module email_verify. There are a couple of Drupal specific calls there, but it should not take a lot of time to clean it up for a generic PHP function:
Also note that some web hosts block outgoing port 25, as it is mostly used by spammers. If your host is practicing such a block, you will not be able to use this form of verification.
You are welcome to use my free PHP function is_email() to validate addresses. It's available here.
It will ensure that an address is fully RFC 5321 compliant. It can optionally also check whether the domain actually exists.
You shouldn't rely on a validator to tell you whether a user's email address actually exists: some ISPs give out non-compliant addresses to their users, particularly in countries which don't use the Latin alphabet. More in my essay about email validation here: http://isemail.info/about.