Tag: code execution
2013
07.02

Summary

A signed Java applet distributed with a number of products by F5 Networks contained a vulnerability which allowed for arbitrary code execution on a local machine under specific circumstances.

The vulnerability has been assigned CVE-2013-0150 and F5 has put together its own security advisory which lists affected applications and provides information on which versions contained patched applets. In the future F5 will ask Oracle to blacklist the applets so that they can not be used in a malicious attack.

Applet Overview

The applet in question is intended to be used to download and execute software from F5 on a user’s machine. The general workflow is as follows:

  1. Applet downloads executable (provided as a parameter to the applet named source)
  2. Applet verifies signature for executable (the signature is also provided as a parameter)
  3. If the signature is valid, the executable is run by the applet.

The vulnerability that I discovered was not in the signature scheme; instead, it involved a bug in how the applet saved the newly downloaded executable.

Vulnerability Details

The applet allowed you to provide a local filename for the downloaded file via a parameter named filename. The file was intended to be saved in the system temporary directory (%TEMP%, /tmp, etc). However, the filename parameter was vulnerable to a directory traversal attack. As a result, the file saved anywhere on the filesystem and would overwrite existing file contents.

For an attack on Windows machines, I realized that the executable could be saved in C:\Users\USERNAME\AppData\Roaming\Microsoft\Windows\Programs\Startup, which would allow the application to be executed when the machine next booted up. The %TEMP% directory by default is C:\Users\USERNAME\AppData\Local\Temp, so my malicious parameter looked like ../../../Roaming/Microsoft/Windows/Start Menu/Programs/Startup/app.exe.

The only interaction required by a user was to allow the signed Java applet to run. That interaction might not even have been necessary if the user had chosen to trust applets signed by F5 Networks in the past.

Disclosure Timeline

  • April 25th, 2013, 8:12 PM: Initial report to security-reporting@f5.com including incorrect proof of concept URLs (lead to 404).
  • April 26th, 2013, 3:34 PM: Reply from F5. Report has been replicated internally, requested correct proof of concept URLs.
  • April 26th, 2013, 4:09 PM: Sent corrected proof of concept URLs to F5
  • April 26th, 2013, 4:22 PM: Reply from F5, asking for confirmation of vulnerability assessment.
  • April 26th, 2013, 4:35 PM: Sent email confirming vulnerability assessment
  • April 26th, 2013, 4:38 PM: Acknowledgement from F5 that the relevant teams were analyzing the report.
  • April 26th, 2013, 5:40 PM: Email from F5 asking about disclosure timeline and finding attribution details
  • April 26th, 2013, 5:50 PM: Replied to F5. Provided additional information about Oracle’s Java blacklist.
  • April 26th, 2013, 5:56 PM: Followup from F5 confirming receipt of additional information.
  • May 2nd, 2013: Followup from F5. Issue is being triaged and fixes are being scheduled.
  • May 21st, 2013: Followup from F5. Fixes are being built and tested, updated products will be released soon.
  • June 7th, 2013: Followup from F5. Patches in place for many products, working on public announcement.
  • June 21st, 2013: Followup from F5. Fixes continue to be developed and released.
  • July 2nd, 2013, 11:26 AM: Followup from F5. Public announcement has been made.
  • July 2nd, 2013 6:30 PM: Blog post published

Conclusion

Signed Java applets are still a source of major insecurity beyond the many vulnerabilities discovered in the JVM itself. Developers working with signed Java applets should be especially cautions

This vulnerability was reported to F5 Networks in accordance with their policies on reporting suspected vulnerabilities. I want to thank them for their thoroughness and commend them for their smooth disclosure and remediation process.

2013
06.23

Summary

The JS-YAML module for Node.js contained a code execution vulnerability prior to version 2.0.5. The maintainers of JS-YAML have patched this vulnerability and, beginning in version 2.1.0, have provided a safeLoad method for parsing YAML. Developers that use this module should make sure they have upgraded and should strongly consider porting their code to use the new safeLoad method.

Update: The code execution vulnerability has been assigned CVE-2013-4660.

Vulnerability Details

The module allowed code execution due to a custom data-type that it defined and parsed called !!js/function. The way it would parse the data was to create a new Function object in JavaScript based on the input, which is equivalent to calling eval on the input:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
function resolveJavascriptFunction(object /*, explicit*/) {
  /*jslint evil:true*/
  var func;

  try {
    func = new Function('return ' + object);
    return func();
  } catch (error) {
    return NIL;
  }
}

That meant the code snippet below, when run, would execute code instead of simply defining a function:

1
2
3
4
5
6
7
8
var yaml = require('js-yaml');

x = "test: !!js/function > \n  \
function f() { \n    \
console.log(1); \n  \
}();"

yaml.load(x);

The vulnerability was patched under 24 hours after I initially contacted the module’s maintainers: the esprima package is now used to parse the input and validate it before execution.[1]

Why switch to safeLoad

Starting in version 2.1.0, the JS-YAML module provides a safeLoad function for use by developers. It is recommended by the maintainers as the default, in place of the load function demonstrated above.

The main difference between the two functions is what types are parsed:

  • safeLoad recognizes a “DEFAULT_SAFE_SCHEMA“, which parses “all supported YAML types, without unsafe ones (!!js/undefined, !!js/regexp and !!js/function)”
  • load recognizes a “DEFAULT_FULL_SCHEMA“, which parses all tags (including those which safeLoad does not).

A proof of concept from the module’s README demonstrates why load can be dangerous:

1
2
3
4
var untrusted_code = '"toString": !<tag:yaml.org,2002:js/function> "function (){very_evil_thing();}"';

// I'm just converting that string, what could possibly go wrong?
require('js-yaml').load(untrusted_code) + ''

By overriding functions like toString with arbitrary code or providing other unexpected input, an attacker can perform malicious actions as part of a Node application. Switching to safeLoad mitigates this risk because “dangerous” types are not parsed.

Conclusion

Developers using the JS-YAML module should make sure that they are working with an up-to-date version and should strongly consider porting their code to use safeLoad in place of load, especially when accepting YAML derived from user input.

If you’re interested in the security of Node modules, be sure to check out the Node Security project.