Backend · How To · Linux · Web Security

How to set up ubuntu secure ssh login (AWS & Digital Ocean)

Ubuntu Initial Setup: setup ubuntu secure ssh login on digitalocean or Amazon Web Services EC2 instance

Download PDF:  Download Secure Login Cheat Sheet PDF

This post is a “cut to the chase”, “gitter dun” list of things to do for initial setup of an ubuntu server. To gain a deeper understanding of the process of securing your new ubuntu server, consult this well written article posted by ubuntu on the subject.

When starting up a new ubuntu server it is best to immediately take steps to secure the access to the server with the following steps.

As root, connect via ssh.

As root, make a new user .

As root, make the new user have sudo privileges.

Make ssh rsa keypair for the new user.

Copy local RSA key to remote authorized_keys
Digital Ocean


What this does on AWS ubuntu server:

As root, make /home/.ssh/authorized_keys have restricted access.

Passwordless Authentication: Configure ssh daemon
Edit sshd_config file to ensure that users can only connect with their SSH key

Make the following edits to the file. Search for the following settings and set them to the values shown below.

Then restart the ssh service

IMPORTANT: Before you log out, TEST.
Open a NEW TERMINAL use the new user to login.


Backend · File System Related · How To · Linux · Web Security

How to use multiple ssh keys for different accounts

I wanted to have multiple rsa keys for various different hosts to help prevent hidden connection issues.

Issues may arises when an rsa key is changed on one host that may have been used on another host effectively severing the connection without your knowledge.

By having different rsa keys when dealing with a host that is critical, one may prevent this.

The ~/.ssh/config file (on your local machine) can be edited so that it will refer to different ssh keys for different hosts.

Open the ~/.ssh/config file in a plain text editor. Then make modifications like this:

Note that these are NOT the public key but the private key.

Save the file and now you computer will use the appropriate key when visiting a host.

Ansible · Apache · Backend · File System Related · How To · Linux · Web Security

How To Create a Password Hash with Python passlib

Create a password hash with python passlib

A quick and easy way to create a password hash is with python passlib.

Install passlib with pip like this:

Then, run the command below. Of course, you will replace the text “myplaintextpassword” with YOUR OWN plain text password, right?

You’ll get back something that looks like this.

Linux · Web Security

umask Explained with Examples

umask is a unix command that sets the default file permissions for all newly created files and directories. It can be used to control the default file permission for new files.

This little blurb assumes that you understand the numeric mode of file permissions. That is, if someone tells you to make sure a file has permission 644, you’d be able to do that.

New directories have a default permission of 777, and files have a default permission of 666. Since that is wide open to the world, we to make it more secure.

This is where the umask command can help. The umask command automatically runs a chmod on newly created files. When a new file is created, the umask is subtracted from the permissions.

If we have a umask of 022 (pretty standard on most Linux distributions). When we create new directories, they end up with permissions of 755 (777 – 022 = 755). When we create new files, they end up with default permissions of 644 (666 – 022 = 644).

Here is another example of setting a more secure umask — 027. We do this by issuing the command umask 027. Now, newly created directories have permissions 750 (777 – 027 = 750), and newly created files will have 640 (666 – 027 = 640).

umask is typically run when the user logs in to the system, and is typically found in the /etc/profile shell script. Your system may be a little different.

also see:

Linux · Web Security

Using SGID to Control Group Ownership of Directories

1. My login id is paul and my primary group is webdev. I’m also a member of several other groups including staff. By default, any file (including a directory) I create will be marked with the group webdev (my primary group) .
$mkdir mydir
$ls -ld mydir
drwxr-xr-x 2 paul webdev 512 May 06 11:14 mydir
2. If I want my colleagues in staff to write to this directory, I need to change the group on the directory to staff and set the permissions to write for the group.
$chgrp staff mydir
$chmod 775 mydir
$ls -ld mydir
drwxrwxr-x 2 paul staff 512 May 06 11:14 mydir
3. Now staff can write to the directory, but we still have a problem if staff is not everyone’s primary group. Look what happens when paul, a member of staff who’s primary group is webdev, creates a file (paulfile) in the directory (mydir):
$touch mydir/paulfile
$ls -l mydir
total 0
-rw-r–r– 1 paul webdev 0 May 06 11:20 paulfile
At this point, I could issue the chgrp command and set the permissions manually.
There’s another solution.
4. The owner of the directory can set the SGID bit and all files subsequently placed there will have the group id of the directory automatically.
Make sure the group name is set first on the directory.
Give the group write permission on the directory.
Issue the command chmod g+s directory_name
$chmod g+s mydir
$ls -ld mydir
drwxrwsr-x 2 paul staff 512 May 06 11:20 mydir
Notice the “s” next to the group permissions in the listing.
(You can reverse it with chmod g-s)
5. Now, when I create a file in the directory, it will be marked with staff as the group, even though my primary group is webdev.
$touch mydir/anotherfile
$ls -l mydir
total 0
-rw-r–r– 1 paul webdev 0 May 06 11:20 paulfile
-rw-r–r– 1 paul staff 0 May 06 11:30 anotherfile
Notice that the pre-existing file “paulfile” didn’t change. I’d still have to issue chgrp on it.
Of course, I still need to set the group permissions to write if I want others to be able to edit these files.
What if you:
ftp a file into an SGID directory? — It inherits the GID of the directory, as above.
mv a file into an SGID directory? — It keeps its current GID.
cp a file into an SGID directory? — It inherits the GID of the directory.
mkdir inside an SGID directory? — It inherits the GID of the enclosing directory and is also marked SGID.

Backend · Drupal · Drupal 6 & Drupal 7 · PHP · Web Security

Secure URL Handling with Drupal

In most cases dynamic data in forms is handled by the forms API which does a pretty good job of keeping it clean. Since the variables in hook_menu() for example are picked up as a % sign and then translated into a callback array, they are “cleansed” as they are passed through the Drupal Core code.

On the other hand, there may be times when you you really need to pass dynamic data as a $_GET variable that is tacked onto an URL. In this case you need to pass the code through the urlencode() function.

When you are passing a user submitted URL in a hyperlink, rather than using check_plain(), the Drupal documentation says to use urlencode() instead.

Drupal · Drupal 6 & Drupal 7 · How To · Web Design · Web Security

Drupal Security Best Practices When Outputting Text Into HTML

When creating a module in Drupal it is very important to be aware of some security best practices when outputting text into HTML. This helps prevent XSS (Cross Site Scripting) exploits and keeps your code in general good health as it prevents problems with user input like angle brackets or ampersands.

Be sure to read the documentation for db_query() on how to use the database API securely.

When passing plain-text from the user to HTML markup, you need to pass it through the check_plain() function first. Drupal’s check_plain() converts quotes, ampersands and angle brackets into entities. This causes the string to be shown in a literal way on the browser screen.

There are a few themeable functions that automatically sanitize text by first passing it through check_plain(). They are: t() , menu items and breadcrumbs, Block descriptions (‘but not titles’), theme(‘ plain-text placeholder’), theme_username() and Drupal Form API #default_value element and #options element when the type is a select box.


As a Drupal module developer, it is important to commit to memory some common places where sanitizing plain text is important.

Setting the page title:

Form elements #description and #title

Form elements – #options when #type = checkboxes or #type = radios

Form elements – #value of #type markup and item need to be safe.
Note that the default form element #type is markup!

This information was gleaned from the Drupal documentation at “Handle text in a secure fashion”, which covers this topic more extensively than this post.

Backend · Drupal · Drupal 6 & Drupal 7 · Frontend · PHP · User Iterface Design · Web Security

Drupal Comments In A Block

Why would you need to put Drupal comments into a block?  Well, recently I was working with another developer that decided to use Quick Tabs to create a menu that would show the current content type’s comments. Quick Tabs uses blocks, so there is one reason I can think of.

Ok, so getting the content type’s comments into a block is pretty easy once you know how.

This method will require you to use PHP code from within the block you will create to show the comments. So the first thing is to make sure that this is possible by going to site building and then modules and turning on the PHP Filter under the category of Core Optional (if it is not already on that is).

NOTE: Check at admin/settings/filters to be sure that only trusted roles can use the PHP filter, otherwise your web site could be vulnerable to attack. By default, only the administrator can use this filter.

Create a new block and select a region for it. Put the following code on the body textarea:

comments in block php code for drupal

Do not forget to select the PHP filter from the list of the input filters. After entering the rest of the settings for your block click save.

Now your new block should be ready to assign to whatever region you want. If the page you load has comments related to it. They should now appear via the block.

The arg() funtion may seem a bit cryptic if you’re new to Drupal. Here is a quick explanation from George Notaras in his post: Drupal Tip: List a node’s taxonomy terms inside a Block which I found helpful in compiling this information.

“Now to some technical details about arg(0) and arg(1), which probably seem a bit cryptic to a user that is not experienced with Drupal (like me). Assume we have the following URL to a node:, which means that the path to the page is /node/23. Well, arg(0) is the node part and arg(1) is the second part; 23 that is. Read about the arg() function.”

I hope this was helpful.

AJAX · Backend · Frontend · How To · MySQL · PHP · Web Security

How to Protect Against SQL Injection

One of the most common web security problems is SQL Injection. As the name implies, SQL injections works by introducing malicious SQL code where it doesn’t belong. Since it is SQL code you could probably guess that the attacker “injects” his poison via database queries. Web developers often pass some sort of variable to their database queries. Very common are variables that are influenced by user input. User input, to variable, then to query,- get it? So, there is a need for a way of eliminating the user’s ability to manipulate the variable in any way that could effect the query.

What Happens With SQL Injection

By passing an unexpected string of code into a user input, such a form, an attacker send damaging code that causes an otherwise good query to go haywire. For example:

Backend · PHP · Web Security

PHP Error Reporting and Security

Error reporting in PHP gives valuable insight during the development stages. This Insight can be a great aid to problem solving. There are others, however who are interested in why your web site has failed on occasion. The information thrown out by many PHP errors gives the kind of information about your web application that can make you vulnerable to crackers (malicious web site breakers). In fact apart from reading the code itself, error reporting is some of the most valuable intelligence an attacker can gather when looking for vulnerabilities in your web application.

So, what should be done once you launch your new web site? Well, as proud as you may be of your new creative geniuses, a wise web developer has the humility to recognize that bugs are still likely to surface from time to time. While you do not want any attackers to see error