GithubHelp home page GithubHelp logo

mlh-fellowship / pyre-check Goto Github PK

View Code? Open in Web Editor NEW

This project forked from facebook/pyre-check

3.0 8.0 1.0 63.51 MB

Performant type-checking for python.

Home Page: https://pyre-check.org/

License: MIT License

Makefile 0.01% OCaml 79.22% C 1.19% Standard ML 0.27% Python 19.23% Shell 0.03% TypeScript 0.03% Dockerfile 0.02%

pyre-check's Introduction

lint tests pyre License: MIT

Pyre is a performant type checker for Python compliant with PEP 484. Pyre can analyze codebases with millions of lines of code incrementally – providing instantaneous feedback to developers as they write code.

Pyre ships with Pysa, a security focused static analysis tool we've built on top of Pyre that reasons about data flows in Python applications. Please refer to our documentation to get started with our security analysis.

Requirements

To get started, you need Python 3.6 or later and watchman working on your system. On MacOS you can get everything with homebrew:

$ brew install python3 watchman

On Ubuntu, Mint, or Debian; use apt-get and homebrew:

$ sudo apt-get install python3 python3-pip python3-venv
$ brew install watchman

We tested Pyre on Ubuntu 18.04.5 LTS, CentOS 7, as well as OSX 10.11 and later.

Setting up a Project

We start by creating an empty project directory and setting up a virtual environment:

$ mkdir my_project && cd my_project
$ python3 -m venv ~/.venvs/venv
$ source ~/.venvs/venv/bin/activate
(venv) $ pip install pyre-check

Next, we teach Pyre about our new project:

(venv) $ pyre init

This command will set up a configuration for Pyre (.pyre_configuration) as well as watchman (.watchmanconfig) in your project's directory. Accept the defaults for now – you can change them later if necessary.

Running Pyre

We are now ready to run Pyre:

(venv) $ echo "i: int = 'string'" > test.py
(venv) $ pyre
 ƛ Found 1 type error!
test.py:1:0 Incompatible variable type [9]: i is declared to have type `int` but is used as type `str`.

This first invocation will start a daemon listening for filesystem changes – type checking your project incrementally as you make edits to the code. You will notice that subsequent invocations of pyre will be faster than the first one.

For more detailed documentation, see https://pyre-check.org.

Join the Pyre community

See CONTRIBUTING.md for how to help out.

License

Pyre is licensed under the MIT license.

pyre-check's People

Contributors

sinancepel avatar grievejia avatar shannonzhu avatar dkgi avatar mrkmndz avatar pradeep90 avatar stroxler avatar arthaud avatar maggiemoss avatar fahndrich avatar gbleaney avatar kbansal avatar rvantonder avatar samchou19815 avatar jerryliu55 avatar onionymous avatar 0xedward avatar r0rshark avatar zlandau avatar manishsaha avatar abishekvashok avatar yuhshin-oss avatar jknoxville avatar simranvirk avatar winsonlyu avatar dependabot[bot] avatar dirn avatar alexkassil avatar dark avatar m0mosenpai avatar

Stargazers

 avatar Prasansha Satpathy  avatar  avatar

Watchers

James Cloos avatar Javid avatar  avatar  avatar  avatar  avatar Eshika Shah avatar  avatar

Forkers

abishekvashok

pyre-check's Issues

[Summer 2021] Add coverage for flask.request.json

Investigate if it is possible to add coverage for flask.request.json. The get_json() function is covered, this should be a one-liner but the stubs don't have the request attribute so this might get tricky.

[Summer 2021] SAPP Cli add support for AddFeature Pipeline

We want to support in SAPP Cli the capability to automatically add a specific features to all the imported issues.
This can be done by creating a new "pipeline" here e.g AddFeatures which process all the issues and add .
We can then add a cli option to the analyze command here to conditionally add the AddFeatures pipeline step adding the features specified in the command line

Step N: Roadmap

Here's a complete list of feature request for the plugin, in roughly priority order. We can flesh this out into tasks as you make progress through the existing tasks:

  • #4 Start surfacing errors from the Pysa binary in line in the editor
  • #7 TODO Build right click menu to automatically generate models. I can go from def foo(arg) in a .py file to def fully.qualified.name.for.foo(arg): ....
  • #6 Set up syntax highlighting. For .pysa files, the highlighting should look like exactly what you get in a .py file (likely, all you need to do is trick a Python syntax highlighter into treating the fully qualified function name the same as a normal unqualified function name). taint.config files are just JSON files, so all you need to do is apply a JSON highligher
  • #TODO Publish plugin to VSCode store
  • #TODO Document plugin on the website
  • #TODO Jump to definition/usage
    • cmd + click
      • Source, sink feature in .pysa → location in taint.config
      • Function/attribute model → function definition
    • Right click menu
      • Function definition → list of models
      • Source, sink, or feature in taint.config → list of models
  • #TODO Autocomplete
    • Fully qualified function names
    • Generic python syntax
    • Query DSL
  • #TODO Validation in taint.config files
    • Source and sink names specified exist when referenced from rules
    • No duplicate codes exist when adding new rules

[Summer 2021] Feature Request - Reduce number of interactions in Web UI to stop filtering and show all issues

Scenario

Assume a user currently has Test Filter 1 applied on their list of issues and the user wants to go back to viewing all the issues for the Pysa run they are currently reviewing

Expected workflow:

The following is the flow a user would expect to accomplish the scenario above:

  • Click some Clear button visible next to the Filter button or whatever alternative solution we come up with
  • They can now view all issues

Actual workflow:

But the current flow to accomplish the scenario above:

  • Click the Filter button
  • Click the Clear button
  • Click the Apply button

Step 0: Read the docs

Welcome to Pysa! It's really exciting to have you help us out by doing this project.

Pysa is an open source Python Static Taint Flow Analysis tool we (Facebook) created. Pysa is built on top of Pyre, which is our Python type checker. Things get get a little confusing, since both Pysa and Pyre live in the same repo, get distributed through the same PyPI package, and even get compiled into the same binary. But they are conceptually different tools, and your focus will be on building a VS Code plugin to support Pysa (Pyre actually already has one).

To get started, I recommend you:

  1. Read this blog post explaining what Pysa is and how it works
  2. Read through the Pyre and Pysa sections of our public docs
  3. Work through the Pysa Tutorial to get some hands on experience with Pysa and learn about the different file formats and how they work
  4. Read through the Getting Started section on VSCode extensions
  5. Learn about Language Server Extensions, which is what our extension is going to be

Once that's all done, you should be ready to move on and start working on this plugin!

[Summer 2021] Create models for Server Side Template Injection

Server side template injection is a very impactful vulnerability which can lead to Remote Code Execution (https://portswigger.net/research/server-side-template-injection).
Currently we have defined some of them (jinja) in the general.pysa file. We should move them to a specific file e.g. server_side_template_injection_sinks.pysa and cover other libraries like

We should make sure to have pysa models for the functions which can allow arbitrary input in the template definition leading to RCE. Documentation at https://pyre-check.org/docs/pysa-basics

[Summer 2021] Test Pysa on multiple projects

Let's run Pysa on some projects with known vulnerabilities to make sure we catch them.

  • Run pysa and check the results
  • Use pyre infer to increase type coverage https://pyre-check.org/docs/pysa-coverage/#pyre-infer
  • Review the codebase to identify if pysa is able to understand where the user controlled input is coming from. To do this I usually put an eval(user_input) and verify Pysa catches the issue.
  • If Pysa is not able to correctly understand the user input I try to verify if we have the models for it and modify the code to add type information or ways to make Pysa models understand the user controlled input. For example in a django application I would rename request parameters in request: HTTPRequest so that pysa is now able to identify that it is a user controlled value. Some nice suggestions on how to debug this cases in https://pyre-check.org/docs/pysa-false-negatives#common-causes-of-false-negatives
  • Check if we have models for the sink and create them if we don't.
  • Run Pysa again

After trying on different project we likely:

  • Identify a good process to effectively setup pysa and run it on a project which we can document
  • Find some missing sources/sinks which we can implement (we should create separate issues for each of them)

Example projects with known vulnerabilities:

Once we came up with a process to effectively run Pysa and we are good at detecting issues in vulnerable projects we can move to real world ones and try to find real issues :)

[Fall 2021] Step 3: VSCode Plugin - right click to generate model

When Pysa developers are working on a rule, they often look at a function in code such as:

def foo(arg):
   pass

If they want to write a model for that function, they need to figure out the fully qualified name for that function, so that they can write a model like this:

def module.file.foo(arg) -> TaintSource[SomeSource]: ...

It would be really convenient if they could just right click on the function itself, and auto-generate the model. Ideally, if a user right clicked on foo and chose "Generate Pysa Model", this would be placed on their clipboard:

def module.file.foo(arg): ...

They could then paste that in some .pysa file, and add their TaintSource/TaintSink annotations.

To implement this you'll probably need to:

  1. Register a custom right click menu: https://code.visualstudio.com/api/references/contribution-points#contributes.menus
  2. Have that menu trigger the generation of a model
  3. Get the function name and file
  4. Query Pyre to get information on the file. Eg. pyre query "types('module/file.py')" | jq will give something like this:
        ...
        {
          "location": {
            "start": {
              "line": 11,
              "column": 8
            },
            "stop": {
              "line": 11,
              "column": 16
            }
          },
          "annotation": "typing.Callable(module.Class.__init__)[[Named(self, module.Class), Named(environ, typing.Dict[str, typing.Any])], None]"
        },
        ...
  1. In there you can see module.Class.__init__ is the fully qualified name of the function I was looking for. You'll need to extract that. It might be worth modifying pyre query to have a more specific API you can query so you don't have to do the extraction within the plugin itself.
  2. Create a Pysa model using the fully qualified function name
  3. Put the model on to the user's clipboard - https://code.visualstudio.com/api/references/vscode-api#Clipboard
  4. Show a little message saying that you've put the model on the clipboard - search showInformationMessage here: https://code.visualstudio.com/api/references/vscode-api

[Summer 2021] Step 0: Read the docs

Pysa is an open source Python Static Taint Flow Analysis tool we (Facebook) created. Pysa is built on top of Pyre, which is our Python type checker. Things get get a little confusing, since both Pysa and Pyre live in the same repo, get distributed through the same PyPI package, and even get compiled into the same binary but they are conceptually different tools
* To get started, I recommend you:
* Read this blog post explaining what Pysa is and how it works
* Read through the Pyre and Pysa sections of our public docs
* Work through the Pysa Tutorial to get some hands on experience with Pysa and learn about the different file formats and how they work
* Complete the contributor license agreement

[Summer 2021] SAPP Feature Request - Create easier access to selecting saved filters in Web UI

The current workflow to loading a saved filter on SAPP Web UI is to:

  • sapp --database-name starter.db server
  • Click the Filter button
  • Click the saved filter field
  • Click the name of the saved filter you want to apply
  • Click the Apply button and wait for the page to refresh
    One idea to make it easier to select filters is to create a sidebar with a list of saved filters and clicking on one saved filter applies the filter and refreshes the page

[Summer 2021] Coverage Improvements - tornado.web.RequestHandler subclassing

A way to define an HTTPRequest handler with tornado framework is to subclass tornado.web.RequestHandler and implement methods like "get", "post" . We should review Tornado RequestHandler API https://www.tornadoweb.org/en/stable/web.html and create a DSL model generator (documentation) to automatically create User Controlled models .
Given this class:

class WhateverHandler(tornado.web.RequestHandler):

    def get(self, path):
        pass

The DSL model generator should generate models like this:
def whatever.WhateverHandler.get(path: TaintSource[UserControlled]): ...

[Summer 2021] Small bug fix and feature

  1. As in picture below there seem to be a rendering bug on the status dropdown when viewing an issue. (URL /run/1/issue/1)

Screenshot 2021-08-12 at 11 51 17

  1. In the sapp.db we are storing the first_seen time of the issue but we are not surfacing it in the UI. Let's add it to the issue detail and lit
sqlite> select * from issues LIMIT 2;
id|handle|code|first_seen|status|task_number|triage_history_fbid|feedback_fbid
1|tools.run-dev.BaseHandler.prepare:27|27|62:6302:402d4dcf54cfdb36|6302|2021-07-23 21:57:00.537787|uncategorized|||
2|zerver.webhooks.yo.view.api_yo_app_webhook:10|77|81:5008:42ddca5d9b5606b5|5008|2021-07-23 21:57:00.537787|uncategorized|||

[Summer 2021] Project B: OpenSource Pysa Tests in Github CI

We would like to implement a basic integration tests verifying that running Pysa on the deliberately_vulnerable_app (https://github.com/facebook/pyre-check/tree/master/documentation/deliberately_vulnerable_flask_app) would catch the issue we are expecting. To achieve this we need:

First run Pysa on the deliberately_vulnerable_app and validate we are catching the right issues. In the previous step we should already be able to test pysa on this project

Then we should create a python script which run pysa on the deliberately_vulnerable_app and compare the issues detected with an json file containing the list of issue we are expecting to identify. If there is a mismatch an error is returned and the difference between the expected result and the actual result is shown.

Finally we should setup a github new action here which setups the environment and launches the previously created script. We may need to modify how the current setup.sh script works to be able to run it in the github CI

[Summer 2021] [SAPP] Feature Request - Reduce number of interactions in Web UI required to re-save a filter

Scenario

Suppose a user has a saved filter named Test Filter 1 that filters for Code == 5008, but the user wants Test Filter 1 to filter for Code == 5008 and Code == 5012.

Expected workflow:

The following is the flow a user would expect to accomplish the scenario above:
Ensure you have a Pysa run in a SAPP db that contains issues with code 5008 and 5012

  • sapp --database-name test.db server
  • Click the Filter button
  • Click the saved filter field
  • Click Test Filter 1
  • Add 5012 to Codes field
  • Click the menu button and click Save. Notice on this step that the Save button is grayed out and the user isn't able to save the edited filter.

Actual workflow:

But the current flow to accomplish the scenario above:
Ensure you have a Pysa run in a SAPP db that contains issues with code 5008 and 5012

  • sapp --database-name test.db server
  • Click the Filter button
  • Click the saved filter field
  • Click Test Filter 1
  • Remember all the field values populated or screenshot the field values populated
  • Click the Clear button
  • Click the Filter button
  • Fill in the fields from your memory or a screenshot from Step 5
  • Add the additional things you wanted to filter for - Add 5012 to Codes field
  • Click the menu button and click Save
  • Type in the name of the filter you want to save as - Test Filter 1

Step 4: Syntax Highlighting

The goal here is to have the plugin turn on syntax highlighting for the two kinds of files relavent to Pysa: taint.config and *.pysa files.

Here are the VSCode docs on syntax highlighting.

For .pysa files, the highlighting should look like exactly what you get in a .py file. As a start, see if we can just get a Python syntax highlighter to passably highlight the file. As a stretch goal, see if you can modify the Python syntax highlighter into treating the fully qualified function name the same as a normal unqualified function name. As a REAL stretch goal, see if you can treat DSL code in .pysa files as an embedded language and highlight it differently

taint.config files are just JSON files, so all you need to do is apply a JSON highlighter to the file.

[Summer 2021] Update vulnerable dependency in SAPP

GitHub has detected that a package defined in the sapp/ui/frontend/package-lock.json file of the facebook/sapp repository contains a security vulnerability.

Package name: react-dev-utils
Affected versions: >= 0.4.0, < 11.0.4
Fixed in version: 11.0.4
Severity: MODERATE

Identifier(s):
GHSA-5q6m-3h65-w53x
CVE-2021-24033

We should likely just update this dependency and make sure there are no conflicts and nothing breaks

[Summer 2021] Project A: Add more examples to the deliberately_vulnerable_app application

In order to showcase how Pysa can be used to detect bugs we created a vulnerable Flask application. Currently the application is only showing Remote Code Execution examples in the rce.py file. We should also add more usecases to show how Pysa can be used to catch other type of vulnerabilities.

The first step is getting familiar with Flask documentation. The application is currently very simple so it doesn't require a deep Flask understanding but the quickstart provides some useful concepts.

The second step is to code these vulnerable functions for showcasing the vulnerable code. Take some time understanding the vulnerability (this is a great opportunity to learn some basic security skills :) )and after that write the code which would be vulnerable to it:

  • Path Traversal: user controlled input from the request is flowing into a file system operation (details) . We can use the python library open and read/write to implement this
  • XXE: user controlled input from the request is flowing into a XML function (details) .We can use the python library lxml library to implement this
  • SSRF: user controlled input from the request is flowing into an arbitrary request sending function (details). We can use the requests library
  • SQL injection: user controlled input from the request is flowing into an SQL query. SQL injection is a security issue described here in details . To implement this function we can use the MysqlDb library here
  • XSS: user controlled input from the request is returned to the user unescaped. XSS injection is a security issue described here in details . To implement this function we can use the flask.Markup library

After having implemented the vulnerable functions we should make sure that running Pysa on the app correctly detects the issue

pyre analyze --no-verify --save-results-to .
python3 -m sapp.cli analyze taint-output.json
python3 -m sapp.cli server

Finally we should create some documentation in the Pysa website to explain the vulnerability and how to fix it. (We have some internal doc I may be able to make public but we may still need to add information on how to fix the issue for Opensource users)

[Fall 2021] Step 0: Onboarding - Read the docs

Welcome to Pysa! :) We're really excited to have you all help us improve Pysa.

Pysa is an open source Python Static Taint Flow Analysis tool we (Facebook) created. Pysa is built on top of Pyre, which is our Python type checker. Things get a little confusing, since both Pysa and Pyre live in the same repo, get distributed through the same PyPI package, and even get compiled into the same binary.

To get started, I recommend you:

  1. Read this blog post explaining what Pysa is and how it works
  2. Read through the Pyre and Pysa sections of our public docs
  3. Work through the Pysa Tutorial to get some hands on experience with Pysa and learn about the different file formats and how they work
  4. Read over the OWASP Top 10 to get familiar with common classes of security vulnerabilities you will likely see while working with Pysa
  5. Set up Pytorch for development and run Mypy by following their contribution guide

To setup your dev environment, follow the steps in Pysa Quickstart guide. If you run into any issues during the setup process, the solution might be in the Common Issues section of the Quickstart. If you can't find a solution that works for you there, please comment here and we'll be happy to help you debug.

Once that's all done, you should be ready to start contributing to Pysa! :)

Step 1: Create a plugin

To get started, we're going to want to create our own minimal plugin. There's already a VSCode plugin for Pyre here, so you can use that as your template, and create a new directory in ide_plugins adjacent to vscode (we'll probably want to rename that to pyre_vscode or something later). Most of what we will be doing is following the existing guide of how that Pyre plugin works, and adding new functionality for Pysa.

The Pyre plugin is actually dead simple, because all it's really doing is creating a connection to a Language Server written in Python:

    const languageClient = new LanguageClient(
        'pyre',
	'Pyre Language Client',
	serverOptions,
	clientOptions,
    )

The main logic for the language server lives in client/commands/v2/language_server_protocol.py and client/commands/v2/persistent.py, which we'll come back to later.

To get your new plugin working, lets:

  1. Copy tools/ide_plugins/vscode to tools/ide_plugins/pysa_vscode but leave it totally unchanged
  2. Figure out how to load your new plugin into VSCode (you're definitely going to want to use VSCode as your main editor here), and make sure you can actually see it working for doing python type checking with Pyre
  • You'll need to have gone through the Pyre Getting Started and have some sample project open in VSCode that Pyre is running on
  • You will want to have built Pyre from source, rather than used the PyPI package, so that you can make changes later
  1. At this point, we'll have a working plugin, which is just an exact clone of the already working Pyre plugin. Don't forget to update all the language in the README, comments, etc, to indicate this is now a Pysa plugin, rather than a Pyre plugin

[Summer 2021] Investigate SQL exception raised by SAPP server

When performing some action on SAPP UI I noticed we are raising a SQL exception

  1. python3 -m sapp.cli server --source-directory ../zulip
  2. Visit localhost:5000
  3. Select a filter and then clear it
    The following error is raised
2021-08-02 15:29:34,553 [ERROR] Exception during reset or similar
Traceback (most recent call last):
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 682, in _finalize_fairy
    fairy._reset(pool)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 887, in _reset
    pool._dialect.do_rollback(self)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 667, in do_rollback
    dbapi_connection.rollback()
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 123145560453120 and this is thread id 123145565708288.
2021-08-02 15:29:34,568 [ERROR] Exception closing connection <sqlite3.Connection object at 0x105044650>
Traceback (most recent call last):
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 682, in _finalize_fairy
    fairy._reset(pool)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 887, in _reset
    pool._dialect.do_rollback(self)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 667, in do_rollback
    dbapi_connection.rollback()
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 123145560453120 and this is thread id 123145565708288.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 244, in _close_connection
    self._dialect.do_close(connection)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 673, in do_close
    dbapi_connection.close()
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 123145560453120 and this is thread id 123145565708288.
2021-08-02 15:29:34,569 [ERROR] Exception during reset or similar
Traceback (most recent call last):
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 682, in _finalize_fairy
    fairy._reset(pool)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 887, in _reset
    pool._dialect.do_rollback(self)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 667, in do_rollback
    dbapi_connection.rollback()
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 123145560453120 and this is thread id 123145565708288.
2021-08-02 15:29:34,569 [ERROR] Exception closing connection <sqlite3.Connection object at 0x105044e30>
Traceback (most recent call last):
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 682, in _finalize_fairy
    fairy._reset(pool)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 887, in _reset
    pool._dialect.do_rollback(self)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 667, in do_rollback
    dbapi_connection.rollback()
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 123145560453120 and this is thread id 123145565708288.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 244, in _close_connection
    self._dialect.do_close(connection)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 673, in do_close
    dbapi_connection.close()
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 123145560453120 and this is thread id 123145565708288.
2021-08-02 15:29:34,570 [ERROR] Exception during reset or similar
Traceback (most recent call last):
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 682, in _finalize_fairy
    fairy._reset(pool)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 887, in _reset
    pool._dialect.do_rollback(self)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 667, in do_rollback
    dbapi_connection.rollback()
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 123145570963456 and this is thread id 123145565708288.
2021-08-02 15:29:34,570 [ERROR] Exception closing connection <sqlite3.Connection object at 0x1053071f0>
Traceback (most recent call last):
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 682, in _finalize_fairy
    fairy._reset(pool)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 887, in _reset
    pool._dialect.do_rollback(self)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 667, in do_rollback
    dbapi_connection.rollback()
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 123145570963456 and this is thread id 123145565708288.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 244, in _close_connection
    self._dialect.do_close(connection)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 673, in do_close
    dbapi_connection.close()
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 123145570963456 and this is thread id 123145565708288.
2021-08-02 15:29:34,570 [ERROR] Exception during reset or similar
Traceback (most recent call last):
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 682, in _finalize_fairy
    fairy._reset(pool)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 887, in _reset
    pool._dialect.do_rollback(self)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 667, in do_rollback
    dbapi_connection.rollback()
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 123145560453120 and this is thread id 123145565708288.
2021-08-02 15:29:34,570 [ERROR] Exception closing connection <sqlite3.Connection object at 0x105307730>
Traceback (most recent call last):
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 682, in _finalize_fairy
    fairy._reset(pool)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 887, in _reset
    pool._dialect.do_rollback(self)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 667, in do_rollback
    dbapi_connection.rollback()
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 123145560453120 and this is thread id 123145565708288.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 244, in _close_connection
    self._dialect.do_close(connection)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 673, in do_close
    dbapi_connection.close()
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 123145560453120 and this is thread id 123145565708288.
2021-08-02 15:29:34,571 [ERROR] Exception during reset or similar
Traceback (most recent call last):
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 682, in _finalize_fairy
    fairy._reset(pool)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 887, in _reset
    pool._dialect.do_rollback(self)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 667, in do_rollback
    dbapi_connection.rollback()
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 123145576218624 and this is thread id 123145565708288.
2021-08-02 15:29:34,571 [ERROR] Exception closing connection <sqlite3.Connection object at 0x105307490>
Traceback (most recent call last):
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 682, in _finalize_fairy
    fairy._reset(pool)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 887, in _reset
    pool._dialect.do_rollback(self)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 667, in do_rollback
    dbapi_connection.rollback()
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 123145576218624 and this is thread id 123145565708288.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 244, in _close_connection
    self._dialect.do_close(connection)
  File "/Users/fons/.venvs/sapp/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 673, in do_close
    dbapi_connection.close()
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 123145576218624 and this is thread id 123145565708288.

[Fall 2021] Step 2: Coverage Improvement - Cover Flask class based views

Flask is a popular open-source web framework written in Python. Pysa already has some models for Flask (see flask_sources_sinks.pysa), but we are missing some coverage.

A view function in Flask is code that responds to an application, which can take in user-controlled data and return a response. Flask also supports class-based views as an alternate way of defining views.

It looks like some functions on the View classes such as (but not limited to) get/post/other verbs as well as dispatch_request can accept user-controlled data and return data to users. We should taint all the function parameters as being sources of UserControlled data and the functions as being returning data to users. Consider also looking into the as_view function and how we might model that.

The Pysa DSL might be useful for doing this.

Submitting a PR

We use the following linters internally, so to save everyone's time, please make sure you run the following linters locally and fix errors related to the files you modified before submitting a PR:

black && usort format . && flake8

To install the linters, you can run the following command:

pip install flake8 usort black==21.4b2

[Summer 2021] Improve SAPP filtering

SAPP (https://github.com/MLH-Fellowship/sapp/) takes the raw results of Pysa and makes them explorable both through a command line interface and a web UI. Currently, SAPP UI is missing the ability to filter by Source Name, Source Kind, Sink Name, and Sink Kind. We should add the possibility to filter by those values as well. This work will likely consist of:

  1. Adding the filtering support for those values in the python server (https://github.com/MLH-Fellowship/sapp/blob/master/sapp/ui/schema.py#L81)
  2. Support the filtering in the ReactJS UI https://github.com/MLH-Fellowship/sapp/blob/master/sapp/ui/frontend/src/Filter.js

[Fall 2021] Step 3: Create GitHub action for Pysa with SARIF output

The goal is to document and probably implent a github action which can be used by python projects to integrate with Pysa and run it in the CI pipeline surfacing possible issues as comment in the diff.
In the past we did some collaboration with Zulip so their project can be a good starting point. We can fork https://github.com/zulip/zulip and experiment how this process should look like .
Some work to generate SARIF results was done for surfacing Pyre type checking issues in facebook#427

Step 2: Create a new language server

Currently, our plugin is connecting to the existing Pyre server, launched by running pyre persistent. We want Pyre and Pysa to have different language servers, because they're going to handle different files, and be used by different users.

Currently the language server is run through this call chain:

  1. https://github.com/facebook/pyre-check/blob/b5d50044dc5682dc0e22cefba28484ce1c27086c/client/pyre.py#L813
  2. https://github.com/facebook/pyre-check/blob/b5d50044dc5682dc0e22cefba28484ce1c27086c/client/commands/v2/persistent.py#L819
  3. https://github.com/facebook/pyre-check/blob/b5d50044dc5682dc0e22cefba28484ce1c27086c/client/commands/v2/persistent.py#L773
  4. https://github.com/facebook/pyre-check/blob/b5d50044dc5682dc0e22cefba28484ce1c27086c/client/commands/v2/persistent.py#L392

Introduce a new flag to the persistent command, something like --tool with options of pyre and pysa, and thread it down to the point where Server is launched. That flag will determine whether you launch the existing Server class or a new PysaServer class, which you'll introduce (please consider a refactor to rename Server -> PyreServer). The new PysaServer can be an exact copy of the original Server for now.

Once you've got that flag working, update your VSCode plugin to pass the flag needed to launch the new PysaServer you've created and to indicate that it runs on Pysa code rather than Python code (*.pysa and taint.config files).

[Summer 2021] Create model verification tests

Currently we have the integration tests which make sure we do not have regression for a limited set of important categories however we do not have a way to make sure that all the models are valid.

The idea is to create a model validation testing system for the Opensource models and run it in the Github CI. This would require

  1. Create a folder in pyre-check/tools/pysa_integration_tests/verify_models with
  • a requirements.txt file which will contain the library dependencies needed for the model defined
  • (probably) a main.py file with an empty main function (just use to run pysa on this folder with the environment created by)
  • Readme explaining the folder content
  1. A python script which
  • Creates a python environment installing the libraries in the requirements.txt
  • Create a Pyre connection with specific configuration options pointing the source_directory to the pyre-check/tools/pysa_integration_tests/verify_models and including the environment created in the previous step. This can be done by creating a temporary .pyre_configuration.local file and specifying "source_directories" configuration. We may run into issue since there is a top level .pyre_configuration file. In this case we can create a temporary top level folder and store the temporary .pyre_configuration file there:
temporary_file_path = pyre_root_dir / hashlib.sha1(
            ",".join((targets or []) + (source_directories or [])).encode()
        ).hexdigest()
  • Call the get_invalid_taint_models
  • Parse the input and allow filtering out based on the model regex or filesystem path. The configuration with the information of which models/filepath to filter out can be a file called verify_models.conf in JSON format

[Summer 2021] Improve SAPP UI development

Currently to test UI changes in SAPP we need to run everytime https://github.com/facebook/sapp#development-environment-setup

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

It would be nice if we can do this without having to run npm run-script build every time.
We can achieve this by using

python3 -m sapp.cli server --debug -> serve the graphql api on localhost:5000
cd sapp/ui/frontend && npm start -> serve react app on localhost:3000

To make this work:

  1. When we are in development mode we need to change the URL used by Apollo in ReactJS from /graphql to localhost:5000/graphql
  2. When we are in development mode (DEBUG environment variable) we can allows CORS request coming from localhost:3000 (react app started with npm start)

To define development specific config we can use environment variables in react https://create-react-app.dev/docs/adding-custom-environment-variables/

[Summer 2021] [SAPP] Bug - Previously applied filter in Web UI to Run `n` persists across accesses to different Runs

Scenario

Suppose a user has a saved filter named Test Filter 1 that only filters for issues with code 5003

Steps to reproduce

Ensure you have two Pysa runs in a SAPP db that both contains issues with code 5003

  • sapp --database-name test.db server and go to http://localhost:5000/
  • Click Issues for Run 1
  • Click the Filter button
  • Apply Test Filter 1 and notice only issues with code 5003 are shown
  • Go to http://localhost:5000/runs
  • Click Issues for Run 2
  • Notice the list only displays issues with code 5003 and Test Filter 1 is still applied
    The expected behavior after step 5 and 6 is to remove Test Filter 1 and display the full list of issues in Run 2. Same behaviour should apply when loading the same Run again basically we want to remove every filters when a Run is loaded

[Fall 2021] Step 3: Add support for --output=sarif to pyre

facebook#427 added support for surfacing type errors inline on github through a script that takes the output of pyre --output=json and converts it into SARIF (https://github.com/microsoft/sarif-tutorials), the file format GitHub understands. Ideally there should be an easier way for projects to set up the integration by just running pyre --output=sarif. This task is about adding that support to pyre.

References:
GitHub CI setup and script generating SARIF format: facebook#427
Pyre printing logic:
https://github.com/MLH-Fellowship/pyre-check/blob/master/client/error.py#L244

[Summer 2021] Mirror internal linter/formatter behaviour in opensource

At Facebook we use an internal formatter a way to replicate a similar behaviour in the Opensource repo is

  1. Use µfmt instead of using black or µsort directly. This combines the import sorting and formatting into a single, atomic step, to minimize the chance of CI failures for inconsistent formatting between the two tools.
    $ ufmt <format|check|diff> <path>
  2. Configure µsort to disable first party namespace detection. In your project's pyproject.toml. This matches the general behavior of the internal formatter , where anything is sorted with third-party packages:
[tool.usort]
first_party_detection = false
  1. Make sure you pin dependencies in your requirements.txt to the same versions as the internal linter. We try to stay up to date, but may be delayed in upgrading.
black version 21.4b2
usort version 0.6.4
libcst version 0.3.19

We can update the https://github.com/MLH-Fellowship/pyre-check/blob/master/.github/workflows/lint.yml lint action with this setup and test if it works :)

[Fall 2021] Step 3: VSCode Plugin - Handle model validation errors

Now that we have a separate running server for Pysa, let's start customizing it for Pysa. This is where the real engineering work comes in, so this task and the tasks going forward will be a bit more open ended. Have fun, and don't be afraid to ask for help!

At a high level, our goal is to get model validation errors that you can access through pyre query "validate_taint_models()" to start showing up in .pysa files. We can start by running the validation every time .pysa files are saved, and reporting the results back to VSCode.

A few notes:

  • At this point you're probably going to want to clean up the cruft in PysaServer, to remove anything unrelated to the pysa functionality you're adding
  • The validate_taint_models functionality is available through the query API, so you'll probably want to get the model validation data back through there, rather than by trying to do the parsing yourself.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.