Posted on 1 Comment

The ultimate Guide of Security – Infrastructure Web application Hardening

This guide is written in order to help the IT Security Administrators secure their Infrastructure (VM in the cloud or something equivalent) that host web applications. It encloses knowledge that has been gained from multiple penetrations test from different vendors in projects that I have participated. It cannot protect you 100% but is a good and detailed way to start your security hardening.

Table of contents:

  • OS patching
  • Strong passwords and permissions
  • SSL Certificate
  • Install fail2ban
  • Set up firewall
  • Limit ssh access
  • PHP Hardening
  • Apache Hardening

OS patching:
Keep always your OS ( Red Hat Linux or equivalent) up to date with the latest security updates and patches. As a result before starting your installations perform an OS update. It is very important also to keep your Apache and PHP packages patched.

Strong passwords and permissions:
Create strong passwords for your users and add users with separate directories and permissions. Each user should have its own directory to manipulate files and should not have root access. For example if user X should be the application owner, then he should have permissions only to write/upload files in /var/www/application folder and no root permissions.

SSL Certificate:
Install a valid SSL Certificate and redirect all http traffic to https. You can view my blog post on how to install your apache SSL certificate from here. Redirection can be implemented by adding the appropriate rule in your .htaccess file.

Install fail2ban:
Fail2Ban scans log files like /var/log/auth.log and bans IP addresses conducting too many failed login attempts. You can find it from Github and configure it appropriately.

Set up firewall:
You should consider enabling a firewall for your infrastructure like Cloudflare that enables WAF/DDOS protection actions. You could also enable the build in Linux firewall and set up rules through iptables.

Limit ssh access:
Limit IP addresses that could access your infrastructure server. You could do that by disabling all from /etc/hosts.deny and allow only the IP addresses that you will use in /etc/hosts.allow . As a result you should

/etc/hosts.deny:
sshd : ALL

/etc/hosts.allow:
sshd : YOUR_IPS/24

PHP Hardening:
open_basedir, if set, limits all file operations to the defined directory and below. When a script tries to access the filesystem for example using fsockopen() the location of the file is checked. If the file is outside the defined directory PHP will refuse access.
Set openbasedir to your site directory. For example if your web application is a drupal installed in the directory /var/www/drupal then your openbasedir should be set to include your app directory and every other directory that you want (see below example).

open_basedir = "/home/X/:/var/www/drupal/:/tmp/"

Also you should consider disabling some php functions for security reasons like the below.

disable_functions = phpinfo,exec,shell_exec,passthru,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source,proc_close,symlink,apache_getenv,apache_get_modules,apache_get_version,apache_lookup_uri,apache_note,apache_request_headers,apache_reset_timeout,apache_response_headers,apache_setenv,closelog,curl_exec,curl_multi_exec,debugger_off,debugger_on,define_syslog_var,define_syslog_variables,diskfreespace,disk_free_space,dl,escapeshellarg,escapeshellcmd,exec,ftok,ftp_connect,ftp_exec,ftp_get,ftp_login,ftp_nb_fput,ftp_put,ftp_raw,ftp_rawlist,getmypid,getmyuid,highlight_file,ignore_user_abord,ini_alter,ini_get_all,ini_restore,leak,limit,link,listen,mysql_list_dbs,openlog,parse_ini_file,passthru,pclose,pcntl_exec,pg_host,php_uname,popen,posix_access,posix_ctermid,posix_getcwd,posix_getegid,posix_geteuid,posix_getgid,posix_getgrgid,posix_getgrnam,posix_getgroups,posix_getlogin,posix_getpgid,posix_getpgrp,posix_getpid,posix_getpwnam,posix_getpwuid,posix_getrlimit,posix_getsid,posix_getuid,posix_isatty,posix_kill,posix_mkfifo,posix_mknod,posix_setegid,posix_seteuid,posix_setgid,posix_setp,posix_setpgid,posix_setsid,posix_setuid,posix_times,posix_ttyname,posix_uname,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,readfile,readlink,safe_dir,satty,scandir,set_time,set_time_limit,shell_exec,show_source,socket_accept,socket_bind,socket_clear_error,socket_close,socket_connect,source,symlink,syslog,system,tmpfile,virtual

Disable allow_url_include and allow_url_fopen

allow_url_fopen=Off
allow_url_include=Off

The previous described actions should be applied on /etc/php.ini file.

Some of them may disable your web application behavior so you should check if you need them.

Apache Hardening:


Disable content or MIME sniffing:

Header set X-Content-Type-Options: "nosniff"

Defense from Clickjacking attack:

Header set X-Frame-Options: "sameorigin"

Set Strict-Transport-Security header settings configured for a timespan of 2 years:

Header set Strict-Transport-Security "max-age=63072000; includeSubDomains;"

Add X-XSS-Protection header to prevent some level of XSS:

Header set X-XSS-Protection "1; mode=block"

Add Referrer-Policy header to your webserver:

Header always set Referrer-Policy "same-origin"

Deny TRACE/TRACK requests:

RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
RewriteRule .* - [F]

Hide Apache Information:

ServerSignature Off
ServerTokens Prod

Of course there are a lot more things that could be applied for your infrastructure hardening per case. The system Administrator should always be up to date with the security standards and discoveries in order to eliminate risks from malicious unauthorized access.

Posted on 1 Comment

Consume php backend nested array on a C# Application – Json.NET

Lets assume you got a MYSQL database that contains data for your application and you want to consume this information on a C# Application in order to handle it on a client.

For the sake of this example the following table will be parsed

As depicted the following information is returned from the api:

  • the state of the response (succeeded or not)
  • a message that will show the response result
  • the actual result that in this case is a list of trips

Each trip contains id, fromlocation, tolocation, date and time properties that have to be returned to the application.

The php code that was used to create the data from the database is the following:

         $trips =array();
         while ( $row = $stmt->fetch() ) {         
         $obj["id"]= $row['id'];
         $obj['fromlocation']= $row['fromlocation'];
         $obj['tolocation'] = $row['tolocation'];       
         $obj['date']= $row['date'];
         $obj['time'] = $row['time'];         
         array_push($trips,$obj);
         }

         $response["success"] = 1;
         $response["message"] = "Trips returned successfully!";
         $response["trips"] = $trips;
         die(json_encode($response));

So in order to parse this json result we will need a plugin like Newtonsoft.Json

The class that will be used to encapsulate the response would be the following:

public class GetTrips
    {
        [JsonProperty("success")]
        public int Success { get; set; }

        [JsonProperty("message")]
        public string Message { get; set; }
        [JsonProperty("trips")]
        public Trip[]  Trips { get; set; }

       
        public class Trip
        {
            [JsonProperty("id")]
            public string Id { get; set; }
            [JsonProperty("fromlocation")]
            public string FromLocation { get; set; }
            [JsonProperty("tolocation")]
            public string ToLocation { get; set; }
            [JsonProperty("date")]
            public string Date { get; set; }
            [JsonProperty("time")]
            public string Time { get; set; }
        }

    }

And then we will consume the json response with the following code in C#. In this example data from the API came from a POST request on a web Form.

public async TaskGetTripsAsync(string username,string password)
        {
            try
            {
                var keyValues = new Liststring, string>>
                {
                    new KeyValuePair("username",username),
                    new KeyValuePair("password",password)
                };

                var request = new HttpRequestMessage(HttpMethod.Post, Url);
                request.Content = new FormUrlEncodedContent(keyValues);

                var client = new HttpClient();
                var result = await client.SendAsync(request);
                var content = await result.Content.ReadAsStringAsync();
                var tripsResult = JsonConvert.DeserializeObject (content);
                return tripsResult;
            }
            catch (Exception)
            {
                return null;
            }
        }

Posted on Leave a comment

SQL queries with PHP on MYSQL database – Azure

A few days ago i activated Azure for students through Dreamspark. I am very happy microsoft give those tools for free in students. After searching the options that are available for free, i found that i could use some mysql databases. As mysql is very common and frequently used, i created a database and wanted to add some data. Unfortunately i couldn’t find a tool for managing the database. As you may know most linux servers come with phpmyadmin pre-installed. So what about Azure?

There are many options for Azure.

  1. You can connect to your database with mysql commands using mysql command line tool.
  2. You can download a GUI tool and do the work (mysql workbench)
  3. You can use any php code to connect.

So here comes this github project with which you can connect on a mysql database that is stored in Azure.

See more details in the below pictures

First of all you must create a mysql database.

new_mysql

After you create the database you must press properties window to see the connection credentials. Those are: Host name, Database Name, Username, Password.

connection

Then you are ready to start using your mysql database. And here comes the PHPqAzure.

As you can see, after entering your credentials you can run your queries. Query result is returned after query is executed.

Example:

Create a test table.

 

create_table

Add some data

insert

And you are ready. You can see the result with a mysql GUI management tool like Mysql Workbench.

program_view

You can perform as many queries as you want. Make sure your queries executed successfully with the results tab.

If i enter something wrong then the result will inform me for that.

wrong-query