搜尋此網誌

2009年9月24日 星期四

[工具介紹] Static Application Scanner for Java

這幾年應用程式(尤其是網站應用程式,Web Application)的安全問題受到各方重視,一些新的、舊的概念,只要跟此議題有所關聯都因此而浮上檯面。包含SSDLC/SDL、WAF、Secure Coding、Application Security Scanner等在內的各式各樣工具或規範,試著從不同的面向去解決程式安全的問題。

Gartner 於今年年初出了一篇有關靜態程式安全掃描的市場分析,分析對象為目前市場上主要的玩家。但是這些產品大多所費不貲(除了整在 IDE 中的形式,可能會有免費使用的陽春功能),而且甚至很多產品在台灣還沒有直接取得的管道。所以我們今天要介紹一些免費的工具,這些工具的共通點就是提供靜態應用程式檢測的功能,而且以 Java 程式語言做為目標。除了可以當作獨立的工具使用外,有些工具還可以透過外掛的方式整合至 IDE (像是 Eclipse),使用上更加方便。除此之外,各個工具之間可說是具有相當的差異性。檢測的對象可能是原始程式碼,也有可能是 Byte Code。而著重的面向也不一樣,可能是原始程式碼的不良結構,也可能是針對程式不合常理的錯誤,又或者是針對不好的寫作方式。這些問題都跟軟體的品質有關,而品質當然也包含了安全的問題。

這些工具都不是以安全做為訴求的出發點,而且大多也不支援網站應用程式,所以僅能當作增進一般應用程式品質/安全的工具之一,而無法有效的面對現今網站程式開發所面臨的威脅。雖說如此,網站應用程式依舊是屬於應用程式的一種,所以其安全性的問題不應只是考慮到網路的部分,包含基本的程式結構等也是我們應當注意的項目。這些工具部分的檢測功能其實 IDE 本身可能就已經具備,但是以目前現況而言,IDE 主要的功能依舊還在不此,所以能夠偵測的項目相對較少。

在這篇文章中,我先列出這些工具的名稱與簡述。簡述皆為從官方網站截取的描述,所以是英文的形式。之後我會針對各個工具撰寫相關的使用說明,說明時除了做功能的介紹外,也會利用實際的應用程式作為範例。採用的應用程式有兩個,一個是 log4j 1.2.15 ,另外一個則是 struts 2.1.6。如果該工具支援 Eclispe 的外掛,我將會以 Eclipse 作為操作的 IDE 環境。因此我先將兩個應用程式的程式碼匯入為 Eclipse 的專案,透過畫面我們可以看到 Eclipse 本身就產生了很多的警告訊息。我個人認為 Eclipse 提供的警告訊息雖然跟程式錯誤與否無關,但是大多數的建議可以讓我們的程式碼更加清楚、更加容易明瞭。對程式碼而言,這是最重要的要求。因為錯誤不只在開發的時候會產生,在後續的維護中更容易產生。透過清楚而易了解的程式碼,可以大幅降低後續維護時產生錯誤的機會。也因此我個人建議這些警告訊息應該先進行處理,之後再利用其他工具找尋其他的問題。

 

將 log4j 1.2.15 的程式碼匯入 Eclipse 中。

eclipse log4j

將 struts 2.1.6 的程式碼匯入 Eclipse 中。

eclipse struts

 

PMD scans Java source code and looks for potential problems like:
  • Possible bugs - empty try/catch/finally/switch statements
  • Dead code - unused local variables, parameters and private methods
  • Suboptimal code - wasteful String/StringBuffer usage
  • Overcomplicated expressions - unnecessary if statements, for loops that could be while loops
  • Duplicate code - copied/pasted code means copied/pasted bugs

Checkstyle is a development tool to help programmers write Java code that adheres to a coding standard. It automates the process of checking Java code to spare humans of this boring (but important) task. This makes it ideal for projects that want to enforce a coding standard.

Checkstyle is highly configurable and can be made to support almost any coding standard. An example configuration file is supplied supporting the Sun Code Conventions. As well, other sample configuration files are supplied for other well known conventions.

Beyond the level of what Javadoc does, DoctorJ compares documentation against code. Among what it detects:
  • misspelled words
  • parameter and exception names:
    • missing
    • misordered
    • misspelled
  • Javadoc tags:
    • invalid
    • misordered
    • missing expected arguments
    • invalid arguments
    • missing descriptions
    • undocumented classes, methods, fields, parameters

ESC/Java2 (Eclipse plugin available)
The Extended Static Checker for Java version 2 (ESC/Java2) is a programming tool that attempts to find common run-time errors in JML-annotated Java programs by static analysis of the program code and its formal annotations. Users can control the amount and kinds of checking that ESC/Java2 performs by annotating their programs with specially formatted comments called pragmas.

FindBugs (Eclipse plugin available)
FindBugs looks for bugs in Java programs.  It is based on the concept of bug patterns.  A bug pattern is a code idiom that is often an error.  Bug patterns arise for a variety of reasons:
  • Difficult language features
  • Misunderstood API methods
  • Misunderstood invariants when code is modified during maintenance
  • Garden variety mistakes: typos, use of the wrong boolean operator
FindBugs uses static analysis to inspect Java bytecode for occurrences of bug patterns.  Static analysis means that FindBugs can find bugs by simply inspecting a program's code: executing the program is not necessary.  This makes FindBugs very easy to use: in general, you should be able to use it to look for bugs in your code within a few minutes of downloading it.  FindBugs works by analyzing Java bytecode (compiled class files), so you don't even need the program's source code to use it.  Because its analysis is sometimes imprecise, FindBugs can report false warnings, which are warnings that do not indicate real errors.  In practice, the rate of false warnings reported by FindBugs is less than 50%.

FindBugs supports a plugin architecture allowing anyone to add new bug detectors.  The publications page contains links to articles describing how to write a new detector for FindBugs.  If you are familiar with Java bytecode you can write a new FindBugs detector in as little as a few minutes.

FindBugs is free software, available under the terms of the Lesser GNU Public License.  It is written in Java, and can be run with any virtual machine compatible with Sun's JDK 1.5.  It can analyze programs written for any version of Java.  FindBugs was originally developed by Bill Pugh and David Hovemeyer.  It is maintained by Bill Pugh, and a team of volunteers.

FindBugs uses BCEL to analyze Java bytecode.  As of version 1.1, FindBugs also supports bug detectors written using the ASM bytecode framework.  FindBugs uses dom4j for XML manipulation.

JeSS is a plugin for the Eclipse IDE. It is a static security scanner for Java source code. The plugin creates an AST for the source code and then uses the visitor pattern to find patterns in the AST that could be possible security bugs.

Hammurapi is a code quality governance platform to mitigate risks of outsourcing of software development.

Hammurapi produces a consolidated report for the entire application. The report identifies most significant problems in the application and allows to navigate to the source of the problem in a few clicks.

Modern applications consist of source artifacts developed in different languages. For example, a typical Java application contains at least Java sources and XML configuration files. A Java-based web application also contains JSP(X) files. With AJAX and Flex gaining popularity, more and more functionality gets developed in JavaScript. Therefore, analysis of just one type of source artifacts is not sufficient for gaining confidence in the application.

Currently Hammurapi can review Java and XML-based artifacts. Support of JavaScript is coming in the first half of 2009.

JAMIT, the Java Access Modifier Inference Tool can be used on Java class-files to infer tighter access modifiers. Tight access modifiers are commonly perceived as good programming practice. Nevertheless, refactoring of code or just ignorance at the time where the code is written often lead to modifiers that are less restrictive than they could be.

More restrictive modifiers help to increase encapsulation, one of the major goals in object oriented program design. They can also serve as a criteria for good software engineering. In some cases, more restrictive modifiers can even help the compiler to produce better (= faster) code.

The most restrictive modifier supported by Jamit is dead. In other words, Jamit can be used to eliminate dead code from Java applications and libraries. In this sense it is similar to JAX. Eliminating dead code with Jamit is easy. You specify the main method, a file that defines native and reflective behavior, the input directory with the original classes and an output directory where the optimized classes are to be written to. The resulting code can often be significantly smaller, especially if the code was using small parts of a larger framework.

JCSC is a powerful tool to check source code against a highly definable coding standard and potential bad code.

The standard covers naming conventions for class, interfaces, fields, parameter, ... . Also the structural layout of the type (class/interface) can be defined. Like where to place fields, either before or after the methods and in which order. The order can be defined through the visibility or by type (instance, class, constant). The same is applicable for methods. Each of those rules is highly customizable. Readability is enhanced by defining where to put white spaces in the code and when to use braces. The existence of correct JavaDoc can be enforced and various levels. Apart from that, it finds weaknesses in the the code -- potential bugs -- like empty catch/finally block, switch without default, throwing of type 'Exception', slow code, ... .  JCSC is inspired by lint.

JCSC features a graphical UI for easy rule configuration, a command line interface, an Ant task which produces a JavaDoc style webpage and is CruiseControl compatible (see screenshot). Also, the NCSS/CCN metrics have been added for easier code quality assesment. Plugin for IntelliJ IDEA enables ad hoc checking from within the IDE. (see screenshot)

Currently JCSC supports over 100 enforceable rules -- this is not all and there is more to come!

Jikes is a compiler that translates Java source files as defined in The Java Language Specification into the bytecoded instruction set and binary format defined in The Java Virtual Machine Specification.

You may wonder why the world needs another Java compiler, considering that Sun provides javac free with its SDK. Jikes has five advantages that make it a valuable contribution to the Java community: [OSI Certified Logo]
  • Open source. Jikes is OSI Certified Open Source Software. OSI Certified is a certification mark of the Open Source Initiative.
  • Strictly Java compatible. Jikes strives to adhere to both The Java Language Specification and The Java Virtual Machine Specification as tightly as possible, and does not support subsets, supersets, or other variations of the language. The FAQ describes some of the side effects of this strict language conformance.
  • High performance. Jikes is a high performance compiler, making it ideal for use with larger projects.
  • Dependency analysis. Jikes performs a dependency analysis on your code that provides two very useful features: Incremental builds and makefile generation.
  • Constructive Assistance. Jikes strives to help the programmer write better code in two key ways. Jikes has always strived to provide clear error and warning text to assist the programmer in understanding problems, and now with release 1.19 Jikes helps point out common programming mistakes as documented in Effective Java.

Jlint will check your Java code and find bugs, inconsistencies and synchronization problems by doing data flow analysis and building the lock graph.  Jlint is extremely fast - even on large projects, it requires only one second to check all classes!  It is easy to learn and requires no changes to the class files.  Jlint has been used in an industrial environment and successfully uncovered faults with little effort!

JPF is a system to verify executable Java™ bytecode programs. In its basic form, it is a Java™ Virtual Machine (JVM) that is used as an explicit state software model checker, systematically exploring all potential execution paths of a program to find violations of properties like deadlocks or unhandled exceptions. Unlike traditional debuggers, JPF reports the entire execution path that leads to a defect. JPF is especially well-suited to finding hard-to-test concurrency defects in multithreaded programs.

While software model checking in theory sounds like a safe and robust verification method, reality shows that it does not scale well. To make it practical, a model checker has to employ flexible heuristics and state abstractions. JPF is unique in terms of its configurability and extensibility, and hence is a good platform to explore new ways to improve scalability.

JPF is a pure Java application that can be run either as a standalone command line tool, or embedded into systems like development environments. It was mostly developed - and is still used - at the NASA Ames Research Center. Started in 1999 as a feasibility study for software model checking, JPF has found its way into academia and industry, and has even helped detect defects in real spacecraft.

About