PHP: Sanitize User Input Using Filters & Regex

In this article I share my recent experience implementing the sanitization of user input in a PHP web application using PHP filters and regular expressions.

In this article I share my recent experience implementing the sanitization of user input in a PHP web application using PHP filters and regular expressions.

For background, I was recently troubleshooting a production PHP application and needed to create a form that takes in an ID parameter from the URL and uses it to retrieve a specific record from a table then sends an email using that data.

To keep this as simple as possible, the example below shows how to sanitize user input by not allowing a value based on a PHP filter rule using a regular expression. You’ll need to get comfortable with a little dependency injection as that is how we get our filter options in to PHP at runtime.

If you want to validate that an ID value passed through the URL is exactly two digits, you can use the filter_input() function with a custom regular expression through the FILTER_VALIDATE_REGEXP filter. This approach allows you to specify a pattern that the input must match to be considered valid.

For an ID that consists of exactly two digits (i.e., from 00 to 99), you can use the following code snippet:

$options = array(
    "options" => array(
        // Regular expression for exactly two digits
        "regexp" => "/^\d{2}$/"
    )
);

$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_REGEXP, $options);

if ($id !== false) {
    echo "The ID '$id' is valid.";
} else {
    echo "The ID is not valid. Please provide a two-digit ID.";
}

Here’s a breakdown of how this works:

  • INPUT_GET specifies that the input is expected to come from the query parameters in the URL.
  • 'id' is the name of the parameter you’re trying to validate.
  • FILTER_VALIDATE_REGEXP is the filter used for validating against a regular expression.
  • $options is an associative array that specifies the options for the filter. In this case, it contains a regular expression defined by the regexp key. The expression /^\d{2}$/ ensures that the input consists of exactly two digits:
    • ^ asserts the start of the string.
    • \d{2} matches exactly two digits (\d is a digit, and {2} specifies exactly two occurrences).
    • $ asserts the end of the string.

This code validates that the user input is exactly two digits. If the input meets the criteria, it is considered valid; otherwise, the script returns an error message indicating the input is not valid. This is a straightforward way to enforce specific formats for input values in PHP.

Lastly, the example above focuses on getting a parameter from the URL using the GET HTTP method. If you’re using a form, replace INPUT_GET with INPUT_POST.

I hope this example helps you secure your PHP applications.

~Cyber Abyss

Sending Email with PHP

Configuring the mail() function in PHP to send emails involves setting up the underlying mail sending system on the server. The configuration depends on the operating system of your web server and the mail transfer agent (MTA) software that is being used (e.g., Sendmail, Postfix, Exim).

Configuring Email in PHP

Configuring the mail() function in PHP to send emails involves setting up the underlying mail sending system on the server. The configuration depends on the operating system of your web server and the mail transfer agent (MTA) software that is being used (e.g., Sendmail, Postfix, Exim).

For Linux/Unix Servers

On most Linux/Unix servers, mail() is configured to use Sendmail or a Sendmail-compatible MTA by default. Here’s a general approach to configure it:

  1. Install Sendmail or another MTA: Ensure that Sendmail, Postfix, or another MTA is installed on your server. For example, to install Sendmail on a Debian-based system, you can use:bashCopy codesudo apt-get install sendmail
  2. Configure PHP to Use Sendmail: The default configuration in php.ini usually works out of the box with Sendmail. However, you can check or modify the path to Sendmail in your php.ini file:iniCopy code[mail function] ; For Sendmail and Sendmail-like systems sendmail_path = "/usr/sbin/sendmail -t -i" Make sure the path to sendmail matches the location of the Sendmail executable on your system.
  3. Configure Sendmail or MTA Settings: Depending on your server setup, you might need to configure your MTA to handle emails correctly. This could involve setting up relay options, modifying the mail queue, or adjusting security settings. This is highly specific to your server and network setup.
  4. Restart Apache or PHP-FPM: After making changes to php.ini, make sure to restart your web server or the PHP-FPM service to apply the changes.bashCopy codesudo systemctl restart apache2 Or for PHP-FPM:bashCopy codesudo systemctl restart php7.x-fpm (Replace 7.x with your specific PHP version.)

For Windows Servers

On Windows servers, mail() can be configured to use an SMTP server directly through the php.ini file:

  1. Configure SMTP Settings in php.ini: Locate your php.ini file and specify the SMTP server and related settings:iniCopy code[mail function] ; Setup for Windows systems SMTP = smtp.example.com smtp_port = 25 sendmail_from = user@example.com Replace smtp.example.com with your SMTP server’s hostname, 25 with your SMTP server’s port (often 587 for TLS or 465 for SSL), and user@example.com with the email address you want to send emails from.
  2. Restart Your Web Server: Apply the changes by restarting your web server software.

Note

  • Security: Sending emails from web applications exposes them to spam and abuse risks. Ensure you have mechanisms in place to prevent abuse (e.g., CAPTCHAs, rate limiting).
  • SPF, DKIM, and DMARC: To improve email deliverability, consider setting up SPF, DKIM, and DMARC records in your domain’s DNS. These help verify that your emails are legitimately coming from your domain and are not being spoofed.
  • Using External SMTP: For better reliability and deliverability, consider using an external SMTP service like Amazon SES, SendGrid, or Mailgun. These services often require authentication, and you’ll likely need to use a library like PHPMailer or SwiftMailer to integrate them into your PHP applications.

Configuring mail() requires access to server settings and might involve complex configurations depending on your hosting environment. If you’re unsure, consult with your hosting provider or a system administrator.

Sending an Email in PHP

Sending an email in PHP can be achieved using the mail() function. This function allows you to send emails directly from a PHP script. Below is a simple example that demonstrates how to use the mail() function to send an email:

phpCopy code<?php
// The recipient email address
$to = 'recipient@example.com';

// Subject of the email
$subject = 'Test Email from PHP';

// Message content for the email
$message = 'Hello, this is a test email sent from a PHP script.';

// Headers for the email
$headers = 'From: YourName <yourname@example.com>' . "\r\n" . // Sender's email address
           'Reply-To: yourname@example.com' . "\r\n" . // Reply-to address
           'X-Mailer: PHP/' . phpversion();

// Sending the email
if(mail($to, $subject, $message, $headers)) {
    echo "Email sent successfully!";
} else {
    echo "Email sending failed.";
}
?>

Here’s what each part does:

  1. $to: Specifies the recipient’s email address.
  2. $subject: The subject line of the email.
  3. $message: The body content of the email.
  4. $headers: Email headers to specify additional information like the sender’s email address, reply-to address, and the X-Mailer (which indicates the software used to send the email, in this case, PHP).

To use this script:

  • Replace 'recipient@example.com' with the actual recipient’s email address.
  • Change 'YourName <yourname@example.com>' in the $headers variable to your name and email address. This will be used as the “From” address.
  • You might need to adjust settings or configurations depending on your server or hosting provider to properly send emails.

Keep in mind, for bulk or more complex email sending tasks (like HTML emails, attachments, or using SMTP authentication), it’s recommended to use a library such as PHPMailer or SwiftMailer, as they offer more flexibility and functionality than the basic mail() function.

Sending Email with Attachments in PHP

Sending an email with an attachment in PHP requires a bit more work than a simple text email because you have to format the email to conform to MIME standards. This involves encoding the attachment in base64 and splitting the email body from the attachment using a unique boundary string.

Below is a basic example of how to send an email with an attachment using PHP:

phpCopy code<?php
// Recipient email address
$to = 'recipient@example.com';

// Subject of the email
$subject = 'Email with Attachment from PHP';

// File to attach
$file_path = '/path/to/your/attachment.pdf';
$file_name = basename($file_path);
$file_size = filesize($file_path);
$file_content = chunk_split(base64_encode(file_get_contents($file_path))); // encode the attachment

// Boundary 
$boundary = md5(time());

// Headers
$headers = "From: YourName <yourname@example.com>\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: multipart/mixed; boundary=\"{$boundary}\"";

// Message Body
$body = "--{$boundary}\r\n";
$body .= "Content-Type: text/plain; charset=ISO-8859-1\r\n";
$body .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$body .= "This is a MIME encoded message.\r\n\r\n"; // Message before attachment

// Add attachment
$body .= "--{$boundary}\r\n";
$body .= "Content-Type: application/octet-stream; name=\"{$file_name}\"\r\n";
$body .= "Content-Disposition: attachment; filename=\"{$file_name}\"\r\n";
$body .= "Content-Transfer-Encoding: base64\r\n\r\n";
$body .= $file_content . "\r\n\r\n";
$body .= "--{$boundary}--";

// Send email
if(mail($to, $subject, $body, $headers)) {
    echo "Email sent with attachment successfully.";
} else {
    echo "Email sending failed.";
}
?>

Steps Explained:

  1. Specify the Recipient, Subject, and File: Set the $to, $subject, and the path to the attachment with $file_path.
  2. Read and Encode the Attachment: The file’s contents are read, encoded in base64, and then chunk split to ensure it adheres to email standards.
  3. Create MIME Headers and Body: The email is composed using MIME standards with a unique boundary to separate different parts of the email. The headers include Content-Type set to multipart/mixed to accommodate both the text and the attachment.
  4. Constructing the Email: The email body contains both the text message and the attachment, separated by the boundary. Each part has appropriate headers to describe its content type, encoding, and disposition.
  5. Sending the Email: The mail() function is used with the recipient, subject, composed body, and headers.

Notes:

  • Make sure to replace /path/to/your/attachment.pdf with the actual path to your attachment file.
  • Update the From email address in the headers to your email.
  • This is a basic example. For more complex scenarios, like multiple attachments or different content types, it’s advisable to use a library like PHPMailer, as it greatly simplifies the process of sending emails with attachments, HTML content, and more.

I hope this article helps you figure out how to send email using PHP.

~Cyber Abyss