├── .gitignore ├── LICENSE ├── Pipfile ├── Pipfile.lock ├── README.md ├── fixme ├── images ├── 00-repo-security-tab.png ├── 01-repo-secruity-setup-code-scanning.png ├── 02-repo-security-setup-codeql-workflow.png ├── 03-actions-sample-workflow.png ├── 04-actions-sample-events.png ├── 05-actions-completed.png ├── 06-security-codeql-alert.png ├── 07-security-codeql-show-more.png ├── 08-security-codeql-full-desc.png ├── 09-security-codeql-show-paths.png ├── 10-security-codeql-show-paths-details.png ├── 11-fix-source-code.png ├── 12-fix-pr-in-progress.png ├── 13-fix-pr-done.png ├── 14-fix-detail.png ├── 15-fixed-alert.png ├── 16-fix-history.png ├── 17-fork-repo.png ├── 18-create-vulnerable-pr.png ├── 19-vulnerabiltliy-detail.png └── 20-files-changed-vulnerabilities.png ├── server ├── __init__.py ├── __main__.py ├── models │ ├── __init__.py │ └── books.py ├── routes.py └── webapp.py └── templates └── books.html /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.db 3 | 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | *$py.class 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | wheels/ 26 | pip-wheel-metadata/ 27 | share/python-wheels/ 28 | *.egg-info/ 29 | .installed.cfg 30 | *.egg 31 | MANIFEST 32 | 33 | # PyInstaller 34 | # Usually these files are written by a python script from a template 35 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 36 | *.manifest 37 | *.spec 38 | 39 | # Installer logs 40 | pip-log.txt 41 | pip-delete-this-directory.txt 42 | 43 | # Unit test / coverage reports 44 | htmlcov/ 45 | .tox/ 46 | .nox/ 47 | .coverage 48 | .coverage.* 49 | .cache 50 | nosetests.xml 51 | coverage.xml 52 | *.cover 53 | *.py,cover 54 | .hypothesis/ 55 | .pytest_cache/ 56 | 57 | # Translations 58 | *.mo 59 | *.pot 60 | 61 | # Django stuff: 62 | *.log 63 | local_settings.py 64 | db.sqlite3 65 | db.sqlite3-journal 66 | 67 | # Flask stuff: 68 | instance/ 69 | .webassets-cache 70 | 71 | # Scrapy stuff: 72 | .scrapy 73 | 74 | # Sphinx documentation 75 | docs/_build/ 76 | 77 | # PyBuilder 78 | target/ 79 | 80 | # Jupyter Notebook 81 | .ipynb_checkpoints 82 | 83 | # IPython 84 | profile_default/ 85 | ipython_config.py 86 | 87 | # pyenv 88 | .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 98 | __pypackages__/ 99 | 100 | # Celery stuff 101 | celerybeat-schedule 102 | celerybeat.pid 103 | 104 | # SageMath parsed files 105 | *.sage.py 106 | 107 | # Environments 108 | .env 109 | .venv 110 | env/ 111 | venv/ 112 | ENV/ 113 | env.bak/ 114 | venv.bak/ 115 | 116 | # Spyder project settings 117 | .spyderproject 118 | .spyproject 119 | 120 | # Rope project settings 121 | .ropeproject 122 | 123 | # mkdocs documentation 124 | /site 125 | 126 | # mypy 127 | .mypy_cache/ 128 | .dmypy.json 129 | dmypy.json 130 | 131 | # Pyre type checker 132 | .pyre/ 133 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 OctoDemo 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 | -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | url = "https://pypi.org/simple" 3 | verify_ssl = true 4 | name = "pypi" 5 | 6 | [packages] 7 | flask = "*" 8 | python-dotenv = "*" 9 | 10 | [dev-packages] 11 | 12 | [requires] 13 | python_version = "3.8" 14 | -------------------------------------------------------------------------------- /Pipfile.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "hash": { 4 | "sha256": "069f33d2dc75b242fa5ee44daf090c80831812dc6cc59824e94c22a677eac958" 5 | }, 6 | "pipfile-spec": 6, 7 | "requires": { 8 | "python_version": "3.8" 9 | }, 10 | "sources": [ 11 | { 12 | "name": "pypi", 13 | "url": "https://pypi.org/simple", 14 | "verify_ssl": true 15 | } 16 | ] 17 | }, 18 | "default": { 19 | "click": { 20 | "hashes": [ 21 | "sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a", 22 | "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6" 23 | ], 24 | "markers": "python_version >= '3.6'", 25 | "version": "==8.0.1" 26 | }, 27 | "flask": { 28 | "hashes": [ 29 | "sha256:7b2fb8e934ddd50731893bdcdb00fc8c0315916f9fcd50d22c7cc1a95ab634e2", 30 | "sha256:cb90f62f1d8e4dc4621f52106613488b5ba826b2e1e10a33eac92f723093ab6a" 31 | ], 32 | "index": "pypi", 33 | "version": "==2.0.2" 34 | }, 35 | "itsdangerous": { 36 | "hashes": [ 37 | "sha256:5174094b9637652bdb841a3029700391451bd092ba3db90600dea710ba28e97c", 38 | "sha256:9e724d68fc22902a1435351f84c3fb8623f303fffcc566a4cb952df8c572cff0" 39 | ], 40 | "markers": "python_version >= '3.6'", 41 | "version": "==2.0.1" 42 | }, 43 | "jinja2": { 44 | "hashes": [ 45 | "sha256:827a0e32839ab1600d4eb1c4c33ec5a8edfbc5cb42dafa13b81f182f97784b45", 46 | "sha256:8569982d3f0889eed11dd620c706d39b60c36d6d25843961f33f77fb6bc6b20c" 47 | ], 48 | "markers": "python_version >= '3.6'", 49 | "version": "==3.0.2" 50 | }, 51 | "markupsafe": { 52 | "hashes": [ 53 | "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298", 54 | "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64", 55 | "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b", 56 | "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567", 57 | "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff", 58 | "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724", 59 | "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74", 60 | "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646", 61 | "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35", 62 | "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6", 63 | "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6", 64 | "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad", 65 | "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26", 66 | "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38", 67 | "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac", 68 | "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7", 69 | "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6", 70 | "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75", 71 | "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f", 72 | "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135", 73 | "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8", 74 | "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a", 75 | "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a", 76 | "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9", 77 | "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864", 78 | "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914", 79 | "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18", 80 | "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8", 81 | "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2", 82 | "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d", 83 | "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b", 84 | "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b", 85 | "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f", 86 | "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb", 87 | "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833", 88 | "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28", 89 | "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415", 90 | "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902", 91 | "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d", 92 | "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9", 93 | "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d", 94 | "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145", 95 | "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066", 96 | "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c", 97 | "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1", 98 | "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f", 99 | "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53", 100 | "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134", 101 | "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85", 102 | "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5", 103 | "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94", 104 | "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509", 105 | "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51", 106 | "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872" 107 | ], 108 | "markers": "python_version >= '3.6'", 109 | "version": "==2.0.1" 110 | }, 111 | "python-dotenv": { 112 | "hashes": [ 113 | "sha256:aae25dc1ebe97c420f50b81fb0e5c949659af713f31fdb63c749ca68748f34b1", 114 | "sha256:f521bc2ac9a8e03c736f62911605c5d83970021e3fa95b37d769e2bbbe9b6172" 115 | ], 116 | "index": "pypi", 117 | "version": "==0.19.0" 118 | }, 119 | "werkzeug": { 120 | "hashes": [ 121 | "sha256:63d3dc1cf60e7b7e35e97fa9861f7397283b75d765afcaefd993d6046899de8f", 122 | "sha256:aa2bb6fc8dee8d6c504c0ac1e7f5f7dc5810a9903e793b6f715a9f015bdadb9a" 123 | ], 124 | "markers": "python_version >= '3.6'", 125 | "version": "==2.0.2" 126 | } 127 | }, 128 | "develop": {} 129 | } 130 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Code Scanning Python Tutorial 2 | 3 | Welcome to the Code Scanning Python Tutorial! This tutorial will take you through how to set up Github Advanced Security: Code Scanning as well as interpret results that it may find. The following repository contains SQL injection vulnerability for demonstration purpose. 4 | 5 | ## Introduction 6 | 7 | Code scanning is a feature that you use to analyze the code in a GitHub repository to find security vulnerabilities and coding errors. Any problems identified by the analysis are shown in GitHub. 8 | 9 | You can use code scanning with CodeQL, a semantic code analysis engine. CodeQL treats code as data, allowing you to find potential vulnerabilities in your code with greater confidence than traditional static analyzers. 10 | 11 | This tutorial with use CodeQL Analysis with Code Scanning in order to search for vulnerabilities within your code. 12 | 13 | ## Instructions 14 | 15 |
16 | Fork this repo 17 |

18 | 19 | Begin by [forking this repo](https://docs.github.com/en/free-pro-team@latest/github/getting-started-with-github/fork-a-repo). 20 | 21 | NOTE: Make sure you uncheck "Copy the `main` branch only" 22 | 23 | 24 | 25 |

26 | 27 |
28 | 29 |
30 | Enable Code Scanning 31 |

32 | 33 | #### Security tab 34 | 35 | Click on the `Security` tab. 36 | 37 | 38 | 39 | 40 | #### Set up code scanning 41 | 42 | Click `Set up code scanning`. 43 | 44 | 45 | 46 | #### Setup Workflow 47 | 48 | Click the `Setup this workflow` button by CodeQL Analysis. 49 | 50 | 51 | 52 | This will create a GitHub Actions Workflow file with CodeQL already set up. Since Python is an interpreted language you do not need to add any additional compile flags. See the [documentation](https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/running-codeql-code-scanning-in-your-ci-system) if you would like to configure CodeQL Analysis with a 3rd party CI system instead of using GitHub Actions. 53 |

54 |
55 | 56 |
57 | 58 | Actions Workflow file 59 |

60 | 61 | #### Actions Workflow 62 | 63 | The Actions Workflow file contains a number of different sections including: 64 | 1. Checking out the repository 65 | 2. Initializing the CodeQL Action 66 | 3. Running the CodeQL Analysis 67 | 68 | 69 | 70 | Click `Start Commit` -> `Commit this file` to commit the changes to _main_ branch. 71 |

72 |
73 | 74 |
75 | 76 | Workflow triggers 77 |

78 | 79 | #### Workflow triggers 80 | 81 | There are a [number of events](https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows) that can trigger a GitHub Actions workflow. In this example, the workflow will be triggered on 82 | 83 | 84 | 85 | - push to _main_ branch 86 | - pull request to merge to _main_ branch 87 | - on schedule, at 6:33 every Thursday 88 | 89 | Setting up the new CodeQL workflow and committing it to _main_ branch in the step above will trigger the scan. 90 | 91 |

92 |
93 | 94 | 95 |
96 | GitHub Actions Progress 97 | 98 |

99 | 100 | #### GitHub Actions Progress 101 | 102 | Click `Actions` tab -> `CodeQL` 103 | 104 | Click the specific workflow run. You can view the progress of the Workflow run until the analysis completes. 105 | 106 | 107 | 108 |

109 |
110 | 111 |
112 | Security Issues 113 |

114 | 115 | Once the Workflow has completed, click the `Security` tab -> ` Code Scanning Alerts`. An security alert "Query built from user-controlled sources" should be visible. 116 | 117 | #### Security Alert View 118 | 119 | Clicking on the security alert will provide details about the security alert including:
120 |

126 | 127 | 128 | #### Security Alert Description 129 | 130 | Click `Show more` to view a full desciption of the alert including examples and links to additional information. 131 | 132 | 133 | 134 | #### Security Full Description 135 | 136 | 137 | 138 |

139 |
140 | 141 |
142 | Show Paths 143 |

144 | 145 | #### Show Paths Button 146 | 147 | CodeQL Analysis is able to trace the dataflow path from source to sink and gives you the ability to view the path traversal within the alert. 148 | 149 | Click `show paths` in order to see the dataflow path that resulted in this alert. 150 | 151 | 152 | 153 | #### Show Paths View 154 | 155 | 156 | 157 |

158 |
159 | 160 |
161 |

162 | 163 |

Fix the Security Alert 164 | 165 | In order to fix this specific alert, we will need to ensure parameters used in the SQL query is validated and sanitized. 166 | 167 | Click on the `Code` tab and [Edit](https://docs.github.com/en/free-pro-team@latest/github/managing-files-in-a-repository/editing-files-in-your-repository) the file [`routes.py`](./server/routes.py) in the `server` folder, replace the content with the file [`fixme`](./fixme). 168 | 169 | 170 | 171 | Click `Create a new branch for this commit and start a pull request`, name the branch `fix-sql-injection`, and create the Pull Request. 172 | 173 | #### Pull Request Status Check 174 | 175 | In the Pull Request, you will notice that the CodeQL Analysis has started as a status check. Wait until it completes. 176 | 177 | 178 | 179 | #### Security Alert Details 180 | 181 | After the Workflow has completed click on `Details` by the `Code Scanning Results / CodeQL` status check. 182 | 183 | 184 | 185 | #### Fixed Alert 186 | 187 | Notice that Code Scanning has detected that this Pull Request will fix the SQL injection vulnerability that was detected before. 188 | 189 | 190 | 191 | Merge the Pull Request. After the Pull Request has been merged, another Workflow will kick off to scan the repository for any vulnerabilties. 192 | 193 | #### Closed Security Alerts 194 | 195 | After the final Workflow has completed, navigate back to the `Security` tab and click `Closed`. Notice that the **Query built from user-controlled sources** security alert now shows up as a closed issue. 196 | 197 | 198 | 199 | #### Traceability 200 | 201 | Click on the security alert and notice that it details when the fix was made, by whom, and the specific commit. This provides full traceability to detail when and how a security alert was fixed and exactly what was changed to remediate the issue. 202 | 203 | 204 | 205 |

206 |
207 | 208 |
209 | Introduce a Security Vulnerability in a PR 210 |

211 | 212 | Now let's explore the typical developer view when introducing a vulnerability. 213 | 214 | A branch called `new-feature` introduces a new feature but also security vulnerabilities. Open a Pull Request comparing `new-feature` to `main`: 215 | 216 | 1. Go to the Pull Request tab 217 | 2. Select "New Pull Request" 218 | 3. Create the PR with 219 | - `base repository: ` 220 | - `head repository: ` 221 | - `base: main` 222 | - `compare: new-feature` 223 | 4. _If you don't see the `new-feature` branch, change the `head repository: octodemo/advanced-security-python`_ 224 | 225 | 226 | 227 | #### Pull Request Status Check 228 | 229 | In the Pull Request, you will notice that the CodeQL Analysis has started as a status check again. Wait until it completes. 230 | 231 | #### Security Alert Details 232 | 233 | After the Workflow has completed click on `Details` by the `Code Scanning Results / CodeQL` status check. 234 | 235 | #### Security Alert 236 | 237 | Notice that Code Scanning has detected that this Pull Request will introduce 2 medium-severity vulnerabilties 238 | 239 | 240 | 241 | #### 'Files Changed' tab 242 | 243 | Click on the "Files Changed" tab of the PR. Scroll down and notice the Advanced Security annotations for new vulnerabilities. 244 | 245 | You have the ability to dismiss, dive deeper into, or comment on these alerts directly from here. 246 | 247 | 248 | 249 | As a developer, this is where you would be interacting with Code Scanning 250 | 251 |

252 | 253 | ## Next Steps 254 | 255 | Ready to talk about advanced security features for GitHub Enterprise? [Contact Sales](https://enterprise.github.com/contact) for more information! 256 | 257 | Check out [GitHub's Security feature page](https://github.com/features/security) for more security features embedded into GitHub. 258 | 259 | Check out the Code Scanning [documentation](https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/about-code-scanning) for additional configuration options and technical details. 260 | 261 | -------------------------------------------------------------------------------- /fixme: -------------------------------------------------------------------------------- 1 | 2 | from flask import request, render_template, make_response 3 | 4 | from server.webapp import flaskapp, cursor 5 | from server.models import Book 6 | 7 | 8 | @flaskapp.route('/') 9 | def index(): 10 | name = request.args.get('name') 11 | author = request.args.get('author') 12 | read = bool(request.args.get('read')) 13 | 14 | if name: 15 | cursor.execute( 16 | "SELECT * FROM books WHERE name LIKE :name", {'name': f"%{name}%"} 17 | ) 18 | books = [Book(*row) for row in cursor] 19 | 20 | elif author: 21 | cursor.execute( 22 | "SELECT * FROM books WHERE author LIKE :author", {'author': f"%{author}%"} 23 | ) 24 | books = [Book(*row) for row in cursor] 25 | 26 | else: 27 | cursor.execute("SELECT name, author, read FROM books") 28 | books = [Book(*row) for row in cursor] 29 | 30 | return render_template('books.html', books=books) 31 | -------------------------------------------------------------------------------- /images/00-repo-security-tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/00-repo-security-tab.png -------------------------------------------------------------------------------- /images/01-repo-secruity-setup-code-scanning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/01-repo-secruity-setup-code-scanning.png -------------------------------------------------------------------------------- /images/02-repo-security-setup-codeql-workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/02-repo-security-setup-codeql-workflow.png -------------------------------------------------------------------------------- /images/03-actions-sample-workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/03-actions-sample-workflow.png -------------------------------------------------------------------------------- /images/04-actions-sample-events.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/04-actions-sample-events.png -------------------------------------------------------------------------------- /images/05-actions-completed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/05-actions-completed.png -------------------------------------------------------------------------------- /images/06-security-codeql-alert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/06-security-codeql-alert.png -------------------------------------------------------------------------------- /images/07-security-codeql-show-more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/07-security-codeql-show-more.png -------------------------------------------------------------------------------- /images/08-security-codeql-full-desc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/08-security-codeql-full-desc.png -------------------------------------------------------------------------------- /images/09-security-codeql-show-paths.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/09-security-codeql-show-paths.png -------------------------------------------------------------------------------- /images/10-security-codeql-show-paths-details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/10-security-codeql-show-paths-details.png -------------------------------------------------------------------------------- /images/11-fix-source-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/11-fix-source-code.png -------------------------------------------------------------------------------- /images/12-fix-pr-in-progress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/12-fix-pr-in-progress.png -------------------------------------------------------------------------------- /images/13-fix-pr-done.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/13-fix-pr-done.png -------------------------------------------------------------------------------- /images/14-fix-detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/14-fix-detail.png -------------------------------------------------------------------------------- /images/15-fixed-alert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/15-fixed-alert.png -------------------------------------------------------------------------------- /images/16-fix-history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/16-fix-history.png -------------------------------------------------------------------------------- /images/17-fork-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/17-fork-repo.png -------------------------------------------------------------------------------- /images/18-create-vulnerable-pr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/18-create-vulnerable-pr.png -------------------------------------------------------------------------------- /images/19-vulnerabiltliy-detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/19-vulnerabiltliy-detail.png -------------------------------------------------------------------------------- /images/20-files-changed-vulnerabilities.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/images/20-files-changed-vulnerabilities.png -------------------------------------------------------------------------------- /server/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advanced-security-demo/demo-python/99e8b31393827eb51e2442a5e539d594a1772b4d/server/__init__.py -------------------------------------------------------------------------------- /server/__main__.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append('.') 4 | 5 | from server.webapp import flaskapp, database, cursor, TEMPLATES 6 | from server.models import * 7 | from server.routes import * 8 | 9 | default_books = [ 10 | ("The Hobbit", "JRR Tolkien", True), 11 | ("The Fellowship of the Ring", "JRR Tolkien", True), 12 | ("The Eye of the World", "Robert Jordan", False), 13 | ("A Game of Thrones", "George R. R. Martin", True), 14 | ("The Way of Kings", "Brandon Sanderson", False) 15 | ] 16 | 17 | env_token = "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" 18 | 19 | 20 | if __name__ == "__main__": 21 | cursor.execute( 22 | '''CREATE TABLE books (name text, author text, read text)''' 23 | ) 24 | 25 | for bookname, bookauthor, hasread in default_books: 26 | try: 27 | cursor.execute( 28 | 'INSERT INTO books values (?, ?, ?)', 29 | (bookname, bookauthor, 'true' if hasread else 'false') 30 | ) 31 | 32 | except Exception as err: 33 | print(f'[!] Error Occurred: {err}') 34 | 35 | flaskapp.run('0.0.0.0', debug=bool(os.environ.get('DEBUG', False))) 36 | 37 | cursor.close() 38 | database.close() 39 | -------------------------------------------------------------------------------- /server/models/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from server.models.books import Book 3 | -------------------------------------------------------------------------------- /server/models/books.py: -------------------------------------------------------------------------------- 1 | 2 | from dataclasses import dataclass 3 | 4 | @dataclass 5 | class Book(): 6 | name: str 7 | author: str 8 | read: bool 9 | -------------------------------------------------------------------------------- /server/routes.py: -------------------------------------------------------------------------------- 1 | 2 | from flask import request, render_template, make_response 3 | 4 | from server.webapp import flaskapp, cursor 5 | from server.models import Book 6 | 7 | 8 | @flaskapp.route('/') 9 | def index(): 10 | name = request.args.get('name') 11 | author = request.args.get('author') 12 | read = bool(request.args.get('read')) 13 | 14 | if name: 15 | cursor.execute( 16 | "SELECT * FROM books WHERE name LIKE '%" + name + "%'" 17 | ) 18 | books = [Book(*row) for row in cursor] 19 | 20 | elif author: 21 | cursor.execute( 22 | "SELECT * FROM books WHERE author LIKE '%" + author + "%'" 23 | ) 24 | books = [Book(*row) for row in cursor] 25 | 26 | else: 27 | cursor.execute("SELECT name, author, read FROM books") 28 | books = [Book(*row) for row in cursor] 29 | 30 | return render_template('books.html', books=books) 31 | -------------------------------------------------------------------------------- /server/webapp.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sqlite3 3 | 4 | from flask import Flask 5 | 6 | 7 | ROOT = os.path.dirname(os.path.abspath(os.path.dirname(__file__))) 8 | TEMPLATES = os.path.join(ROOT, 'templates') 9 | 10 | flaskapp = Flask("BookStore", template_folder=TEMPLATES) 11 | flaskapp.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False 12 | 13 | database_uri = os.environ.get('SQLITE_URI', ':memory:') 14 | 15 | database = sqlite3.connect(database_uri, check_same_thread=False) 16 | cursor = database.cursor() 17 | -------------------------------------------------------------------------------- /templates/books.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Book Store 5 | 6 | 7 |

Book Store

8 | 13 | 14 | --------------------------------------------------------------------------------