Skip to content

Java Static Scanner reference

Running the scanner

The SandboxAQ Java Bytecode Scanner is a Java application. To execute it, run either:

  • Linux - /path/to/java-static-scanner-<VERSION>/bin/java-static-scanner
  • Windows - /path/to/java-static-scanner-<VERSION>/bin/java-static-scanner.bat

Note

The example below is for Linux.

./java-static-scanner-<VERSION>/bin/java-static-scanner \
    --search-path /path/to/classes/and/jars \
    --trace /path/to/trace/or/directory \
    --show-calls all \
    --add-call-sites

Computing coverage

The example plain text report presented in Getting Started has limited practicality. The primary purpose of the Java Bytecode Scanner is to work together with the SandboxAQ Java Tracer and AQtive Guard to compute coverage of cryptographic call sites in a trace. The steps below outline how to do this:

  1. Run the application with the Java Tracer attached to generate a trace file. See Tracing the Application for details.

  2. Rather than uploading the trace immediately, use the Java Bytecode Scanner to scan the bytecode and produce an augmented trace:

    Bash
    /path/to/java-static-scanner-<VERSION>/bin/java-static-scanner \
        --search-path /path/to/application/class/and/jars \
        --trace /path/to/trace.cst.gz \
        --add-call-sites
    

    The augmented trace file trace-with-scan.cst.gz is saved in the same directory as the original trace.

  3. You can now upload the augmented trace. Refer to the API Client manual for how to upload a trace.

  4. Generate a report as you normally would. The summary at the top of the inventory page will now include a new Coverage line. Additionally, the Call Sites tab will categorize call sites into three types:

    • Sites found in both the scan and the trace: Indicates all is well.
    • Sites found in the scan but not in the trace: These call sites exist in the application, but weren’t executed during trace generation. If the trace was generated by running the application test suite, inadequate test coverage may be the cause, missing some of your application’s cryptography.
    • Sites found in the trace but not in the scan: Your scan didn’t cover all the bytecode that makes cryptographic calls. These calls likely originate from an external library. Review the calls listed in the Call Sites tab to determine your next steps. For instance, you may need to specify a library’s JAR file in your next scan.

Finding hard-coded cryptographic values

To find hard-coded cryptographic values, start with an application and a trace file generated by the Java Tracer. Run the Java Bytecode Scanner on the application, but this time use the --find-strings option:

Bash
/path/to/java-static-scanner-<VERSION>/bin/java-static-scanner \
    --search-path /path/to/application/class/and/jars \
    --trace /path/to/trace.cst.gz \
    --find-strings

This will add all string literals found in the bytecode to the trace file.

Upload the trace-with-scan.cst.gz augmented trace file and generate a report. Any hard-coded cryptographic keys, passwords, IVs or salts found in the bytecode and used by the application will now be in the vulnerabilities list as violations of Rule 55: Hard-coded Cryptographic Value.

Tip

The --find-strings and --add-call-sites options aren’t exclusive and can be used together in the same run.

Arguments

The arguments that can be used are explained below:

--search-path (required) - Path to the directory containing .class, .jar and .war files to be scanned. This tool only analyzes Java bytecode, not source code.

--add-call-sites (optional) - Only relevant if --trace is also specified. Adds all cryptographic call sites to the trace. If the original trace was in foo.cst.gz, the augmented trace will be in foo-with-scan.cst.gz.

--continue-on-parsing-error (optional) - If the scanner encounters a class that the bytecode parser can’t handle, it logs a warning and continues instead of terminating.

--debug (optional) - This increases the logging verbosity to log every event.

--exclude (optional) - Comma-separated list of package prefixes to be ignored. For instance, if your application bundles the library com.example with cryptographic calls you’d like to exclude, you can use com.example as a prefix to omit classes like com.example.SomeClass or com.example.sub.OtherClass from the scan. Defaults to com.sun,java,javax,org.bouncycastle,sun.

--find-strings (optional) - This finds all string literals in the bytecode, along with their locations. If --trace is also specified, this information will be inserted into the trace. If the original trace was in foo.cst.gz, the augmented trace will be in foo-with-scan.cst.gz. The augmented trace file can be uploaded to AQtive Guard for the detection of hard-coded cryptographic values such as keys, IVs, salts, etc.

  • For text output, this option adds a summary line indicating the number of strings found.
  • In JSON output, the list of strings found is included.

--json (optional) - Generate a report in JSON instead of plain text.

--num-passes (optional) - Define the maximum number of passes the scanner will execute over the code looking for call sites. The initial pass identifies the locations of calls to the Java cryptographic API. Subsequent passes identify where the calls in the previous pass originated. Setting a value of 0 means the scanner will continue exploring the entire application all the way up to the entry point until it doesn’t discover anything new. Defaults to 1.

The primary benefit of this option is if your application uses a wrapper layer around the standard cryptographic API, and you want to discover where in the application this layer is called.

Caution

When using this setting for large applications, the number of indirect call sites found may rapidly increase with the number of scanner passes. Setting --num-passes to 2 or 3 is typically sufficient.

--quiet (optional) - This decreases the logging verbosity to log only the most serious errors.

--trace (optional) - Path to either a Sandbox trace (.cst or .cst.gz file), or a directory containing multiple traces. It’s only useful in conjunction with --add-call-sites, --find-strings, or both.

Here are some examples using different arguments:

Excluding some packages:

./java-static-scanner-<VERSION>/bin/java-static-scanner \
    --search-path /path/to/classes/and/jars \
    --exclude java,javax,sun,org.bouncycastle,org.jboss

Producing a JSON format report:

./java-static-scanner-<VERSION>/bin/java-static-scanner \
    --search-path /path/to/classes/and/jars \
    --json

Missing information in call sites

The Java Bytecode Scanner pulls line number and source file information from the debugging data generated during compilation. If the debug information is missing, your analysis won’t include line numbers or file names.

When compiling your Java source code, make sure to use an option that generates debugging data:

  • Line number and source file information is generated by default.
  • The -g option generates all debugging information, including local variables.
  • Don’t use -g:none, as this stops the required debug data from being generated.

Refer to the javac command documentation for more details.

Caution

Some third-party JAR files may not include any debugging information.

Using the static scanner to enhance a host scan

The Filesystem Scanner can use the bytecode scanner to inspect JAR files found during a host scan and extract any hard-coded keys or certificates in the bytecode. Refer to the Filesystem Scanner reference for more details.