The Sec in SecDevOps

More or less, everyone that works in the software industry should be aware by now of the term DevOps and the life cycle of any application. Something similar to:

  • Plan: Gathering requirements.
  • Code: Write the code.
  • Test: Executing the tests.
  • Package: Package our application for the release.
  • Release: When the application artifacts are generated.
  • Deploy: We make it available to the users (QA, final users, product, …).
  • Operate: Take care of the applications needs.
  • Monitor: Keep an eye on the application.

All these bullet points are a rough description of the main stages of the application no matter what methodologies we are using.

The thing is that, nowadays, we should not just be aware of the term DevOps, we should be aware and, using or introducing, the term SecDevOps in our environments.

The ‘Sec’ stands by ‘Security’ and, it means, basically to add the security component and the help of security professionals to all the stages in the cycle, not just after the deployment like usually happens.

In addition to the common tasks we have in the different stages, if we add the ‘Sec’ approach, we should be adding:

  • Plan: We should be analyzing the Threat Model. For example, user authentication, external servers, encryption, … Here, we will be generating security focus stories.
  • Code: In this stage, the security proffesinal should be training and helping the team with the security concepts: tools, terminology, attacks. This will help developers to be aware of possible problems and write some defensive measures integrated in their code or follow best practices and recommendations.
  • Test: In this stage, specific tests to check security capabilities will be created allowing us to early detect possible problems.
  • Package: Here, we will check vulnerabilities in external libraries, vulnerabilities in our containers or code static analyzers.
  • Release: This stage can be combined with the previous one from a security point of view. Some platforms where the containers are stored, for example, integrate vulnerability scanners.
  • Deploy: Here, we can run dynamic security tests with typical ethical hacking tools.
  • Operate: Here is when the Red Team steps up in addition to resilience checks.
  • Monitor: We can analyze all our logs (we hope previously centralized) trying to discover security problems.

I hope this gives us a simplify view of how we can integrate security awareness and processes in our application cycles.

The Sec in SecDevOps

Random enum

As a software engineers or software developers we need to test what we are implementing (you have a description of types of tests here). When implementing these tests, we can hardcode the data we are using or, we can randomly generate it what, despite we can think it is going to make our life more difficult when debugging errors, it is going to make it easier in the long run. Our code should not be linked to the data it is processing, it should be generic for the type of data it is expecting.

To do this, the easiest way is to implement or use libraries that implement random generators. One of the most interesting and one it is always forgotten is the random generator for our enums.

In Java, there is an easy way to implement it.

It can be just for one enum class:

private static CarBrand randomCarBrand() {
    return CarBrand.class.getEnumConstants()[new Random().nextInt(CarBrand.class.getEnumConstants().length)];
}

Or, even more interesting, it can be a generic random generator that it receives as a parameter an enum class and return the random value:

public static <T extends Enum<?&gt;&gt; T randomEnum(Class<T&gt; clazz) {
    int x = random.nextInt(clazz.getEnumConstants().length);
    return clazz.getEnumConstants()[x];
}

We can see an example here:

import java.util.Random;

public class RandomEnum {

    public static void main(String[] args) {

        for (int i = 0; i < 10; i++) {
            System.out.println(randomCarBrand());
        }
    }

    private static CarBrand randomCarBrand() {
        return CarBrand.class.getEnumConstants()[new   Random().nextInt(CarBrand.class.getEnumConstants().length)];
    }

    enum CarBrand {
        ARUTI_SUZUKI,
        TATA,
        HONDA,
        HYUNDAI,
        FORD,
        MAHINDRA,
        SKODA,
        ARIEL,
        ASHOK_LEYLAND,
        ASTON_MARTIN,
        AUDI,
        BAJAJ,
        BENTLEY,
        BMW,
    }
}

Do not forget, from know on, if you are not doing it, try to make all your tests, except if you want to test an edge case, random and see how it goes.

Random enum

Checking certificate dates

Sometime, when we are working or doing some investigations in our spare time we need to check the dates a web certificate has, especially, the expiration date. Obviously, we can go to our browser, introduce the desired url and with a few clicks check the issued and expiration dates.

But, there is another way more simple, easier and, in case we need it, we can script.

echo | openssl s_client -servername www.google.co.uk -connect www.google.co.uk:443 2>/dev/null | openssl x509 -noout -dates

This simple command gives us the information we want.

I hope it is useful.

Checking certificate dates

Change file date and time

Sometimes if we need to perform some tests we need some files to have a modification day and time matching our criteria. If we are in a Unix/Linux based system, we can use easily the command line tool “touch”.

An example command will be:

touch -t 01010001 file.txt
touch execution

Extracted from “man touch”. The option “-t” changes the access and modification times to the specified time instead of the current time of day.  The argument is of the form:[[CC]YY]MMDDhhmm[.SS]

Change file date and time

Headless browser

A lot of people do not know but some browsers have a “headless” option we can use to execute operations using the console or terminal. This is useful for scripts, invocations from our applications or anything we can think of.

We just need to execute the next instruction:

firefox --headless --screenshot ~/image.png www.google.com

The result is going to be something like:

Headless browser

Java reflection: Accessing a private field

Sometimes, when we import 3rd-party libraries, we can find cases where the information we want is has been populated in an object but, the property is a private one and there are no methods to recover it. Here, it is where the Java reflection capabilities can help us.

Note: Use reflection carefully and, usually, as a last resource.

Let’s say we have a simple class with a private property:

class A {
    private String value = "value";
}

We want to access the property “value” but, for obvious reasons, we cannot do it.

We can implement our reflection method to access the property value:

import java.lang.reflect.Field;

public class Reflection {

   public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
      final A a = new A();
      final Field secureRenegotiationField = a.getClass().getDeclaredField("value");

      secureRenegotiationField.setAccessible(true);

      System.out.println((String) secureRenegotiationField.get(a));
   }
}

With these few lines of code, we will be able to access the value.

Java reflection: Accessing a private field

Groups in Regular Expressions

We cannot discuss the power of regular expression, an amazing tool with unlimited (usually our imagination) capabilities to progress strings. Every developer should, at least, have a basic understanding of them. But, lately, I have realized not a lot of people knows the possibility of creating and labeling “groups”. Groups allow us to access in a very  simple and clear way to the expressions matching our regular expression.

Regular expressions allow us to not just match text but also to extract information for further processing. This is done by defining groups of characters and capturing them using the special parentheses “(” and “)” metacharacters. Any subpattern inside a pair of parentheses will be captured as a group. In practice, this can be used to extract information like phone numbers or emails from all sorts of data.

Here, I am just going to write a little example to show the basic behavior and, I leave to all of you to find the appropriate use cases. In the example, I am going to extract some different hashes for further processing.

public static void main(String[] args) {
    final Pattern HASH_PATTERN = Pattern.compile("^(?<md5&gt;[0-9a-f]{32})(?:/)(?<sha1&gt;[0-9a-f]{40})(?:/)(?<sha256&gt;[0-9a-f]{64})$");
    final Matcher matcher = HASH_PATTERN.matcher("ce114e4501d2f4e2dcea3e17b546f339/a54d88e06612d820bc3be72877c74f257b561b19/c7be1ed902fb8dd4d48997c6452f5d7e509fbcdbe2808b16bcf4edce4c07d14e");

    if (matcher.matches()) {         
        final String md5 = matcher.group("md5");         
        final String sha1 = matcher.group("sha1");         
        final String sha256 = matcher.group("sha256");         
        ...
    }     
    ... 
}

As you can see, the example is pretty simple, it takes one line that contains a string and extracts the MD5, SHA1 and SHA256 hashes. We can see the code is easy to read and understand because everything is using human readable labels not just numbers to access the groups and there is no need to process the string with split operations or similars.

The syntax for the groups is:

(?<name>X)– X, as a named-capturing group

(?:X) – X, as a non-capturing group

With this, we can easily make our code easier to read and maintain when we are extracting information or doing some text processing.

For further information, check the Java documentation: Pattern (Java SE 10 & JDK 10)

Groups in Regular Expressions