├── .flake8
├── .github
└── workflows
│ └── pylint.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .pylintrc
├── .ruff.toml
├── .vscode
└── settings.json
├── CITATION.cff
├── LICENSE
├── README.md
├── github.db
├── pics
├── db.png
├── demo.png
├── demo2.png
└── warning1.png
├── requirements.txt
└── src
├── configs.py
├── main.py
├── manager.py
└── utils.py
/.flake8:
--------------------------------------------------------------------------------
1 | [flake8]
2 | ignore = E501, E203
3 | max-line-length = 200
4 |
--------------------------------------------------------------------------------
/.github/workflows/pylint.yml:
--------------------------------------------------------------------------------
1 | name: Pylint
2 |
3 | on: [push]
4 |
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 | strategy:
9 | matrix:
10 | python-version: ["3.12"]
11 | steps:
12 | - uses: actions/checkout@v4
13 | - name: Set up Python ${{ matrix.python-version }}
14 | uses: actions/setup-python@v3
15 | with:
16 | python-version: ${{ matrix.python-version }}
17 | - name: Install dependencies
18 | run: |
19 | python -m pip install --upgrade pip
20 | pip install pylint
21 | - name: Analysing the code with pylint
22 | run: |
23 | pylint $(git ls-files '*.py')
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | cookies.pkl
7 | .progress.txt
8 | # C extensions
9 | *.so
10 |
11 | # Distribution / packaging
12 | .Python
13 | build/
14 | develop-eggs/
15 | dist/
16 | downloads/
17 | eggs/
18 | .eggs/
19 | lib/
20 | lib64/
21 | parts/
22 | sdist/
23 | var/
24 | wheels/
25 | share/python-wheels/
26 | *.egg-info/
27 | .installed.cfg
28 | *.egg
29 | MANIFEST
30 |
31 | # PyInstaller
32 | # Usually these files are written by a python script from a template
33 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
34 | *.manifest
35 | *.spec
36 |
37 | # Installer logs
38 | pip-log.txt
39 | pip-delete-this-directory.txt
40 |
41 | # Unit test / coverage reports
42 | htmlcov/
43 | .tox/
44 | .nox/
45 | .coverage
46 | .coverage.*
47 | .cache
48 | nosetests.xml
49 | coverage.xml
50 | *.cover
51 | *.py,cover
52 | .hypothesis/
53 | .pytest_cache/
54 | cover/
55 |
56 | # Translations
57 | *.mo
58 | *.pot
59 |
60 | # Django stuff:
61 | *.log
62 | local_settings.py
63 | db.sqlite3
64 | db.sqlite3-journal
65 |
66 | # Flask stuff:
67 | instance/
68 | .webassets-cache
69 |
70 | # Scrapy stuff:
71 | .scrapy
72 |
73 | # Sphinx documentation
74 | docs/_build/
75 |
76 | # PyBuilder
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 | # For a library or package, you might want to ignore these files since the code is
89 | # intended to run in multiple environments; otherwise, check them in:
90 | # .python-version
91 |
92 | # pipenv
93 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
94 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
95 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
96 | # install all needed dependencies.
97 | #Pipfile.lock
98 |
99 | # poetry
100 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
101 | # This is especially recommended for binary packages to ensure reproducibility, and is more
102 | # commonly ignored for libraries.
103 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
104 | #poetry.lock
105 |
106 | # pdm
107 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
108 | #pdm.lock
109 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
110 | # in version control.
111 | # https://pdm.fming.dev/#use-with-ide
112 | .pdm.toml
113 |
114 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
115 | __pypackages__/
116 |
117 | # Celery stuff
118 | celerybeat-schedule
119 | celerybeat.pid
120 |
121 | # SageMath parsed files
122 | *.sage.py
123 |
124 | # Environments
125 | .env
126 | .venv
127 | env/
128 | venv/
129 | ENV/
130 | env.bak/
131 | venv.bak/
132 |
133 | # Spyder project settings
134 | .spyderproject
135 | .spyproject
136 |
137 | # Rope project settings
138 | .ropeproject
139 |
140 | # mkdocs documentation
141 | /site
142 |
143 | # mypy
144 | .mypy_cache/
145 | .dmypy.json
146 | dmypy.json
147 |
148 | # Pyre type checker
149 | .pyre/
150 |
151 | # pytype static type analyzer
152 | .pytype/
153 |
154 | # Cython debug symbols
155 | cython_debug/
156 |
157 | # PyCharm
158 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
159 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
160 | # and can be added to the global gitignore or merged into this file. For a more nuclear
161 | # option (not recommended) you can uncomment the following to ignore the entire idea folder.
162 | #.idea/
163 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | # See https://pre-commit.com for more information
2 | # See https://pre-commit.com/hooks.html for more hooks
3 | repos:
4 | - repo: https://github.com/PyCQA/isort
5 | rev: 5.13.2
6 | hooks:
7 | - id: isort
8 | args: [--profile, black]
9 |
10 | # Using this mirror lets us use mypyc-compiled black, which is about 2x faster
11 | - repo: https://github.com/psf/black-pre-commit-mirror
12 | rev: 24.4.2
13 | hooks:
14 | - id:
15 | black
16 | # It is recommended to specify the latest version of Python
17 | # supported by your project here, or alternatively use
18 | # pre-commit's default_language_version, see
19 | # https://pre-commit.com/#top_level-default_language_version
20 | language_version: python3.12
21 | args: ["--line-length", "200", "--exclude", "migrations/"]
22 |
23 | - repo: https://github.com/astral-sh/ruff-pre-commit
24 | rev: v0.0.285
25 | hooks:
26 | - id: ruff
27 | alias: autoformat
28 | args: [--fix]
29 |
30 | - repo: https://github.com/pycqa/flake8
31 | rev: 7.1.0
32 | hooks:
33 | - id: flake8
34 | exclude: ^tests/(data|examples)/
35 |
36 | - repo: https://github.com/pre-commit/mirrors-mypy
37 | rev: v1.10.1
38 | hooks:
39 | - id: mypy
40 | args: [--ignore-missing-imports, --no-namespace-packages]
41 |
42 | - repo: https://github.com/pre-commit/pre-commit-hooks
43 | rev: v3.2.0
44 | hooks:
45 | - id: trailing-whitespace
46 | - id: end-of-file-fixer
47 | - id: check-yaml
48 | - id: check-added-large-files
49 |
--------------------------------------------------------------------------------
/.pylintrc:
--------------------------------------------------------------------------------
1 | [FORMAT]
2 | max-line-length=200
3 |
4 | [MASTER]
5 | extension-pkg-whitelist=tqdm,selenium,rich,openai
6 |
7 | [TYPECHECK]
8 | ignored-modules=tqdm,selenium,rich,openai
9 |
--------------------------------------------------------------------------------
/.ruff.toml:
--------------------------------------------------------------------------------
1 | # Exclude a variety of commonly ignored directories.
2 | exclude = [
3 | ".bzr",
4 | ".direnv",
5 | ".eggs",
6 | ".git",
7 | ".git-rewrite",
8 | ".hg",
9 | ".ipynb_checkpoints",
10 | ".mypy_cache",
11 | ".nox",
12 | ".pants.d",
13 | ".pyenv",
14 | ".pytest_cache",
15 | ".pytype",
16 | ".ruff_cache",
17 | ".svn",
18 | ".tox",
19 | ".venv",
20 | ".vscode",
21 | "__pypackages__",
22 | "_build",
23 | "buck-out",
24 | "build",
25 | "dist",
26 | "node_modules",
27 | "site-packages",
28 | "venv",
29 | ]
30 |
31 | line-length = 200
32 | target-version = "py312"
33 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "black-formatter.args": [
3 | "--line-length",
4 | "200"
5 | ]
6 | }
--------------------------------------------------------------------------------
/CITATION.cff:
--------------------------------------------------------------------------------
1 | cff-version: 1.2.0
2 | message: "If you use this software, please cite it as below."
3 | authors:
4 | - family-names: "Hou"
5 | given-names: "Junyi"
6 | orcid: "https://orcid.org/0009-0003-0443-456X"
7 |
8 | title: "ChatGPT-API-Leakage"
9 | version: 1.5
10 | # doi: 10.5281/zenodo.1234
11 | date-released: 2024-02-21
12 | url: "https://github.com/Junyi-99/ChatGPT-API-Leakage"
13 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Junyi
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.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ChatGPT-API-Scanner
2 |
3 | This tool scans GitHub for available OpenAI API Keys.
4 |
5 | 
6 |
7 | > [!NOTE]
8 | > As of `August 21, 2024`, GitHub has enabled push protection to prevent API key leakage, which could significantly impact this repository.
9 |
10 | > [!NOTE]
11 | > As of `March 11, 2024`, secret scanning and push protection will be enabled by default for all new user-owned public repositories that you create.
12 | > Check this announcement [here](https://docs.github.com/en/code-security/getting-started/quickstart-for-securing-your-repository).
13 |
14 | > [!WARNING]
15 | > **⚠️ DISCLAIMER**
16 | >
17 | > THIS PROJECT IS ONLY FOR ***SECURITY RESEARCH*** AND REMINDS OTHERS TO PROTECT THEIR PROPERTY, DO NOT USE IT ILLEGALLY!!
18 | >
19 | > The project authors are not responsible for any consequences resulting from misuse.
20 |
21 | ## Keeping Your API Key Safe
22 |
23 | It's important to keep it safe to prevent unauthorized access. Here are some useful resources:
24 |
25 | - [Best Practices for API Key Safety](https://help.openai.com/en/articles/5112595-best-practices-for-api-key-safety)
26 |
27 | - [My API is getting leaked.. need advice!](https://community.openai.com/t/my-api-is-getting-leaked-need-advice/280564)
28 |
29 | - [My OpenAI API Key Leaked! What Should I Do?](https://www.gitguardian.com/remediation/openai-key)
30 |
31 | ## Prerequisites
32 |
33 | This project has been tested and works perfectly on macOS, Windows and WSL2 (see [Run Linux GUI apps on the Windows Subsystem for Linux](https://learn.microsoft.com/en-us/windows/wsl/tutorials/gui-apps))
34 |
35 | Ensure you have the following installed on your system:
36 |
37 | - Google Chrome
38 | - Python3
39 |
40 | ## Installation
41 |
42 | 1. Clone the repository:
43 |
44 | ```bash
45 | git clone https://github.com/Junyi-99/ChatGPT-API-Leakage
46 |
47 | cd ChatGPT-API-Leakage
48 | ```
49 |
50 | 2. Install required pypi packages
51 |
52 | ```bash
53 | pip install selenium tqdm openai rich
54 | ```
55 |
56 | ## Usage
57 |
58 | 1. Run the main script:
59 |
60 | ```bash
61 | python3 src/main.py
62 | ```
63 |
64 | 2. You will be prompted to log in to your GitHub account in the browser. Please do so.
65 |
66 | That's it! The script will now scan GitHub for available OpenAI API Keys.
67 |
68 | ## Command Line Arguments
69 |
70 | The script supports several command line arguments for customization:
71 |
72 | | Parameter | Description | Default |
73 | |-----------|-------------|---------|
74 | | `--from-iter` | Start scanning from a specific iteration | `None` |
75 | | `--debug` | Enable debug mode for detailed logging | `False` |
76 | | `-ceko, --check-existed-keys-only` | Only check existing keys in the database | `False` |
77 | | `-k, --keywords` | Specify a list of search keywords | Default keyword list |
78 | | `-l, --languages` | Specify a list of programming languages to search | Default language list |
79 |
80 | Examples:
81 |
82 | ```bash
83 | # Start scanning from iteration 100
84 | python3 src/main.py --from-iter 100
85 |
86 | # Only check existing keys
87 | python3 src/main.py --check-existed-keys-only
88 |
89 | # Use custom keywords and languages
90 | python3 src/main.py -k "openai" "chatgpt" -l python javascript
91 | ```
92 |
93 | ## Results
94 |
95 | The results are stored in the `github.db` SQLite database, which is created in the same directory as the script.
96 |
97 | You can view the contents of this database using any SQLite database browser of your choice.
98 |
99 |
100 |
103 |
104 | Running Demo
105 |
106 |
107 |
108 |
109 |
112 |
113 | Result stored in SQLite (different API Key status)
114 |
115 |
116 |
117 | ## FAQ
118 |
119 | **Q: Why are you using Selenium instead of the GitHub Search API?**
120 |
121 | A: The official GitHub search API does not support regex search. Only web-based search does.
122 |
123 | **Q: Why are you limiting the programming language in the search instead of searching all languages?**
124 |
125 | A: The web-based search only provides the first 5 pages of results. There are many API keys available. By limiting the language, we can break down the search results and obtain more keys.
126 |
127 | **Q: Why don't you use multithreading?**
128 |
129 | A: Because GitHub searches and OpenAI are rate-limited. Using multithreading does not significantly increase efficiency.
130 |
131 | **Q: Why is the API Key provided in your repository not working?**
132 |
133 | A: The screenshots in this repo demonstrate the tool's ability to scan for available API keys. However, these keys may expire within hours or days. Please use the tool to scan for your own keys instead of relying on the provided examples.
134 |
135 | **Q: What's the push protection?**
136 |
137 | A: see picture.
138 |
139 |