Python Secure Coding
Python Secure Coding
About Me
Started to work in IT in 1997, moved to information security in 2001. Working
in information security for over a decade with experience in software security,
information security management, and information security R&D.
Worked in many roles like Senior Security Engineer, Security Architect,
Disaster Recovery Specialist, Microsoft Security Specialist, etc etc...
Leader of OWASP Python Security Project
http://www.pythonsecurity.org/
Co-Leader of OWASP Project Metrics Project
https://github.com/OWASP/OWASP-Project-Metrics
24th October 2014, Bucureti, Romnia
7,000
6,000
5,000
4,000
http://web.nvd.nist.gov/view/vuln/statistics
3,000
2,000
1,000
0
2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013
Series1
http://web.nvd.nist.gov/view/vuln/statistics
7,000
6,000
5,000
4,000
3,000
2,000
1,000
0
2004
2005
2006
2007
Series1
2008
2009
2010
Series2
2011
2012
2013
2004
2005
2006
Series3
2007
Series1
2008
2009
Series2
2010
2011
2012
2013
Series3
http://web.nvd.nist.gov/view/vuln/statistics
5,000
4,500
4,000
3,500
3,000
5
2,500
4
2,000
3
1,500
1,000
500
0
2003
2004
2005
2006
Series1
2007
2008
2009
Series2
2010
2011
2012
2013
0
2003
2004
2005
Series3
2006
2007
Series1
2008
2009
Series2
2010
2011
2012
2013
Series3
http://web.nvd.nist.gov/view/vuln/statistics
10
def genjudyfrags():
pkts=scapy.plist.PacketList()
pkts.append(IP(flags="MF",frag=0)/("1"*24))
pkts.append(IP(flags="MF",frag=4)/("2"*16))
pkts.append(IP(flags="MF",frag=6)/("3"*24))
pkts.append(IP(flags="MF",frag=1)/("4"*32))
pkts.append(IP(flags="MF",frag=6)/("5"*24))
pkts.append(IP(frag=9)/("6"*24))
return pkts
11
12
13
14
15
150
Generate
1024bits SSL key
Generate
128bits SSL key
100
1
17
33
49
65
81
97
113
129
145
161
177
193
209
225
241
257
273
289
305
321
337
353
369
385
401
417
433
449
465
481
497
513
529
545
561
577
593
609
625
641
657
673
689
705
721
737
753
769
785
801
817
833
849
865
881
897
913
929
50
16
Haveged Running
Haveged Running
3500
3000
2500
2000
1500
1000
Haveged Stopped
500
1
27
53
79
105
131
157
183
209
235
261
287
313
339
365
391
417
443
469
495
521
547
573
599
625
651
677
703
729
755
781
807
833
859
885
911
937
963
989
1015
1041
1067
1093
1119
1145
1171
1197
1223
1249
1275
1301
1327
1353
1379
1405
1431
1457
1483
1509
17
libdnet
dpkt
Impacket
pypcap
pynids
Dirtbags py-pcap
flowgrep
Mallory
Pytbull
0trace
Peach Fuzzing
antiparser
TAOF
untidy
Powerfuzzer
Mistress
Fuzzbox
WSBang
Construct
Fusil
SMUDGE
18
19
20
21
(http://en.wikipedia.org/wiki/Operational_acceptance_testing)
(http://en.wikipedia.org/wiki/Functional_testing)
22
23
24
import sys
import io
fd = io.open(sys.stdout.fileno(), 'wb')
fd.close()
try:
sys.stdout.write("test for error")
except Exception:
raise
25
26
27
28
The problem is due to a bug in the "codec" library that detects the character
"F4" and assumes this is the first character of a sequence of characters and wait
to receive the remaining 3 bytes, and the resulting string is truncated.
A better and safer approach would be to read the entire stream and only then
proceed to the decoding phase, as done by the io module.
24th October 2014, Bucureti, Romnia
29
30
31
32
33
# python 3
import pickle
import collections
dct = collections.defaultdict()
f = pickle.dumps(dct, protocol=1)
print (repr(f))
g = pickle.dumps(dct, protocol=1,
fix_imports=False)
print (repr(g))
h = pickle.dumps(dct, protocol=2)
print (repr(h))
i = pickle.dumps(dct, protocol=2,
fix_imports=False)
print (repr(i))
34
35
smtplib_1.py
import smtplib
try:
s = smtplib.SMTP_SSL("localhost", 45678)
except Exception:
raise
RESULT:
ssl.SSLError: [Errno 1] _ssl.c:504: error:140770FC:SSL
routines:SSL23_GET_SERVER_HELLO:unknown protocol
lsof -P | grep python | grep ":45678"
python 16725 user01 3u IPv4 31510356 0t0 TCP localhost:45678 (LISTEN)
The underlying socket connection remains open, but you can't access it or close it.
24th October 2014, Bucureti, Romnia
36
CLIENT
import poplib
HOST = '127.0.0.1'
PORT = 45678
try:
print "Connecting to %r:%d..." % (HOST, PORT)
pop = poplib.POP3(HOST, PORT)
print "Welcome:", repr(pop.welcome)
print "Listing..."
reply = pop.list()
print "LIST:", repr(reply)
except Exception, ex:
print "Error: %r" % str(ex)
print "End."
import socket
HOST = '127.0.0.1'
PORT = 45678
NULLS = '\0' * (1024 * 1024) # 1 MB
sock = socket.socket()
sock.bind((HOST, PORT))
sock.listen(1)
while 1:
conn, _ = sock.accept()
conn.sendall("+OK THIS IS A TEST\r\n")
conn.recv(4096)
DATA = NULLS
try:
while 1:
for _ in xrange(1024):
conn.sendall(DATA)
except IOError, ex:
print "Error: %r" % str(ex)
SERVER
37
38
39
multiprocessing
os.exec
os.popen
os.spawn
os.system
parser
pickle
pipes
24th October 2014, Bucureti, Romnia
pty
rexec
shelve
subprocess
tarfile
yaml
zipfile
40
HTTPie
ProxMon
WSMap
Twill
Ghost
Windmill
FunkLoad
spynner
mitmproxy
pathod / pathoc
scrapy
41
IDAPython
pyasm2
pype32
apkjet
libdisassemble
PyBFD
python-adb
AsmJit-Python
llvmpy
PyCodin
python-ptrace
BeaEnginePython
Miasm
pydasm
PythonGdb
Binwalk
ollydbg2-python
PyDBG
PyVEX
Buggery
OllyPython
pydbgr
pywindbg
cuckoo
PDBparse
PyELF
Rekall
Disass
pefile
pyew
Vivisect
ElfParserLib
PIDA
pygdb2
Volatility
Frida
PyADB
pyMem
WinAppDbg
42
Closing Summary
Python is a powerful and easy to learn
language BUT has to be used with care.
There are no limits or controls in the language,
is responsibility of the coder to know what can
be done and what to avoid.
24th October 2014, Bucureti, Romnia
43
Crypto Issues
Weak ciphers
Small keys
Invalid SSL certs
Architectural Aspects
Kernel Architecture
Data write policy
NIC configuration
Entropy pool
Language Issues
File operations
Object evaluations
Instruction Validation
Variable Manipulation
String/Input Evaluation
Unicode encode/decode
Serialization
Data limits
44
Contact
Enrico Branca
OWASP Python Security Project
http://www.pythonsecurity.org/
Email: enrico.branca@owasp.org
Linkedin: http://fr.linkedin.com/in/ebranca
24th October 2014, Bucureti, Romnia
45