forked from username/flaskpaste
add security testing suite and update docs
- tests/security/pentest_session.py: comprehensive 10-phase pentest - tests/security/profiled_server.py: cProfile-enabled server - tests/security/cli_security_audit.py: CLI security checks - tests/security/dos_memory_test.py: memory exhaustion tests - tests/security/race_condition_test.py: concurrency tests - docs: add pentest results, profiling analysis, new test commands
This commit is contained in:
80
tests/security/profiled_server.py
Normal file
80
tests/security/profiled_server.py
Normal file
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env python3
|
||||
"""FlaskPaste server with cProfile profiling enabled."""
|
||||
|
||||
import atexit
|
||||
import cProfile
|
||||
import io
|
||||
import pstats
|
||||
import signal
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, "/home/user/git/flaskpaste")
|
||||
|
||||
from app import create_app
|
||||
|
||||
# Global profiler
|
||||
profiler = cProfile.Profile()
|
||||
profile_output = "/tmp/flaskpaste_profile.prof"
|
||||
stats_output = "/tmp/flaskpaste_profile_stats.txt"
|
||||
|
||||
|
||||
def save_profile():
|
||||
"""Save profiling results on exit."""
|
||||
profiler.disable()
|
||||
|
||||
# Save raw profile data
|
||||
profiler.dump_stats(profile_output)
|
||||
print(f"\nProfile data saved to: {profile_output}", file=sys.stderr)
|
||||
|
||||
# Save human-readable stats
|
||||
s = io.StringIO()
|
||||
ps = pstats.Stats(profiler, stream=s)
|
||||
ps.strip_dirs()
|
||||
ps.sort_stats("cumulative")
|
||||
ps.print_stats(50)
|
||||
|
||||
with open(stats_output, "w") as f:
|
||||
f.write("=" * 80 + "\n")
|
||||
f.write("FlaskPaste Profiling Results\n")
|
||||
f.write("=" * 80 + "\n\n")
|
||||
f.write(s.getvalue())
|
||||
|
||||
# Also get callers for top functions
|
||||
s2 = io.StringIO()
|
||||
ps2 = pstats.Stats(profiler, stream=s2)
|
||||
ps2.strip_dirs()
|
||||
ps2.sort_stats("cumulative")
|
||||
ps2.print_callers(20)
|
||||
f.write("\n\n" + "=" * 80 + "\n")
|
||||
f.write("Top Function Callers\n")
|
||||
f.write("=" * 80 + "\n\n")
|
||||
f.write(s2.getvalue())
|
||||
|
||||
print(f"Stats saved to: {stats_output}", file=sys.stderr)
|
||||
|
||||
|
||||
def signal_handler(signum, frame):
|
||||
"""Handle shutdown signals."""
|
||||
print(f"\nReceived signal {signum}, saving profile...", file=sys.stderr)
|
||||
save_profile()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
# Register cleanup handlers
|
||||
atexit.register(save_profile)
|
||||
signal.signal(signal.SIGTERM, signal_handler)
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Starting FlaskPaste with profiling enabled...", file=sys.stderr)
|
||||
print(f"Profile will be saved to: {profile_output}", file=sys.stderr)
|
||||
print(f"Stats will be saved to: {stats_output}", file=sys.stderr)
|
||||
print("Press Ctrl+C to stop and save profile.\n", file=sys.stderr)
|
||||
|
||||
app = create_app("development")
|
||||
|
||||
# Start profiling
|
||||
profiler.enable()
|
||||
|
||||
# Run the server
|
||||
app.run(host="127.0.0.1", port=5099, threaded=True, use_reloader=False)
|
||||
Reference in New Issue
Block a user