mongo-secure 0.1.0__py3-none-any.whl
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.
mongo_secure/__init__.py
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
|
|
3
|
+
from functools import wraps
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
MONGO_OPERATOR_REPLACEMENTS = {
|
|
7
|
+
"$all",
|
|
8
|
+
"$elemMatch",
|
|
9
|
+
"$size",
|
|
10
|
+
"$bitsAllClear",
|
|
11
|
+
"$bitsAllSet",
|
|
12
|
+
"$bitsAnyClear",
|
|
13
|
+
"$bitsAnySet",
|
|
14
|
+
"$eq",
|
|
15
|
+
"$ne",
|
|
16
|
+
"$gt",
|
|
17
|
+
"$gte",
|
|
18
|
+
"$lt",
|
|
19
|
+
"$lte",
|
|
20
|
+
"$in",
|
|
21
|
+
"$nin",
|
|
22
|
+
"$exists",
|
|
23
|
+
"$type",
|
|
24
|
+
"$expr",
|
|
25
|
+
"$jsonSchema",
|
|
26
|
+
"$mod",
|
|
27
|
+
"$regex",
|
|
28
|
+
"$where",
|
|
29
|
+
"$and",
|
|
30
|
+
"$not",
|
|
31
|
+
"$nor",
|
|
32
|
+
"$or",
|
|
33
|
+
"$geoIntersects",
|
|
34
|
+
"$geoWithin",
|
|
35
|
+
"$near",
|
|
36
|
+
"$nearSphere",
|
|
37
|
+
"$meta",
|
|
38
|
+
"$slice",
|
|
39
|
+
"$currentDate",
|
|
40
|
+
"$inc",
|
|
41
|
+
"$min",
|
|
42
|
+
"$max",
|
|
43
|
+
"$mul",
|
|
44
|
+
"$rename",
|
|
45
|
+
"$set",
|
|
46
|
+
"$setOnInsert",
|
|
47
|
+
"$unset",
|
|
48
|
+
"$[]",
|
|
49
|
+
"$addToSet",
|
|
50
|
+
"$pop",
|
|
51
|
+
"$pull",
|
|
52
|
+
"$push",
|
|
53
|
+
"$pullAll",
|
|
54
|
+
"$each",
|
|
55
|
+
"$position",
|
|
56
|
+
"$sort",
|
|
57
|
+
"$bit",
|
|
58
|
+
"$text",
|
|
59
|
+
"$search",
|
|
60
|
+
"$comment",
|
|
61
|
+
"$options",
|
|
62
|
+
"$rand",
|
|
63
|
+
"$natural",
|
|
64
|
+
"$",
|
|
65
|
+
"$setField",
|
|
66
|
+
"$unsetField",
|
|
67
|
+
"$replaceRoot",
|
|
68
|
+
"$replaceWith",
|
|
69
|
+
"$match",
|
|
70
|
+
"$project",
|
|
71
|
+
"$addFields",
|
|
72
|
+
"$group",
|
|
73
|
+
"$limit",
|
|
74
|
+
"$skip",
|
|
75
|
+
"$lookup",
|
|
76
|
+
"$graphLookup",
|
|
77
|
+
"$unwind",
|
|
78
|
+
"$facet",
|
|
79
|
+
"$bucket",
|
|
80
|
+
"$bucketAuto",
|
|
81
|
+
"$count",
|
|
82
|
+
"$sortByCount",
|
|
83
|
+
"$sample",
|
|
84
|
+
"$unionWith",
|
|
85
|
+
"$documents",
|
|
86
|
+
"$densify",
|
|
87
|
+
"$fill",
|
|
88
|
+
"$geoNear",
|
|
89
|
+
"$indexStats",
|
|
90
|
+
"$listLocalSessions",
|
|
91
|
+
"$listSessions",
|
|
92
|
+
"$planCacheStats",
|
|
93
|
+
"$redact",
|
|
94
|
+
"$searchMeta",
|
|
95
|
+
"$setWindowFields",
|
|
96
|
+
"$collStats",
|
|
97
|
+
"$out",
|
|
98
|
+
"$merge",
|
|
99
|
+
"$abs",
|
|
100
|
+
"$add",
|
|
101
|
+
"$ceil",
|
|
102
|
+
"$divide",
|
|
103
|
+
"$exp",
|
|
104
|
+
"$floor",
|
|
105
|
+
"$ln",
|
|
106
|
+
"$log",
|
|
107
|
+
"$log10",
|
|
108
|
+
"$multiply",
|
|
109
|
+
"$pow",
|
|
110
|
+
"$round",
|
|
111
|
+
"$sqrt",
|
|
112
|
+
"$subtract",
|
|
113
|
+
"$trunc",
|
|
114
|
+
"$arrayElemAt",
|
|
115
|
+
"$arrayToObject",
|
|
116
|
+
"$concatArrays",
|
|
117
|
+
"$filter",
|
|
118
|
+
"$first",
|
|
119
|
+
"$firstN",
|
|
120
|
+
"$indexOfArray",
|
|
121
|
+
"$isArray",
|
|
122
|
+
"$last",
|
|
123
|
+
"$lastN",
|
|
124
|
+
"$map",
|
|
125
|
+
"$maxN",
|
|
126
|
+
"$minN",
|
|
127
|
+
"$objectToArray",
|
|
128
|
+
"$range",
|
|
129
|
+
"$reduce",
|
|
130
|
+
"$reverseArray",
|
|
131
|
+
"$sortArray",
|
|
132
|
+
"$zip",
|
|
133
|
+
"$cond",
|
|
134
|
+
"$ifNull",
|
|
135
|
+
"$switch",
|
|
136
|
+
"$cmp",
|
|
137
|
+
"$allElementsTrue",
|
|
138
|
+
"$anyElementTrue",
|
|
139
|
+
"$setDifference",
|
|
140
|
+
"$setEquals",
|
|
141
|
+
"$setIntersection",
|
|
142
|
+
"$setIsSubset",
|
|
143
|
+
"$setUnion",
|
|
144
|
+
"$concat",
|
|
145
|
+
"$dateFromString",
|
|
146
|
+
"$indexOfBytes",
|
|
147
|
+
"$indexOfCP",
|
|
148
|
+
"$ltrim",
|
|
149
|
+
"$regexFind",
|
|
150
|
+
"$regexFindAll",
|
|
151
|
+
"$regexMatch",
|
|
152
|
+
"$replaceOne",
|
|
153
|
+
"$replaceAll",
|
|
154
|
+
"$rtrim",
|
|
155
|
+
"$split",
|
|
156
|
+
"$strLenBytes",
|
|
157
|
+
"$strLenCP",
|
|
158
|
+
"$strcasecmp",
|
|
159
|
+
"$substr",
|
|
160
|
+
"$substrBytes",
|
|
161
|
+
"$substrCP",
|
|
162
|
+
"$toLower",
|
|
163
|
+
"$toString",
|
|
164
|
+
"$trim",
|
|
165
|
+
"$toUpper",
|
|
166
|
+
"$dateAdd",
|
|
167
|
+
"$dateDiff",
|
|
168
|
+
"$dateFromParts",
|
|
169
|
+
"$dateSubtract",
|
|
170
|
+
"$dateToParts",
|
|
171
|
+
"$dateToString",
|
|
172
|
+
"$dateTrunc",
|
|
173
|
+
"$dayOfMonth",
|
|
174
|
+
"$dayOfWeek",
|
|
175
|
+
"$dayOfYear",
|
|
176
|
+
"$hour",
|
|
177
|
+
"$isoDayOfWeek",
|
|
178
|
+
"$isoWeek",
|
|
179
|
+
"$isoWeekYear",
|
|
180
|
+
"$millisecond",
|
|
181
|
+
"$minute",
|
|
182
|
+
"$month",
|
|
183
|
+
"$second",
|
|
184
|
+
"$week",
|
|
185
|
+
"$year",
|
|
186
|
+
"$convert",
|
|
187
|
+
"$toBool",
|
|
188
|
+
"$toDate",
|
|
189
|
+
"$toDecimal",
|
|
190
|
+
"$toDouble",
|
|
191
|
+
"$toInt",
|
|
192
|
+
"$toLong",
|
|
193
|
+
"$toObjectId",
|
|
194
|
+
"$let",
|
|
195
|
+
"$literal",
|
|
196
|
+
"$function",
|
|
197
|
+
"$accumulator",
|
|
198
|
+
"$getField",
|
|
199
|
+
"$mergeObjects",
|
|
200
|
+
"$bsonSize",
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def replace_blocked_mongo_operators(value):
|
|
205
|
+
"""
|
|
206
|
+
basically just turns any mongo operator that's above into _OPERATION instead of $OPERATION
|
|
207
|
+
"""
|
|
208
|
+
try:
|
|
209
|
+
if isinstance(value, dict):
|
|
210
|
+
cleaned = {}
|
|
211
|
+
for key, nested_value in value.items():
|
|
212
|
+
cleaned_key = replace_blocked_mongo_operators(key)
|
|
213
|
+
cleaned_value = replace_blocked_mongo_operators(nested_value)
|
|
214
|
+
cleaned[cleaned_key] = cleaned_value
|
|
215
|
+
return cleaned
|
|
216
|
+
if isinstance(value, list):
|
|
217
|
+
return [replace_blocked_mongo_operators(item) for item in value]
|
|
218
|
+
if isinstance(value, tuple):
|
|
219
|
+
return tuple(replace_blocked_mongo_operators(item) for item in value)
|
|
220
|
+
if isinstance(value, set):
|
|
221
|
+
return {replace_blocked_mongo_operators(item) for item in value}
|
|
222
|
+
if isinstance(value, str):
|
|
223
|
+
if value in MONGO_OPERATOR_REPLACEMENTS:
|
|
224
|
+
return value.replace("$", "_", 1)
|
|
225
|
+
return value
|
|
226
|
+
return value
|
|
227
|
+
except Exception:
|
|
228
|
+
return value
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def sanitize(*arg_names):
|
|
232
|
+
"""
|
|
233
|
+
decorator that can be used on functions to take an argument name and replace the operators
|
|
234
|
+
|
|
235
|
+
for example:
|
|
236
|
+
|
|
237
|
+
@sanitize_mongo_args("name")
|
|
238
|
+
def hello_world(name):
|
|
239
|
+
print(f"hello {name}")
|
|
240
|
+
|
|
241
|
+
hello_world("$toInt") -> hello _toInt
|
|
242
|
+
hello_world("$dateFromParts") -> hello _dateFromParts
|
|
243
|
+
"""
|
|
244
|
+
arg_names = set(arg_names)
|
|
245
|
+
def decorator(func):
|
|
246
|
+
sig = inspect.signature(func)
|
|
247
|
+
@wraps(func)
|
|
248
|
+
def wrapper(*args, **kwargs):
|
|
249
|
+
try:
|
|
250
|
+
bound = sig.bind_partial(*args, **kwargs)
|
|
251
|
+
bound.apply_defaults()
|
|
252
|
+
|
|
253
|
+
for name in arg_names:
|
|
254
|
+
if name in bound.arguments:
|
|
255
|
+
bound.arguments[name] = replace_blocked_mongo_operators(
|
|
256
|
+
bound.arguments[name]
|
|
257
|
+
)
|
|
258
|
+
return func(*bound.args, **bound.kwargs)
|
|
259
|
+
except Exception:
|
|
260
|
+
return None
|
|
261
|
+
return wrapper
|
|
262
|
+
return decorator
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mongo_secure
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Sanitize MongoDB operator strings in selected function arguments.
|
|
5
|
+
Author-email: Thomas Perkins <contact@perkinsfund.org>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/YOUR_USERNAME/mongo_secure
|
|
8
|
+
Project-URL: Repository, https://github.com/YOUR_USERNAME/mongo_secure
|
|
9
|
+
Project-URL: Issues, https://github.com/YOUR_USERNAME/mongo_secure/issues
|
|
10
|
+
Keywords: mongodb,sanitize,decorator,security
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Python: >=3.9
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# mongo_secure
|
|
25
|
+
|
|
26
|
+
Sanitize selected function arguments by replacing MongoDB operators.
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
pip install mongo_secure
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from mongo_secure import sanitize
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@sanitize("name", "place")
|
|
41
|
+
def hello_world(name, place):
|
|
42
|
+
print(name)
|
|
43
|
+
print(place)
|
|
44
|
+
|
|
45
|
+
hello_world("$toInt", "$gt")
|
|
46
|
+
#<= _toInt
|
|
47
|
+
#<= _gt
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Nested objects are sanitized recursively
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from mongo_secure import replace_blocked_mongo_operators
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
payload = {
|
|
57
|
+
"$set": {
|
|
58
|
+
"age": "$toInt",
|
|
59
|
+
"tags": ["safe", "$where"]
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
print(replace_blocked_mongo_operators(payload))
|
|
65
|
+
#<= {"_set": {"age": "_toInt", "tags": ["safe", "_where"]}}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## License
|
|
69
|
+
MIT
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
mongo_secure/__init__.py,sha256=P0IO5TyGHiGk8BJMBpOSzccUOdO9nHgnvApuhOJ5gSU,137
|
|
2
|
+
mongo_secure/sanitizer.py,sha256=TuEgf8f_fTcN0wWGHiPBRmwD3DwKEMm72jS8dHX8ysE,5564
|
|
3
|
+
mongo_secure-0.1.0.dist-info/METADATA,sha256=pF9QJn-7BrbyGPlWTosBiooZiZo7Bid7RamwyIqdssA,1733
|
|
4
|
+
mongo_secure-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
5
|
+
mongo_secure-0.1.0.dist-info/top_level.txt,sha256=Y-zAbzxsZAv6oc4arw0HeN0OY8X8OM735mj61LH-6oI,13
|
|
6
|
+
mongo_secure-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
mongo_secure
|