The Owasp Orizon Framework

Revision as of 16:54, 15 January 2009 by KirstenS (Talk | contribs)

Jump to: navigation, search
OWASP Code Review Guide Table of Contents



A lot of open source projects exist in the wild, performing static code review analysis. This is good, it means that source code testing for security issues is becoming a constraint.

Such tools bring a lot of valuable points:

  • community support
  • source code freely available to anyone
  • costs

On the other side, these tools don't share the most valuable point among them: the security knowledge. All these tools have their own security library, containing a lot of checks, without sharing such knowledge.

In 2006, the Owasp Orizon project wass born to provide a common underlying layer to all opensource projects concerning static analysis.

Orizon project includes:

  • a security library with checks to apply to source code.
  • a tool, Milk, which is able to static analyze a source code using Orizon Framework.

The Owasp Orizon Architecture


The Owasp Orizon v1.0 architecture


Your personal butler: the SkyLine class




The main SkyLine input is:

public boolean launch(String service)



private int goodService(String service) {
  int ret = -1;
  if (service.equalsIgnoreCase("init"))
  if (service.equalsIgnoreCase("translate"))
  if (service.equalsIgnoreCase("static_analysis"))
  if (service.equalsIgnoreCase("score"))
      ret = Cons.OC_SERVICE_SCORE;
  return ret;



This example will explain better:

public static void main(String[] args) {
   String fileName = "";
   OldRecipe r;
   DefaultLibrary dl;

   SkyLine skyLine = new SkyLine(args);


The command line format must follow this convention

 -o orizon_key=value

or the long format

 --orizon orizon_key=value

And these are the keys that the framework cares about:

  • "input-name"
  • "input-kind"
  • "working-dir"
  • "lang"
  • "recurse"
  • "output-format"
  • "scan-type";



SkyLine is contained in the org.owasp.orizon package.

Give me something to remind: the Session class





public boolean launch(String service) {
   int code, stats;
   boolean ret = false;

      return log.error("unknown service: " + service);
   switch (code) {
       // init service
            ret = session.init();
       // translation service
            stats = session.collectStats();
            if (stats > 0) {
               ret = false;
            } else
               ret = true;
       // static analysis service
            ret = session.staticReview();
       // score service
       case Cons.OC_SERVICE_SCORE:
            return log.error("unknown service: " + service);
       return ret;


  * Starts a static analysis over the files being reviewed
  * @return true if static analysis can be performed or false
  *         if one or more files fail being analyzed.
public boolean staticReview() {
   boolean ret = true;
   if (!active)
       if (! sessions[i].staticReview())
          ret = false;
   return ret;

Where sessions variable is declared as:

private SessionInfo[] sessions;



The following method is stolen from org.owasp.orizon.SessionInfo class.

  * Perform a static analysis over the given file
  * A full static analysis is a mix from:
  *  * local analysis (control flow)
  *  * global analysis (call graph)
  *  * taint propagation
  *  * statistics
  * @return true if the file being reviewed doesn't violate any
  *         security check, false otherwise.
  public boolean staticReview() {
     boolean ret = false;
     s = new Source(getStatFileName());
     ret = s.analyzeStats();
     return ret;

The Translation factory


  • Java
  • C, C++
  • C#
  • perl
  • ...



  • an XML file containing statistical information
  • an XML file containing variables tracking information
  • an XML file containing program control flow (local analysis)
  • an XML file containing call graph (global analysis)


Translation phase is requested from org.owasp.orizon.SessionInfo.inspect() method. Depending from the source file language, the appropriate Translator is called and the scan() method is called.

   * Inspects the source code, building AST trees
   * @return
   public boolean inspect() {
      boolean ret = false;
      switch (language) {
         case Cons.O_JAVA:
             t = new JavaTranslator();
             if (!t.scan(getInFileName())) 
                return log.error("can't scan " + getInFileName() + ".");
                ret = true;
             log.error("can't inspect language: " +;
      return ret;

Scan method is an abstract method defined in org.owasp.orizon.translator.DefaultTranslator class and declared as the following:

 public abstract boolean scan(String in);

Every class implementing DefaultTranslator must implement how to scan the source file and build ASTs in this method.

Aside from scan() method, there are four abstract method needful to create XML input files.

 public abstract boolean statService(String in, String out);
 public abstract boolean callGraphService(String in, String out);
 public abstract boolean dataFlowService(String in, String out);
 public abstract boolean controlFlowService(String in, String out);

All these methods are called in the translator() method, the one implemented directly from DefaultTranslator class.

 public final boolean translate(String in, String out, int service) {
    if (!isGoodService(service))
       return false;
    if (!scanned)
       if (!scan(in))
          return log.error(in+ ": scan has been failed");
    switch (service) {
      case Cons.OC_TRANSLATOR_STAT:
          return statService(in, out);
      case Cons.OC_TRANSLATOR_CF:
          return controlFlowService(in, out);
      case Cons.OC_TRANSLATOR_CG:
          return callGraphService(in, out);
      case Cons.OC_TRANSLATOR_DF:
          return dataFlowService(in, out);
          return log.error("unknown service code");

So, when from a language specific translator is prompted for translate() method, this recalls the language specific service methods.

Every translator contains as private field a language specific scanner containing ASTs to be used in input file generation.

Consider class, it is declared as follows:

 public class JavaTranslator extends DefaultTranslator {
   static SourcePositions positions;
   private JavaScanner j;

JavaScanner is a class from package and it uses Sun JDK 6 Compiler API to scan a java file creating in memory ASTs. Trees are created in scan() method, implemented for Java source language as follow:

 public final boolean scan(String in) {
    boolean ret = false;
    String[] parms = { in };
    Trees trees;
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    if (compiler == null) 
       return log.error("I can't find a suitable JAVA compiler. Is a JDK installed?");
    DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
    Iterable<? extends JavaFileObject> fileObjects = fileManager.getJavaFileObjects(parms);

    JavacTask task = (com.sun.source.util.JavacTask) compiler.getTask(null,fileManager, diagnostics, null, null, fileObjects);

    try {
        trees = Trees.instance(task);
        positions = trees.getSourcePositions();
        Iterable<? extends CompilationUnitTree> asts = task.parse();
        for (CompilationUnitTree ast : asts) {
            j = new JavaScanner(positions, ast);
            j.scan(ast, null);
        scanned = true;
        return true;
    } catch (IOException e) {
        return log.fatal("an exception occured while translate " + in + ": " +e.getLocalizedMessage());

Statistical gathering

To implement statistic information gathering, DefaultTranslator abstract method statService() must be implemented. In the following example, the method is the JavaTranslator's one. Statistics information are stored in JavaScanner object itself and retrieved by getStats() method.

 public final boolean statService(String in, String out) {
    boolean ret = false;
    if (!scanned)
       return log.error(in + ": call scan() before asking translation...");
    log.debug(". Entering statService(): collecting stats for: " + in);
    try {
        xml("<source name=\"" + in+"\" >");

    } catch (FileNotFoundException e) {
    } catch (UnsupportedEncodingException e) {
    } catch (IOException e) {
        ret = log.error("an exception occured: " + e.getMessage());
    ret = true;
    log.debug("stats written into: " + out);
    log.debug(". Leaving statService()");
    return ret;

Variable tracking gathering

Local analysis information gathering

Global analysis information gathering



You can drop also a line to Orizon author: