{ "info": { "author": "fuzzit.dev", "author_email": "support@fuzzit.dev", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Topic :: Software Development :: Testing" ], "description": "# pythonfuzz: coverage-guided fuzz testing for python\n[![Join the chat at https://slack.fuzzit.dev](https://app.fuzzit.dev/static/slack-join.svg)](https://slack.fuzzit.dev)\n\n\nPythonFuzz is coverage-guided [fuzzer](https://developer.mozilla.org/en-US/docs/Glossary/Fuzzing) for testing python packages.\n\nFuzzing for safe languages like python is a powerful strategy for finding bugs like unhandled exceptions, logic bugs,\nsecurity bugs that arise from both logic bugs and Denial-of-Service caused by hangs and excessive memory usage.\n\nFuzzing can be seen as a powerful and efficient strategy in real-world software in addition to classic unit-tests.\n\n## Usage\n\n### Fuzz Target\n\nThe first step is to implement the following function (also called a fuzz\ntarget). Here is an example of a simple fuzz function for the built-in `html` module\n\n```python\nfrom html.parser import HTMLParser\nfrom pythonfuzz.main import PythonFuzz\n\n\n@PythonFuzz\ndef fuzz(buf):\n try:\n string = buf.decode(\"ascii\")\n parser = HTMLParser()\n parser.feed(string)\n except UnicodeDecodeError:\n pass\n\n\nif __name__ == '__main__':\n fuzz()\n```\n\nFeatures of the fuzz target:\n\n* fuzz will call the fuzz target in an infinite loop with random data (according to the coverage guided algorithm) passed to `buf`( in a separate process).\n* The function must catch and ignore any expected exceptions that arise when passing invalid input to the tested package.\n* The fuzz target must call the test function/library with with the passed buffer or a transformation on the test buffer \nif the structure is different or from different type.\n* Fuzz functions can also implement application level checks to catch application/logical bugs - For example: \ndecode the buffer with the testable library, encode it again, and check that both results are equal. To communicate the results\nthe result/bug the function should throw an exception.\n* pythonfuzz will report any unhandled exceptions as crashes as well as inputs that hit the memory limit specified to pythonfuzz\nor hangs/they run more the the specified timeout limit per testcase.\n\n\n### Running\n\nThe next step is to download pythonfuzz and then run your fuzzer\n\n```bash\npip install pythonfuzz\npython examples/htmlparser/fuzz.py\n\n#394378 NEW cov: 608 corp: 24 exec/s: 1119 rss: 10.73828125 MB\nsubclasses of ParserBase must override error()\nTraceback (most recent call last):\n File \"/Users/yevgenyp/fuzzitdev/pythonfuzz/pythonfuzz/fuzzer.py\", line 21, in worker\n target(buf)\n File \"examples/htmlparser/fuzz.py\", line 12, in fuzz\n pass\n File \"/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/html/parser.py\", line 111, in feed\n self.goahead(0)\n File \"/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/html/parser.py\", line 179, in goahead\n k = self.parse_html_declaration(i)\n File \"/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/html/parser.py\", line 264, in parse_html_declaration\n return self.parse_marked_section(i)\n File \"/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/_markupbase.py\", line 159, in parse_marked_section\n self.error('unknown status keyword %r in marked section' % rawdata[i+3:j])\n File \"/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/_markupbase.py\", line 34, in error\n \"subclasses of ParserBase must override error()\")\nNotImplementedError: subclasses of ParserBase must override error()\ncrash was written to crash-dbfa437e5956643645681fe6a3ac76997be0b29a7c7af82d88c8c390f379502d\ncrash = 3c215b63612121\n```\n\nThis example quickly finds an an unhandled exception/flow in a few minutes.\n\n### Corpus\n\nPythonFuzz will generate and test various inputs in an infinite loop. `corpus` is optional directory and will be used to\nsave the generated testcases so later runs can be started from the same point and provided as seed corpus.\n\nPythonFuzz can also start with an empty directory (i.e no seed corpus) though some valid test-cases in the seed corpus\nmay speed up the fuzzing substantially. \n\nPythonFuzz tries to mimic some of the arguments and output style from [libFuzzer](https://llvm.org/docs/LibFuzzer.html).\n\nMore fuzz targets examples (for real and popular libraries) are located under the examples directory and\nbugs that were found using those targets are listed in the trophies section.\n\n## Credits & Acknowledgments\n\nPythonFuzz is a port of [fuzzitdev/jsfuzz](https://github.com/fuzzitdev/jsfuzz)\n\nwhich is in turn heavily based on [go-fuzz](https://github.com/dvyukov/go-fuzz) originally developed by [Dmitry Vyukov's](https://twitter.com/dvyukov).\nWhich is in turn heavily based on [Michal Zalewski](https://twitter.com/lcamtuf) [AFL](http://lcamtuf.coredump.cx/afl/).\n\nFor coverage PythonFuzz is using [coverage](https://coverage.readthedocs.io/en/v4.5.x/) instrumentation and coverage library. \n\n## Contributions\n\nContributions are welcome!:) There are still a lot of things to improve, and tests and features to add. We will slowly post those in the\nissues section. Before doing any major contribution please open an issue so we can discuss and help guide the process before\nany unnecessary work is done.\n\n\n## Trophies\n\n* [python built-in HTMLParser - unhandled exception](https://bugs.python.org/msg355287)\n\n**Feel free to add bugs that you found with pythonfuzz to this list via pull-request**", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/fuzzitdev/pythonfuzz", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "pythonfuzz", "package_url": "https://pypi.org/project/pythonfuzz/", "platform": "", "project_url": "https://pypi.org/project/pythonfuzz/", "project_urls": { "Homepage": "https://github.com/fuzzitdev/pythonfuzz" }, "release_url": "https://pypi.org/project/pythonfuzz/1.0.3/", "requires_dist": null, "requires_python": ">=3.5.3", "summary": "coverage-guided fuzz testing for python", "version": "1.0.3", "yanked": false, "yanked_reason": null }, "last_serial": 10963012, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "a153f2e1a21435cf66d9d579a52f6ed9", "sha256": "7bfb59ea84596aa8133f2ae5d00cd29190fd265dfcf9a081fe7bead149d154d1" }, "downloads": -1, "filename": "pythonfuzz-1.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "a153f2e1a21435cf66d9d579a52f6ed9", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5.3", "size": 7675, "upload_time": "2019-10-24T07:16:18", "upload_time_iso_8601": "2019-10-24T07:16:18.473300Z", "url": "https://files.pythonhosted.org/packages/1a/3a/15e8503437ed2d670ef48ca40fe3c77088aef5b732182d93b84d89a1303a/pythonfuzz-1.0.0-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "e94ee59102ae0b5982f75a121ed2ef36", "sha256": "052474d13be5b248c7a53e6926d12442cd0a0d23725d2c8061b8895db139b74b" }, "downloads": -1, "filename": "pythonfuzz-1.0.0.tar.gz", "has_sig": false, "md5_digest": "e94ee59102ae0b5982f75a121ed2ef36", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5.3", "size": 8088, "upload_time": "2019-10-24T07:16:21", "upload_time_iso_8601": "2019-10-24T07:16:21.098789Z", "url": "https://files.pythonhosted.org/packages/10/a2/1e447e42442ff1fd7aadbbdc118b233f1d8bb306e11ec4142447360a2fab/pythonfuzz-1.0.0.tar.gz", "yanked": false, "yanked_reason": null } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "a7b452ebb9e7ca96bcb15f311420c5a4", "sha256": "8cc7db2714e0cc6cc6fe5ef65e10d675cd2acf465b198eb1b741850055c3013a" }, "downloads": -1, "filename": "pythonfuzz-1.0.1.tar.gz", "has_sig": false, "md5_digest": "a7b452ebb9e7ca96bcb15f311420c5a4", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5.3", "size": 8175, "upload_time": "2019-11-01T21:32:09", "upload_time_iso_8601": "2019-11-01T21:32:09.035202Z", "url": "https://files.pythonhosted.org/packages/83/9b/d20eab4cc49d4770643c712c4484fda341bdde5e3aa03961ef7209b9eebc/pythonfuzz-1.0.1.tar.gz", "yanked": false, "yanked_reason": null } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "3c14afccd86f5bd3615d097b80a364bf", "sha256": "3b24c1d9be893680d55e3e75c730c4231cd1c30c9fbd3e8c4e6aee4217ce0c89" }, "downloads": -1, "filename": "pythonfuzz-1.0.2.tar.gz", "has_sig": false, "md5_digest": "3c14afccd86f5bd3615d097b80a364bf", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5.3", "size": 8195, "upload_time": "2019-11-01T21:36:52", "upload_time_iso_8601": "2019-11-01T21:36:52.967898Z", "url": "https://files.pythonhosted.org/packages/00/12/cb6239c601fd08662ae399d60c7337bd055441856b669f913f098733bff2/pythonfuzz-1.0.2.tar.gz", "yanked": false, "yanked_reason": null } ], "1.0.3": [ { "comment_text": "", "digests": { "md5": "20db9027c6829fb4633b6041ff7e46c5", "sha256": "0a243f0da859088ccc94669f35431e3b159a3645f670fde6b5e3fc3b6e7d7182" }, "downloads": -1, "filename": "pythonfuzz-1.0.3.tar.gz", "has_sig": false, "md5_digest": "20db9027c6829fb4633b6041ff7e46c5", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5.3", "size": 8224, "upload_time": "2019-11-02T08:46:31", "upload_time_iso_8601": "2019-11-02T08:46:31.570031Z", "url": "https://files.pythonhosted.org/packages/e1/a4/e34d9023af8143fc6e294728d7b288ca58ae110a4fb0233f56d3abc75ced/pythonfuzz-1.0.3.tar.gz", "yanked": false, "yanked_reason": null } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "20db9027c6829fb4633b6041ff7e46c5", "sha256": "0a243f0da859088ccc94669f35431e3b159a3645f670fde6b5e3fc3b6e7d7182" }, "downloads": -1, "filename": "pythonfuzz-1.0.3.tar.gz", "has_sig": false, "md5_digest": "20db9027c6829fb4633b6041ff7e46c5", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5.3", "size": 8224, "upload_time": "2019-11-02T08:46:31", "upload_time_iso_8601": "2019-11-02T08:46:31.570031Z", "url": "https://files.pythonhosted.org/packages/e1/a4/e34d9023af8143fc6e294728d7b288ca58ae110a4fb0233f56d3abc75ced/pythonfuzz-1.0.3.tar.gz", "yanked": false, "yanked_reason": null } ], "vulnerabilities": [] }