Advertisement
  1. Code
  2. PHP
Code

Building Your Startup: Increasing Security

by
Difficulty:IntermediateLength:MediumLanguages:
This post is part of a series called Building Your Startup With PHP.
Building Your Startup: Invite People via URL
Building Your Startup: Preparing for Text Messaging
Final product image
What You'll Be Creating

This tutorial is part of the Building Your Startup With PHP series on Envato Tuts+. In this series, I'm guiding you through launching a startup from concept to reality using my Meeting Planner app as a real-life example. Every step along the way, I'll release the Meeting Planner code as open-source examples you can learn from. I'll also address startup-related business issues as they arise.

In the prior episode, I covered primarily web server security and access control. In today's episode, I'll discuss additional safeguards that I added to Meeting Planner. Since all the code is written in the Yii2 Framework for PHP, I was able to leverage the framework for a number of these fortifications. If you'd like to learn more about Yii2, check out our parallel series Programming With Yii2.

You can try out Meeting Planner right now by scheduling your first meeting. Feel free to post feedback about your experience in the comments below. I'm also open to new feature ideas and topic suggestions for future tutorials.

Building Increased Security

Implementing the various levels of security for Meeting Planner will take several episodes. Now that the server is more robustly configured, I want to guide you through other areas of security for the application code.

Protecting Keys and Codes

Obviously, it's important to keep authenticating keys away from hackers, but it's also pretty easy to publish them to GitHub. Stories are told of accidental check-ins of files with a service password or API key. 

To prevent this in Yii, I keep an external .ini file outside of the code tree. This gets loaded at the top of /frontend/config/main.php and is used for any component configuration that's necessary:

In the example above, you can see the Facebook API secrets loaded from the initialization file.

The format of the initialization file is a fairly straightforward one:

Yii2 encourages you to place some of these settings in the /environments directory, especially when the settings vary between development and production.

Thus, it's important that your .gitignore file exclude the local versions of these files:

Here's an example of one of my local parameter files, /frontend/config/params-local.php:

I could probably spend even more time better organizing these.

Blocking Bad Signups

Building Your Own Startup - Preventing Spam Signups

For the alpha release, I sent out updates in waves. And, in the early stages of Meeting Planner, there were a larger number of bad emails than I expected. Mailgun made it easy to identify the bounces and failures:

Most of these are likely from the gap in time when Meeting Planner was new and sat idle—during my brain tumor treatment and surgery

More recently, by adding the social logins, I've made signing up for Meeting Planner quite easy, but spam sign-ups are still possible. I wanted to make it more difficult for people to register with bad emails.

Fortunately, Yii offers a couple of features that support this.

Captcha

Yii2 now offers a built-in captcha. So, anyone signing up with the old school email and password method has to enter a captcha. You can see the captcha field below:

Then, compliance with the captcha is added as a rule for the SignupForm model:

If people don't enter the correct captcha response, they can't sign up. This makes automated registration difficult for spammers.

CheckDNS

I also wanted to minimize registration with a fake email address. Yii's checkDNS validation actually looks for a valid MX record based on the email address's domain:

So, for example, if I mistyped gmail.com as gmal.com, checkDNS returns false. There is no registered MX record for gmal.com. Similarly, there is none for spambotolympics9922.com.

Ultimately, security is an iterative process. There's always more to do.

Limiting Abusive Actions

Next, I wanted to add common limits to the number of actions people could perform, to limit abuse and to keep the application from becoming unwieldy.

Meeting Creation

To prevent people from creating lots of empty meetings, I created a findEmptyMeeting which looks for an empty meeting and reuses it when someone tries to create a new one:

In other words, if a user goes to create a new meeting 1,700 times, they will always be presented with the first empty meeting they created.

Limiting Frequency of Actions

I also created a commonly structured withinLimit method for reuse around the application which could prevent too many actions in too short a time. The example below checks that no more than n number of meetings have been created in the last hour and last day:

Anytime someone tries to create a meeting, we check withinLimit to see if they can. If not, we show the flash error message:

Limiting the Number of Actions

I also wanted to limit the overall number of actions. For example, each meeting participant can only add seven meeting date times per meeting. Within MeetingTime.php, I set MEETING_LIMIT, so it can be changed later:

Then, MeetingTime::withinLimit() checks to make sure that no more than seven times have been suggested by any user:

When they go to create a MeetingTime, the controller create method checks the limits:

Securing CRON Jobs

Finally today, I wanted to secure access to remote cron jobs. There are some interesting approaches described out on the interwebs. For now, I'm checking that the $_SERVER['REMOTE_ADDR'] (the requesting IP address) is the same server as the hosting $_SERVER['SERVER_ADDR'], the local IP address.  $_SERVER['REMOTE_ADDR'] is safe to use for security—in other words, I've read that it can't be spoofed.

For my own testing, I also allow a logged-in administrator to run cron jobs.

Eventually, I may also add a password to my cron jobs and move them to command-line operations.

Looking Ahead

I've accomplished a lot of security improvements over the past two episodes, but there's still more to do. On my shortlist is deeper review of access security, especially via AJAX, IP address tracking and blocking, and carefully filtering all user input.

Again, what are you waiting for? Schedule your first meeting, and share your feedback in the comments. I'd also appreciate your comments on security issues. 

As always, you can watch for upcoming tutorials in the Building Your Startup With PHP series or follow me @reifman. There are a few more big features coming up.

Related Links

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.