evase-analysis


Nameevase-analysis JSON
Version 1.0.8.5 PyPI version JSON
download
home_page
SummaryA Python package with tools for the detection of SQL injection vulnerabilities in projects.
upload_time2023-04-12 20:35:54
maintainer
docs_urlNone
author
requires_python>=3.7
license
keywords attack security sql injection
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            [![CI Tests](https://github.com/tony-zeidan/EvaseAnalysis/actions/workflows/ci_tests.yml/badge.svg)](https://github.com/tony-zeidan/EvaseAnalysis/actions/workflows/ci_tests.yml)

# Evase Analysis Library
This library intends to help users detect SQL Injection vulnerabilities from their source code. 
It has several structures that take-in Python source code and use abstract-syntax trees (ASTs) to analyze for such vulnerabilities.
The code was initially part of a much bigger project, but as to provide separation of concerns, the functionality
for detecting the SQL injection-related vulnerabilities was separated out into this package.

## What's New

In the latest version of the library:
- The performance of the code has been slightly improved by the removal of creating unnecessary expensive `NodeVisitor` and `NodeTransformer` objects.
  - Instead, the objects are created as a single instance and have their states reset.
- Most classes in the system now use `@property` annotations for getters and setters now.
- The `ProjectAnalysisStruct` class can now be queried for module structures like a dictionary.
  - By passing the name of the module, you can retrieve the corresponding `ModuleAnalysisStruct`.
- The functions are able to fail more gracefully when encountering unexpected AST nodes.
- The Breadth-First search functions keep track of paths traversed.
  - The main traversal function (`traversal_from_exec`) now outputs a mapping of ending nodes to their possible paths.
- The dependency graph generated by `ProjectAnalysisStruct` has been tested for many use cases and seems to work very well.
- Some bugs in the module imports generated by `ModuleImportResolver` have been fixed.
  - The resolver now better handles variant imports like:
    - `from <one or more (.)> import <function|module|*>`
    - If we can backtrack to a module (through the count of '.' characters) we assume the object being imported is a module, otherwise it is a function.
- The graph node grouping mechanism in `AnalysisPerformer` has had some bugs resolved.
- Nodes in the graph now appear with the form `<package style name>:<function name>` for functions found WITHIN the analysis of the code (not external libraries).

## Issues

There are still a variety of issues with the handling of the various errors that our traversal mechanisms encounter.
- Those `Flask` endpoints that do not accept function parameters, (POST-type requests) aren't considered vulnerable due to inadequacies with the `collect_vulnerable_vars` function.
- There are many ways of writing imports, and it is likely that the `ModuleImportResolver` doesn't consider all of these.

## Usage
This package was developed initially with the intention that it be used in the Backend for the Evase web-application,
so it is structured as such. To use it in a program, the user first needs to specify information pertaining to the project.


The user is able to analyze the project with an instance of the `AnalysisPerformer` class. 

```python
from evase.structures.analysisperformer import AnalysisPerformer

code_analyzer = AnalysisPerformer(
    project_name="myProject",
    project_root="<filepath to root>"
)

code_analyzer.perform_analysis()

print(code_analyzer.get_results())

# optionally, output to JSON
code_analyzer.results_to_JSON("<output directory>")
```

Behind the scenes, this instance is performing multiple traversals of the abstract syntax trees (ASTs) generated from
the source code in the project.

## Important Information

The code made in this package relies on various functions applied to Abstract Syntax Trees (ASTs).

Many of the functions in the code are required to perform other functions.
The functions directly relating to ASTs at a low level require that the input ASTs be modified. 
The functions inside of input ASTs must have their scopes resolved. 
```python
# example.py

def foo():
  print("FOO")
  
class Bar:
  
  def foo(self):
    print("FOO")
```
In this example, the AST output would look something like:
```
<FunctionDef name='foo'>
<ClassDef name='Bar'>
  <FunctionDef name='foo'>
```
As you can see, while traversing using a `NodeVisitor` it would be difficult to determine the scope of the inner
function.
As such we created the `ScopeResolver` such that the output AST would look something like:
```
<FunctionDef name='foo'>
<ClassDef name='Bar'>
  <FunctionDef name='Bar.foo'>
```

For functions involving the analysis of dependencies, the import nodes inside of input ASTs must also have their
`module` attribute be absolute rather than relative. The importable items from the imported module must also be directly
specified if an import in the form of `<from | import> ... *` is being used. Take the following script for example:

```python
# package/imported.py
def foo():
  print("FOO")
  
def bar():
  print("BAR")
  
class Bar:
  
  def bar(self):
    print("BAR")

# package/inner/example.py

from ..imported import *
```
Imports in this form are very hard to analyze because ASTs don't provide any information other than the form of the
import. The AST for `package/inner/example.py` would look something like:
```
<Import module=None names="*">
```
It's clear that this doesn't help much when analyzing dependencies. For this reason we created the `SurfaceLevelVisitor`
and `ModuleImportResolver` that work in tandem.
The `SurfaceLevelVisitor` collects all the surface level importable items from a module. We then combine these
into a list and make an instance of `ModuleImportResolver` that resolves module names in import nodes and their imported
items. Using these two instances properly retrieves the following AST.
```
<Import module="package.imported" names=["foo", "bar", "Bar"]>
```

Most of the classes within this library rely on the fact that the scopes will be resolved, and that the imports are
correctly resolved.

## Installation
This package is available on PyPI! You can install it using:
```
pip install evase-analysis
```

Or you can simply clone the repository and run:

```
pip install .
```
(in the directory with `pyproject.toml`)


            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "evase-analysis",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "Tony Abou Zeidan <tony.azp25@gmail.com>, Anthony Dooley <anthonydooley@cmail.carleton.ca>, Ethan Chase <e281828c@gmail.com>, Shaopeng Liu <shaopengliu@cmail.carleton.ca>, Jason Jaskolka <jason.jaskolka@carleton.ca>",
    "keywords": "attack,security,SQL,injection",
    "author": "",
    "author_email": "Tony Abou Zeidan <tony.azp25@gmail.com>, Anthony Dooley <anthonydooley@cmail.carleton.ca>, Ethan Chase <e281828c@gmail.com>, Shaopeng Liu <shaopengliu@cmail.carleton.ca>, Jason Jaskolka <jason.jaskolka@carleton.ca>",
    "download_url": "https://files.pythonhosted.org/packages/95/e8/abf08ad0e00ac26510a6affe67b540a87ecd367cc8910eede8d48b14fb08/evase-analysis-1.0.8.5.tar.gz",
    "platform": null,
    "description": "[![CI Tests](https://github.com/tony-zeidan/EvaseAnalysis/actions/workflows/ci_tests.yml/badge.svg)](https://github.com/tony-zeidan/EvaseAnalysis/actions/workflows/ci_tests.yml)\r\n\r\n# Evase Analysis Library\r\nThis library intends to help users detect SQL Injection vulnerabilities from their source code. \r\nIt has several structures that take-in Python source code and use abstract-syntax trees (ASTs) to analyze for such vulnerabilities.\r\nThe code was initially part of a much bigger project, but as to provide separation of concerns, the functionality\r\nfor detecting the SQL injection-related vulnerabilities was separated out into this package.\r\n\r\n## What's New\r\n\r\nIn the latest version of the library:\r\n- The performance of the code has been slightly improved by the removal of creating unnecessary expensive `NodeVisitor` and `NodeTransformer` objects.\r\n  - Instead, the objects are created as a single instance and have their states reset.\r\n- Most classes in the system now use `@property` annotations for getters and setters now.\r\n- The `ProjectAnalysisStruct` class can now be queried for module structures like a dictionary.\r\n  - By passing the name of the module, you can retrieve the corresponding `ModuleAnalysisStruct`.\r\n- The functions are able to fail more gracefully when encountering unexpected AST nodes.\r\n- The Breadth-First search functions keep track of paths traversed.\r\n  - The main traversal function (`traversal_from_exec`) now outputs a mapping of ending nodes to their possible paths.\r\n- The dependency graph generated by `ProjectAnalysisStruct` has been tested for many use cases and seems to work very well.\r\n- Some bugs in the module imports generated by `ModuleImportResolver` have been fixed.\r\n  - The resolver now better handles variant imports like:\r\n    - `from <one or more (.)> import <function|module|*>`\r\n    - If we can backtrack to a module (through the count of '.' characters) we assume the object being imported is a module, otherwise it is a function.\r\n- The graph node grouping mechanism in `AnalysisPerformer` has had some bugs resolved.\r\n- Nodes in the graph now appear with the form `<package style name>:<function name>` for functions found WITHIN the analysis of the code (not external libraries).\r\n\r\n## Issues\r\n\r\nThere are still a variety of issues with the handling of the various errors that our traversal mechanisms encounter.\r\n- Those `Flask` endpoints that do not accept function parameters, (POST-type requests) aren't considered vulnerable due to inadequacies with the `collect_vulnerable_vars` function.\r\n- There are many ways of writing imports, and it is likely that the `ModuleImportResolver` doesn't consider all of these.\r\n\r\n## Usage\r\nThis package was developed initially with the intention that it be used in the Backend for the Evase web-application,\r\nso it is structured as such. To use it in a program, the user first needs to specify information pertaining to the project.\r\n\r\n\r\nThe user is able to analyze the project with an instance of the `AnalysisPerformer` class. \r\n\r\n```python\r\nfrom evase.structures.analysisperformer import AnalysisPerformer\r\n\r\ncode_analyzer = AnalysisPerformer(\r\n    project_name=\"myProject\",\r\n    project_root=\"<filepath to root>\"\r\n)\r\n\r\ncode_analyzer.perform_analysis()\r\n\r\nprint(code_analyzer.get_results())\r\n\r\n# optionally, output to JSON\r\ncode_analyzer.results_to_JSON(\"<output directory>\")\r\n```\r\n\r\nBehind the scenes, this instance is performing multiple traversals of the abstract syntax trees (ASTs) generated from\r\nthe source code in the project.\r\n\r\n## Important Information\r\n\r\nThe code made in this package relies on various functions applied to Abstract Syntax Trees (ASTs).\r\n\r\nMany of the functions in the code are required to perform other functions.\r\nThe functions directly relating to ASTs at a low level require that the input ASTs be modified. \r\nThe functions inside of input ASTs must have their scopes resolved. \r\n```python\r\n# example.py\r\n\r\ndef foo():\r\n  print(\"FOO\")\r\n  \r\nclass Bar:\r\n  \r\n  def foo(self):\r\n    print(\"FOO\")\r\n```\r\nIn this example, the AST output would look something like:\r\n```\r\n<FunctionDef name='foo'>\r\n<ClassDef name='Bar'>\r\n  <FunctionDef name='foo'>\r\n```\r\nAs you can see, while traversing using a `NodeVisitor` it would be difficult to determine the scope of the inner\r\nfunction.\r\nAs such we created the `ScopeResolver` such that the output AST would look something like:\r\n```\r\n<FunctionDef name='foo'>\r\n<ClassDef name='Bar'>\r\n  <FunctionDef name='Bar.foo'>\r\n```\r\n\r\nFor functions involving the analysis of dependencies, the import nodes inside of input ASTs must also have their\r\n`module` attribute be absolute rather than relative. The importable items from the imported module must also be directly\r\nspecified if an import in the form of `<from | import> ... *` is being used. Take the following script for example:\r\n\r\n```python\r\n# package/imported.py\r\ndef foo():\r\n  print(\"FOO\")\r\n  \r\ndef bar():\r\n  print(\"BAR\")\r\n  \r\nclass Bar:\r\n  \r\n  def bar(self):\r\n    print(\"BAR\")\r\n\r\n# package/inner/example.py\r\n\r\nfrom ..imported import *\r\n```\r\nImports in this form are very hard to analyze because ASTs don't provide any information other than the form of the\r\nimport. The AST for `package/inner/example.py` would look something like:\r\n```\r\n<Import module=None names=\"*\">\r\n```\r\nIt's clear that this doesn't help much when analyzing dependencies. For this reason we created the `SurfaceLevelVisitor`\r\nand `ModuleImportResolver` that work in tandem.\r\nThe `SurfaceLevelVisitor` collects all the surface level importable items from a module. We then combine these\r\ninto a list and make an instance of `ModuleImportResolver` that resolves module names in import nodes and their imported\r\nitems. Using these two instances properly retrieves the following AST.\r\n```\r\n<Import module=\"package.imported\" names=[\"foo\", \"bar\", \"Bar\"]>\r\n```\r\n\r\nMost of the classes within this library rely on the fact that the scopes will be resolved, and that the imports are\r\ncorrectly resolved.\r\n\r\n## Installation\r\nThis package is available on PyPI! You can install it using:\r\n```\r\npip install evase-analysis\r\n```\r\n\r\nOr you can simply clone the repository and run:\r\n\r\n```\r\npip install .\r\n```\r\n(in the directory with `pyproject.toml`)\r\n\r\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "A Python package with tools for the detection of SQL injection vulnerabilities in projects.",
    "version": "1.0.8.5",
    "split_keywords": [
        "attack",
        "security",
        "sql",
        "injection"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ac140070fd71ffe62050d0242ca63ef34f7a83cd828c445ba94477c608a09264",
                "md5": "2d5ae4b10f93ae50d1ffb28e4c4e77d0",
                "sha256": "b0a9991e5a5868b69cb2de952aa86aed81fcb678d5d739c584c884552721ef6b"
            },
            "downloads": -1,
            "filename": "evase_analysis-1.0.8.5-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "2d5ae4b10f93ae50d1ffb28e4c4e77d0",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 48475,
            "upload_time": "2023-04-12T20:35:51",
            "upload_time_iso_8601": "2023-04-12T20:35:51.287548Z",
            "url": "https://files.pythonhosted.org/packages/ac/14/0070fd71ffe62050d0242ca63ef34f7a83cd828c445ba94477c608a09264/evase_analysis-1.0.8.5-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "95e8abf08ad0e00ac26510a6affe67b540a87ecd367cc8910eede8d48b14fb08",
                "md5": "63ab35d3cc2b3099cb7835a76863ea73",
                "sha256": "4a0105f10592492f4ad237b1f4e639b6db50f4d928a1dbf831f5fe95e1145050"
            },
            "downloads": -1,
            "filename": "evase-analysis-1.0.8.5.tar.gz",
            "has_sig": false,
            "md5_digest": "63ab35d3cc2b3099cb7835a76863ea73",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 38043,
            "upload_time": "2023-04-12T20:35:54",
            "upload_time_iso_8601": "2023-04-12T20:35:54.711470Z",
            "url": "https://files.pythonhosted.org/packages/95/e8/abf08ad0e00ac26510a6affe67b540a87ecd367cc8910eede8d48b14fb08/evase-analysis-1.0.8.5.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-04-12 20:35:54",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "lcname": "evase-analysis"
}
        
Elapsed time: 0.05610s