OWASP O2 Platform Blog

Creating the the “Util – View Fvdl Traces.h2” script (lots of data analysis code samples)

If you are trying to write a script to filter Fortify’s FVDL files, here are a number of code snippets that should give you a good idea of the type of scripting and analysis that you can do with O2.

This workflow represents the creation of a GUI to visualize an FVDL file. You can see the end result in the Util – View Fvdl Traces.h2 script which can be found in the following local O2 scripts folder

This is what the script looks like when executed for the first time

And this is what it looks like after an *.fvdl file is dropped in the top left treeview:

… and (after load)

 

Here is the workflow and code snippets:

Start with:

var topPanel = panel.clear().add_Panel();
var fvdlFile = @"C:\O2\Demos\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl";
var fortifyScan = fvdlFile.fortifyScan();
topPanel.add_PropertyGrid()
.helpVisible(false)
.show(fortifyScan);
return fortifyScan.typeName();
//O2File:API_Fortify_1_6.cs

add treeview

var fortifyScan = fvdlFile.fortifyScan();
var treeView = topPanel.add_TreeView_with_PropertyGrid(false);

add Vulnerabilities in treeview and show details in propertygrid

var fortifyScan = fvdlFile.fortifyScan();
var treeView = topPanel.add_TreeView_with_PropertyGrid(false);
treeView.add_Nodes(fortifyScan.Vulnerabilities);
treeView.selectFirst();

Get list of unique ‘Confidence’ values

return (from vulnerability in fortifyScan.Vulnerabilities
       select vulnerability.Confidence).Distinct();

Get list of unique ‘InstanceSeverity’ values

return (from vulnerability in fortifyScan.Vulnerabilities 
       select vulnerability.InstanceSeverity).Distinct();

Create dictionary of vulnerabilties mapped by ‘InstanceSeverity’

var fortifyScan = fvdlFile.fortifyScan();
var mappedBySeverity = new Dictionary<decimal, List<Fortify_Vulnerability>>();
foreach(var vulnerability in fortifyScan.Vulnerabilities)
    mappedBySeverity.add(vulnerability.InstanceSeverity, vulnerability);
return mappedBySeverity;

Add dictionary to treeView (loads all data)

foreach(var item in mappedBySeverity)
    treeView.add_Node("{0}        ({1} vulnerabilities)".format(item.Key.str(),item.Value.size()))
            .add_Nodes(item.Value);
treeView.selectFirst();

Add dictionary to treeView (with support for lazy loading of vulnerabilities (beter for bigger files))

foreach(var item in mappedBySeverity)
    treeView.add_Node("{0}        ({1} vulnerabilities)".format(item.Key.str(),item.Value.size()),
                     item.Value,
                     true);
                    
treeView.beforeExpand<List<    Fortify_Vulnerability>>(
    (treeNode,vulnerabilities)=>{
                                    treeNode.add_Nodes(vulnerabilities);
                                });
                               
treeView.selectFirst()
        .selected()
        .expand();
return mappedBySeverity;

populate treeview with two types of dictionaries (first ‘by Severity’ then ‘by Type’)

var mappedBySeverity = new Dictionary<decimal, List<Fortify_Vulnerability>>();
foreach(var vulnerability in fortifyScan.Vulnerabilities)
    mappedBySeverity.add(vulnerability.InstanceSeverity, vulnerability);
 
 
foreach(var bySeverity in mappedBySeverity)
{
    var mappedByType = new Dictionary<string, List<Fortify_Vulnerability>>();
    foreach(var vulnerability in bySeverity.Value)
        mappedByType.add(vulnerability.Type, vulnerability);           
    var severityNode = treeView.add_Node("{0}      ({1}x)".format(bySeverity.Key.str(),bySeverity.Value.size()));
    foreach(var byType in mappedByType)               
         severityNode.add_Node("{0}  ({1}x)".format(byType.Key, byType.Value.size()), byType.Value, true);
}
treeView.beforeExpand<List<    Fortify_Vulnerability>>(
    (treeNode,vulnerabilities)=>{
                                    treeNode.add_Nodes(vulnerabilities);
                                });
                               
treeView.selectFirst()
        .selected()
        .expand();

Move dictionary and treeView creation to Lambda method (same funcionality as previous example)

Action<Fortify_Scan, TreeView> mapScanToTreeView_BySeverityAndType =
    (fortifyScan, treeView)
        =>{
                treeView.clear();
                var mappedBySeverity = new Dictionary<decimal, List<Fortify_Vulnerability>>();
                foreach(var vulnerability in fortifyScan.Vulnerabilities)
                    mappedBySeverity.add(vulnerability.InstanceSeverity, vulnerability);
                              
                foreach(var bySeverity in mappedBySeverity)
                {
                    var mappedByType = new Dictionary<string, List<Fortify_Vulnerability>>();
                    foreach(var vulnerability in bySeverity.Value)
                        mappedByType.add(vulnerability.Type, vulnerability);           
                    var severityNode = treeView.add_Node("{0}      ({1}x)".format(bySeverity.Key.str(),bySeverity.Value.size()));
                    foreach(var byType in mappedByType)                                       
                        severityNode.add_Node("{0}  ({1}x)".format(byType.Key, byType.Value.size()), byType.Value, true);
                }
               
                treeView.beforeExpand<List<    Fortify_Vulnerability>>(
                    (treeNode,vulnerabilities)=>{
                                                    treeNode.add_Nodes(vulnerabilities);
                                                });
        };
var fvdlFile = @"C:\O2\Demos\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl";
var _treeView = topPanel.add_TreeView_with_PropertyGrid(false).sort();
var _fortifyScan = fvdlFile.fortifyScan();

mapScanToTreeView_BySeverityAndType(_fortifyScan, _treeView);

_treeView.focus()
         .selectFirst()
         .selected()
         .expand();

Add a treeView to right and a source code viewer bellow it

var fvdlFile = @"C:\O2\Demos\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl";
var _treeView = topPanel.add_GroupBox("Vulnerabilities results").add_TreeView_with_PropertyGrid(true).sort();
var _fortifyScan = fvdlFile.fortifyScan();
var tracesTreeView = topPanel.insert_Right("Traces").add_TreeView();
var codeViewer = tracesTreeView.parent().insert_Below("Source Code View").add_SourceCodeViewer();

mapScanToTreeView_BySeverityAndType(_fortifyScan, _treeView);

Show traces on Vulnerability select , show traces properties on trace select (using the dspace.fvdl file since it is a java scan and it has more traces) 

//var fvdlFile = @"C:\O2\Demos\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl";
var fvdlFile = @"C:\O2\Demos\Fortify-Sate-2008\sate2008-Fvdl\dspace.fvdl";
var _treeView = topPanel.add_GroupBox("Vulnerabilities results").add_TreeView_with_PropertyGrid(true).sort();
_treeView.add_Node(".... loading file: {0}".format(fvdlFile));
var _fortifyScan = fvdlFile.fortifyScan();
var tracesTreeView = topPanel.insert_Right("Traces").add_TreeView();
var tracesProperties = tracesTreeView.insert_Right().add_PropertyGrid();
var codeViewer = tracesTreeView.parent().insert_Below("Source Code View").add_SourceCodeViewer();

_treeView.afterSelect<Fortify_Vulnerability>(
    (vulnerability)=>{                       
                        tracesTreeView.clear();
                        tracesTreeView.add_Nodes(vulnerability.Traces);
                     });
tracesTreeView.afterSelect<Fortify_TraceEntry>(
    (traceEntry)=>{
                    tracesProperties.show(traceEntry); 
                  });
                
mapScanToTreeView_BySeverityAndType(_fortifyScan, _treeView);
_treeView.focus()
         .selectFirst()
         .selected()
         .expand().nodes()[0].selected()
         .expand().nodes()[0].selected();

tracesTreeView.selectFirst();

Move data loading into a separate thread

O2Thread.mtaThread(
    ()=>{
            var _fortifyScan = fvdlFile.fortifyScan();
            mapScanToTreeView_BySeverityAndType(_fortifyScan, _treeView);
           
            _treeView.focus()
                     .selectFirst()
                     .selected()
                     .expand().nodes()[0].selected()
                     .expand().nodes()[0].selected();
           
            tracesTreeView.selectFirst();       
        });

and move it to a Lambda method (with callback for when data is loaded)

Action<string, TreeView, Action> loadFvdlDataIntoTreeView =
    (fvdlFile, vulnerabilitiesTreeView, loadCompleteCallback)
        =>{
            vulnerabilitiesTreeView.add_Node(".... loading file: {0}".format(fvdlFile));           
            vulnerabilitiesTreeView.pink();
            O2Thread.mtaThread(
                ()=>{                       
                        var _fortifyScan = fvdlFile.fortifyScan();
                        mapScanToTreeView_BySeverityAndType(_fortifyScan, vulnerabilitiesTreeView);
                        loadCompleteCallback();
                        vulnerabilitiesTreeView.white();
                    });
         };
var _fvdlFile = @"C:\O2\Demos\Fortify-Sate-2008\sate2008-Fvdl\dspace.fvdl";
//var fvdlFile = @"C:\O2\Demos\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl";
loadFvdlDataIntoTreeView(_fvdlFile,_treeView,
        ()=>{
               
                _treeView.focus()
                         .selectFirst()
                         .selected()
                         .expand().nodes()[0].selected()
                         .expand().nodes()[0].selected();               
                tracesTreeView.selectFirst();            
            });

add support for Code Snippets

var codeSnippets = new Dictionary<string, Fortify_Snippet>();
Action<Fortify_Scan> loadCodeSnippets =
    (_fortifyScan)=>{
                        codeSnippets.Clear();
                        foreach(var snippet in _fortifyScan.Snippets)
                            codeSnippets.Add(snippet.Id, snippet);                   
                        show.info(codeSnippets);                   
                    };
...
var _fortifyScan = fvdlFile.fortifyScan();
loadCodeSnippets(_fortifyScan);

Show code snippet when trace is selected

tracesTreeView.afterSelect<Fortify_TraceEntry>(
    (traceEntry)=>{
                    tracesProperties.show(traceEntry); 
                    if (codeSnippets.hasKey(traceEntry.SourceLocation_Snippet))
                        codeViewer.set_Text(codeSnippets[traceEntry.SourceLocation_Snippet].Text);
                    else
                        if (codeSnippets.hasKey(traceEntry.SecundaryLocation_Snippet))
                        codeViewer.set_Text(codeSnippets[traceEntry.SecundaryLocation_Snippet].Text);
                   
                  });

Only show traces that have valid code snippets

_treeView.afterSelect<Fortify_Vulnerability>(
    (vulnerability)=>{                       
                        tracesTreeView.clear();
                        var tracesWithSnippets = (from traceEntry in vulnerability.Traces
                                                where traceEntry.SourceLocation_Snippet.valid() || traceEntry.SecundaryLocation_Snippet.valid()
                                                select traceEntry).Distinct;
                        tracesTreeView.add_Nodes(tracesWithSnippets);
                     });

Add DragAndDrop support

Action<string> loadFvdlFile =
    (fvdlFile)=>{
                    loadFvdlDataIntoTreeView(fvdlFile,_treeView,
                            ()=>{
                                   
                                    _treeView.focus();
                                /*             .selectFirst()
                                             .selected()
                                             .expand().nodes()[0].selected()
                                             .expand().nodes()[0].selected();               
                                    tracesTreeView.selectFirst();             */
                                });
                };
_treeView.onDrop(
    (file)=>{
                loadFvdlFile(file);
            });

and open the GUI in a new window

var topPanel = "Util - View Fvdl Traces".popupWindow(1000,400);

FOR REFERENCE: Here is the complete script:

var topPanel = "Util = View Fvdl Traces".popupWindow(1000,400);
//var topPanel = panel.clear().add_Panel();</pre>
&nbsp;

Action<Fortify_Scan, TreeView> mapScanToTreeView_BySeverityAndType =
    (fortifyScan, treeView)
        =>{
                treeView.clear();
                var mappedBySeverity = new Dictionary<decimal, List<Fortify_Vulnerability>>();
                foreach(var vulnerability in fortifyScan.Vulnerabilities)
                    mappedBySeverity.add(vulnerability.InstanceSeverity, vulnerability);
               
               
                foreach(var bySeverity in mappedBySeverity)
                {
                    var mappedByType = new Dictionary<string, List<Fortify_Vulnerability>>();
                    foreach(var vulnerability in bySeverity.Value)
                        mappedByType.add(vulnerability.Type, vulnerability);           
                    var severityNode = treeView.add_Node("{0}      ({1}x)".format(bySeverity.Key.str(),bySeverity.Value.size()));
                    foreach(var byType in mappedByType)                                       
                        severityNode.add_Node("{0}  ({1}x)".format(byType.Key, byType.Value.size()), byType.Value, true);
                }
               
                treeView.beforeExpand<List<    Fortify_Vulnerability>>(
                    (treeNode,vulnerabilities)=>{
                                                    treeNode.add_Nodes(vulnerabilities);
                                                });
        };                               

var _treeView = topPanel.add_GroupBox("Vulnerabilities results").add_TreeView_with_PropertyGrid(true).sort();
var tracesTreeView = topPanel.insert_Right("Traces").add_TreeView();
var codeViewer = tracesTreeView.parent().insert_Below("Source Code View").add_SourceCodeViewer();
var tracesProperties = tracesTreeView.insert_Right().add_PropertyGrid();

_treeView.afterSelect<Fortify_Vulnerability>(
    (vulnerability)=>{                       
                        tracesTreeView.clear();
                        var tracesWithSnippets = (from traceEntry in vulnerability.Traces
                                                where traceEntry.SourceLocation_Snippet.valid() || traceEntry.SecundaryLocation_Snippet.valid()
                                                select traceEntry);
                        tracesTreeView.add_Nodes(tracesWithSnippets);
                     });

var codeSnippets = new Dictionary<string, Fortify_Snippet>();

Action<Fortify_Scan> loadCodeSnippets =
    (_fortifyScan)=>{
                        codeSnippets.Clear();
                        foreach(var snippet in _fortifyScan.Snippets)
                            codeSnippets.Add(snippet.Id, snippet);                                           
                    };
                   
tracesTreeView.afterSelect<Fortify_TraceEntry>(
    (traceEntry)=>{
                    tracesProperties.show(traceEntry); 
                    if (codeSnippets.hasKey(traceEntry.SourceLocation_Snippet))
                        codeViewer.set_Text(codeSnippets[traceEntry.SourceLocation_Snippet].Text);
                    else
                        if (codeSnippets.hasKey(traceEntry.SecundaryLocation_Snippet))
                        codeViewer.set_Text(codeSnippets[traceEntry.SecundaryLocation_Snippet].Text);
                   
                  });

Action<string, TreeView, Action> loadFvdlDataIntoTreeView =
    (fvdlFile, vulnerabilitiesTreeView, loadCompleteCallback)
        =>{
            vulnerabilitiesTreeView.add_Node(".... loading file: {0}".format(fvdlFile));           
            vulnerabilitiesTreeView.pink();
            O2Thread.mtaThread(
                ()=>{                       
                        var _fortifyScan = fvdlFile.fortifyScan();
                        loadCodeSnippets(_fortifyScan);
                        mapScanToTreeView_BySeverityAndType(_fortifyScan, vulnerabilitiesTreeView);
                        loadCompleteCallback();
                        vulnerabilitiesTreeView.white();
                    });
         };
Action<string> loadFvdlFile =
    (fvdlFile)=>{
                    loadFvdlDataIntoTreeView(fvdlFile,_treeView,
                            ()=>{
                                   
                                    _treeView.focus();
                                /*             .selectFirst()
                                             .selected()
                                             .expand().nodes()[0].selected()
                                             .expand().nodes()[0].selected();               
                                    tracesTreeView.selectFirst();             */
                                });
                };
_treeView.onDrop(
    (file)=>{
                loadFvdlFile(file);
            });

return "ok";

//O2File:API_Fortify_1_6.cs

July 29, 2011 Posted by | Fortify | Leave a comment

O2 Scripting – solving the missing references compilation problem (using FVDL as an example)

A common error when starting to write O2 scripts is the “The name ‘…’ does not exist in the current context” compilation problem. This tends to happen because the C# comments that provide the dll and namespace references were not used (since it can easy to assume that they are not needed 🙂  )

Here is how to replicate the problem and how to fix it.

Start with an new instance of an O2 Quick Development GUI

Right-click on the source code editor and chose the ‘show log view option)

Then (for example) paste the code below:

var topPanel = panel.clear().add_Panel();
var xmlFile = @"C:\O2\Fortify\test.fvdl";
var xsdFile = @"C:\O2\Fortify\test.fvdl.xsd";
var csharpFile = xsdFile.xsdCreateCSharpFile();
csharpFile.fileContents().insertBefore("//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll".line()).saveAs(csharpFile);
var fvdl = FVDL.Load(xmlFile);

… this will trigger the code compilation, which will fail with the error:

[8:24:04 AM] ERROR: [CSharp_FastCompiler] Compilation Error: 32::14::CS0103::The name ‘FVDL’ does not exist in the current context::c:\Users\o2\AppData\Local\Temp\meqvg7zx.0.cs

The reference that is missing is the C# file that has the FVDL class.

In fact, in this case, the script (sent to me by an O2 user who was following the code samples in the  Fortify FVDL files – Creating and consuming the schema and CSharp file blog post) is actually jumping a step (btw, see  here for more posts about O2 support for Fortify’s FVDL files)

Let’s comment the last line,  and make the code compile

Before we execute it, let’s change the script a little bit to create the XSD file and then return the value of the csharpFile variable (which is the C# file created that represents the XSD file)

var xmlFile = @"C:\O2\Demos\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl";
var xsdFile = xmlFile.xmlCreateXSD();
var csharpFile = xsdFile.xsdCreateCSharpFile();
return csharpFile.fileContents().insertBefore("//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll".line()).saveAs(csharpFile);

In this case (due to the format of the Fortify XSD), the XML -> XSD conversion using Linq2Xml will not work (see the post  Fortify FVDL files – Creating and consuming the schema and CSharp file for more details and for a solution using Visual Studio 2010):

To show how to fix the  “The name ‘…’ does not exist in the current context” problem, let go back to the orignal script, without the bits that are not needed (and using a file from the SATE 2008 project):

var topPanel = panel.clear().add_Panel();
var xmlFile = @"C:\O2\Demos\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl";
var fvdl = FVDL.Load(xmlFile);

To compile this we need to add two things:

1) a C#file or dll that has the FVDL class
2) an include reference to the namespace that contains the FVDL class:

In this case we are going to use the file that was created in the previous blog post example, which is now included in the local O2 Scripts folder:

To consume this file (and tell the O2 scripting engine to compile it with the current script), use this syntax:

//O2File:C:\O2\O2Scripts_Database\_Scripts\3rdParty_Tools\Fortify\Fortify.fvdl.1.6.xsd.cs

The compilation process now will show a lot more activity,  including an entry with ‘Compilated OK to: C:\O2\_tempDir\7-29-2011\tmp3A4C.tmp.dll‘  , which basically means that the files we provided as references compiled ok.

The reason we sill get the original error is because we are missing the namespace reference (altough you can already gain acccess to the imported code/dll Code Complete :

… and here is the FVDL class:

… which when  used as a reference using this syntax:

//using xmlns.www.fortifysoftware.com.schema.fvdl

… will result in this error:

 … which is also a very common error, and basically means that we also need to provide the C# compiler a reference to the O2_Misc_Microsoft_MPL_Libs.dll.

This can be done using this syntax:

//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll

which will make the following code

var xmlFile = @"C:\O2\Demos\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl";
var fvdl = FVDL.Load(xmlFile);</pre>
&nbsp;

//using xmlns.www.fortifysoftware.com.schema.fvdl
//O2File:C:\O2\O2Scripts_Database\_Scripts\3rdParty_Tools\Fortify\Fortify.fvdl.1.6.xsd.cs
//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll

 

… to compile OK :

Note that since the Fortify.fvdl.1.6.xsd.cs file is included inside the O2 Scripts folder, we can use it just its filename:

var xmlFile = @"C:\O2\Demos\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl";
var fvdl = FVDL.Load(xmlFile);
 
//using xmlns.www.fortifysoftware.com.schema.fvdl
//O2File:Fortify.fvdl.1.6.xsd.cs
//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll

To see the object created add a return statement:

…. (since we are inside the O2 Quick Development Gui and have access to a panel),  add a PropertyGrid to the provided Panel control and show the FVDL object there:

var topPanel = panel.clear().add_Panel();
var xmlFile = @"C:\O2\Demos\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl";
var fvdl = FVDL.Load(xmlFile);
topPanel.add_PropertyGrid().show(fvdl);
 
//using xmlns.www.fortifysoftware.com.schema.fvdl
//O2File:Fortify.fvdl.1.6.xsd.cs
//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll</pre>
&nbsp;

 

And if want to make this into a stand alone tool (that can be shared with others and invoked directly from the windows explorer), replace with first line with a call to open a popup window

//var topPanel = panel.clear().add_Panel();   
var topPanel = "View FVDL file".popupWindow(500,370);

If you save this script as a stand alone tool, go to the script editor, right click on it, and chose the current source code ->  save As menu item

Chose a location:

and execute this script by double clicking on it:

You might have noticed that I saved this file on my local development box in one of the O2 Scripts folders.

This means that to add it to the O2 scripts that exist locally to O2 users (and that O2 automatically syncs up when the main GUI starts), I just need to do this:

and it is done:

 … by the time you are reading this blog post you should have this script on your local O2 Scripts folder

July 28, 2011 Posted by | Fortify, O2 Internals | Leave a comment

Fortify FVDL Files – Simple Viewer based on PropertyGrid

The .NET PropertyGrid Control can be a very powerful way to visualize objects.

For exampe, the script below creates a WinForm with just a PropertyGrid Control (and some drag and drop support to load up the files)

var topPanel = "Util - FVDL viewer (just PropertyGrid) - drop file to load".popupWindow(400, 400);
topPanel.insert_LogViewer();
var propertyGrid = topPanel.add_PropertyGrid().helpVisible(false);   
Action<string> loadAndShowFile =   
    (file)=> O2Thread.mtaThread(
        ()=>    propertyGrid.show(new API_Fortify().convertToFortifyScan(file)));

propertyGrid.onDrop(loadAndShowFile);           
//O2File:API_Fortify_1_6.cs
//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll 

which looks like this when opened

…and like this after dropping the 36Mb dspace.fvdl file:

Since most Fortify_* objects have been designed as lists, the PropertyGrid will show them in special pop-up windows:

CalledWithNoDefs

Contexts

Descriptions

Scanned Files

Sinks

Snippets

Sources

Vulnerabilities

Vulnerabilities -> Traces

July 18, 2011 Posted by | Fortify, Interoperability | Leave a comment

Fortify FVDL Files – Looking at the API_Fortify classes that parse the fvdl data

Here is the source code that create the environment/GUI/tool shown in the Fortify FVDL Files – First working Parser and Viewer for *.fvdl files post

Heavily based on  the first version of this API , the data classes have been refactored and expanded, now covering most of the data contained in the *.fvdl files:

public class Fortify_Scan
    {
        public FVDL _fvdl;
       
        public string BuildID { get; set; }
        public uint Loc { get; set; }
        public string SourceBasePath { get; set; }
        public uint ScanTime { get; set; }       
        public DateTime CreatedDateTime { get; set; }
        public string Errors { get; set; }
        public List<Fortify_ScannedFile> ScannedFiles { get; set; }   
        public List<Fortify_Context> Contexts { get; set; }
        public List<Fortify_Description> Descriptions { get; set; }
        public List<Fortify_CalledWithNoDef> CalledWithNoDefs { get; set; }       
        public List<Fortify_Sink> Sinks { get; set; }
        public List<Fortify_Source> Sources { get; set; }
        public List<Fortify_Snippet> Snippets { get; set; }
        public List<Fortify_Vulnerability> Vulnerabilities { get; set; }
       
        public Fortify_Scan()
        {
            ScannedFiles = new List<Fortify_ScannedFile>();
            Contexts = new List<Fortify_Context>();
            Descriptions = new List<Fortify_Description>();
            CalledWithNoDefs = new List<Fortify_CalledWithNoDef>();
            Sinks = new List<Fortify_Sink>();
            Sources = new List<Fortify_Source>();
            Snippets = new List<Fortify_Snippet>();
            Vulnerabilities = new List<Fortify_Vulnerability>();
        }
    }       
   
    public class Fortify_ScannedFile
    {
        public uint Loc { get; set; }
        public uint Size { get; set; }
        public ulong Timestamp { get; set; }
        public string Type { get; set; }
        public string Path { get; set; }
    }
    public class Fortify_Context
    {
        public string Id { get; set; }
        public Fortify_Function Function { get; set; }
    }   
    public class Fortify_Function
    {
        public string FunctionName { get; set; }
        public Fortify_CodeLocation CodeLocation { get; set; }   
       
        public Fortify_Function()
        {}
               
        public Fortify_Function(string functionName, object location)
        {
            FunctionName =  functionName;   
            CodeLocation = new Fortify_CodeLocation(location);
        }
       
        public override string ToString()
        {
            return "{{ name: {0} , path: {1} , line: {2}, lineEnd: {3}, colStart: {4}, colEnd: {5} }}"
                        .format(FunctionName, CodeLocation.Path, CodeLocation.Line, CodeLocation.LineEnd, CodeLocation.ColStart, CodeLocation.ColEnd);
        }
    }   
    public class Fortify_CodeLocation
    {
        public string Path { get; set; }
        public uint Line { get; set; }
        public uint LineEnd { get; set; }
        public uint ColStart { get; set; }
        public uint ColEnd { get; set; }
       
        public Fortify_CodeLocation()
        {}
       
        public Fortify_CodeLocation(object location)
        {                                   
            Path = (string)location.prop("path");                                                           
            Line = (uint)location.prop("line");
            LineEnd = (uint)location.prop("lineEnd");
            ColStart = UInt16.Parse(location.prop("colStart").str());
            ColEnd = UInt16.Parse(location.prop("colEnd").str());                                                       
        }
        public override string ToString()
        {
            if (ColStart == 0 && ColEnd==0)
                return "{{ path: {0} , line: {1}, lineEnd: {2}}}".format(Path, Line, LineEnd);
               
            return "{{ path: {0} , line: {1}, lineEnd: {2}, colStart: {3}, colEnd: {4} }}"
                        .format(Path, Line, LineEnd, ColStart, ColEnd);
        }
    }   
    public class Fortify_Description
    {
        public string Abstract { get; set; }
        public string ClassID { get; set; }
        public string ContentType { get; set; }
        public string Explanation { get; set; }
        public string Recommendations { get; set; }
        public List<string> Tips { get; set; }       
       
        public string Tips_as_String { get { return Tips.join(" , ");} } //viewer helper
       
        public Fortify_Description()
        {
            Tips = new List<string>();
        }
       
    }   
   
    public class Fortify_CalledWithNoDef
    {
        public string Name { get; set; }
        public string Namespace { get; set; }
        public string EnclosingClass { get; set; }
    }
   
    public class Fortify_Sink
    {
        public string RuleID { get; set; }
        public Fortify_Function Function_Call{ get; set;}               
    }
    public class Fortify_Source
    {
        public string RuleID { get; set; }
        public Fortify_Function Function_Call{ get; set;}
        public Fortify_Function Function_Entry{ get; set;}               
        public List<string> TaintFlags { get; set;}
       
        public string TaintFlags_as_String { get { return TaintFlags.join(" , ");} } //viewer helper
       
        public Fortify_Source()
        {
            TaintFlags = new List<string>();
        }
    }       
    public class Fortify_Snippet
    {
        public string Id { get; set; }
        public Fortify_CodeLocation CodeLocation { get; set; }       
        public string Text { get; set;}       
    }
   
    public class Fortify_ReplacementDefinitions
    {
        public Items Definitions { get; set; }
        //public List<Fortify_Function> LocationDefinitions { get; set; }  // add later if needed (Fortify_Function is not the best since the LocationDef has a 'key'  value
       
        public Fortify_ReplacementDefinitions()
        {
            Definitions = new Items();           
        }
        public override string ToString()
        {   
            return "{0} definitions".format(Definitions.size());
        }
    }
   
    public class Fortify_TraceEntry
    {
        public uint NodeRefId                                 { get; set; }    // when this one is set, the ones below are not set                       
        public string ActionType                             { get; set; }
        public string ActionValue                             { get; set; }
        public bool DetailsOnly                             { get; set; }
        public bool IsDefault                                 { get; set; }       
        public List<Fortify_TraceEntryFact> KnowledgeFacts    { get; set; }
        public string Reason_RuleId                            { get; set; }
        public string Reason_TraceRef                        { get; set; }       
        public string Reason_Internal                        { get; set; }       
        public Fortify_CodeLocation SourceLocation             { get; set; }       
        public Fortify_CodeLocation SecundaryLocation         { get; set; }
        public uint SourceLocation_ContextId                 { get; set; }
        public string SourceLocation_Snippet                 { get; set; }       
        public string SecundaryLocation_Snippet                { get; set; }               
        public string Label                                    { get; set; }               
       
        public Fortify_TraceEntry()
        {
            KnowledgeFacts = new List<Fortify_TraceEntryFact>();           
        }
    }
    public class Fortify_TraceEntryFact
    {
        public bool Primary {get;set;}
        public string Type {get;set;}
        public string Value {get;set;}
    }   
   
    public class Fortify_Vulnerability
    {
        public Fortify_Function Context { get; set; }    // from AnalysisInfo
        public Fortify_ReplacementDefinitions ReplacementDefinitions { get; set; }
        public List<Fortify_TraceEntry> Traces { get; set; }
        public string Kingdom { get; set; }                // from ClassInfo
        public string AnalyzerName { get; set; }
        public string ClassId { get; set; }
        public decimal DefaultSeverity { get; set; }
        public string  Type { get; set; }
        public string  SubType { get; set; }
       
        public decimal Confidence { get; set; }            // from InstanceInfo
        public string InstanceId { get; set; }
        public decimal InstanceSeverity { get; set; }                           
       
        public Fortify_Vulnerability()
        {
            ReplacementDefinitions = new Fortify_ReplacementDefinitions();
            Traces = new List<Fortify_TraceEntry>();
        }
    }

The main API_Fortify class is still quite small:

public class API_Fortify
    {               
        public Fortify_Scan convertToFortifyScan(string fvdlFile)
        {
            var scan = new Fortify_Scan();
            scan._fvdl = loadFvdl_Raw(fvdlFile);
            scan.mapFvdlData();
            return scan;
        }
       
        public FVDL loadFvdl_Raw(string fvdlFile)
        {
            "Loading fvdl file: {0}".info(fvdlFile);
            try
            {
                var chachedFvdl = (FVDL)O2LiveObjects.get(fvdlFile);
                if (chachedFvdl.notNull())
                    return chachedFvdl;
            }
            catch { }
            
            var o2Timer = new O2Timer("loading {0} file".format(fvdlFile.fileName())).start();       
             var _fvdl = FVDL.Load(fvdlFile);   
             O2LiveObjects.set(fvdlFile,_fvdl);
             o2Timer.stop();
             return _fvdl; 
        }
    }

With all the heavy lifting of convering the *.fvdl data into the multiple O2 Fortify_* classes , done via ExtensionMethods

public static class Fortify_Scan_ExtensionMethods_MappingFvdl
    {
        public static Fortify_Scan mapFvdlData(this Fortify_Scan fortifyScan)
        {
            var o2Timer = new O2Timer("Mapped Fvdl Data").start();
            fortifyScan.mapScanDetails()
                       .mapContextPool()
                       .mapDescriptions()
                       .mapCalledWithNoDefs()
                       .mapSinks()
                       .mapSources()
                       .mapSnippets()
                       .mapVulnerabilities();
            o2Timer.stop();          
            return fortifyScan;
        }
       
        public static Fortify_Scan mapScanDetails(this Fortify_Scan fortifyScan)
        {
            var fvdl = fortifyScan._fvdl;
            fortifyScan.BuildID = fvdl.Build.BuildID;
            fortifyScan.Loc = fvdl.Build.LOC;
            fortifyScan.SourceBasePath = fvdl.Build.SourceBasePath;
            fortifyScan.ScanTime = fvdl.Build.ScanTime.value;
            fortifyScan.CreatedDateTime = DateTime.Parse("{0} {1}".format(fortifyScan._fvdl.CreatedTS.date.ToShortDateString() ,
                                                                          fortifyScan._fvdl.CreatedTS.time.ToLongTimeString() ));                       
            fortifyScan.Errors = fvdl.EngineData.Errors.str()!= "<Errors xmlns=\"xmlns://www.fortifysoftware.com/schema/fvdl\" />"
                                        ? fvdl.EngineData.Errors.str()
                                        : "";
            foreach(var file in fvdl.Build.SourceFiles.File)
                fortifyScan.ScannedFiles.Add(new Fortify_ScannedFile ()
                                                    {
                                                        Loc = file.loc,
                                                        Size = file.size,
                                                        Timestamp = file.timestamp,
                                                        Type = file.type,
                                                        Path = file.TypedValue
                                                    });
            return fortifyScan;
        }
       
        public static Fortify_Scan mapContextPool(this Fortify_Scan fortifyScan)
        {
            foreach(var context in fortifyScan._fvdl.ContextPool.Context)
            {
                //var location = context.FunctionDeclarationSourceLocation;
                fortifyScan.Contexts.Add(
                    new Fortify_Context()
                            {
                                Id = context.id.str() ,   
                                Function = new Fortify_Function(context.Function.name,context.FunctionDeclarationSourceLocation)                                           
                            });                                       
            }
            return fortifyScan;       
        }               
       
        public static Fortify_Scan mapDescriptions(this Fortify_Scan fortifyScan)
        {                
                foreach(var description in fortifyScan._fvdl.Description)
                {
                      var fortifyDescription = new Fortify_Description
                              {
                                  Abstract = description.Abstract,
                                  ClassID = description.classID,
                                  ContentType = description.contentType,                                 
                                  Explanation = description.Explanation,
                                  Recommendations = description.Recommendations,
                            };
                    if (description.Tips.notNull())
                        foreach(var tip in description.Tips.Tip)
                            fortifyDescription.Tips.Add(tip);
                    fortifyScan.Descriptions.add(fortifyDescription);   
                }
                return fortifyScan;
        }
       
        public static Fortify_Scan mapCalledWithNoDefs(this Fortify_Scan fortifyScan)
        {
            //have to map this using the xElement because the xsd/cs schema doesn't support it (at the moment)  
            foreach(var function in fortifyScan._fvdl.ProgramData.CalledWithNoDef.xElement().elements())
            {               
                fortifyScan.CalledWithNoDefs.Add(
                    new Fortify_CalledWithNoDef()
                            {
                                Name = function.attribute("name").value(),
                                Namespace = function.attribute("namespace").value(),
                                EnclosingClass = function.attribute("enclosingClass").value()
                            });                                       
            }
            return fortifyScan;       
        }   
       
        public static Fortify_Scan mapSinks(this Fortify_Scan fortifyScan)
        {
            foreach(var sink in fortifyScan._fvdl.ProgramData.Sinks.SinkInstance)
            {               
                fortifyScan.Sinks.Add(
                    new Fortify_Sink()
                            {
                                RuleID = sink.ruleID.str() ,
                                Function_Call = new Fortify_Function(sink.FunctionCall.Function.name,sink.FunctionCall.SourceLocation)
                            });                                       
            }
            return fortifyScan;       
        }
       
        public static Fortify_Scan mapSources(this Fortify_Scan fortifyScan)
        {
            foreach(var source in fortifyScan._fvdl.ProgramData.Sources.SourceInstance)
            {               
                var fortifySource = new Fortify_Source()
                                            {
                                                RuleID = source.ruleID.str() ,                                               
                                            };
                if (source.FunctionCall.notNull())                                           
                    fortifySource.Function_Call = new Fortify_Function(source.FunctionCall.Function.name,source.FunctionCall.SourceLocation);
                if (source.FunctionCall.notNull())   
                    fortifySource.Function_Entry = new Fortify_Function(source.FunctionCall.Function.name,source.FunctionCall.SourceLocation);
                if (source.TaintFlags.notNull())
                    fortifySource.TaintFlags = (from taintFlag in source.TaintFlags.TaintFlag
                                                select taintFlag.name).toList();
                fortifyScan.Sources.Add(fortifySource);
            }
            return fortifyScan;       
        }
        public static Fortify_Scan mapSnippets(this Fortify_Scan fortifyScan)
        {
            foreach(var snippet in fortifyScan._fvdl.Snippets.Snippet)
            {               
                fortifyScan.Snippets.Add(
                    new Fortify_Snippet()
                            {
                                Id = snippet.id.str() ,   
                                Text = snippet.Text,
                                CodeLocation = new Fortify_CodeLocation()
                                                        {
                                                            Path = snippet.File,
                                                            Line = snippet.StartLine,
                                                            LineEnd = snippet.EndLine                                                           
                                                        }                                           
                            });                                       
            }           
            return fortifyScan;       
        }               

        public static Fortify_Scan mapVulnerabilities(this Fortify_Scan fortifyScan)
        {                
            foreach(var vulnerability in fortifyScan._fvdl.Vulnerabilities.Vulnerability)               
                if (vulnerability.notNull())
                {
                      var fortifyVulnerability = new Fortify_Vulnerability();
                           
                    //from ClassInfo                                       
                    fortifyVulnerability.AnalyzerName      = vulnerability.ClassInfo.AnalyzerName;
                    fortifyVulnerability.ClassId          = vulnerability.ClassInfo.ClassID;
                    fortifyVulnerability.DefaultSeverity = vulnerability.ClassInfo.DefaultSeverity;
                    fortifyVulnerability.Kingdom          = vulnerability.ClassInfo.Kingdom;                   
                    fortifyVulnerability.Type              = vulnerability.ClassInfo.Type;                   
                    fortifyVulnerability.SubType          = vulnerability.ClassInfo.Subtype;                   
                   
                    //from
                    fortifyVulnerability.InstanceId         = vulnerability.InstanceInfo.InstanceID;
                    fortifyVulnerability.InstanceSeverity     = vulnerability.InstanceInfo.InstanceSeverity;
                    fortifyVulnerability.Confidence         = vulnerability.InstanceInfo.Confidence;
                   
                    //
                   
                    //from AnalysisInfo       
                    var analysisInfo =     vulnerability.AnalysisInfo;                   
                    if (analysisInfo.Unified.notNull())
                    {
                        if (analysisInfo.Unified.Context.notNull() && analysisInfo.Unified.Context.Function.notNull())                       
                            fortifyVulnerability.Context = new Fortify_Function(analysisInfo.Unified.Context.Function.name,
                                                                                analysisInfo.Unified.Context.FunctionDeclarationSourceLocation);                       
                        if (analysisInfo.Unified.ReplacementDefinitions.notNull())                                                                       
                            foreach(var def in analysisInfo.Unified.ReplacementDefinitions.Def)                       
                                fortifyVulnerability.ReplacementDefinitions.Definitions.add(def.key, def.value);
                        foreach(var trace in analysisInfo.Unified.Trace)
                            foreach(var entry in trace.Primary.Entry)
                            {
                                var traceEntry = new Fortify_TraceEntry();
                                if (entry.NodeRef.notNull())
                                    traceEntry.NodeRefId = entry.NodeRef.id;
                                if (entry.Node.notNull())
                                {
                                    var node = entry.Node;
                                    traceEntry.DetailsOnly = node.detailsOnly ?? false;
                                    traceEntry.IsDefault = node.isDefault ?? false;
                                    traceEntry.Label = node.label ?? "";
                                   
                                    if (node.Action.notNull())
                                    {
                                        traceEntry.ActionType = node.Action.type;
                                        traceEntry.ActionValue = node.Action.TypedValue;
                                    }                                   
                                    if (node.Knowledge.notNull())
                                    {
                                        foreach(var fact in node.Knowledge.Fact)
                                            traceEntry.KnowledgeFacts.Add(new Fortify_TraceEntryFact()
                                                                                {
                                                                                    Primary = fact.primary,
                                                                                    Type = fact.type,
                                                                                    Value = fact.TypedValue
                                                                                });
                                    }                                   
                                    if (node.Reason.notNull())
                                    {
                                        traceEntry.Reason_RuleId = node.Reason.Rule.notNull()
                                                                        ? node.Reason.Rule.ruleID
                                                                        : "";
                                        traceEntry.Reason_TraceRef = node.Reason.TraceRef.notNull()
                                                                         ? node.Reason.TraceRef.str()
                                                                         : "";
                                        traceEntry.Reason_Internal = node.Reason.Internal.notNull()
                                                                         ? node.Reason.Internal.str()
                                                                         : "";                                    
                                    }   
                                    if (node.SourceLocation.notNull())
                                    {
                                        traceEntry.SourceLocation = new Fortify_CodeLocation(node.SourceLocation);
                                        traceEntry.SourceLocation_ContextId = node.SourceLocation.contextId ?? 0;
                                        traceEntry.SourceLocation_Snippet = "node.SourceLocation.snippet";
                                    }
                                    if (node.SecondaryLocation.notNull())
                                    {
                                        traceEntry.SecundaryLocation = new Fortify_CodeLocation(node.SecondaryLocation);                                       
                                        traceEntry.SecundaryLocation_Snippet = node.SecondaryLocation.snippet;                                       
                                    }                                   
                                }
                                fortifyVulnerability.Traces.Add(traceEntry);                                               
                            }
                    }       
                    fortifyScan.Vulnerabilities.add(fortifyVulnerability);   
                }
               
            return fortifyScan;
        }
    }       

 
Since all the data conversion is happening at the backend classes, the GUI script is now just focused on showing the data (with most objects shown on separate tabs)

//var topPanel = panel.clear().add_Panel(); 
var topPanel = "Util - FVDL viewer (drop *.fvdl on the left-hand-side PropertyGrid)".popupWindow(1000,500);
topPanel.insert_LogViewer();
  </pre>
&nbsp;

var tabControl = topPanel.add_TabControl();
var scannedFiles_Table = tabControl.add_Tab("Scanned Files").add_TableList();
var context_Table = tabControl.add_Tab("Contexts").add_TableList();
var description_Table = tabControl.add_Tab("Descriptions").add_TableList();
var calledWithNoDefs_Table = tabControl.add_Tab("CalledWithNoDefs").add_TableList();
var sinks_Table = tabControl.add_Tab("Sinks").add_TableList();
var sources_Table = tabControl.add_Tab("Sources").add_TableList();
var snippets_Table = tabControl.add_Tab("Snippets").add_TableList();
var vulnerabilities_Table = tabControl.add_Tab("Vulnerabilities").add_TableList();

//var traceNodes_Table = tabControl.add_Tab("TraceNodes").add_TableList();

var propertyGrid = topPanel.insert_Left().add_PropertyGrid();

Fortify_Scan fortifyScan = null;
var apiFortify = new API_Fortify();

Action<string> showUserMessage =
    (message)=> {
//                    userMessages_Label.set_Text(message);                     
                    message.info();
                };
               
Action<Fortify_Scan> showFvdl = 
    (scan) =>  
        {  
                 vulnerabilities_Table.title("Showing {0} Vulnerabilties".format(scan.Vulnerabilities.size()))   
                                      .show(scan.Vulnerabilities);        
                scannedFiles_Table.show(scan.ScannedFiles);
                context_Table.show(scan.Contexts); //.makeColumnWidthMatchCellWidth();
                description_Table.show(scan.Descriptions);
                calledWithNoDefs_Table.show(scan.CalledWithNoDefs);                
                sinks_Table.show(scan.Sinks);
                sources_Table.show(scan.Sources);
                vulnerabilities_Table.show(scan.Vulnerabilities);
                snippets_Table.show(scan.Snippets);
//                traceNodes_Table.show((from vulnerability in scan.Vulnerabilities    
//                                       select vulnerability.Traces).SelectMany(p=>p).toList()); 
        };
 
Action<string> loadAndShowFile =
    (file)=>{ 
                showUserMessage("... loading file: {0}".format(file.fileName())); 
                O2Thread.mtaThread(()=>{                                                                                          
                                            fortifyScan = apiFortify.convertToFortifyScan(file);
                                            showFvdl(fortifyScan);         
                                            propertyGrid.show(fortifyScan);
                                            showUserMessage("loaded fvdl file: {0}".format(file.fileName()));
                                        });
            };

propertyGrid.onDrop(loadAndShowFile);
  
return "done";       
      
//O2File:API_Fortify_1_6.cs
//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll 
 

July 18, 2011 Posted by | Fortify, Interoperability | Leave a comment

Fortify FVDL Files – First working Parser and Viewer for *.fvdl files

Following from the previous Fortify FVDL posts (herehere, here and here), here is a first working tool that is able to load up *.fvdl files, parse its relevant data into a new set of classes, and then visuzalize its contents into a number of tabs.

This is what the main GUI look like (after loading/dropping the 35Mb dspace.fvdl file):

On the left there is a PropertyGrid control that shows a view of the new O2 Fortify_Scan class, and on the right there is a TabControl with a number of Tab Pages (each containing a raw view of the classes created).

Here is what each of the  tab pages looks like:

ScannedFiles

Contexts:

Descriptions

CalledWithNoDefs

Sinks

Sources

Snippets

Vulnerabilities

 The next post will show what the updated API_Fortify looks like, and the code that was used to create this GUI

July 18, 2011 Posted by | Fortify, Interoperability | 1 Comment

Fortify FVDL files – Creating .NET classes that map to Fvdl xml structure

I’m still getting my head around how the *.fvdl files are structured, but after looking at the data that they seem to contains (using the fvdl.details() viewer), I’ve created the following classes which (I think) represent the type of data that is contained in the fvdl files (I tried to consolidate the data structures a bit, but I’m sure there is still quite a bit of refectoring and optimization that can be done):

    public class Fortify_Scan
    {
        public FVDL _fvdl;
       
        public string BuildID { get; set; }
        public string LOC { get; set; }
        public string SourceBasePath { get; set; }
        public string CreatedDate { get; set; }
        public string CreatedTime { get; set; }       
        public List<Fortify_Vulnerability> Vulnerabilities { get; set; }
        public List<Fortify_Context> Contexts { get; set; }
        public List<Fortify_Description> Descriptions { get; set; }
        public List<Fortify_Sink> Sinks { get; set; }
        public List<Fortify_Source> Sources { get; set; }
       
        public Fortify_Scan()
        {
            Vulnerabilities = new List<Fortify_Vulnerability>();
            Contexts = new List<Fortify_Context>();
            Descriptions = new List<Fortify_Description>();
            Sinks = new List<Fortify_Sink>();
            Sources = new List<Fortify_Source>();
        }
    }       
           
    public class Fortify_Context
    {
        public string Id { get; set; }
        public Fortify_Function Function { get; set; }
    }
   
    public class Fortify_Function
    {
        public string FunctionName { get; set; }
        public Fortify_CodeLocation CodeLocation { get; set; }       
    }
   
    public class Fortify_CodeLocation
    {
        public string Path { get; set; }
        public string Line { get; set; }
        public string LineEnd { get; set; }
        public string ColStart { get; set; }
        public string ColEnd { get; set; }
    }
   
    public class Fortify_Description
    {
        public string Abstract { get; set; }
        public string ClassID { get; set; }
        public string ContentType { get; set; }
        public string Explanation { get; set; }
        public string Recommendations { get; set; }
        public string Tips { get; set; }       
    }
   
    public class Fortify_Sink
    {
        public string ruleID { get; set; }
        public Fortify_Function Function_Call{ get; set;}               
    }
   
    public class Fortify_Source
    {
        public string ruleID { get; set; }
        public Fortify_Function Function_Call{ get; set;}               
        public Fortify_Function Function_Entry{ get; set;}               
        public List<string> TaintFlags { get; set;}
        public Fortify_Source()
        {
            TaintFlags = new List<string>();
        }
    }       
   
    public class Fortify_Snippet
    {
        public string Id { get; set; }
        public Fortify_CodeLocation CodeLocation { get; set; }       
        public string Text { get; set;}       
    }
    public class Fortify_TraceEntry
    {
        public Fortify_TraceEntryNode Node         { get; set; }
        public string NodeRef                     { get; set; }
    }
    public class Fortify_TraceEntryNode
    {
        public bool IsDefault                             { get; set; }
        public string ActionType                         { get; set; }
        public string ActionValue                         { get; set; }
        public Fortify_CodeLocation SourceLocation         { get; set; }
        public Fortify_CodeLocation SecundaryLocation     { get; set; }
        public Fortify_Snippet Snippet                     { get; set; }
        public string ContextId                            { get; set; }
        public string ReasonRuleId                        { get; set; }
        public string Label                                { get; set; }
        public List<Fortify_TraceEntryFact> Facts        { get; set; }
       
    }
   
    public class Fortify_TraceEntryFact
    {
        public bool Primary {get;set;}
        public string Type {get;set;}
        public string Value {get;set;}
    }
    public class Fortify_Vulnerability
    {
        public string Kingdom { get; set; }                // from ClassInfo
        public string Analyzer { get; set; }
        public string ClassId { get; set; }
        public decimal DefaultSeverity { get; set; }
        public string  Type { get; set; }
        public string  SubType { get; set; }
       
        public decimal Confidence { get; set; }            // from InstanceInfo
        public string InstanceId { get; set; }
        public decimal InstanceSeverity { get; set; }
       
       
        public Fortify_Function Function { get; set; }       
        public Items ReplacementDefinitions { get; set; }
        public List<Fortify_TraceEntry> Traces { get; set; }
    }

(also, the data structures that I’m seeing are directly mapped to the object that was created from the current XSD/C# file, so if you know the inner structure of the *.fvdl files and see missing bits of data that are very useful to have or visualize, please let me know)

To reflect the new Classes (and the fact that the main object is now the Fortify_Scan class), I’ve modified the API_Fortify class (note that there is still quite a bit to go, since the mapping functions are just importing some of the vulnerability data available)

    public class API_Fortify
    {               
        public Fortify_Scan convertToFortifyScan(string fvdlFile)
        {
            var scan = new Fortify_Scan();
            scan._fvdl = loadFvdl_Raw(fvdlFile);
            scan.mapFvdlData();
            return scan;
        }
       
        public FVDL loadFvdl_Raw(string fvdlFile)
        {
            try
            {
                var chachedFvdl = (FVDL)O2LiveObjects.get(fvdlFile);
                if (chachedFvdl.notNull())
                    return chachedFvdl;
            }
            catch { }
            
            var o2Timer = new O2Timer("loading {0} file".format(fvdlFile.fileName())).start();       
             var _fvdl = FVDL.Load(fvdlFile);   
             O2LiveObjects.set(fvdlFile,_fvdl);
             o2Timer.stop();
             return _fvdl; 
        }
    }
   
    public static class Fortify_Scan_ExtensionMethods_MappingFvdl
    {
        public static Fortify_Scan mapFvdlData(this Fortify_Scan fortifyScan)
        {
            fortifyScan.mapVulnerabilities();
            return fortifyScan;
        }
       
        public static Fortify_Scan mapVulnerabilities(this Fortify_Scan fortifyScan)
        {                
                foreach(var vulnerability in fortifyScan._fvdl.Vulnerabilities.Vulnerability)
                {
                      var fortifyVulnerability = new Fortify_Vulnerability
                              {
                                Kingdom = vulnerability.ClassInfo.Kingdom,
                                Analyzer = vulnerability.ClassInfo.AnalyzerName,
                                ClassId = vulnerability.ClassInfo.ClassID,
                                DefaultSeverity = vulnerability.ClassInfo.DefaultSeverity,
                                InstanceId = vulnerability.InstanceInfo.InstanceID,
                                InstanceSeverity = vulnerability.InstanceInfo.InstanceSeverity,
                                Confidence = vulnerability.InstanceInfo.Confidence,                                          
/*                                Function = vulnerability.AnalysisInfo.Unified.notNull() && vulnerability.AnalysisInfo.Unified.Context.Function.notNull()
                                            ? vulnerability.AnalysisInfo.Unified.Context.Function.name
                                            : "" ,
                                File = vulnerability.AnalysisInfo.Unified.notNull() && vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.notNull()
                                            ? vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.path
                                            : "" ,
                                Line = vulnerability.AnalysisInfo.Unified.notNull() && vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.notNull()
                                            ? vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.line
                                            : 0
*/                                           
                            };
                    fortifyScan.Vulnerabilities.add(fortifyVulnerability);   
                };                               
                return fortifyScan;
        }
    }       

Here is the updated viewer (that now consumes a Fortify_Scan object)

var topPanel = panel.clear().add_Panel();
//var topPanel = "Util - Simple FVDL viewer".popupWindow(1000,400);</pre>
&nbsp;

var tableList = topPanel.clear().add_TableList().title("Drop an *.fvdl file here to load it");
var propertyGrid = topPanel.insert_Left().add_PropertyGrid();
var apiFortify = new API_Fortify();

Action<List<Fortify_Vulnerability>> showFvdl =
    (vulnerabilities) =>
        {
                 tableList.title("Showing {0} Vulnerabilties".format(vulnerabilities.size()))
                         .show(vulnerabilities);                                                        
        };
 
Action<string> loadAndShowFile =
    (file)=>{
                tableList.title("... loading file: {0}".format(file.fileName()));
                O2Thread.mtaThread(()=>{                                                                                       
                                            var fortifyScan = apiFortify.convertToFortifyScan(file);
                                            showFvdl(fortifyScan.Vulnerabilities);       
                                            propertyGrid.show(fortifyScan);
                                        });
            };

tableList.onDrop(loadAndShowFile);
tableList.getListViewControl().onDrop(loadAndShowFile);
   
var testFile = @"C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl";
loadAndShowFile(testFile);
/*(var _fortifyScan = apiFortify.convertToFortifyScan(xmlFile);
propertyGrid.show(_fortifyScan);   
showFvdl(_fortifyScan.Vulnerabilities);*/

return "done"; 

//O2File:C:\O2\O2Scripts_Database\_Scripts\3rdParty_Tools\Fortify\API_Fortify_1_6.cs
//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll

Note that I added a PropertyGrid to the left of the GUI which will show the contents of the Fortity_Scan object

July 17, 2011 Posted by | Fortify, Interoperability | 2 Comments

Fortify FVDL files – Creating an API and consumining it

Following from the (Fortify FVDL related) Creating and consuming the schema and CSharp file and Simple TableList Viewer Tool posts, this one shows the next evolutionary step, which is the creation of an API that can be easily consumed by *.h2 scripts.

The script show here will have the same funcionality has the one shown in Simple TableList Viewer Tool, but the its structure will be completely different.

 The data will be stored in a dedicated class (previously we used an anonymous class)

public class Fortify_Vulnerability
    {
        public string Kingdom { get; set; }
        public string Analyzer { get; set; }
        public string ClassId { get; set; }
        public decimal DefaultSeverity { get; set; }
        public string InstanceId { get; set; }
        public decimal InstanceSeverity { get; set; }
        public decimal Confidence { get; set; }
        public string Function { get; set; }
        public string File { get; set; }
        public int Line { get; set; }
    }

And the main functions of loading and parsing are now exposed in an API file called API_Fortify_1_6.cs (which provides the class API_Fortify):

    public class API_Fortify
    {
        public FVDL loadFvdl(string fvdlFile)
        {
            try
            {
                var chachedFvdl = (FVDL)O2LiveObjects.get(fvdlFile);
                if (chachedFvdl.notNull())
                    return chachedFvdl;
            }
            catch { }
            
            var o2Timer = new O2Timer("loading {0} file".format(fvdlFile.fileName())).start();       
             var _fvdl = FVDL.Load(fvdlFile);   
             O2LiveObjects.set(fvdlFile,_fvdl);
             o2Timer.stop();
             return _fvdl; 
        }
       
       
        public List<Fortify_Vulnerability> getVulnerabilities(FVDL fvdl)
        {
                
                 var fortifyVulnerabities = new List<Fortify_Vulnerability>();               
                foreach(var vulnerability in fvdl.Vulnerabilities.Vulnerability)
                {
                      var fortifyVulnerability = new Fortify_Vulnerability
                              {
                                Kingdom = vulnerability.ClassInfo.Kingdom,
                                Analyzer = vulnerability.ClassInfo.AnalyzerName,
                                ClassId = vulnerability.ClassInfo.ClassID,
                                DefaultSeverity = vulnerability.ClassInfo.DefaultSeverity,
                                InstanceId = vulnerability.InstanceInfo.InstanceID,
                                InstanceSeverity = vulnerability.InstanceInfo.InstanceSeverity,
                                Confidence = vulnerability.InstanceInfo.Confidence,                                          
                                Function = vulnerability.AnalysisInfo.Unified.notNull() && vulnerability.AnalysisInfo.Unified.Context.Function.notNull()
                                            ? vulnerability.AnalysisInfo.Unified.Context.Function.name
                                            : "" ,
                                File = vulnerability.AnalysisInfo.Unified.notNull() && vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.notNull()
                                            ? vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.path
                                            : "" ,
                                Line = vulnerability.AnalysisInfo.Unified.notNull() && vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.notNull()
                                            ? vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.line
                                            : 0
                            };
                    fortifyVulnerabities.add(fortifyVulnerability);   
                };
                return fortifyVulnerabities;
        }
    }       

The GUI script is now much smaller and is mailly focused on creating the GUI and consuming the API_Fortify class:

//var topPanel = panel.clear().add_Panel();
var topPanel = "Util - Simple FVDL viewer".popupWindow(1000,400);
var tableList = topPanel.clear().add_TableList().title("Drop an *.fvdl file here to load it");

var apiFortify = new API_Fortify();

Action<List<Fortify_Vulnerability>> showFvdl =
    (vulnerabilities) =>
        {
                 tableList.title("Showing {0} Vulnerabilties".format(vulnerabilities.size()))
                         .show(vulnerabilities);                                                        
        };
 
Action<string> loadAndShowFile =
    (file)=>{
                tableList.title("... loading file: {0}".format(file.fileName()));
                O2Thread.mtaThread(()=>{
                                            var fvdl = apiFortify.loadFvdl(file);
                                            showFvdl(apiFortify.getVulnerabilities(fvdl));
                                        });
            };

tableList.onDrop(loadAndShowFile);
tableList.getListViewControl().onDrop(loadAndShowFile);
   
//var xmlFile = @"C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl";
//var _fvdl = apiFortify.loadFvdl(xmlFile);
//showFvdl(apiFortify.getVulnerabilities(_fvdl));

return "done"; 

//O2File:C:\O2\O2Scripts_Database\_Scripts\3rdParty_Tools\Fortify\API_Fortify_1_6.cs
//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll

The end result is the same as with the script shown in the  Simple TableList Viewer Tool post:

July 17, 2011 Posted by | Fortify, Interoperability | 1 Comment

Fortify FVDL files – Simple TableList Viewer Tool

Following on from the Fortify FVDL files – Creating and consuming the schema and CSharp file  post , let’s now build a generic simple tool to view fvdl files (which as long as they are compliant with the XSD we created, they should load).

Note: These scripts are going to use the demo files referenced in the previous post, and that you can download from http://s3.amazonaws.com/Demo_Files/Fortify-Sate-2008.zip . This zip should had been unziped to the ‘C:\O2\_tempDir\_Fortify-Sate-2008\’ folder (as per the previous scripts) and the C# that I’m going to use is the one that you will find at ‘C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\Fortify.fvdl.1.6.cs’ (this is the same one as created by the previous example, except that is located on a different folder and has a different name)

The first step is to load up a file and view it in a ListView (this is the last example of the previous script)

var topPanel = panel.clear().add_Panel();
var xmlFile = @"C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl";
var fvdl = FVDL.Load(xmlFile);
var vulnerabilities = fvdl.Vulnerabilities.Vulnerability; 

var results =  (from vulnerability in vulnerabilities
                  select new  {
                                kingdom = vulnerability.ClassInfo.Kingdom,
                                analyzer = vulnerability.ClassInfo.AnalyzerName,
                                classId = vulnerability.ClassInfo.ClassID,
                                defaultSeverity = vulnerability.ClassInfo.DefaultSeverity,
                                instanceId = vulnerability.InstanceInfo.InstanceID,
                                instanceSeverity = vulnerability.InstanceInfo.InstanceSeverity,
                                confidence = vulnerability.InstanceInfo.Confidence,
                                function = vulnerability.AnalysisInfo.Unified.Context.Function.name,
                                file = vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.path,
                                line = vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.line,
                                col = vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.colStart
                               
                            }).toList();

topPanel.add_TableList("Showing {0} Vulnerabilties".format(results.size()))
        .show(results);                           
return "done";

//using xmlns.www.fortifysoftware.com.schema.fvdl
//O2File:C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\Fortify.fvdl.1.6.cs
//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll

 

The first thing to do is to move the loading of the fvdl into a separate Lamdba method:

Func<string, FVDL> loadFvdl =
    (fvdlFile)=>{
                    var o2Timer = new O2Timer("loading {0} file".format(fvdlFile.fileName())).start();       
                     var _fvdl = FVDL.Load(fvdlFile);   
                     o2Timer.stop();
                     return _fvdl;
                };
 
var xmlFile = @"C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl";
var fvdl = loadFvdl(xmlFile);

Then also  move the code that shows the results into its own Lambda function

Action<FVDL> showFvdl =
     (_fvdl)=>{
                var vulnerabilities = _fvdl.Vulnerabilities.Vulnerability;
 
                var results =  (from vulnerability in vulnerabilities
                  select new  {
                                kingdom = vulnerability.ClassInfo.Kingdom,
                                analyzer = vulnerability.ClassInfo.AnalyzerName,
                                classId = vulnerability.ClassInfo.ClassID,
                                defaultSeverity = vulnerability.ClassInfo.DefaultSeverity,
                                instanceId = vulnerability.InstanceInfo.InstanceID,
                                instanceSeverity = vulnerability.InstanceInfo.InstanceSeverity,
                                confidence = vulnerability.InstanceInfo.Confidence,
                                function = vulnerability.AnalysisInfo.Unified.Context.Function.name,
                                file = vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.path,
                                line = vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.line,
                                col = vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.colStart
                               
                            }).toList();
                tableList.title("Showing {0} Vulnerabilties".format(results.size()))
                         .show(results);                                       
                
              };

Next add Drag & Drop support so that can just drop an *.fvdl file to see it:

Action<string> loadAndShowFile =
    (file)=>{ 
                 var fvdl = loadFvdl(file);
                 showFvdl(fvdl);
            };

tableList.onDrop(loadAndShowFile);
tableList.getListViewControl().onDrop(loadAndShowFile);

…and show a message to the user (while loading the data in a separate thread)

Action<string> loadAndShowFile =
    (file)=>{
                tableList.title("... loading file: {0}".format(file.fileName()));
                O2Thread.mtaThread(()=>{
                                            var fvdl = loadFvdl(file);
                                            showFvdl(fvdl);
                                        });
            };
tableList.onDrop(loadAndShowFile);
tableList.getListViewControl().onDrop(loadAndShowFile);

Change the getFvdl method to add support for caching the loaded objects (helps when dealing with large files that are loaded more than one time during the same session)

Func<string, FVDL> loadFvdl =
    (fvdlFile)=>{       
                    try
                    {
                        return (FVDL)O2LiveObjects.get(fvdlFile);
                    }
                    catch { }
                    
                    var o2Timer = new O2Timer("loading {0} file".format(fvdlFile.fileName())).start();       
                     var _fvdl = FVDL.Load(fvdlFile);   
                     O2LiveObjects.set(fvdlFile,_fvdl);
                     o2Timer.stop();
                     return _fvdl; 
                };

Change the getFvdl method to detect some cases where there is no data for: function, file or line

Action<FVDL> showFvdl =
     (_fvdl)=>{
                var vulnerabilities = _fvdl.Vulnerabilities.Vulnerability;
 
                var results =  (from vulnerability in vulnerabilities
                  select new  {
                                kingdom = vulnerability.ClassInfo.Kingdom,
                                analyzer = vulnerability.ClassInfo.AnalyzerName,
                                classId = vulnerability.ClassInfo.ClassID,
                                defaultSeverity = vulnerability.ClassInfo.DefaultSeverity,
                                instanceId = vulnerability.InstanceInfo.InstanceID,
                                instanceSeverity = vulnerability.InstanceInfo.InstanceSeverity,
                                confidence = vulnerability.InstanceInfo.Confidence,                                          
                                function = vulnerability.AnalysisInfo.Unified.notNull() && vulnerability.AnalysisInfo.Unified.Context.Function.notNull()
                                            ? vulnerability.AnalysisInfo.Unified.Context.Function.name
                                            : "" ,
                                file = vulnerability.AnalysisInfo.Unified.notNull() && vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.notNull()
                                            ? vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.path
                                            : "" ,
                                line = vulnerability.AnalysisInfo.Unified.notNull() && vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.notNull()
                                            ? vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.line
                                            : 0
                            }).toList();
                tableList.title("Showing {0} Vulnerabilties".format(results.size()))
                         .show(results);                                                        
              };

Make this a generic tool and add a title to the TableList that indicates to the user that he/she needs to drop an *.fvdl file to load it:

//var topPanel = panel.clear().add_Panel();
var topPanel = "Util - Simple FVDL viewer".popupWindow(1000,400);</pre>
&nbsp;

var tableList = topPanel.clear().add_TableList().title("Drop an *.fvdl file here to load it");

Finally, save it as an *.h2 file so that it can be invoked as a stand alone tool:

To execute this script, just double click on it, and the following GUI should appear:

Now drag and drop a *.fvdl file to load it and see detals about its vulnerabilities:

 naim.fvdl

lighttpd.fvdl

nagios.fvdl

mvnforum.fvdl

For reference here is the complete script (available as the Util – Simple FVDL viewer.h2 script):

//var topPanel = panel.clear().add_Panel();
var topPanel = "Util - Simple FVDL viewer".popupWindow(1000,400);

var tableList = topPanel.clear().add_TableList().title("Drop an *.fvdl file here to load it");

Func<string, FVDL> loadFvdl =
    (fvdlFile)=>{       
                    try
                    {
                        var chachedFvdl = (FVDL)O2LiveObjects.get(fvdlFile);
                        if (chachedFvdl.notNull())
                            return chachedFvdl;
                    }
                    catch { }
                    
                    var o2Timer = new O2Timer("loading {0} file".format(fvdlFile.fileName())).start();       
                     var _fvdl = FVDL.Load(fvdlFile);   
                     O2LiveObjects.set(fvdlFile,_fvdl);
                     o2Timer.stop();
                     return _fvdl; 
                };
 
 Action<FVDL> showFvdl =
     (_fvdl)=>{
                var vulnerabilities = _fvdl.Vulnerabilities.Vulnerability;
 
                var results =  (from vulnerability in vulnerabilities
                  select new  {
                                kingdom = vulnerability.ClassInfo.Kingdom,
                                analyzer = vulnerability.ClassInfo.AnalyzerName,
                                classId = vulnerability.ClassInfo.ClassID,
                                defaultSeverity = vulnerability.ClassInfo.DefaultSeverity,
                                instanceId = vulnerability.InstanceInfo.InstanceID,
                                instanceSeverity = vulnerability.InstanceInfo.InstanceSeverity,
                                confidence = vulnerability.InstanceInfo.Confidence,                                          
                                function = vulnerability.AnalysisInfo.Unified.notNull() && vulnerability.AnalysisInfo.Unified.Context.Function.notNull()
                                            ? vulnerability.AnalysisInfo.Unified.Context.Function.name
                                            : "" ,
                                file = vulnerability.AnalysisInfo.Unified.notNull() && vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.notNull()
                                            ? vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.path
                                            : "" ,
                                line = vulnerability.AnalysisInfo.Unified.notNull() && vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.notNull()
                                            ? vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.line
                                            : 0
                            }).toList();
                tableList.title("Showing {0} Vulnerabilties".format(results.size()))
                         .show(results);                                                        
              };
 

Action<string> loadAndShowFile =
    (file)=>{
                tableList.title("... loading file: {0}".format(file.fileName()));
                O2Thread.mtaThread(()=>{
                                            var fvdl = loadFvdl(file);
                                            showFvdl(fvdl);
                                        });
            };

tableList.onDrop(loadAndShowFile);
tableList.getListViewControl().onDrop(loadAndShowFile);
   

return "done"; 

//using xmlns.www.fortifysoftware.com.schema.fvdl
//O2File:C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\Fortify.fvdl.1.6.cs
//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll

July 17, 2011 Posted by | Fortify, Interoperability | 2 Comments

Fortify FVDL files – Creating and consuming the schema and CSharp file

An o2 user send me a nice 400Mb Fortify file to see if O2 could do something with it (since Fortify’s GUI was not able to load it).

The next couple posts will document how to go from an XML file to creating an API to consume and to visualize it.

For this demo I will use the Fortify FVDL files that where published by SATE 2008 results (part of NIST SAMATE project) which Fortify participated. You can download the entire SATE 2008 data from their website (which includes the findings files from all participats and SATE’s result), or you can download just the Fortify FVDL (and xsd) from O2’s S3 repository: Fortify-Sate-2008.zip (the scripts below will use this files, but if you have access to *.fvdl files, you can use them)

To start, open an ‘O2 Quick Development Environment GUI’

Then download the demos files and unzip them to a local temp folder:

var demoFileUrl = "http://s3.amazonaws.com/Demo_Files/Fortify-Sate-2008.zip";
var localFile = demoFileUrl.uri().download();

Next step is to unzip the file:

var localFile = "".tempDir().pathCombine("Fortify-Sate-2008.zip");
if (localFile.fileExists().isFalse())
{
    var demoFileUrl = "http://s3.amazonaws.com/Demo_Files/Fortify-Sate-2008.zip";
    demoFileUrl.uri().download();
}   
return localFile.unzip_File();

Then add a check to only unzip if the target folder doesn’t exist and package it in a Lambda method which can be easily consumed by the main script:

Func<string> getFolderWithFvdlDemoFiles =
    ()=>{
            var localFile = "".tempDir().pathCombine("Fortify-Sate-2008.zip");
            if (localFile.fileExists().isFalse())
            {
                var demoFileUrl = "http://s3.amazonaws.com/Demo_Files/Fortify-Sate-2008.zip";
                demoFileUrl.uri().download();
            }    
            var targetFolder = @"..\_Fortify-Sate-2008".tempDir(false).fullPath(); // by default this willl resolve to C:\O2\_tempDir\_Fortify-Sate-2008
            if (targetFolder.dirExists().isFalse())
                localFile.unzip_File(targetFolder);            
            return targetFolder;
        };

var folderWithFvdlFiles = getFolderWithFvdlDemoFiles();       
return folderWithFvdlFiles.files(true,"*.fvdl");

There a number of *.fvdl files available, and since the first thing we need is to create an *.xsd for them, let’s pick the smaller one (in this case naim.fvdl)

var folderWithFvdlFiles = getFolderWithFvdlDemoFiles();        
var naimFvdl = folderWithFvdlFiles.files(true,"naim.fvdl").first();
return naimFvdl;

Usually at this stage we can use the O2 Fluent XML Apis to do this. Basically, in most cases this works:

var folderWithFvdlFiles = getFolderWithFvdlDemoFiles();        
var naimFvdl = folderWithFvdlFiles.files(true,"naim.fvdl").first();


return naimFvdl.xmlCreateXSD(); // creates XSD from Xml file

Unfortunately, for this XML file, we get the error “The table (Node) cannot be the child table to itself in nested relations.” (which is quite a common error when creating XSDs from XML files)

The 2nd usual attempt is to try to use the XSD.exe tool that comes with Visual Studio, But that just returns the same error:

The 3rd attempt is to use VisualStudio 2010 for the conversion. Before we open the file in visual studio, we will need to create a new copy (or rename it) with an .xml extension (ie C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl.xml)

 Then from the XML menu, select the ‘Create Schema’ menu Item

Which this time around should work 🙂 :

Save this file locally

Now go back to the O2 development Gui (or open up a new one), and lets create the CSharp file. Start by making sure you have a correct reference to the file:

var xsdFile = @"C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl.xsd";
return xsdFile.fileExists();

call the xsdCreateCSharpFile method to create a CSharp file:

var xsdFile = @"C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl.xsd";
return xsdFile.xsdCreateCSharpFile(); 

This will create a file called ‘C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl.cs’, which you can take look by opening it in a source code editor control

var topPanel = panel.clear().add_Panel();
var xsdFile = @"C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl.xsd";
var csharpFile = xsdFile.xsdCreateCSharpFile(); 
var codeEditor = topPanel.add_SourceCodeEditor(); // add source code editor to topPanel
codeEditor.invoke("setMaxLoadSize","1000");       // invoke the private method that sets the max size of the file to load using the SharpDevelop control (if bigger the file is opended in a listview)
codeEditor.open(csharpFile);                        // open file

if try to compile this csharp file, you will get a number of “The type of namespace ‘xyz’ could not be found”  errors

This is caused because the CSharp file was created using the Link2Xml Apis which are included in the O2_Misc_Microsoft_MPL_Libs.dll.

The solution is to add this as a reference at the top of the file, which will make the compilation work

Note that this extra reference could had also be introduced programatically like this:

var xsdFile = @"C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl.xsd";
var csharpFile = xsdFile.xsdCreateCSharpFile(); 

csharpFile.fileContents()
      .insertBefore("//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll".line())
      .saveAs(csharpFile);

The final step, now that we have the CSharp file (‘C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl.cs’), is to use it as a reference and load up the original Xml file using it.

To make it clear, lets do this on a clean O2 Development GUI Environment

If you look at the CSHarp file you should notice that there is namespace

namespace xmlns.www.fortifysoftware.com.schema.fvdl {

…which contains a FVDL class

public partial class FVDL : XTypedElement, IXMetaData {

…which contains a Load static method

        public static FVDL Load(string xmlFile) {
            return XTypedServices.Load<FVDL>(xmlFile);
        }

This is the method that we will need to call , so that we can get a strongly typed version of our XML file

var xmlFile = @"C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl";
var fvdl = FVDL.Load(xmlFile);
return fvdl;

//using xmlns.www.fortifysoftware.com.schema.fvdl
//O2File:C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl.cs
//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll

 … which finally gives us the object that we want:

…and provides strongly-typed access to the fvdl data, including code-complete support

  ->

As a first exampe,  here is the list of vulnerability objects in the loaded xml file:

Note: one way to see in more details the type of objects that are availble is to call the {object}.details() method:

var xmlFile = @"C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl";
var fvdl = FVDL.Load(xmlFile);
var vulnerabilities = fvdl.Vulnerabilities.Vulnerability; 
vulnerabilities.details();

..which opens a popup window that can be navigated by properties or fields (note that the data is only loaded on selection)

Going back into Vulnerability filtering …

… where it gets really powerful is when we use Linq queries to filter the data:

var xmlFile = @"C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl";
var fvdl = FVDL.Load(xmlFile);
var vulnerabilities = fvdl.Vulnerabilities.Vulnerability; 

return (from vulnerability in vulnerabilities
        select vulnerability.ClassInfo.Kingdom).Distinct(); 

In this case, here is a distinct list of the vunerability’s Kingdoms

…  or a quick consolidated view of  the vulnerability data:

var topPanel = panel.clear().add_Panel();
var xmlFile = @"C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl";
var fvdl = FVDL.Load(xmlFile);
var vulnerabilities = fvdl.Vulnerabilities.Vulnerability; </pre>
&nbsp;

var results =  (from vulnerability in vulnerabilities
                  select new  {
                                kingdom = vulnerability.ClassInfo.Kingdom,
                                analyzer = vulnerability.ClassInfo.AnalyzerName,
                                classId = vulnerability.ClassInfo.ClassID,
                                defaultSeverity = vulnerability.ClassInfo.DefaultSeverity,
                                instanceId = vulnerability.InstanceInfo.InstanceID,
                                instanceSeverity = vulnerability.InstanceInfo.InstanceSeverity,
                                confidence = vulnerability.InstanceInfo.Confidence,
                                function = vulnerability.AnalysisInfo.Unified.Context.Function.name,
                                file = vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.path,
                                line = vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.line,
                                col = vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.colStart
                               
                            });
return results;

 

This  ‘Linq result’ object, is a local C# anonymous class, and is better seen and analyed on a TableList:

var topPanel = panel.clear().add_Panel();
var xmlFile = @"C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl";
var fvdl = FVDL.Load(xmlFile);
var vulnerabilities = fvdl.Vulnerabilities.Vulnerability; </pre>
&nbsp;

var results =  (from vulnerability in vulnerabilities
                  select new  {
                                kingdom = vulnerability.ClassInfo.Kingdom,
                                analyzer = vulnerability.ClassInfo.AnalyzerName,
                                classId = vulnerability.ClassInfo.ClassID,
                                defaultSeverity = vulnerability.ClassInfo.DefaultSeverity,
                                instanceId = vulnerability.InstanceInfo.InstanceID,
                                instanceSeverity = vulnerability.InstanceInfo.InstanceSeverity,
                                confidence = vulnerability.InstanceInfo.Confidence,
                                function = vulnerability.AnalysisInfo.Unified.Context.Function.name,
                                file = vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.path,
                                line = vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.line,
                                col = vulnerability.AnalysisInfo.Unified.Context.FunctionDeclarationSourceLocation.colStart
                               
                            }).toList();

topPanel.add_TableList("Showing {0} Vulnerabilties".format(results.size()))
        .show(results);                           
return "done";

//using xmlns.www.fortifysoftware.com.schema.fvdl
//O2File:C:\O2\_tempDir\_Fortify-Sate-2008\Fortify-Sate-2008\sate2008-Fvdl\naim.fvdl.cs
//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll

That wraps up this example, the next related entries will continue from here 🙂

July 16, 2011 Posted by | Fortify, Interoperability | 3 Comments