Skip to main content

Static Analysis Post-Processor for processing taint analysis results.

Project description

lint tests pyre

SAPP

SAPP stands for Static Analysis Post Processor. SAPP takes the raw results of Pysa and makes them explorable both through a command line interface and a web UI.

Installation

SAPP can be installed through PyPI with pip install fb-sapp.

Getting Started

This guide assumes that you have results from a Pysa run saved in a ~/example directory. If you are new to Pysa, you can follow this tutorial to get started.

Processing the Results

The postprocessing will translate the raw output containing models for every analyzed function into a format that is more suitable for exploration.

[~/example]$ sapp --database-name sapp.db analyze taint-output.json

After the results have been processed we can now explore them through the UI and a command line interface. We will briefly look at both of those methods here.

Web Interface

Start the web interface with

[~/example]$ sapp --database-name sapp.db server --source-directory=<WHERE YOUR CODE LIVES>

and visit http://localhost:5000 in your browser (note: the URL displayd in the code output currently will not work). You will be presented with a list of issues that provide access to example traces.

Command Line Interface

The same information can be accessed through the command line interface:

[~/example]$ sapp --database-name sapp.db explore

This will launch a custom IPython interface that's connected to the sqlite file. In this mode, you can dig into the issues that Pyre surfaces. Following is an example of how to use the various commands.

Start out by listing all known issues:

==========================================================
Interactive issue exploration. Type 'help' for help.
==========================================================

[ run 1 ]
>>> issues
Issue 1
    Code: 5001
 Message: Possible shell injection Data from [UserControlled] source(s) may reach [RemoteCodeExecution] sink(s)
Callable: source.convert
 Sources: input
   Sinks: os.system
Location: source.py:9|22|32
Found 1 issues with run_id 1.

As expected, we have 1 issue. To select it:

[ run 1 ]
>>> issue 1
Set issue to 1.

Issue 1
    Code: 5001
 Message: Possible shell injection Data from [UserControlled] source(s) may reach [RemoteCodeExecution] sink(s)
Callable: source.convert
 Sources: input
   Sinks: os.system
Location: source.py:9|22|32

View how the data flows from source to sink:

[ run 1 > issue 1 > source.convert ]
>>> trace
     # ⎇  [callable]       [port]      [location]
     1    leaf             source      source.py:8|17|22
 --> 2    source.convert   root        source.py:9|22|32
     3    source.get_image formal(url) source.py:9|22|32
     4    leaf             sink        source.py:5|21|28

Move to the next callable:

[ run 1 > issue 1 > source.convert ]
>>> n
     # ⎇  [callable]       [port]      [location]
     1    leaf             source      source.py:8|17|22
     2    source.convert   root        source.py:9|22|32
 --> 3    source.get_image formal(url) source.py:9|22|32
     4    leaf             sink        source.py:5|21|28

Show the source code at that callable:

[ run 1 > issue 1 > source.get_image ]
>>> list
In source.convert [source.py:9|22|32]
     4      command = "wget -q https:{}".format(url)
     5      return os.system(command)
     6
     7  def convert() -> None:
     8      image_link = input("image link: ")
 --> 9      image = get_image(image_link)
                              ^^^^^^^^^^

Move to the next callable and show source code:

[ run 1 > issue 1 > source.get_image ]
>>> n
     # ⎇  [callable]       [port]      [location]
     1    leaf             source      source.py:8|17|22
     2    source.convert   root        source.py:9|22|32
     3    source.get_image formal(url) source.py:9|22|32
 --> 4    leaf             sink        source.py:5|21|28

[ run 1 > issue 1 > leaf ]
>>> list
In source.get_image [source.py:5|21|28]
     1  import os
     2
     3  def get_image(url: str) -> int:
     4      command = "wget -q https:{}".format(url)
 --> 5      return os.system(command)
                             ^^^^^^^
     6
     7  def convert() -> None:
     8      image_link = input("image link: ")
     9      image = get_image(image_link)

Jump to the first callable and show source code:

[ run 1 > issue 1 > leaf ]
>>> jump 1
     # ⎇  [callable]       [port]      [location]
 --> 1    leaf             source      source.py:8|17|22
     2    source.convert   root        source.py:9|22|32
     3    source.get_image formal(url) source.py:9|22|32
     4    leaf             sink        source.py:5|21|28

[ run 1 > issue 1 > leaf ]
>>> list
In source.convert [source.py:8|17|22]
     3  def get_image(url: str) -> int:
     4      command = "wget -q https:{}".format(url)
     5      return os.system(command)
     6
     7  def convert() -> None:
 --> 8      image_link = input("image link: ")
                         ^^^^^
     9      image = get_image(image_link)

You can refer to the help command to get more information about available commands in the command line interface.

Terminology

A single SAPP database can keep track of more than just a single run. This opens up the possibility of reasoning about newly introduced issues in a codebase.

Every invocation of

[~/example]$ sapp --database-name sapp.db analyze taint-output.json

will add a single run to the database. An issue can exist over multiple runs (we typicall call the issue in a single run an instance). You can select a run from the web UI and look at all the instances of that run. You can also chose to only show the instances of issues that are newly introduced in this run in the filter menu.

Each instance consists of a data flow from a particular source kind (e.g. user controlled input) into a callable (i.e. a function or method), and a data flow from that callable into a particular sink kind (e.g. RCE).

Note: the data can come from different sources of the same kind and flow into different sinks of the same kind. The traces view of a single instance represents a multitude of traces, not just a single trace.

Development Environment Setup

Start by cloning the repo and setting up a virtual environment:

$ git clone git@github.com:facebook/sapp.git && cd sapp
$ python3 -m venv ~/.venvs/sapp
$ source ~/.venvs/sapp/bin/activate
(sapp) $ pip3 install -r requirements.txt

Run the flask server:

(sapp) $ python3 -m sapp.cli server

Parse static analysis output and save to disk:

(sapp) $ python3 -m sapp.cli analyze taint-output.json

If you make any changes to files under sapp/ui/frontend/*, you will need to run npm install once to install dependencies and npm run-script build each time you make changes before running the flask server to see the changes you made reflected:

Installing dependencies:

(sapp) $ cd sapp/ui/frontend && npm install

Build static files and run the flask server:

(sapp) $ cd sapp/ui/frontend && npm run-script build
(sapp) $ python3 -m sapp.cli server --debug

FAQ

Why is SAPP it's own project and not just part of Pysa?

Stay tuned for future annoucements.

License

SAPP is licensed under the MIT license.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fb-sapp-0.2.10.tar.gz (1.8 MB view details)

Uploaded Source

Built Distribution

fb_sapp-0.2.10-py3-none-any.whl (1.9 MB view details)

Uploaded Python 3

File details

Details for the file fb-sapp-0.2.10.tar.gz.

File metadata

  • Download URL: fb-sapp-0.2.10.tar.gz
  • Upload date:
  • Size: 1.8 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.24.0 setuptools/54.1.2 requests-toolbelt/0.9.1 tqdm/4.51.0 CPython/3.9.2

File hashes

Hashes for fb-sapp-0.2.10.tar.gz
Algorithm Hash digest
SHA256 21ee96e8b0744671cc23dd9d607bfe3c215bad1a44cb86457a0ec013e2a69d6d
MD5 c5c2ad8995621d44c496be5a90098eed
BLAKE2b-256 135dee2f4df6c3337261508b95247a62f274c9d311d8dd9a5020cafeed784317

See more details on using hashes here.

Provenance

File details

Details for the file fb_sapp-0.2.10-py3-none-any.whl.

File metadata

  • Download URL: fb_sapp-0.2.10-py3-none-any.whl
  • Upload date:
  • Size: 1.9 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.24.0 setuptools/54.1.2 requests-toolbelt/0.9.1 tqdm/4.51.0 CPython/3.9.2

File hashes

Hashes for fb_sapp-0.2.10-py3-none-any.whl
Algorithm Hash digest
SHA256 fb08b4da12a93bffc75ce7afefa66200b29c6a60f3a69ca9ebe35cd990074a59
MD5 ee80adb4fcdbcc2d315febfa4f35b323
BLAKE2b-256 317f1644f478427e71684a4e78bf9282b59f2a76e794e1b968752e472b71c9d4

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page