10 mistakes hackers want you to make

Thursday, December 20, 2018

There are many types of security measurements which can be applied to your application. Security on the network, on the platform, even physical security measurements. But these kind of security levels are mostly out of the control of developers. What are some common mistakes application developers make on an application level? Which mistakes do hackers want you to make?

1. Using dependencies with known vulnerabilities

One of the most important issues in application security is the use of libraries which are known to be vulnerable for exploits. In fact, more than 70% of real-world attacks exploit a known vulnerability for which a fix was already available but has not yet been applied.

Last year, Equifax, a US credit bureau, got hacked by exactly this kind of bad practice. It led to a  massive data breach and the exposure of personal data of nearly 143 million Americans. They were using a vulnerable version of the Apache Struts library, for which there was already a patched release version available before the hack occurred.

This was a wake-up call for us. We can easily automatically manage our dependency versions with Maven. But did you know Maven can compare the dependency versions that you’re using with the newer version which are available on Maven Central?

- Mvn versions:display-parent-updates

There’s also a command to update these versions to the latest ones.

- Mvn versions:update-parent

But honestly, we’re lazy and we’re probably not going to run these commands anyway. We can add a Maven plugin “dependency-updates-report” to our pom.xml to generate report with all available dependency version updates and let this plugin run each night for example.

<plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>versions-maven-plugin</artifactId>
      <version>2.7</version>
      <reportSets>
        <reportSet>
          <reports>
            <report>dependency-updates-report</report>
          </reports>
        </reportSet>
      </reportSets>
    </plugin>

This is a nice approach, but we can do even better.

Snyk

Snyk is a “Continuous Vulnerability Detection & Resolution” product. Snyk is a product which will continuously monitor your app to check if you’re using outdated, vulnerable dependencies and will send you a notification if this is the case. It will map your dependencies and check this against a database with known vulnerabilities to see if your dependency is at (high) risk. This product has a free edition but to use this professionally, you will need to pay.

2.Unsanitized User Input

We all know validating user input is important to secure our apps to well-known attacks like SQL-injection.

But there are more unexpected issues. Recently there was a vulnerability in a Python web framework which allowed hackers to enter a really long password, like 4000 chars long, to create a Denial of Service attack. The server would then try to encrypt this password to compare it to the password stored into the database. But the process of encrypting such a long password took so long that the server eventually went of out memory and crashed.

To secure our apps from this, we can add validation at the backend side, with annotations for example, to set the correct constraints. But we also need to validate the user input more early in the process.

Schema Validation

If you’re using JSON to transfer user input, you can use JSON Schema validation frameworks, such as everit.org/json-schema, to strictly validate the structure and contents of the JSON file.

The same goes for XML formats. Besides having XSD validation, check out Schematron for example. It’s an easy to use framework, based on XPath to define custom schema rules on XML content. For example, you can define how many times you want a certain combination of attributes within the same parent tag.

You can create a Filter or Interceptor, to validate your user input whenever a request comes in.

3. Unsafe RegEx

Hackers can exploit unsafe regular expressions to create a Regex Denial of Service attack. They will enter specially crafted Strings to make the server use so much resources trying to match the Regex, resulting in a crash.

Safe Regex

If you’re using Regex in your application, make sure to validate it. There are a few frameworks, like SafeRegex, which can validate Regex to see if it’s vulnerable to attacks.

4. Failure to prevent abusive requests

There will always be people who will try to exploit or gain information about our systems by sending abusive requests.

To prevent this behavior we can throttle, sometimes blacklist, our users by IP address to other headers.

Bucket4j

This framework uses a “token bucket algorithm” to group requests of certain types based on various properties. You can then configure the amount of bandwidth you want to make available for these certain groups or types of requests. It supports clustering, so if you’re running your application on multiple, clustered servers, it will still be able to group the requests. It’s used by the JHipster API Gateway. You can easily add it your application with Spring and configure the framework with a .yaml file.

5. Blindly following Stackoverflow accepted answers for Spring Security

A study found out that a significant amount of accepted answers on Stackoverflow had actually vulnerabilities in the code they were suggesting. A common case was in fact misconfiguration of Spring Security. For example using “permitAll” in the wrong places!

The bottom line is, don’t trust people on the internet!

6. Secrets in your source code

Application configuration should be strictly separate from the code. Basically, don’t check passwords into git. Especially not production secrets. It’s not because the git repository is private to your company that it’s ok to do so. The code is still stored in plain text on some server in California, USA.

Take action by using environment variables for example, or by dynamically adding property files to the deployment by authorized personnel in your company.

7. Allowing HTTP requests

HTTPS is everywhere nowadays. Disable HTTP requests on your application server. Install a Apache HTTP server in front of your application which redirects to the HTTPS ports of your application, if possible. Or if you’re using Spring, you can use the HttpSecurity method “requireSecure()”.

8.​ Disabling certificate checking

Make sure to configure your JVM truststore correctly. Add the right root certificates to allow requests to other servers.

If you get an exception saying a signature cannot be validated, you need to examine this issue carefully. On Stackoverflow, some answers suggest to disable certificate checking. Don’t do this! Again, don’t trust people on the internet.

9. Lack of intrusion detection

We’re going to get intrusion attempts no matter what. Sometimes it will be successful. So we need to be able to detect those attacks so we can respond to this quickly as possible.

Log

The OWASP group suggests to log the following actions:

  • Logins
  • Logouts
  • Password changes
  • User profile changes
  • Password reset
  • User de-registration
  • Authorization failures
  • Changes to access levels
  • Operational activities
  • Input validation failures
  • Any sensitive operation

But equally important, what should we NOT log:

  • Session ID for correlation (hash instead)
  • Passwords
  • Anything sensitive

Remember that logs are stored in plain text so any type of sensitive data should not be logged.

OWASP also recommends to log with special security markers

  • SECURITY_SUCCESS
  • SECURITY_FAILURE
  • SECURITY_AUDIT

If you’re using Logback as a logging framework you can create custom markers, next to the default ones like INFO, WARN, ERROR, etc.

Detection with AppSensor

Logging is not enough. We need to have some sort of intrusion detection. Most implementations of intrusion detection operate on a level below our application level. But these kind of systems have no knowledge of any business rules, for example this user is logged in and is trying to access a resource they’re not supposed to obtain. That’s something we can only capture from within the application.

OWASP has a project called “AppSensor”. It allows us to detect but also to respond to this kind of attacks. AppSensor is in fact a specification but there’s also a reference implementation, written in Java which uses Spring Boot.

AppSensor will add a client or agent to your application which will send events to the AppSensor service. This service will analyze those events to determine if they’re malicious and then send a response back to the webapp. For example, when a user tries to login with a bad passwords, they probably just typed it wrong. If they retry this multiple times, it may be a brute force attack. AppSensor can detect this kind of behavior and send a response back to the webapp.

10. You!

Human error is still a real threat to application security. While it’s sometimes common sense, we still need to be careful. Use Two-Factor Auth for important functions. Don’t leave laptop unlocked. Update your passwords frequently.

And most importantly, log out of Facebook when using a public computer, you don’t want to learn this one the hard way.

 

Laurens Dirkx

This blog is based on the talk of Joe Kutner at Devoxx. Rewatch it here or view the slideshow.