Building scalable and secure e-commerce websites is a complex endeavor. There are enough problems to worry about when managing PCI compliance, firewalls, DDoS attacks, and malicious hackers. Today we are going to tackle the low-hanging fruit that can help you avert fraudulent credit card orders or cyber-attacks from outside your country of origin.
In 2013, Indonesia surpassed China for hacking-related Internet traffic as reported by Akamai. These two countries account for over 70% of attack traffic. When you only offer local shipping, there are few reasons to leave your e-commerce website open to every country in the world. Lets explore how to allow or block countries or even whole continents in a PHP application.
Minion is a framework for running command line (CLI) tasks in Kohana PHP. This is handy for executing cron jobs that have access to your full stack of code much like regular controllers; however, they are not visible to public facing URIs for security reasons.
Using a Minion Task we are able to download the monthly updated GeoLite2 City and Country IP geolocation database. For completeness, we verify the md5 checksum prior to installing the new DB files. The GeoLite2 database is distributed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. A more accurate commercial GeoIP2 database is a drop-in replacement when you decide to upgrade.
./minion —-task=Maxmind:GeoLite2 —-city=1
The next step is to install the PHP MaxMind-DB-Reader API to gain access to the IP-to-geolocation database. You can skip this step if you are using our Vagrant development environment! Using Maxmind’s C API wrapper is essential for performance.
We can geolocate a client by IP address using a custom Maxmind PHP Class. Below are the various ways our Maxmind Admin Controller Action can present the geo details in html, txt, and json. This is the framework for the geolocation API in Zen Kommerce.
/admin/system/maxmind?ip=64.233.160.0
/admin/system/maxmind.txt?ip=64.233.160.0
<?php Array ( ["remote ip"] => 64.233.160.0, ["city"] => "Mountain View", ["postal code"] => 94043, ["continent"] => "North America", ["iso-3316"] => "US", ["country"] => "United States", ["latitude"] => 37.4192, ["longitude"] => -122.0574, ["metro_code"] => 807, ["time_zone"] => "America/Los_Angeles", )
/admin/system/maxmind.json?ip=64.233.160.0
{ "remote ip": "64.233.160.0", "city": "Mountain View", "postal code": "94043", "continent": "North America", "iso-3316": "US", "country": "United States", "latitude": 37.4192, "longitude": -122.0574, "metro_code": "807", "time_zone": "America\/Los_Angeles" }
With the geo details in hand, restricting access is simple as checking the iso-3316 code against a list of approved or denied countries. We accomplish this in our Kohana module init script with Kommerce::verify_country() which checks the environment configuration file for a list of allowed/denied countries and presents a 403 Forbidden HTTP status code for unauthorized access.
Using Codeception we can verify specific countries are blocked from our application.
You now have a functional IP geolocation database that can be used to restrict traffic by continent, country, or even city. Equipped with this new ability to secure your web application from malicious regions, you have another way to provide a reliable web experience for your customers. We are well on our way to building a scalable and secure e-commerce platform with Zen Kommerce.