-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsecurity_examples.py
More file actions
375 lines (294 loc) · 10.3 KB
/
security_examples.py
File metadata and controls
375 lines (294 loc) · 10.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
"""
Security examples for qdata-expression.
"""
from qdata_expr import (
ExpressionEngine,
Sandbox,
SandboxConfig,
SecurityViolationError,
get_expression_safety_issues,
is_expression_safe,
validate_expression_safety,
)
def safe_expressions():
"""Examples of safe expressions."""
print("=== Safe Expressions ===")
engine = ExpressionEngine()
# 这些表达式都是安全的
safe_exprs = [
"2 + 3 * 4",
"abs(-5) + round(3.14, 2)",
"max(1, 2, 3) * min(4, 5, 6)",
"'hello' + ' ' + 'world'",
"len([1, 2, 3])",
"sum([1, 2, 3, 4, 5])",
"True and False or True",
"5 > 3 and 10 < 20",
"{'a': 1, 'b': 2}['a'] + 10",
"[x**2 for x in range(5)]",
]
for expr in safe_exprs:
try:
result = engine.evaluate(expr)
print(f"✓ {expr} = {result}")
except Exception as e:
print(f"✗ {expr} -> Error: {e}")
print()
def unsafe_expressions():
"""Examples of unsafe expressions that should be blocked."""
print("=== Unsafe Expressions (Blocked) ===")
engine = ExpressionEngine()
# 这些表达式是不安全的,应该被阻止
unsafe_exprs = [
"eval('1+1')",
"exec('print(\"hacked\")')",
"__import__('os').system('echo hacked')",
"open('/etc/passwd').read()",
"globals()['__builtins__']['eval']('1+1')",
"getattr(object, '__class__')",
"compile('print(\"hacked\")', '', 'exec')",
"import os",
"from os import system",
"type(1)",
"vars(object)",
"dir()",
"locals()",
"sys._getframe()",
"object.__subclasses__()",
]
for expr in unsafe_exprs:
try:
result = engine.evaluate(expr)
print(f"⚠ {expr} = {result} (Should have been blocked!)")
except SecurityViolationError as e:
print(f"✓ {expr} -> Blocked: {e}")
except Exception as e:
print(f"✓ {expr} -> Blocked: {type(e).__name__}: {e}")
print()
def sandbox_configuration():
"""Sandbox configuration examples."""
print("=== Sandbox Configuration ===")
# 默认沙箱配置
sandbox = Sandbox()
print("Default sandbox created")
# 严格模式
strict_config = SandboxConfig(
strict_private_access=True,
max_execution_time=2.0,
max_recursion_depth=50,
max_string_length=10000,
max_collection_size=1000,
)
strict_sandbox = Sandbox(strict_config)
print("Strict sandbox created")
# 测试表达式
test_exprs = [
"2 + 3",
"abs(-5)",
"'hello'.upper()",
]
for expr in test_exprs:
result = sandbox.check_expression(expr)
if result:
print(f"'{expr}' is safe")
else:
print(f"'{expr}' is unsafe")
# 测试不安全的表达式
unsafe_expr = "eval('1+1')"
result = sandbox.check_expression(unsafe_expr)
if result:
print(f"'{unsafe_expr}' issues: {result}")
print()
def expression_validation():
"""Expression validation examples."""
print("=== Expression Validation ===")
# 使用便捷函数验证
safe_exprs = ["2 + 3", "x + y", "abs(-5)"]
unsafe_exprs = ["eval('1+1')", "exec('pass')"]
print("Validating safe expressions:")
for expr in safe_exprs:
try:
validate_expression_safety(expr)
print(f"✓ {expr} is safe")
except SecurityViolationError as e:
print(f"✗ {expr} is unsafe: {e}")
print("\nValidating unsafe expressions:")
for expr in unsafe_exprs:
try:
validate_expression_safety(expr)
print(f"⚠ {expr} should have been blocked!")
except SecurityViolationError as e:
print(f"✓ {expr} correctly blocked: {e}")
print()
def safety_issues():
"""Get detailed safety issues."""
print("=== Safety Issues Analysis ===")
# 获取详细的安全问题
expressions = [
"eval('1+1')",
"__import__('os')",
"getattr(object, '__class__')",
"open('/etc/passwd')",
]
for expr in expressions:
issues = get_expression_safety_issues(expr)
print(f"Expression: {expr}")
if issues:
for issue in issues:
print(f" - {issue}")
else:
print(" - No issues found")
print()
def is_safe_function():
"""Using is_expression_safe function."""
print("=== is_expression_safe Function ===")
test_cases = [
("2 + 3", True),
("abs(-5)", True),
("'hello'.upper()", True),
("eval('1+1')", False),
("exec('print()')", False),
("open('file.txt')", False),
("__import__('os')", False),
]
for expr, expected in test_cases:
result = is_expression_safe(expr)
status = "✓" if result == expected else "✗"
print(f"{status} {expr} -> {result} (expected {expected})")
print()
def private_attribute_access():
"""Private attribute access examples."""
print("=== Private Attribute Access ===")
# 默认配置(允许私有属性访问)
engine_default = ExpressionEngine()
# 严格配置(阻止私有属性访问)
strict_config = SandboxConfig(strict_private_access=True)
engine_strict = ExpressionEngine(
sandbox_config=strict_config
)
# 测试私有属性访问
test_cases = [
"'hello'._private_attr",
"obj.__class__",
"obj.__init__",
]
print("Default engine:")
for expr in test_cases:
try:
result = engine_default.evaluate(expr, {"obj": object()})
print(f" {expr} -> {result}")
except Exception as e:
print(f" {expr} -> {type(e).__name__}: {e}")
print("\nStrict engine:")
for expr in test_cases:
try:
result = engine_strict.evaluate(expr, {"obj": object()})
print(f" {expr} -> {result}")
except Exception as e:
print(f" {expr} -> {type(e).__name__}: {e}")
print()
def recursion_limit():
"""Recursion limit examples."""
print("=== Recursion Limit ===")
# 创建低递归限制的引擎
config = SandboxConfig(max_recursion_depth=10)
engine = ExpressionEngine(sandbox_config=config)
# 测试递归
expr = "f(f(f(f(f(f(f(f(f(f(1))))))))))"
try:
result = engine.evaluate(expr, {"f": lambda x: x + 1})
print(f"Deep recursion result: {result}")
except RecursionError as e:
print(f"Recursion limit exceeded: {e}")
print()
def string_length_limit():
"""String length limit examples."""
print("=== String Length Limit ===")
# 创建限制字符串长度的沙箱
config = SandboxConfig(max_string_length=100)
sandbox = Sandbox(config)
# 测试短字符串(应该通过)
short_expr = "'a' * 50"
issues = sandbox.check_expression(short_expr)
print(f"'a' * 50: {'Safe' if not issues else 'Unsafe: ' + str(issues)}")
# 测试长字符串(应该被阻止)
long_expr = "'a' * 200"
issues = sandbox.check_expression(long_expr)
print(f"'a' * 200: {'Safe' if not issues else 'Unsafe: ' + str(issues)}")
print()
def collection_size_limit():
"""Collection size limit examples."""
print("=== Collection Size Limit ===")
# 创建限制集合大小的沙箱
config = SandboxConfig(max_collection_size=10)
sandbox = Sandbox(config)
# 测试小集合(应该通过)
small_expr = "list(range(5))"
issues = sandbox.check_expression(small_expr)
print(f"list(range(5)): {'Safe' if not issues else 'Unsafe: ' + str(issues)}")
# 测试大集合(应该被阻止)
large_expr = "list(range(20))"
issues = sandbox.check_expression(large_expr)
print(f"list(range(20)): {'Safe' if not issues else 'Unsafe: ' + str(issues)}")
print()
def template_security():
"""Template security examples."""
print("=== Template Security ===")
engine = TemplateEngine()
# 安全的模板
safe_templates = [
"Hello, {{ name }}!",
"Total: {{ price * quantity }}",
"{% if user.age >= 18 %}Adult{% else %}Minor{% endif %}",
]
print("Safe templates:")
for template in safe_templates:
try:
result = engine.render(template, {"name": "Alice", "price": 100, "quantity": 2, "user": {"age": 25}})
print(f" ✓ {template} -> {result}")
except Exception as e:
print(f" ✗ {template} -> {e}")
# 注意:模板引擎本身应该已经处理了安全问题
print()
def best_practices():
"""Security best practices."""
print("=== Security Best Practices ===")
print("1. Always use the sandbox:")
print(" engine = ExpressionEngine(enable_sandbox=True)")
print("\n2. Validate user input:")
print(" if not is_expression_safe(user_expression):")
print(" raise ValueError('Unsafe expression')")
print("\n3. Set appropriate limits:")
print(" config = SandboxConfig(")
print(" max_execution_time=5.0,")
print(" max_recursion_depth=50,")
print(" max_string_length=10000,")
print(" max_collection_size=1000,")
print(" )")
print("\n4. Use strict mode for sensitive applications:")
print(" config = SandboxConfig(strict_private_access=True)")
print("\n5. Regular security audits:")
print(" issues = get_expression_safety_issues(expression)")
print(" if issues:")
print(" log_warning(f'Potential security issues: {issues}')")
print("\n6. Whitelist allowed functions:")
print(" config = SandboxConfig(")
print(" allowed_functions={'abs', 'round', 'len', 'sum'}")
print(" )")
print()
def main():
"""Run all security examples."""
safe_expressions()
unsafe_expressions()
sandbox_configuration()
expression_validation()
safety_issues()
is_safe_function()
private_attribute_access()
recursion_limit()
string_length_limit()
collection_size_limit()
template_security()
best_practices()
if __name__ == "__main__":
main()