pywebguard 0.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pywebguard-0.0.0/LICENSE +21 -0
- pywebguard-0.0.0/PKG-INFO +319 -0
- pywebguard-0.0.0/README.md +280 -0
- pywebguard-0.0.0/pywebguard/__init__.py +87 -0
- pywebguard-0.0.0/pywebguard/cli.py +1022 -0
- pywebguard-0.0.0/pywebguard/core/__init__.py +0 -0
- pywebguard-0.0.0/pywebguard/core/base.py +792 -0
- pywebguard-0.0.0/pywebguard/core/config.py +455 -0
- pywebguard-0.0.0/pywebguard/filters/__init__.py +0 -0
- pywebguard-0.0.0/pywebguard/filters/base.py +44 -0
- pywebguard-0.0.0/pywebguard/filters/ip_filter.py +233 -0
- pywebguard-0.0.0/pywebguard/filters/user_agent.py +102 -0
- pywebguard-0.0.0/pywebguard/frameworks/__init__.py +0 -0
- pywebguard-0.0.0/pywebguard/frameworks/_fastapi.py +191 -0
- pywebguard-0.0.0/pywebguard/frameworks/_flask.py +182 -0
- pywebguard-0.0.0/pywebguard/limiters/__init__.py +0 -0
- pywebguard-0.0.0/pywebguard/limiters/base.py +46 -0
- pywebguard-0.0.0/pywebguard/limiters/rate_limit.py +415 -0
- pywebguard-0.0.0/pywebguard/logging/__init__.py +0 -0
- pywebguard-0.0.0/pywebguard/logging/backends/__init__.py +17 -0
- pywebguard-0.0.0/pywebguard/logging/backends/_elasticsearch.py +307 -0
- pywebguard-0.0.0/pywebguard/logging/backends/_meilisearch.py +310 -0
- pywebguard-0.0.0/pywebguard/logging/backends/_mongodb.py +303 -0
- pywebguard-0.0.0/pywebguard/logging/base.py +117 -0
- pywebguard-0.0.0/pywebguard/logging/logger.py +408 -0
- pywebguard-0.0.0/pywebguard/security/__init__.py +0 -0
- pywebguard-0.0.0/pywebguard/security/base.py +44 -0
- pywebguard-0.0.0/pywebguard/security/cors.py +204 -0
- pywebguard-0.0.0/pywebguard/security/penetration.py +265 -0
- pywebguard-0.0.0/pywebguard/storage/__init__.py +0 -0
- pywebguard-0.0.0/pywebguard/storage/_mongodb.py +396 -0
- pywebguard-0.0.0/pywebguard/storage/_postgresql.py +539 -0
- pywebguard-0.0.0/pywebguard/storage/_redis.py +314 -0
- pywebguard-0.0.0/pywebguard/storage/_sqlite.py +374 -0
- pywebguard-0.0.0/pywebguard/storage/_tinydb.py +271 -0
- pywebguard-0.0.0/pywebguard/storage/base.py +327 -0
- pywebguard-0.0.0/pywebguard/storage/memory.py +245 -0
- pywebguard-0.0.0/pywebguard/utils/__init__.py +0 -0
- pywebguard-0.0.0/pywebguard/utils/ip.py +84 -0
- pywebguard-0.0.0/pywebguard/utils/request.py +65 -0
- pywebguard-0.0.0/pywebguard.egg-info/PKG-INFO +319 -0
- pywebguard-0.0.0/pywebguard.egg-info/SOURCES.txt +46 -0
- pywebguard-0.0.0/pywebguard.egg-info/dependency_links.txt +1 -0
- pywebguard-0.0.0/pywebguard.egg-info/entry_points.txt +2 -0
- pywebguard-0.0.0/pywebguard.egg-info/requires.txt +73 -0
- pywebguard-0.0.0/pywebguard.egg-info/top_level.txt +1 -0
- pywebguard-0.0.0/setup.cfg +4 -0
- pywebguard-0.0.0/setup.py +97 -0
pywebguard-0.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 py-daily
|
|
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.
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: pywebguard
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: A comprehensive security library for Python web applications
|
|
5
|
+
Home-page: https://github.com/py-daily/pywebguard
|
|
6
|
+
Author: py-daily
|
|
7
|
+
Author-email: mm@ktechhub.com
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Topic :: Security
|
|
21
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Requires-Python: >=3.8
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
Provides-Extra: fastapi
|
|
26
|
+
Provides-Extra: flask
|
|
27
|
+
Provides-Extra: redis
|
|
28
|
+
Provides-Extra: sqlite
|
|
29
|
+
Provides-Extra: tinydb
|
|
30
|
+
Provides-Extra: mongodb
|
|
31
|
+
Provides-Extra: postgresql
|
|
32
|
+
Provides-Extra: elasticsearch
|
|
33
|
+
Provides-Extra: all-storage
|
|
34
|
+
Provides-Extra: all-frameworks
|
|
35
|
+
Provides-Extra: all
|
|
36
|
+
Provides-Extra: dev
|
|
37
|
+
License-File: LICENSE
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
|
41
|
+
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
|
42
|
+
**Table of Contents** *generated with [DocToc](https://github.com/ktechhub/doctoc)*
|
|
43
|
+
|
|
44
|
+
<!---toc start-->
|
|
45
|
+
|
|
46
|
+
* [PyWebGuard](#pywebguard)
|
|
47
|
+
* [Key Features](#key-features)
|
|
48
|
+
* [Usage](#usage)
|
|
49
|
+
* [Installation](#installation)
|
|
50
|
+
* [Basic Installation](#basic-installation)
|
|
51
|
+
* [Storage Backends](#storage-backends)
|
|
52
|
+
* [Framework Support](#framework-support)
|
|
53
|
+
* [Search Engine Support](#search-engine-support)
|
|
54
|
+
* [Development Dependencies](#development-dependencies)
|
|
55
|
+
* [Full Installation](#full-installation)
|
|
56
|
+
* [Quick Start](#quick-start)
|
|
57
|
+
* [Documentation](#documentation)
|
|
58
|
+
* [Contributors](#contributors)
|
|
59
|
+
* [Contribution](#contribution)
|
|
60
|
+
* [License](#license)
|
|
61
|
+
|
|
62
|
+
<!---toc end-->
|
|
63
|
+
|
|
64
|
+
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
|
65
|
+
# PyWebGuard
|
|
66
|
+
<p align="center">
|
|
67
|
+
<a href="https://badge.fury.io/py/pywebguard"><img src="https://badge.fury.io/py/pywebguard.svg" alt="PyPI version"></a>
|
|
68
|
+
<a href="https://pypi.org/project/pywebguard/"><img src="https://img.shields.io/pypi/pyversions/pywebguard.svg" alt="Python Versions"></a>
|
|
69
|
+
<a href="https://github.com/py-daily/pywebguard/blob/main/LICENSE"><img src="https://img.shields.io/github/license/py-daily/pywebguard.svg" alt="License"></a>
|
|
70
|
+
<a href="#contributors-"><img src="https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square" alt="All Contributors"></a>
|
|
71
|
+
<a href="https://pepy.tech/project/pywebguard"><img src="https://pepy.tech/badge/pywebguard" alt="Downloads"></a>
|
|
72
|
+
</p>
|
|
73
|
+
|
|
74
|
+
<p align="center">
|
|
75
|
+
<img src="https://img.shields.io/badge/Python-3776AB.svg?style=flat&logo=Python&logoColor=white" alt="Python">
|
|
76
|
+
<img src="https://img.shields.io/badge/FastAPI-009688.svg?style=flat&logo=FastAPI&logoColor=white" alt="FastAPI">
|
|
77
|
+
<img src="https://img.shields.io/badge/Flask-000000.svg?style=flat&logo=Flask&logoColor=white" alt="Flask">
|
|
78
|
+
<img src="https://img.shields.io/badge/Docker-2496ED.svg?style=flat&logo=Docker&logoColor=white" alt="Docker">
|
|
79
|
+
<img src="https://img.shields.io/badge/Memory-4CAF50.svg?style=flat&logo=Memory&logoColor=white" alt="Memory">
|
|
80
|
+
<img src="https://img.shields.io/badge/Redis-FF4438.svg?style=flat&logo=Redis&logoColor=white" alt="Redis">
|
|
81
|
+
<img src="https://img.shields.io/badge/SQLite-003B57.svg?style=flat&logo=SQLite&logoColor=white" alt="SQLite">
|
|
82
|
+
<img src="https://img.shields.io/badge/TinyDB-000000.svg?style=flat&logo=TinyDB&logoColor=white" alt="TinyDB">
|
|
83
|
+
<img src="https://img.shields.io/badge/PostgreSQL-336791.svg?style=flat&logo=PostgreSQL&logoColor=white" alt="PostgreSQL">
|
|
84
|
+
<img src="https://img.shields.io/badge/MongoDB-47A248.svg?style=flat&logo=MongoDB&logoColor=white" alt="MongoDB">
|
|
85
|
+
<img src="https://img.shields.io/badge/Meilisearch-000000.svg?style=flat&logo=Meilisearch&logoColor=white" alt="Meilisearch">
|
|
86
|
+
<img src="https://img.shields.io/badge/Elasticsearch-005571.svg?style=flat&logo=Elasticsearch&logoColor=white" alt="Elasticsearch">
|
|
87
|
+
<img src="https://img.shields.io/badge/Pytest-0A9EDC.svg?style=flat&logo=Pytest&logoColor=white" alt="Pytest">
|
|
88
|
+
<img src="https://img.shields.io/badge/Pytest--Cov-0A9EDC.svg?style=flat&logo=Pytest&logoColor=white" alt="Pytest-Cov">
|
|
89
|
+
<img src="https://img.shields.io/badge/Black-000000.svg?style=flat&logo=Python&logoColor=white" alt="Black">
|
|
90
|
+
<img src="https://img.shields.io/badge/CORS-000000.svg?style=flat&logo=CORS&logoColor=white" alt="CORS">
|
|
91
|
+
<img src="https://img.shields.io/badge/GitHub_Actions-2088FF.svg?style=flat&logo=GitHub-Actions&logoColor=white" alt="GitHub Actions">
|
|
92
|
+
<img src="https://img.shields.io/badge/Telegram-26A5E4.svg?style=flat&logo=Telegram&logoColor=white" alt="Telegram">
|
|
93
|
+
</p>
|
|
94
|
+
|
|
95
|
+
A comprehensive security library for Python web applications, providing middleware for IP filtering, rate limiting, and other security features with both synchronous and asynchronous support.
|
|
96
|
+
|
|
97
|
+
For detailed installation instructions and configuration options, see [Installation Guide](https://github.com/py-daily/pywebguard/blob/main/docs/installation.md).
|
|
98
|
+
|
|
99
|
+
## Key Features
|
|
100
|
+
|
|
101
|
+
- **IP Whitelisting and Blacklisting**: Control access based on IP addresses
|
|
102
|
+
- **User Agent Filtering**: Block requests from specific user agents
|
|
103
|
+
- **Rate Limiting**: Limit the number of requests from a single IP
|
|
104
|
+
- **Per-Route Rate Limiting**: Set different rate limits for different endpoints
|
|
105
|
+
- **Bulk Configuration**: Configure rate limits for multiple routes at once
|
|
106
|
+
- **Pattern Matching**: Use wildcards to apply rate limits to groups of routes
|
|
107
|
+
- **Automatic IP Banning**: Automatically ban IPs after a certain number of suspicious requests
|
|
108
|
+
- **Penetration Attempt Detection**: Detect and log potential penetration attempts
|
|
109
|
+
- **Custom Logging**: Log security events to a custom file
|
|
110
|
+
- **CORS Configuration**: Configure CORS settings for your web application
|
|
111
|
+
- **IP Geolocation**: Determine the country of an IP address
|
|
112
|
+
- **Flexible Storage**: Redis-enabled distributed storage, nosql, sql or in-memory storage
|
|
113
|
+
- **Async/Sync Support**: Works with both synchronous (Flask) and asynchronous (FastAPI) frameworks
|
|
114
|
+
- **Logging Backends**: Configurable logging backends with current support for Meilisearch
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
## Usage
|
|
118
|
+
|
|
119
|
+
### Installation
|
|
120
|
+
|
|
121
|
+
PyWebGuard can be installed with various optional dependencies depending on your needs:
|
|
122
|
+
|
|
123
|
+
#### Basic Installation
|
|
124
|
+
```bash
|
|
125
|
+
pip install pywebguard
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### Storage Backends
|
|
129
|
+
```bash
|
|
130
|
+
pip install pywebguard[redis]
|
|
131
|
+
|
|
132
|
+
pip install pywebguard[sqlite]
|
|
133
|
+
|
|
134
|
+
pip install pywebguard[tinydb]
|
|
135
|
+
|
|
136
|
+
pip install pywebguard[mongodb]
|
|
137
|
+
|
|
138
|
+
pip install pywebguard[postgresql]
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
#### Framework Support
|
|
142
|
+
```bash
|
|
143
|
+
pip install pywebguard[flask]
|
|
144
|
+
|
|
145
|
+
pip install pywebguard[fastapi]
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### Search Engine Support
|
|
149
|
+
```bash
|
|
150
|
+
pip install pywebguard[meilisearch]
|
|
151
|
+
|
|
152
|
+
pip install pywebguard[elasticsearch]
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
#### Development Dependencies
|
|
156
|
+
```bash
|
|
157
|
+
pip install pywebguard[test]
|
|
158
|
+
|
|
159
|
+
pip install pywebguard[format]
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
#### Full Installation
|
|
163
|
+
To install all optional dependencies:
|
|
164
|
+
```bash
|
|
165
|
+
pip install pywebguard[all]
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Quick Start
|
|
169
|
+
|
|
170
|
+
Here's a basic example using FastAPI:
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
from fastapi import FastAPI
|
|
174
|
+
from pywebguard import FastAPIGuard, GuardConfig
|
|
175
|
+
from pywebguard.storage.memory import AsyncMemoryStorage
|
|
176
|
+
|
|
177
|
+
app = FastAPI(
|
|
178
|
+
title="PyWebGuard FastAPI Example",
|
|
179
|
+
description="A comprehensive example of PyWebGuard integration with FastAPI",
|
|
180
|
+
version="1.0.0",
|
|
181
|
+
)
|
|
182
|
+
config = GuardConfig(
|
|
183
|
+
ip_filter={
|
|
184
|
+
"enabled": True,
|
|
185
|
+
"whitelist": ["127.0.0.1", "::1", "192.168.1.0/24"],
|
|
186
|
+
"blacklist": ["10.0.0.1", "172.16.0.0/16"],
|
|
187
|
+
},
|
|
188
|
+
rate_limit={
|
|
189
|
+
"enabled": True,
|
|
190
|
+
"requests_per_minute": 100,
|
|
191
|
+
"burst_size": 20,
|
|
192
|
+
"auto_ban_threshold": 200,
|
|
193
|
+
"auto_ban_duration": 3600, # 1 hour in seconds
|
|
194
|
+
},
|
|
195
|
+
user_agent={
|
|
196
|
+
"enabled": True,
|
|
197
|
+
"blocked_agents": ["curl", "wget", "Scrapy", "bot", "Bot"],
|
|
198
|
+
},
|
|
199
|
+
cors={
|
|
200
|
+
"enabled": True,
|
|
201
|
+
"allow_origins": ["http://localhost:3000", "https://example.com"],
|
|
202
|
+
"allow_methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
203
|
+
"allow_headers": ["Content-Type", "Authorization"],
|
|
204
|
+
"allow_credentials": True,
|
|
205
|
+
"max_age": 3600,
|
|
206
|
+
},
|
|
207
|
+
penetration={
|
|
208
|
+
"enabled": True,
|
|
209
|
+
"detect_sql_injection": True,
|
|
210
|
+
"detect_xss": True,
|
|
211
|
+
"detect_path_traversal": True,
|
|
212
|
+
"block_suspicious_requests": True,
|
|
213
|
+
},
|
|
214
|
+
logging={
|
|
215
|
+
"enabled": True,
|
|
216
|
+
"level": "DEBUG", # Change to DEBUG to see all messages
|
|
217
|
+
"log_blocked_requests": True,
|
|
218
|
+
"stream": True,
|
|
219
|
+
"stream_levels": ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
|
|
220
|
+
"meilisearch": {
|
|
221
|
+
"url": "https://meilisearch.dev.ktechhub.com",
|
|
222
|
+
"api_key": os.getenv("MEILISEARCH_API_KEY"),
|
|
223
|
+
"index_name": "pywebguard",
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
route_rate_limits = [
|
|
229
|
+
{
|
|
230
|
+
"endpoint": "/api/limited",
|
|
231
|
+
"requests_per_minute": 5,
|
|
232
|
+
"burst_size": 2,
|
|
233
|
+
"auto_ban_threshold": 10,
|
|
234
|
+
"auto_ban_duration": 1800, # 30 minutes
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"endpoint": "/api/uploads/*",
|
|
238
|
+
"requests_per_minute": 10,
|
|
239
|
+
"burst_size": 5,
|
|
240
|
+
"auto_ban_duration": 1800,
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"endpoint": "/api/admin/**",
|
|
244
|
+
"requests_per_minute": 20,
|
|
245
|
+
"burst_size": 5,
|
|
246
|
+
"auto_ban_threshold": 50,
|
|
247
|
+
"auto_ban_duration": 7200, # 2 hours
|
|
248
|
+
},
|
|
249
|
+
]
|
|
250
|
+
|
|
251
|
+
storage = AsyncMemoryStorage()
|
|
252
|
+
|
|
253
|
+
app.add_middleware(
|
|
254
|
+
FastAPIGuard,
|
|
255
|
+
config=config,
|
|
256
|
+
storage=storage,
|
|
257
|
+
route_rate_limits=route_rate_limits,
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
@app.get("/", tags=["main"])
|
|
261
|
+
async def root():
|
|
262
|
+
"""Root endpoint with default rate limit (100 req/min)"""
|
|
263
|
+
return {"message": "Hello World - Default rate limit (100 req/min)"}
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
@app.get("/api/limited", tags=["main"])
|
|
267
|
+
async def limited_endpoint():
|
|
268
|
+
"""Strictly rate limited endpoint (5 req/min)"""
|
|
269
|
+
return {"message": "This endpoint is strictly rate limited (5 req/min)"}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
For more detailed examples, check the [examples](https://github.com/py-daily/pywebguard/tree/main/examples) folder.
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
## Documentation
|
|
276
|
+
- [Installation Guide](https://github.com/py-daily/pywebguard/blob/main/docs/installation.md)
|
|
277
|
+
- [CLI Usage](https://github.com/py-daily/pywebguard/blob/main/docs/cli.md)
|
|
278
|
+
- [Core Features](https://github.com/py-daily/pywebguard/blob/main/docs/core/)
|
|
279
|
+
- [Framework Integration](https://github.com/py-daily/pywebguard/blob/main/docs/frameworks/)
|
|
280
|
+
- [Storage Backends](https://github.com/py-daily/pywebguard/blob/main/docs/storage/)
|
|
281
|
+
|
|
282
|
+
## Contributors
|
|
283
|
+
|
|
284
|
+
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
|
285
|
+
<!-- prettier-ignore-start -->
|
|
286
|
+
<!-- markdownlint-disable -->
|
|
287
|
+
<table>
|
|
288
|
+
<tbody>
|
|
289
|
+
<tr>
|
|
290
|
+
<td align="center" valign="top" width="14.28%"><a href="https://www.ktechhub.com"><img src="https://avatars.githubusercontent.com/u/43080869?v=4?s=100" width="100px;" alt="Mumuni Mohammed"/><br /><sub><b>Mumuni Mohammed</b></sub></a><br /><a href="#projectManagement-Kalkulus1" title="Project Management">📆</a></td>
|
|
291
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hussein6065"><img src="https://avatars.githubusercontent.com/u/43960479?v=4?s=100" width="100px;" alt="Hussein Baba Fuseini"/><br /><sub><b>Hussein Baba Fuseini</b></sub></a><br /><a href="https://github.com/py-daily/pywebguard/commits?author=hussein6065" title="Documentation">📖</a></td>
|
|
292
|
+
</tr>
|
|
293
|
+
</tbody>
|
|
294
|
+
</table>
|
|
295
|
+
|
|
296
|
+
<!-- markdownlint-restore -->
|
|
297
|
+
<!-- prettier-ignore-end -->
|
|
298
|
+
|
|
299
|
+
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
|
300
|
+
|
|
301
|
+
## Contribution
|
|
302
|
+
|
|
303
|
+
We welcome contributions from the community! Whether it's bug reports, feature requests, or code contributions, every contribution helps make PyWebGuard better.
|
|
304
|
+
|
|
305
|
+
Please read our [Contribution Guidelines](https://github.com/py-daily/pywebguard/blob/main/contribution.md) before submitting any changes. This document provides detailed information about:
|
|
306
|
+
|
|
307
|
+
- How to set up your development environment
|
|
308
|
+
- Our coding standards and style guide
|
|
309
|
+
- The process for submitting pull requests
|
|
310
|
+
- How to report bugs and request features
|
|
311
|
+
- Our commit message conventions
|
|
312
|
+
- Testing requirements
|
|
313
|
+
|
|
314
|
+
Join our community and help make PyWebGuard even better! 🚀
|
|
315
|
+
|
|
316
|
+
## License
|
|
317
|
+
|
|
318
|
+
This project is licensed under the [MIT License](LICENSE).
|
|
319
|
+
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
|
2
|
+
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
|
3
|
+
**Table of Contents** *generated with [DocToc](https://github.com/ktechhub/doctoc)*
|
|
4
|
+
|
|
5
|
+
<!---toc start-->
|
|
6
|
+
|
|
7
|
+
* [PyWebGuard](#pywebguard)
|
|
8
|
+
* [Key Features](#key-features)
|
|
9
|
+
* [Usage](#usage)
|
|
10
|
+
* [Installation](#installation)
|
|
11
|
+
* [Basic Installation](#basic-installation)
|
|
12
|
+
* [Storage Backends](#storage-backends)
|
|
13
|
+
* [Framework Support](#framework-support)
|
|
14
|
+
* [Search Engine Support](#search-engine-support)
|
|
15
|
+
* [Development Dependencies](#development-dependencies)
|
|
16
|
+
* [Full Installation](#full-installation)
|
|
17
|
+
* [Quick Start](#quick-start)
|
|
18
|
+
* [Documentation](#documentation)
|
|
19
|
+
* [Contributors](#contributors)
|
|
20
|
+
* [Contribution](#contribution)
|
|
21
|
+
* [License](#license)
|
|
22
|
+
|
|
23
|
+
<!---toc end-->
|
|
24
|
+
|
|
25
|
+
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
|
26
|
+
# PyWebGuard
|
|
27
|
+
<p align="center">
|
|
28
|
+
<a href="https://badge.fury.io/py/pywebguard"><img src="https://badge.fury.io/py/pywebguard.svg" alt="PyPI version"></a>
|
|
29
|
+
<a href="https://pypi.org/project/pywebguard/"><img src="https://img.shields.io/pypi/pyversions/pywebguard.svg" alt="Python Versions"></a>
|
|
30
|
+
<a href="https://github.com/py-daily/pywebguard/blob/main/LICENSE"><img src="https://img.shields.io/github/license/py-daily/pywebguard.svg" alt="License"></a>
|
|
31
|
+
<a href="#contributors-"><img src="https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square" alt="All Contributors"></a>
|
|
32
|
+
<a href="https://pepy.tech/project/pywebguard"><img src="https://pepy.tech/badge/pywebguard" alt="Downloads"></a>
|
|
33
|
+
</p>
|
|
34
|
+
|
|
35
|
+
<p align="center">
|
|
36
|
+
<img src="https://img.shields.io/badge/Python-3776AB.svg?style=flat&logo=Python&logoColor=white" alt="Python">
|
|
37
|
+
<img src="https://img.shields.io/badge/FastAPI-009688.svg?style=flat&logo=FastAPI&logoColor=white" alt="FastAPI">
|
|
38
|
+
<img src="https://img.shields.io/badge/Flask-000000.svg?style=flat&logo=Flask&logoColor=white" alt="Flask">
|
|
39
|
+
<img src="https://img.shields.io/badge/Docker-2496ED.svg?style=flat&logo=Docker&logoColor=white" alt="Docker">
|
|
40
|
+
<img src="https://img.shields.io/badge/Memory-4CAF50.svg?style=flat&logo=Memory&logoColor=white" alt="Memory">
|
|
41
|
+
<img src="https://img.shields.io/badge/Redis-FF4438.svg?style=flat&logo=Redis&logoColor=white" alt="Redis">
|
|
42
|
+
<img src="https://img.shields.io/badge/SQLite-003B57.svg?style=flat&logo=SQLite&logoColor=white" alt="SQLite">
|
|
43
|
+
<img src="https://img.shields.io/badge/TinyDB-000000.svg?style=flat&logo=TinyDB&logoColor=white" alt="TinyDB">
|
|
44
|
+
<img src="https://img.shields.io/badge/PostgreSQL-336791.svg?style=flat&logo=PostgreSQL&logoColor=white" alt="PostgreSQL">
|
|
45
|
+
<img src="https://img.shields.io/badge/MongoDB-47A248.svg?style=flat&logo=MongoDB&logoColor=white" alt="MongoDB">
|
|
46
|
+
<img src="https://img.shields.io/badge/Meilisearch-000000.svg?style=flat&logo=Meilisearch&logoColor=white" alt="Meilisearch">
|
|
47
|
+
<img src="https://img.shields.io/badge/Elasticsearch-005571.svg?style=flat&logo=Elasticsearch&logoColor=white" alt="Elasticsearch">
|
|
48
|
+
<img src="https://img.shields.io/badge/Pytest-0A9EDC.svg?style=flat&logo=Pytest&logoColor=white" alt="Pytest">
|
|
49
|
+
<img src="https://img.shields.io/badge/Pytest--Cov-0A9EDC.svg?style=flat&logo=Pytest&logoColor=white" alt="Pytest-Cov">
|
|
50
|
+
<img src="https://img.shields.io/badge/Black-000000.svg?style=flat&logo=Python&logoColor=white" alt="Black">
|
|
51
|
+
<img src="https://img.shields.io/badge/CORS-000000.svg?style=flat&logo=CORS&logoColor=white" alt="CORS">
|
|
52
|
+
<img src="https://img.shields.io/badge/GitHub_Actions-2088FF.svg?style=flat&logo=GitHub-Actions&logoColor=white" alt="GitHub Actions">
|
|
53
|
+
<img src="https://img.shields.io/badge/Telegram-26A5E4.svg?style=flat&logo=Telegram&logoColor=white" alt="Telegram">
|
|
54
|
+
</p>
|
|
55
|
+
|
|
56
|
+
A comprehensive security library for Python web applications, providing middleware for IP filtering, rate limiting, and other security features with both synchronous and asynchronous support.
|
|
57
|
+
|
|
58
|
+
For detailed installation instructions and configuration options, see [Installation Guide](https://github.com/py-daily/pywebguard/blob/main/docs/installation.md).
|
|
59
|
+
|
|
60
|
+
## Key Features
|
|
61
|
+
|
|
62
|
+
- **IP Whitelisting and Blacklisting**: Control access based on IP addresses
|
|
63
|
+
- **User Agent Filtering**: Block requests from specific user agents
|
|
64
|
+
- **Rate Limiting**: Limit the number of requests from a single IP
|
|
65
|
+
- **Per-Route Rate Limiting**: Set different rate limits for different endpoints
|
|
66
|
+
- **Bulk Configuration**: Configure rate limits for multiple routes at once
|
|
67
|
+
- **Pattern Matching**: Use wildcards to apply rate limits to groups of routes
|
|
68
|
+
- **Automatic IP Banning**: Automatically ban IPs after a certain number of suspicious requests
|
|
69
|
+
- **Penetration Attempt Detection**: Detect and log potential penetration attempts
|
|
70
|
+
- **Custom Logging**: Log security events to a custom file
|
|
71
|
+
- **CORS Configuration**: Configure CORS settings for your web application
|
|
72
|
+
- **IP Geolocation**: Determine the country of an IP address
|
|
73
|
+
- **Flexible Storage**: Redis-enabled distributed storage, nosql, sql or in-memory storage
|
|
74
|
+
- **Async/Sync Support**: Works with both synchronous (Flask) and asynchronous (FastAPI) frameworks
|
|
75
|
+
- **Logging Backends**: Configurable logging backends with current support for Meilisearch
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
## Usage
|
|
79
|
+
|
|
80
|
+
### Installation
|
|
81
|
+
|
|
82
|
+
PyWebGuard can be installed with various optional dependencies depending on your needs:
|
|
83
|
+
|
|
84
|
+
#### Basic Installation
|
|
85
|
+
```bash
|
|
86
|
+
pip install pywebguard
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### Storage Backends
|
|
90
|
+
```bash
|
|
91
|
+
pip install pywebguard[redis]
|
|
92
|
+
|
|
93
|
+
pip install pywebguard[sqlite]
|
|
94
|
+
|
|
95
|
+
pip install pywebguard[tinydb]
|
|
96
|
+
|
|
97
|
+
pip install pywebguard[mongodb]
|
|
98
|
+
|
|
99
|
+
pip install pywebguard[postgresql]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
#### Framework Support
|
|
103
|
+
```bash
|
|
104
|
+
pip install pywebguard[flask]
|
|
105
|
+
|
|
106
|
+
pip install pywebguard[fastapi]
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
#### Search Engine Support
|
|
110
|
+
```bash
|
|
111
|
+
pip install pywebguard[meilisearch]
|
|
112
|
+
|
|
113
|
+
pip install pywebguard[elasticsearch]
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
#### Development Dependencies
|
|
117
|
+
```bash
|
|
118
|
+
pip install pywebguard[test]
|
|
119
|
+
|
|
120
|
+
pip install pywebguard[format]
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
#### Full Installation
|
|
124
|
+
To install all optional dependencies:
|
|
125
|
+
```bash
|
|
126
|
+
pip install pywebguard[all]
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Quick Start
|
|
130
|
+
|
|
131
|
+
Here's a basic example using FastAPI:
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from fastapi import FastAPI
|
|
135
|
+
from pywebguard import FastAPIGuard, GuardConfig
|
|
136
|
+
from pywebguard.storage.memory import AsyncMemoryStorage
|
|
137
|
+
|
|
138
|
+
app = FastAPI(
|
|
139
|
+
title="PyWebGuard FastAPI Example",
|
|
140
|
+
description="A comprehensive example of PyWebGuard integration with FastAPI",
|
|
141
|
+
version="1.0.0",
|
|
142
|
+
)
|
|
143
|
+
config = GuardConfig(
|
|
144
|
+
ip_filter={
|
|
145
|
+
"enabled": True,
|
|
146
|
+
"whitelist": ["127.0.0.1", "::1", "192.168.1.0/24"],
|
|
147
|
+
"blacklist": ["10.0.0.1", "172.16.0.0/16"],
|
|
148
|
+
},
|
|
149
|
+
rate_limit={
|
|
150
|
+
"enabled": True,
|
|
151
|
+
"requests_per_minute": 100,
|
|
152
|
+
"burst_size": 20,
|
|
153
|
+
"auto_ban_threshold": 200,
|
|
154
|
+
"auto_ban_duration": 3600, # 1 hour in seconds
|
|
155
|
+
},
|
|
156
|
+
user_agent={
|
|
157
|
+
"enabled": True,
|
|
158
|
+
"blocked_agents": ["curl", "wget", "Scrapy", "bot", "Bot"],
|
|
159
|
+
},
|
|
160
|
+
cors={
|
|
161
|
+
"enabled": True,
|
|
162
|
+
"allow_origins": ["http://localhost:3000", "https://example.com"],
|
|
163
|
+
"allow_methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
164
|
+
"allow_headers": ["Content-Type", "Authorization"],
|
|
165
|
+
"allow_credentials": True,
|
|
166
|
+
"max_age": 3600,
|
|
167
|
+
},
|
|
168
|
+
penetration={
|
|
169
|
+
"enabled": True,
|
|
170
|
+
"detect_sql_injection": True,
|
|
171
|
+
"detect_xss": True,
|
|
172
|
+
"detect_path_traversal": True,
|
|
173
|
+
"block_suspicious_requests": True,
|
|
174
|
+
},
|
|
175
|
+
logging={
|
|
176
|
+
"enabled": True,
|
|
177
|
+
"level": "DEBUG", # Change to DEBUG to see all messages
|
|
178
|
+
"log_blocked_requests": True,
|
|
179
|
+
"stream": True,
|
|
180
|
+
"stream_levels": ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
|
|
181
|
+
"meilisearch": {
|
|
182
|
+
"url": "https://meilisearch.dev.ktechhub.com",
|
|
183
|
+
"api_key": os.getenv("MEILISEARCH_API_KEY"),
|
|
184
|
+
"index_name": "pywebguard",
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
route_rate_limits = [
|
|
190
|
+
{
|
|
191
|
+
"endpoint": "/api/limited",
|
|
192
|
+
"requests_per_minute": 5,
|
|
193
|
+
"burst_size": 2,
|
|
194
|
+
"auto_ban_threshold": 10,
|
|
195
|
+
"auto_ban_duration": 1800, # 30 minutes
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"endpoint": "/api/uploads/*",
|
|
199
|
+
"requests_per_minute": 10,
|
|
200
|
+
"burst_size": 5,
|
|
201
|
+
"auto_ban_duration": 1800,
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"endpoint": "/api/admin/**",
|
|
205
|
+
"requests_per_minute": 20,
|
|
206
|
+
"burst_size": 5,
|
|
207
|
+
"auto_ban_threshold": 50,
|
|
208
|
+
"auto_ban_duration": 7200, # 2 hours
|
|
209
|
+
},
|
|
210
|
+
]
|
|
211
|
+
|
|
212
|
+
storage = AsyncMemoryStorage()
|
|
213
|
+
|
|
214
|
+
app.add_middleware(
|
|
215
|
+
FastAPIGuard,
|
|
216
|
+
config=config,
|
|
217
|
+
storage=storage,
|
|
218
|
+
route_rate_limits=route_rate_limits,
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
@app.get("/", tags=["main"])
|
|
222
|
+
async def root():
|
|
223
|
+
"""Root endpoint with default rate limit (100 req/min)"""
|
|
224
|
+
return {"message": "Hello World - Default rate limit (100 req/min)"}
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
@app.get("/api/limited", tags=["main"])
|
|
228
|
+
async def limited_endpoint():
|
|
229
|
+
"""Strictly rate limited endpoint (5 req/min)"""
|
|
230
|
+
return {"message": "This endpoint is strictly rate limited (5 req/min)"}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
For more detailed examples, check the [examples](https://github.com/py-daily/pywebguard/tree/main/examples) folder.
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
## Documentation
|
|
237
|
+
- [Installation Guide](https://github.com/py-daily/pywebguard/blob/main/docs/installation.md)
|
|
238
|
+
- [CLI Usage](https://github.com/py-daily/pywebguard/blob/main/docs/cli.md)
|
|
239
|
+
- [Core Features](https://github.com/py-daily/pywebguard/blob/main/docs/core/)
|
|
240
|
+
- [Framework Integration](https://github.com/py-daily/pywebguard/blob/main/docs/frameworks/)
|
|
241
|
+
- [Storage Backends](https://github.com/py-daily/pywebguard/blob/main/docs/storage/)
|
|
242
|
+
|
|
243
|
+
## Contributors
|
|
244
|
+
|
|
245
|
+
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
|
246
|
+
<!-- prettier-ignore-start -->
|
|
247
|
+
<!-- markdownlint-disable -->
|
|
248
|
+
<table>
|
|
249
|
+
<tbody>
|
|
250
|
+
<tr>
|
|
251
|
+
<td align="center" valign="top" width="14.28%"><a href="https://www.ktechhub.com"><img src="https://avatars.githubusercontent.com/u/43080869?v=4?s=100" width="100px;" alt="Mumuni Mohammed"/><br /><sub><b>Mumuni Mohammed</b></sub></a><br /><a href="#projectManagement-Kalkulus1" title="Project Management">📆</a></td>
|
|
252
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hussein6065"><img src="https://avatars.githubusercontent.com/u/43960479?v=4?s=100" width="100px;" alt="Hussein Baba Fuseini"/><br /><sub><b>Hussein Baba Fuseini</b></sub></a><br /><a href="https://github.com/py-daily/pywebguard/commits?author=hussein6065" title="Documentation">📖</a></td>
|
|
253
|
+
</tr>
|
|
254
|
+
</tbody>
|
|
255
|
+
</table>
|
|
256
|
+
|
|
257
|
+
<!-- markdownlint-restore -->
|
|
258
|
+
<!-- prettier-ignore-end -->
|
|
259
|
+
|
|
260
|
+
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
|
261
|
+
|
|
262
|
+
## Contribution
|
|
263
|
+
|
|
264
|
+
We welcome contributions from the community! Whether it's bug reports, feature requests, or code contributions, every contribution helps make PyWebGuard better.
|
|
265
|
+
|
|
266
|
+
Please read our [Contribution Guidelines](https://github.com/py-daily/pywebguard/blob/main/contribution.md) before submitting any changes. This document provides detailed information about:
|
|
267
|
+
|
|
268
|
+
- How to set up your development environment
|
|
269
|
+
- Our coding standards and style guide
|
|
270
|
+
- The process for submitting pull requests
|
|
271
|
+
- How to report bugs and request features
|
|
272
|
+
- Our commit message conventions
|
|
273
|
+
- Testing requirements
|
|
274
|
+
|
|
275
|
+
Join our community and help make PyWebGuard even better! 🚀
|
|
276
|
+
|
|
277
|
+
## License
|
|
278
|
+
|
|
279
|
+
This project is licensed under the [MIT License](LICENSE).
|
|
280
|
+
|