diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 7b8b55b..5f012a0 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -46,11 +46,11 @@ jobs: - name: BumpVersion if PR 'to-branch' is master if: github.base_ref == 'master' run: | - grep -i 'current_version = ' setup.cfg | tr -d 'current_version = ' + grep -i 'current_version = ' setup.cfg | head -1 | tr -d 'current_version = ' git config --local user.email "action@github.com" git config --local user.name "GitHub Action" - bumpversion minor - grep -i 'current_version = ' setup.cfg | tr -d 'current_version = ' + bump2version minor + grep -i 'current_version = ' setup.cfg | head -1 | tr -d 'current_version = ' - name: Push changes if PR 'to-branch' is master if: github.base_ref == 'master' diff --git a/Pypi_description.md b/Pypi_description.md deleted file mode 100644 index 7329553..0000000 --- a/Pypi_description.md +++ /dev/null @@ -1,142 +0,0 @@ -[![GitHub release](https://img.shields.io/github/release/Santandersecurityresearch/DrHeader.svg)](https://GitHub.com/Santandersecurityresearch/DrHeader/releases/) -[![GitHub commits](https://img.shields.io/github/commits-since/Santandersecurityresearch/DrHeader/v1.2.1.svg)](https://GitHub.com/Santandersecurityresearch/DrHeader/commit/) -[![Github all releases](https://img.shields.io/github/downloads/Santandersecurityresearch/DrHeader/total.svg)](https://GitHub.com/Santandersecurityresearch/DrHeader/releases/) -[![HitCount](http://hits.dwyl.io/Santandersecurityresearch/DrHeader.svg)](http://hits.dwyl.io/Santandersecurityresearch/DrHeader) -[![Total alerts](https://img.shields.io/lgtm/alerts/g/Santandersecurityresearch/DrHeader.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/Santandersecurityresearch/DrHeader/alerts/) -[![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/Santandersecurityresearch/DrHeader.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/Santandersecurityresearch/DrHeader/context:python) -[![MIT license](http://img.shields.io/badge/license-MIT-brightgreen.svg)](http://opensource.org/licenses/MIT) - - -# Welcome to drHEADer - -There are a number of HTTP headers which enhance the security of a website when used. Often ignored, or unknown, these HTTP security headers help prevent common web application vulnerabilities when used. - -DrHEADer helps with the audit of security headers received in response to a single request or a list of requests. - -When combined with the OWASP [Application Security Verification Standard](https://github.com/OWASP/ASVS/blob/master/4.0/en/0x22-V14-Config.md) (ASVS) 4.0, it is a useful tool to include as part of an automated CI/CD pipeline which checks for missing HTTP headers. - -# How Do I Install It? - -This project was developed with Python 3.7.4. -Whilst it works with Python 2.x, End of Life (EOL) is coming so if possible, use 3.x. The easiest way to install drHEADer is to clone this repository and via a terminal window, run the following command: - - -``` console -$ python3 setup.py install --user -``` -This will install all the pre-requisites and you'll end up with a drheader executable. - - -# How Do I Use It? - -There are two ways you could use drHEADer, depending on what you want to achieve. The easiest way is using the CLI. - -## CLI - -drHEADer can perform a single scan against a target and report back which headers are present, like so: - -``` console -$ drheader scan single https://santander.co.uk -``` - -If you wish to scan multiple sites, you'll need the targets in a JSON format, or a txt file, like so: - -``` - [ - { - "url": "https://example.com", - "params": { - "example_parameter_key": "example_parameter_value" - } - }, - ... - ] -``` - -For txt files, use the following command: - -``` console -$ drheader scan bulk -ff targets.txt -``` - -There are a number of parameters you can specify during bulk scans, these are: -| Option | Description | -| :---------------- | :----------------------------------------------------- | -| -p, --post | Use a post request to obtain headers | -| --json | Output report as json | -| --debug | Show error messages | -| --rules FILENAME | Use custom rule set | -| --rules-uri URL | Use custom rule set, to download from a remote server | -| --merge | Merge custom rule set on top of default set | -| --help | Show this message and exit | -| --junit | Creates a junit report in `./reports/junit.xml` folder | - -To save scan results, you can use the --json parameter and pipe it to [jq](https://stedolan.github.io/jq/), which is a lightweight and flexible command-line JSON processor,like so: - -``` console -$ drheader scan single https://santander.co.uk --json | jq '.' -``` - -## In a Project - -It is also possible to call drHEADer from within an existing project, and this is achieved like so: - - from drheader import Drheader - - # create drheader instance - drheader_instance = Drheader(headers={'X-XSS-Protection': '1; mode=block'}, status_code=200) - - report = drheader_instance.analyze() - print(report) - -### Customize HTTP method and headers - -By default, the tool uses **GET** method when making a request, but you can change that by supplying the ```method``` argument like this: - - # create drheader instance - drheader_instance = Drheader(url="http://test.com", method="POST") - -Remember you can use any method supported by ```requests``` such as POST, PUT, GET and DELETE. - -At the same time, you can customize the headers sent by the request. For that, you just have to use the ```request_headers``` argument: - - # create drheader instance - custom_headers = {"token": "1234aerhga"} - drheader_instance = Drheader(url="http://test.com", request_headers=custom_headers) - -As we continue development on drHEADer, we will further enhance this functionality. - -#### Other `requests` arguments - -The _verify_ argument supported by ```requests``` can be included. The default value is set to `True`. - - # create drheader instance - drheader_instance = Drheader(url="http://test.com", verify=False) - -Other arguments may be included in the future such as _timeout_, _allow_redirects_ or _proxies_. - -# How Do I Customise drHEADer Rules? - -DrHEADer relies on a yaml file that defines the policy it will use when auditing security headers. The file is located at `./drheader/rules.yml`, and you can customise it to fit your particular needs. Please follow this [link](RULES.md) if you want to know more. - -# Notes - -* On ubuntu systems you may need to install libyaml-dev to avoid errors related to a missing yaml.h. - -## Roadmap - -We have a lot of ideas for drHEADer, and will push often as a result. Some of the things you'll see shortly are: - -* Building on the Python library to make it easier to embed in your own projects. -* Releasing the API, which is seperate from the core library - the API allows you to hit URLs or endpoints at scale -* Better integration into MiTM proxies. - -# Who Is Behind It? - -DrHEADer was developed by the Santander UK Security Engineering team, who are: - -* David Albone -* [Javier Domínguez Ruiz](https://github.com/javixeneize) -* Fernando Cabrerizo -* [James Morris](https://github.com/actuallyjamez) - diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 0000000..2dbe5f0 --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,41 @@ +# Releasing + +Our approach to releasing new versions is quite simple. A new version will be released everytime there's a push to master branch. + +We've managed to have all the process to bump version for next release in the different files fully automated by using [github actions](https://github.com/features/actions). + +We currently have 2 github actions configured in this repo, which will be triggered when: + +* There's a pull request. + * If the PR is to a non master branch, this action will run standard checks like nosetests, flake8, bandit and safety to ensure everything is good with the code. + * If the PR is to the master branch, this action will run standard checks, automatically bump release version number in appropriate files and commit those changes to the pull request branch. +* There are changes pushed to master branch. + * This action will run standard checks, create the wheel, the release/tag using the version previously bumped and publish the artefact to Pypi + +To bump version in files prior to release, we use [bump2version](https://github.com/c4urself/bump2version). The configuration for it to know what is the current version, what files need to have the version bumped up and what is the next version is in `setup.cfg`. + +```ini +[bumpversion] +current_version = 1.2.2 +commit = True +tag = False +new_version = 2.0.0 + +[bumpversion:file:setup.py] +search = version='{current_version}' +replace = version='{new_version}' + +[bumpversion:file:setup.cfg] +search = current_version = '{current_version}' +replace = current_version = '{new_version}' + +[bumpversion:file:drheader/__init__.py] +search = __version__ = '{current_version}' +replace = __version__ = '{new_version}' + +... +``` + +With this configuration, we are specifying that only those three files need to have the version bumped before release. By default, `bump2version` bumps a minor version (ie . from 1.2.2 to 1.3.0), but if we want it to be a major version or a patch bump, we only need to specify the `new_version` attribute in the configuration with the version we want to use for the release. + +**Note**: Master and develop branches are protected. It means that we require commits to be pushed through pull requests, status checks to pass before merging and restrict who can push to those branches. We aimed to have the release process fully automated, but because issues described [here](https://github.community/t5/GitHub-Actions/How-to-push-to-protected-branches-in-a-GitHub-Action/td-p/29609) or [here](https://github.community/t5/GitHub-Actions/Automatic-version-update-in-protected-branch/m-p/56469#M9895) when using github actions for this, we decided that disabling this protection in **develop** branch just when a PR from develop to master is submitted would be a good approach for us, so that the action that bumps the versions and commits the changes back can complete successfuly. diff --git a/drheader/__init__.py b/drheader/__init__.py index 2411658..0313776 100644 --- a/drheader/__init__.py +++ b/drheader/__init__.py @@ -2,6 +2,6 @@ """Top-level package for drHEADer core.""" -__version__ = '1.2.2' +__version__ = '1.3.0' from drheader.core import Drheader # noqa diff --git a/requirements.txt b/requirements.txt index ff5cfa1..b14b009 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ -requests==2.22.0 +requests>=2.22.0 jsonschema==3.1.1 jsonschema[format] Click>=7.0 -validators==0.14.0 +validators>=0.14.0 tabulate==0.8.3 pyyaml==5.3.1 junit-xml==1.9 diff --git a/requirements_dev.txt b/requirements_dev.txt index ecd735d..7243d99 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -1,4 +1,3 @@ -bumpversion==0.5.3 bump2version==1.0.0 wheel==0.32.1 watchdog==0.9.0 @@ -13,7 +12,7 @@ bandit==1.6.2 flake8==3.6.0 safety==1.8.6 nose>=1.3.6 -validators==0.14.0 +validators>=0.14.0 unittest2==1.1.0 xmlunittest==0.5.0 junit-xml==1.9 diff --git a/setup.cfg b/setup.cfg index fa338ee..a461869 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 1.2.2 +current_version = 1.3.0 commit = True tag = False @@ -9,7 +9,7 @@ replace = version='{new_version}' [bumpversion:file:setup.cfg] search = current_version = '{current_version}' -replace = version='{new_version}' +replace = current_version = '{new_version}' [bumpversion:file:drheader/__init__.py] search = __version__ = '{current_version}' diff --git a/setup.py b/setup.py index c1ea1d8..246d536 100644 --- a/setup.py +++ b/setup.py @@ -62,6 +62,6 @@ test_suite='tests', tests_require=test_requirements, url='https://github.com/santandersecurityresearch/drheader', - version='1.2.2', + version='1.3.0', zip_safe=False, )