|
| 1 | +<p align="center"> |
| 2 | +<img src=".github/assets/capital-logo-white.PNG#center" width="600" height="300" /> |
| 3 | +</p> |
| 4 | + |
| 5 | +[](https://github.com/OWASP/API-Security) |
| 6 | +[](https://github.com/Checkmarx/capital#quickstart) |
| 7 | +[](https://opensource.org/licenses/AGPL-3.0) |
| 8 | + |
| 9 | +Quick facts |
| 10 | +---------- |
| 11 | + |
| 12 | + - **Name**: 'c{api}tal' |
| 13 | + - **Type**: Vulnerable API Security application |
| 14 | + - **Purpose**: Educational |
| 15 | + - **License**: GNU AFFERO GENERAL PUBLIC LICENSE |
| 16 | + - **Language**: Python, JS |
| 17 | + - **Author**: Checkmarx Research team |
| 18 | + |
| 19 | +Description |
| 20 | +---------- |
| 21 | +The Checkmarx research team created c{api}tal to provide users with an active playground in which they hone their API Security skills. <br> The c{api}tal application contains 10 API challenges which map to the <a href="https://owasp.org/www-project-api-security/" target="_blank">OWASP top 10 API risks</a>. <br> It is built with Python (FastAPI) and JS (React). |
| 22 | + |
| 23 | +c{api}tal can also be used for conducting your own API Security CTF event. |
| 24 | + |
| 25 | +Features: |
| 26 | +---------- |
| 27 | +Contains 10 challenges based on the <a href="https://owasp.org/www-project-api-security/" target="_blank">OWASP top 10 API risks</a> |
| 28 | + |
| 29 | +* Built on FastAPI (backend) and React (frontend) |
| 30 | +* UI - Blogging website (i.e medium) |
| 31 | +* OpenAPI3 API JSON specification file that can be imported as a POSTMAN collection |
| 32 | +* JWT token based authentication (lifetime can be adjusted in app) |
| 33 | + |
| 34 | + |
| 35 | +c{api}tal is a blogging application which allow users to register, create and delete posts, |
| 36 | +create and delete comments, follow other users, and more. |
| 37 | + |
| 38 | +<p align="center"> |
| 39 | +<img src="postman/API%20endpoints.PNG#center" width="1000" height="850" /> |
| 40 | +</p> |
| 41 | + |
| 42 | +# Quickstart |
| 43 | + |
| 44 | +Run the full application using docker-compose: |
| 45 | + |
| 46 | + docker-compose up -d |
| 47 | + |
| 48 | + |
| 49 | +The backend will be running on http://localhost:8000/ <br> |
| 50 | +The frontend will be running on http://localhost:4100/ <br> |
| 51 | +Check out the API endpoints specification page at http://localhost:8000/docs <br> |
| 52 | + |
| 53 | +Generate API requests to http://localhost:8000/api (via POSTMAN/Burp for example) <br> |
| 54 | +Import the API collection JSON file to POSTMAN and start generating API requests: <br> |
| 55 | +[click here to download the c{api}tal API json collection file](https://www.capital-ctf.com/files/de1ad03a48959f38c7f131f81f95d42e/capital.postman_collection.json) |
| 56 | + |
| 57 | +<p align="center"> |
| 58 | +<img src=".github/assets/postman%20-%20register%20user%20request.PNG#center" width="1000" height="300" /> |
| 59 | +</p> |
| 60 | + |
| 61 | +To run the web application in debug: |
| 62 | +---------- |
| 63 | + |
| 64 | +First, run ``PostgreSQL``, set environment variables and create database: |
| 65 | + |
| 66 | + export POSTGRES_DB=rwdb POSTGRES_PORT=5432 POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres |
| 67 | + docker run --name pgdb --rm -p 5432:5432 -e POSTGRES_USER="$POSTGRES_USER" -e POSTGRES_PASSWORD="$POSTGRES_PASSWORD" -e POSTGRES_DB="$POSTGRES_DB" postgres |
| 68 | + export POSTGRES_HOST=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' pgdb) |
| 69 | + createdb --host=$POSTGRES_HOST --port=$POSTGRES_PORT --username=$POSTGRES_USER $POSTGRES_DB |
| 70 | + |
| 71 | +[Option 1] Run locally |
| 72 | + |
| 73 | +Then run the following commands to bootstrap your environment: |
| 74 | + |
| 75 | + git clone https://github.com/Checkmarx/capital |
| 76 | + cd capital |
| 77 | + pip install -r requirements.txt |
| 78 | + |
| 79 | + |
| 80 | +Then create ``.env`` file in project root and set environment variables for application: |
| 81 | + |
| 82 | + export POSTGRES_DB=rwdb POSTGRES_PORT=5432 POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres |
| 83 | + export POSTGRES_HOST=localhost |
| 84 | + export DATABASE_URL=postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST:$POSTGRES_PORT/$POSTGRES_DB |
| 85 | + touch .env |
| 86 | + echo APP_ENV=dev |
| 87 | + echo DATABASE_URL=postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST:$POSTGRES_PORT/$POSTGRES_DB >> .env |
| 88 | + echo SECRET_KEY=$(openssl rand -hex 32) >> .env |
| 89 | + |
| 90 | +Then run the backend server: |
| 91 | + |
| 92 | + python3 |
| 93 | + .py |
| 94 | + |
| 95 | +[Option 2] Run backend using docker |
| 96 | +Run the backend using docker build: |
| 97 | + |
| 98 | + docker build . -t capital |
| 99 | + docker run -p 8000:8000 -e DATABASE_URL=postgresql://postgres:postgres@host.docker.internal:5432/rwdb --rm --name backend-capital capital |
| 100 | + |
| 101 | + |
| 102 | +Run tests |
| 103 | +--------- |
| 104 | + |
| 105 | +Tests for this project are defined in the ``tests/`` folder. |
| 106 | + |
| 107 | +Set up environment variable ``DATABASE_URL`` or set up ``database_url`` in ``app/core/settings/test.py`` |
| 108 | + |
| 109 | +This project uses `pytest |
| 110 | +<https://docs.pytest.org/>`_ to define tests because it allows you to use the ``assert`` keyword with good formatting for failed assertations. |
| 111 | + |
| 112 | + |
| 113 | +To run all the tests of a project, simply run the ``pytest`` command: :: |
| 114 | + |
| 115 | + $ pytest |
| 116 | + ================================================= test session starts ================================================== |
| 117 | + platform linux -- Python 3.8.3, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 |
| 118 | + rootdir: /home/some-user/user-projects/fastapi-realworld-example-app, inifile: setup.cfg, testpaths: tests |
| 119 | + plugins: env-0.6.2, cov-2.9.0, asyncio-0.12.0 |
| 120 | + collected 90 items |
| 121 | + |
| 122 | + tests/test_api/test_errors/test_422_error.py . [ 1%] |
| 123 | + tests/test_api/test_errors/test_error.py . [ 2%] |
| 124 | + tests/test_api/test_routes/test_articles.py ................................. [ 38%] |
| 125 | + tests/test_api/test_routes/test_authentication.py .. [ 41%] |
| 126 | + tests/test_api/test_routes/test_comments.py .... [ 45%] |
| 127 | + tests/test_api/test_routes/test_login.py ... [ 48%] |
| 128 | + tests/test_api/test_routes/test_profiles.py ............ [ 62%] |
| 129 | + tests/test_api/test_routes/test_registration.py ... [ 65%] |
| 130 | + tests/test_api/test_routes/test_tags.py .. [ 67%] |
| 131 | + tests/test_api/test_routes/test_users.py .................... [ 90%] |
| 132 | + tests/test_db/test_queries/test_tables.py ... [ 93%] |
| 133 | + tests/test_schemas/test_rw_model.py . [ 94%] |
| 134 | + tests/test_services/test_jwt.py ..... [100%] |
| 135 | + |
| 136 | + ============================================ 90 passed in 70.50s (0:01:10) ============================================= |
| 137 | + $ |
| 138 | + |
| 139 | +If you want to run a specific test, you can do this with `this |
| 140 | +<https://docs.pytest.org/en/latest/usage.html#specifying-tests-selecting-tests>`_ pytest feature: :: |
| 141 | + |
| 142 | + $ pytest tests/test_api/test_routes/test_users.py::test_user_can_not_take_already_used_credentials |
| 143 | + |
| 144 | +Web routes |
| 145 | +---------- |
| 146 | + |
| 147 | +All routes are available on ``/docs`` or ``/redoc`` paths with Swagger or ReDoc. |
| 148 | + |
| 149 | + |
| 150 | +Project structure |
| 151 | +----------------- |
| 152 | + |
| 153 | +Files related to application are in the ``app`` or ``tests`` directories. |
| 154 | +Application parts are: |
| 155 | + |
| 156 | + app |
| 157 | + ├── api - web related stuff. |
| 158 | + │ ├── dependencies - dependencies for routes definition. |
| 159 | + │ ├── errors - definition of error handlers. |
| 160 | + │ └── routes - web routes. |
| 161 | + ├── core - application configuration, startup events, logging. |
| 162 | + ├── db - db related stuff. |
| 163 | + │ ├── migrations - manually written alembic migrations. |
| 164 | + │ └── repositories - all crud stuff. |
| 165 | + ├── models - pydantic models for this application. |
| 166 | + │ ├── domain - main models that are used almost everywhere. |
| 167 | + │ └── schemas - schemas for using in web routes. |
| 168 | + ├── resources - strings that are used in web responses. |
| 169 | + ├── services - logic that is not just crud related. |
| 170 | + ├── credentials - list of common strings for Brute Force. |
| 171 | + ├── postman - api json file for postman. |
| 172 | + ├── redis - redis docker file and conf file. |
| 173 | + ├── scripts |
| 174 | + ├── tests |
| 175 | + └── main.py - FastAPI application creation and configuration. |
| 176 | + |
| 177 | +Presented At |
| 178 | +---------- |
| 179 | + |
| 180 | +[Blackhat Europe 2022 Arsenal](https://www.youtube.com/watch?v=OP4X8Sc8hMs) |
| 181 | + |
| 182 | +[AppSec village at DefCon30](https://www.appsecvillage.com/events/dc-2022/c%7Bapi%7Dtal-api-security-ctf) |
| 183 | + |
| 184 | +Write-ups & Referrences |
| 185 | +---------- |
| 186 | +[c{api}tal CTF event sum-up blog](https://checkmarx.com/blog/how-we-created-an-api-security-ctf) |
| 187 | + |
| 188 | +A great write-up by Maor Tal: <br> |
| 189 | +[Part 1](https://medium.com/@maor_59001/defcon-30-appsec-villiage-ctf-writeup-part-1-1730de791f50) <br> |
| 190 | +[Part 2](https://medium.com/@maor_59001/defcon-30-c-api-tal-ctf-writeup-part-2-ef99a0fc8d28) |
| 191 | + |
| 192 | + |
| 193 | +Stickers from DefCon30: <br> |
| 194 | +<img src=".github/assets/sticker1.png" width="300" height="150" /> |
| 195 | +<img src=".github/assets/sticker2.png" width="300" height="150" /> |
| 196 | +<img src=".github/assets/sticker3.jpeg" width="300" height="150" /> |
| 197 | + |
| 198 | + |
| 199 | +Development and Bugs |
| 200 | +---------- |
| 201 | +Found an issue, or have a great idea? Let us know: |
| 202 | + |
| 203 | +* E-mail - capital@checkmarx.com |
| 204 | + |
| 205 | +Contributions are appreciated and can be done via GitHub. |
| 206 | + |
| 207 | +See CONTRIBUTING.md for more information about how to submit them. |
| 208 | + |
| 209 | +Thanks |
| 210 | +---------- |
| 211 | + |
| 212 | +This project was created at Checkmarx by [Ravid Mazon](https://www.linkedin.com/in/ravid-mazon) with the help of these great contributors: |
| 213 | +[Liad Levy](https://www.linkedin.com/in/liad-levy-93b235211/), |
| 214 | +[Yaniv Nizry](https://www.linkedin.com/in/yaniv-n-8b4a76193/), |
| 215 | +[Guy Lyuboshits](https://www.linkedin.com/in/guy-lyuboshits-075175165/) |
| 216 | + |
| 217 | +The application was built base on ``real-world-app`` , we used these awesome repos: <br> |
| 218 | +<a href="https://github.com/nsidnev/fastapi-realworld-example-app" target="_blank">Backend - FastAPI (Python)</a> <br> |
| 219 | +<a href="https://github.com/khaledosman/react-redux-realworld-example-app" target="_blank">Frontend - React (JS)</a> <br> |
| 220 | +Thanks again for contributing to the open-source community! <br> |
0 commit comments