Dlint is a tool for encouraging best coding practices and helping ensure Python code is secure.

Overview

Dlint

Build Status Build Status Coverage Status Python Versions PyPI Version

Dlint is a tool for encouraging best coding practices and helping ensure Python code is secure.

The most important thing I have done as a programmer in recent years is to aggressively pursue static code analysis. Even more valuable than the hundreds of serious bugs I have prevented with it is the change in mindset about the way I view software reliability and code quality.

For a static analysis project to succeed, developers must feel they benefit from and enjoy using it.

For documentation and a list of rules see docs.

Installing

$ python -m pip install dlint

Specify python2 or python3 to install for a specific Python version.

And double check that it was installed correctly:

$ python -m flake8 -h
Usage: flake8 [options] file file ...

...

Installed plugins: dlint: 0.11.0, mccabe: 0.5.3, pycodestyle: 2.2.0, pyflakes: 1.3.0

Note the dlint: 0.11.0.

Using

Dlint builds on flake8 to perform its linting. This provides many useful features without re-inventing the wheel.

CLI

Let's run a simple check:

$ cat << EOF > test.py
print("TEST1")
exec('print("TEST2")')
EOF
$ python test.py
TEST1
TEST2
$ python -m flake8 --select=DUO test.py
test.py:2:1: DUO105 use of "exec" is insecure

The --select=DUO flag tells flake8 to only run Dlint lint rules.

From here, we can easily run Dlint against a directory of Python code:

$ python -m flake8 --select=DUO /path/to/code

To fine-tune your linting, check out the flake8 help:

$ python -m flake8 --help

Inline Editor

Dlint results can also be included inline in your editor for fast feedback. This typically requires an editor plugin or extension. Here are some starting points for common editors:

Integrating

Dlint can easily be integrated into CI pipelines, or anything really.

For more information and examples see 'How can I integrate Dlint into XYZ?'.

Custom Plugins

Dlint's custom plugins are built on a simple naming convention, and rely on Python modules. To make a Dlint custom plugin use the following conventions:

  • The Python module name must start with dlint_plugin_.
  • The linter class name must start with Dlint.
  • The linter class should inherit from dlint.linters.base.BaseLinter.
    • If for some reason you'd like to avoid this, then you must implement the get_results function appropriately and inherit from ast.NodeVisitor.

See an example plugin for further details.

Developing

First, install development packages:

$ python -m pip install -r requirements.txt
$ python -m pip install -r requirements-dev.txt
$ python -m pip install -e .

Testing

$ pytest

Linting

$ flake8

Coverage

$ pytest --cov

Benchmarking

$ pytest -k test_benchmark_run --benchmark-py-file /path/to/file.py tests/test_benchmark/

Or get benchmark results for linters individually:

$ pytest -k test_benchmark_individual --benchmark-py-file /path/to/file.py tests/test_benchmark/

Or run against a single linter:

$ pytest -k test_benchmark_individual[DUO138-BadReCatastrophicUseLinter] --benchmark-py-file /path/to/file.py tests/test_benchmark/
Comments
  • only trigger DUO116 when shell=True

    only trigger DUO116 when shell=True

    Using shell=False, to make sure default arguments are set, would trigger DUO116:subprocess module with shell=True

    This PR allows shell=False.

    $ cat -n /tmp/shell.py 
         1  #!/usr/bin/python3
         2  
         3  import subprocess
         4  
         5  command = "/bin/echo"
         6  
         7  subprocess.call(command, shell=False)
         8  subprocess.call(command, shell=True)
         9  subprocess.call(command, shell=False)
    $ python3 -m flake8 /tmp/shell.py 
    /tmp/shell.py:3:1: S404 Consider possible security implications associated with subprocess module.
    /tmp/shell.py:7:1: S603 subprocess call - check for execution of untrusted input.
    /tmp/shell.py:8:1: DUO116 use of "shell=True" is insecure in "subprocess" module
    /tmp/shell.py:8:1: S602 subprocess call with shell=True identified, security issue.
    /tmp/shell.py:9:1: S603 subprocess call - check for execution of untrusted input.
    $ python3 -m flake8 -h
    [...]
    Installed plugins: dlint: 0.10.3, flake8-bandit: 2.1.2, flake8-bugbear:
    20.1.4, flake8-darglint: 1.5.5, flake8-executable: 2.0.4, flake8_deprecated:
    1.2, mccabe: 0.6.1, naming: 0.11.1, pycodestyle: 2.6.0, pyflakes: 2.2.0,
    radon: 4.3.2
    

    Signed-off-by: Thomas Sjögren [email protected]

    opened by konstruktoid 7
  • DUO121: Why is tempfile.mkstemp (with

    DUO121: Why is tempfile.mkstemp (with "s") being avoided?

    Hi!

    Section Correct code at https://github.com/dlint-py/dlint/blob/master/docs/linters/DUO121.md#correct-code seems overly complicated to me. Could you elaborate why tempfile.mkstemp is being avoided?

    Thanks and best, Sebastian

    opened by hartwork 4
  • Hashlib linter should not warn when `usedforsecurity=False` is set

    Hashlib linter should not warn when `usedforsecurity=False` is set

    This is a built-in flag that affirms the code is not using md5 for security-related purposes. In my code's case, I'm manually calculating a checksum as required by the AWS S3 API.

    opened by djmattyg007 3
  • replace deprecated ast nodes

    replace deprecated ast nodes

    closes #4

    As issue states, multiple ast nodes have been replaced with ast.Constant. dlint seems to only use ast.Str and NameConstant, so that's what I replaced.

    I also looked for any of the corresponding visit_node functions, and they are not used in the repo.

    opened by clavedeluna 2
  • Remove unsued and old code

    Remove unsued and old code

    Hi there! I've worked in the python security space before and came across this project. I wanted to start helping and figured the best way is to look around and do some low-hanging fruit cleanup of code.

    I found:

    • one location where a util func is unused
    • code that supported old py versions. I see dlint only supports 3.6+.

    should also close #40

    opened by clavedeluna 2
  • Publish sources on PyPi

    Publish sources on PyPi

    Installing the package using pip with the --no-binary flag fails, because no sdist is available on PyPi

    $ python -m pip install dlint --no-binary :all:
    ERROR: Could not find a version that satisfies the requirement dlint (from versions: none)
    ERROR: No matching distribution found for dlint
    
    opened by bramhaag 1
  • Support flake8>=4

    Support flake8>=4

    Please upgrade dlint to support flake8>=4. There doesn't appear to be any breaking changes that will affect dlint.

    https://flake8.pycqa.org/en/latest/release-notes/4.0.0.html#backwards-incompatible-changes

    opened by wwuck 1
  • Relationship to bandit

    Relationship to bandit

    What is the relationship between dlint and bandit?

    What I can see:

    • dlint is a flake8 plugin while bandit is a project of its own (there is flake8-bandit, though)
    • bandit is part of PyCQA which includes also flake8 and flake8-bugbear
    • bandit has 2700 GitHub stars, dlint has 45

    Could somebody maybe point out reasons to use one or the other? Do you maybe use both together? Is there an overlap between the communities?

    opened by MartinThoma 1
  • DUO107 whitelist from xml.etree.ElementTree import Element, SubElement

    DUO107 whitelist from xml.etree.ElementTree import Element, SubElement

    defusedxml is not capable of creating Element or SubElement

    Whitelisting in bad_xml_use.py

    @property
        def whitelisted_modules(self):
            return [
                'xml.sax.saxutils',
                'xml.etree.ElementTree.Element',
                'xml.etree.ElementTree.SubElement',
            ]
    

    would help solve this.

    A work around could then be used as follows:

    from xml.etree.ElementTree import Element, SubElement
    
    import defusedxml.ElementTree as ET
    
    ET.Element = _ElementType = Element
    ET.SubElement = SubElement
    

    Note that we still disallow

    from xml.etree.ElementTree import parse
    
    opened by hm34306 1
  • os.EX_OK not available on Windows

    os.EX_OK not available on Windows

    FYI: os.EX_OK isn't available on Windows and fails when running flake8 --print-dlint-linters

    Not sure what the appropriate substitute is, but I'd be happy to test any changes

    https://github.com/dlint-py/dlint/blob/828a156eead73e4140ddc6925ff85bf65424fabb/dlint/extension.py#L46

    opened by KyleKing 1
  • Create a community Github Action for Dlint

    Create a community Github Action for Dlint

    Similar to these community actions: https://github.com/sdras/awesome-actions

    We should build an action for Dlint. Bonus points for running Dlint against Dlint :)

    opened by mschwager 1
  • Flake8 v6 compatibility

    Flake8 v6 compatibility

    Would it be possible to remove the upper bound on flake8 requirement?

    https://iscinumpy.dev/post/bound-version-constraints/

    If not, can we get that bumped up to flake8<7 please?

    opened by wwuck 0
  • Add input linter when asking for password

    Add input linter when asking for password

    Closes #16

    The goal is to detect when a user uses the built-in input function with an arg or kwarg of string containing "password". Unit tests demonstrate when this may be a false positive, such as input("Please enter your name. Please do not enter your password")

    First pass attempt, would love feedback.

    opened by clavedeluna 0
  • Deprecate DUO101

    Deprecate DUO101

    DUO101 is Python 3.3 only, and these versions are no longer supported by dlint.

    Other than removing the md file in docs and the linter itself plus its tests, what are the other deprecation procedures?

    opened by clavedeluna 0
  • Update DUO108 documentation

    Update DUO108 documentation

    DUO108 is outdated in the following ways:

    1. it mentions Python 2, deprecated by dlint
    2. it says it only runs for Python 2, but that doesn't seem to be the case
    3. it suggests use of raw_input which is also deprecated in py3

    Anything else?

    opened by clavedeluna 0
  • Drop Python 3.6 support

    Drop Python 3.6 support

    Python 3.6 was deprecated 8 months ago so it would be good to drop it. Locations to update:

    1. setup.py 3.6 mention
    2. look for any usage of sys.version_info that needs to be updated accordingly
    opened by clavedeluna 0
Owner
Dlint
Dlint Python static analysis and related projects.
Dlint
A Python Bytecode Disassembler helping reverse engineers in dissecting Python binaries

A Python Bytecode Disassembler helping reverse engineers in dissecting Python binaries by disassembling and analyzing the compiled python byte-code(.pyc) files across all python versions (including Python 3.10.*)

neeraj 95 Dec 26, 2022
A web-app helping to create strong passwords that are easy to remember.

This is a simple Web-App that demonstrates a method of creating strong passwords that are still easy to remember. It also provides time estimates how long it would take an attacker to crack a password using the zxcvbn library developed by Dropbox.

null 2 Jun 4, 2021
PwdGen is a Python Tkinter tool for generating secure 16 digit passwords.

PwdGen ( Password Generator ) is a Python Tkinter tool for generating secure 16 digit passwords. Installation Simply install requirements pip install

zJairO 7 Jul 14, 2022
This is a Cryptographied Password Manager, a tool for storing Passwords in a Secure way

Cryptographied Password Manager This is a Cryptographied Password Manager, a tool for storing Passwords in a Secure way without using external Service

Francesco 3 Nov 23, 2022
This collection of tools that makes it easy to secure and/or obfuscate messages, files, and data.

Scrambler App This collection of tools that makes it easy to secure and/or obfuscate messages, files, and data. It leverages encryption tools such as

Mystic 2 Aug 31, 2022
Python program that generates secure passwords.

Python program that generates secure passwords. The user has the option to select the length of the password, amount of passwords,

null 4 Dec 7, 2021
A secure password generator written in python

gruvbox-factory ?? "The main focus when developing gruvbox is to keep colors easily distinguishable, contrast enough and still pleasant for the eyes"

Paulo Pacitti 430 Dec 27, 2022
Simple python script for generating custom high-secure passwords for securing your social-apps ❤️

Opensource Project Simple Python Password Generator This repository is just for peoples who want to generate strong-passwords for there social-account

K A R T H I K 15 Dec 1, 2022
Create a secure tunnel from a custom domain to localhost using Fly and WireGuard.

Fly Dev Tunnel Developers commonly use apps like ngrok, localtunnel, or cloudflared to expose a local web service at a publicly-accessible URL. This i

null 170 Dec 11, 2022
Delta Sharing: An Open Protocol for Secure Data Sharing

Delta Sharing: An Open Protocol for Secure Data Sharing Delta Sharing is an open protocol for secure real-time exchange of large datasets, which enabl

Delta Lake 497 Jan 2, 2023
Statistical Random Number Generator Attack Against The Kirchhoff-law-johnson-noise (Kljn) Secure Key Exchange Protocol

Statistical Random Number Generator Attack Against The Kirchhoff-law-johnson-noise (Kljn) Secure Key Exchange Protocol

zeze 1 Jan 13, 2022
QHack-2022 - Solutions to the Coding Challenges of QHack 2022

QHack 2022 Problems from Coding Challenges 2022. Rules and how it works To test

Isacco Gobbi 1 Feb 14, 2022
The best Python Backdoor👌

Backdoor The best Python Backdoor Files Server file is used in all of cases If client is Windows, the client need execute EXE file If client is Linux,

null 13 Oct 28, 2022
Pgen is the best brute force password generator and it is improved from the cupp.py

pgen Pgen is the best brute force password generator and it is improved from the cupp.py The pgen tool is dedicated to Leonardo da Vinci -Time stays l

heyheykids 2 Jan 31, 2022
labsecurity is a tool that brings together python scripts made for ethical hacking, in a single tool, through a console interface

labsecurity labsecurity is a tool that brings together python scripts made for ethical hacking, in a single tool, through a console interface. Warning

Dylan Meca 16 Dec 8, 2022
Osint-Tool - Information collection tool in python

Osint-Tool Herramienta para la recolección de información Pronto más opciones In

null 3 Apr 9, 2022
All in One CRACKER911181's Tool. This Tool For Hacking and Pentesting. 🎭

All in One CRACKER911181's Tool. This Tool For Hacking and Pentesting. ??

Cracker 331 Jan 1, 2023
All in One CRACKER911181's Tool. This Tool For Hacking and Pentesting.🎭

This is A Python & Bash Programming Based Termux-Tool Created By CRACKER911181. This Tool Created For Hacking and Pentesting. If You Use This Tool To Evil Purpose,The Owner Will Never be Responsible For That.

CRACKER911181 1 Jan 10, 2022
Vulnerability Scanner & Auto Exploiter You can use this tool to check the security by finding the vulnerability in your website or you can use this tool to Get Shells

About create a target list or select one target, scans then exploits, done! Vulnnr is a Vulnerability Scanner & Auto Exploiter You can use this tool t

Nano 108 Dec 4, 2021