├── .github └── workflows │ └── build-bundles.yml ├── CODEOWNERS ├── LICENSE ├── README.md ├── bundles.json ├── customizations ├── javascript │ └── CustomSources.qll └── ruby │ └── CustomSources.qll └── queries └── javascript ├── .codeqlmanifest.json └── src └── qlpack.yml /.github/workflows/build-bundles.yml: -------------------------------------------------------------------------------- 1 | name: "Custom CodeQL bundles" 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - "customizations/**" 7 | - "bundles.json" 8 | branches: 9 | - main 10 | workflow_dispatch: 11 | inputs: 12 | bundle: 13 | description: "Which bundle to create. Use '*' to use the bundles.json content" 14 | default: "codeql-bundle-20220214" 15 | 16 | env: 17 | FORCE_CUSTOMIZATION: "false" 18 | 19 | jobs: 20 | prepare-bundles-matrix: 21 | name: "Prepare CodeQL bundle matrix" 22 | runs-on: ubuntu-latest 23 | outputs: 24 | matrix: ${{ steps.export-bundle-matrix.outputs.matrix }} 25 | steps: 26 | - name: Checkout repository 27 | uses: actions/checkout@v2 28 | 29 | - name: Export CodeQL bundle matrix 30 | env: 31 | BUNDLE: ${{ github.event.inputs.bundle }} 32 | id: export-bundle-matrix 33 | run: | 34 | if [ $BUNDLE == "*" ] 35 | then 36 | echo "::set-output name=matrix::$( 37 | jq --compact-output . bundles.json 38 | )" 39 | else 40 | echo "::set-output name=matrix::{\"bundle\":[\"$BUNDLE\"]}" 41 | fi 42 | 43 | build-bundles: 44 | name: "Build custom CodeQL bundles" 45 | needs: prepare-bundles-matrix 46 | runs-on: ubuntu-latest 47 | 48 | strategy: 49 | fail-fast: false 50 | matrix: ${{ fromJSON(needs.prepare-bundles-matrix.outputs.matrix) }} 51 | 52 | steps: 53 | - name: Checkout repository 54 | uses: actions/checkout@v2 55 | 56 | - name: "Build custom CodeQL bundle" 57 | env: 58 | CODEQL_BUNDLE: ${{ matrix.bundle }} 59 | GITHUB_TOKEN: ${{ github.token }} 60 | run: | 61 | gh release --repo github/codeql-action download -p codeql-bundle.tar.gz $CODEQL_BUNDLE 62 | 63 | tar xf codeql-bundle.tar.gz 64 | rm codeql-bundle.tar.gz 65 | 66 | for lang_path in customizations/*; do 67 | # Copy custom modules 68 | lang=${lang_path##*/} 69 | 70 | using_packs=1 71 | if [ -d codeql/qlpacks/codeql-$lang-lib ]; then 72 | qllib_path=codeql/qlpacks/codeql-$lang-lib 73 | qlquery_path=codeql/qlpacks/codeql-$lang 74 | using_packs=0 75 | else 76 | qllib_version=$(ls codeql/qlpacks/codeql/$lang-all) 77 | qllib_path=codeql/qlpacks/codeql/$lang-all/$qllib_version 78 | qlquery_version=$(ls codeql/qlpacks/codeql/$lang-queries) 79 | qlquery_path=codeql/qlpacks/codeql/$lang-queries/$qlquery_version 80 | fi 81 | 82 | if [ -d $qllib_path ]; then 83 | if [ ! -f $qllib_path/Customizations.qll ] && [ "$FORCE_CUSTOMIZATION" = "true" ]; then 84 | echo "::warning::Forcing customization for language $lang" 85 | echo "import $lang" > $qllib_path/Customizations.qll 86 | sed -i -e '0,/^import/s//private import Customizations\nimport/' $qllib_path/$lang.qll 87 | fi 88 | 89 | if [ -f $qllib_path/Customizations.qll ]; then 90 | mkdir $qllib_path/customizations 91 | cp $lang_path/*.qll $qllib_path/customizations 92 | 93 | # Import custom modules 94 | for module_path in $lang_path/*.qll; do 95 | module_file=${module_path##*/} 96 | module_name=${module_file%.*} 97 | echo "import customizations.$module_name" >> $qllib_path/Customizations.qll 98 | done 99 | 100 | if [ using_packs ] 101 | then 102 | echo "Rebuilding pack at $qlquery_path" 103 | rm $qlquery_path/codeql-pack.lock.yml 104 | content_dir=$RUNNER_TEMP/$lang 105 | pack_content=$content_dir/codeql/$lang-queries/$qlquery_version 106 | codeql/codeql pack create --additional-packs codeql/qlpacks/codeql/$lang-all:codeql/qlpacks/codeql/suite-helpers -j 0 --output=$content_dir $qlquery_path 107 | echo "Removing old pack content codeql/qlpacks/codeql/$lang-queries/$qlquery_version" 108 | rm -Rf codeql/qlpacks/codeql/$lang-queries/$qlquery_version 109 | echo "Moving pack content from '$pack_content' to codeql/qlpacks/codeql/$lang-queries" 110 | mv -v -f $pack_content codeql/qlpacks/codeql/$lang-queries/ 111 | else 112 | echo "Rebuilding cache" 113 | # Rebuild cache 114 | rm -r $qlquery_path/.cache 115 | codeql/codeql query compile --search-path codeql --threads 0 $qlquery_path 116 | fi 117 | else 118 | echo "::warning::Skipping customization for language $lang, because it doesn't have a Customizations.qll" 119 | fi 120 | else 121 | echo "::error::Unable to customize language $lang, because it is not present in the CodeQL Bundle $CODEQL_BUNDLE" 122 | fi 123 | done 124 | 125 | tar -czf codeql-bundle.tar.gz codeql 126 | rm -r codeql 127 | 128 | gh release create ${CODEQL_BUNDLE}-$(git rev-parse --short $GITHUB_SHA) codeql-bundle.tar.gz 129 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # This project is maintained with love by: @rvermeulen 2 | * @rvermeulen 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 GitHub 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deprecated 2 | 3 | This repository template is deprecated in favour of the GitHub Action [CodeQL Bundle Action](https://github.com/advanced-security/codeql-bundle-action). 4 | The repository will remain available in read-only mode, but it is advised to migrate. 5 | 6 | # Custom CodeQL Bundle 7 | 8 | The Custom CodeQL Bundle repository can be used in combination with GitHub 9 | Actions to automate customizing the behavior of the queries in the CodeQL 10 | standard library for a variety of target languages. It is currently considered 11 | the best practice for customizing the built-in CodeQL queries. 12 | 13 | At current this repository will work with the following languages: 14 | 15 | - Java 16 | - Javascript 17 | - Python 18 | - C# 19 | - Go 20 | 21 | Official support for Ruby will be added when the `Customizations.qll` is made available in the selected CodeQL bundles specified in the `bundles.json`. 22 | As an unofficial workaround you can change the environment variable `FORCE_CUSTOMIZATION` in the `.github/build-bundles.yml` to `"true"`. 23 | The forced customization will create a `Customizations.qll` file and prepend it to the language specific library (e.g., `cpp.qll`, `ruby.qll`). 24 | 25 | # Using the Custom CodeQL Bundle 26 | 27 | Using the Custom CodeQL bundle involves two main steps: 28 | 29 | 1. Creating a copy of the `custom-codeql-bundle` repository within your 30 | organization. 31 | 2. Modifying your CodeQL action to retrieve your custom bundle during query 32 | execution. 33 | 34 | The tooling within this repository takes care of combining your customizations 35 | here with the main codeql-bundle distribution. It uses the `Customizations.qll` 36 | mechanism which ensures that upstream changes are never made, thus making it 37 | possible to rebase your clone of this repository on newer versions of CodeQL 38 | without conflict. 39 | 40 | 1. To use this repository, first start by clicking the `Use This Template` button 41 | on GitHub.com interface located here: 42 | https://github.com/advanced-security/custom-codeql-bundle 43 | 44 | This will allow you to create a copy of this repository that you will customize 45 | with your additions. 46 | 47 | 2. Modify `bundles.json` in the root of this repository. This controls the 48 | CodeQL version that will be used with your queries. 49 | 50 | 3. Add your customizations to the `customizations/` directory within 51 | the root of this repository. You may add as many independent `.qll` 52 | files in these directories as you wish. They will be combined and added to 53 | the appropriate extension points within your target language. 54 | 55 | 4. Modify your `codeql-analysis.yml` file to point at your custom bundle. 56 | If it is private you can use the following configuration that downloads a private release using a GitHub PAT: 57 | ```yaml 58 | - name: Download CodeQL bundle 59 | env: 60 | GITHUB_TOKEN: ${{ secrets.CODEQL_BUNDLE_PAT }} 61 | run: | 62 | gh release -R advanced-security/custom-codeql-bundle download codeql-bundle-20211005-79ff94b 63 | # Initializes the CodeQL tools for scanning. 64 | - name: Initialize CodeQL 65 | uses: github/codeql-action/init@v1 66 | with: 67 | languages: ${{ matrix.language }} 68 | tools: codeql-bundle.tar.gz 69 | ``` 70 | 71 | The relevant portion of that file when the CodeQL bundle repository is private is the following: 72 | 73 | ```yml 74 | steps: 75 | - name: Download CodeQL bundle 76 | env: 77 | GITHUB_TOKEN: ${{ secrets.CODEQL_BUNDLE_PAT }} 78 | run: | 79 | # Download custom CodeQL bundle as codeql-bundle.tar.gz 80 | gh release -R download 81 | # Initializes the CodeQL tools for scanning. 82 | - name: Initialize CodeQL 83 | uses: github/codeql-action/init@v1 84 | with: 85 | languages: ${{ matrix.language }} 86 | # Specify the use of our custom CodeQL bundle 87 | tools: codeql-bundle.tar.gz 88 | ``` 89 | 90 | In the above, you set the location of your bundle as well as the tag. 91 | 92 | If the CodeQL bundle repository is public, or the bundle is stored in a public location, then we can directly specify it in the `tools` configuration like: 93 | 94 | ```yml 95 | steps: 96 | # Initializes the CodeQL tools for scanning. 97 | - name: Initialize CodeQL 98 | uses: github/codeql-action/init@v1 99 | with: 100 | languages: ${{ matrix.language }} 101 | # Specify the use of our custom CodeQL bundle 102 | tools: https:////codeql-bundle.tar.gz 103 | ``` 104 | 105 | Where `` follows the versioning scheme used in the `bundles.json` 106 | 107 | Once these steps are performed, you will be able to analyze your project using 108 | your custom CodeQL bundle with your customizations in place. 109 | 110 | To get an idea of the sorts of customizations that are possible, please 111 | see: 112 | 113 | - https://codeql.github.com/docs/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript/ 114 | - https://codeql.github.com/docs/codeql-language-guides/analyzing-data-flow-in-csharp/#flow-sources 115 | - https://codeql.github.com/docs/codeql-language-guides/modeling-data-flow-in-go-libraries/#sources 116 | - https://codeql.github.com/docs/codeql-language-guides/analyzing-data-flow-in-java/#flow-sources 117 | - https://codeql.github.com/docs/codeql-language-guides/analyzing-data-flow-in-python/#predefined-sources-and-sinks 118 | 119 | 120 | # Limitations 121 | 122 | This repository may be used to refine the behavior of the out of the box queries 123 | by: 124 | - Extending existing [abstract classes](https://codeql.github.com/docs/ql-language-reference/types/#abstract-classes) 125 | - Adding additional sinks and sources specific to your organization 126 | 127 | It may not be used for replacing classes within CodeQL. 128 | 129 | # Contributing 130 | 131 | Please direct your contributions to us by opening up a pull request. 132 | 133 | 134 | -------------------------------------------------------------------------------- /bundles.json: -------------------------------------------------------------------------------- 1 | { 2 | "bundle": [ 3 | "codeql-bundle-20220214", 4 | "codeql-bundle-20211005", 5 | "codeql-bundle-20211208" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /customizations/javascript/CustomSources.qll: -------------------------------------------------------------------------------- 1 | import javascript 2 | 3 | class CustomSource extends RemoteFlowSource, DataFlow::CallNode { 4 | CustomSource() { this.getCalleeName() = "source" } 5 | 6 | override string getSourceType() { result = "a call to source" } 7 | } 8 | -------------------------------------------------------------------------------- /customizations/ruby/CustomSources.qll: -------------------------------------------------------------------------------- 1 | import ruby 2 | import codeql.ruby.dataflow.RemoteFlowSources 3 | 4 | class CustomSource extends RemoteFlowSource::Range { 5 | CustomSource() { this.asExpr().getExpr().(MethodCall).getMethodName() = "source" } 6 | 7 | override string getSourceType() { result = "test" } 8 | } 9 | -------------------------------------------------------------------------------- /queries/javascript/.codeqlmanifest.json: -------------------------------------------------------------------------------- 1 | { "provide": [ 2 | "*/src/qlpack.yml", 3 | "*/test/qlpack.yml" ] } 4 | -------------------------------------------------------------------------------- /queries/javascript/src/qlpack.yml: -------------------------------------------------------------------------------- 1 | name: custom-javascript-queries 2 | version: 0.0.0 3 | libraryPathDependencies: 4 | - codeql/javascript-all 5 | --------------------------------------------------------------------------------