The document discusses several types of security vulnerabilities in Python web applications. It begins by covering the OWASP Top 10 security risks, with sections focused on A9 "Using Components with Known Vulnerabilities" and A7 "Insufficient Attack Protection". For A9, it provides examples of vulnerabilities in popular Python components like Django and Flask. For A7, it discusses ways to strengthen attack protection, such as using the django-defender and Flask-Security extensions, implementing Web Application Firewalls, and analyzing logs. Another section covers A5 "Security Misconfiguration" and gives recommendations for avoiding misconfigurations like using default settings in production or exposing traceback messages. The document emphasizes reviewing documentation, separating environments, and testing configurations to address
12. A9
Using Components with
Known Vulnerabilities
Buffer overflow in the socket.recvfrom_into function in Modules/
socketmodule.c in Python 2.5 before 2.7.7, 3.x before 3.3.4, and
3.4.x before 3.4rc1 allows remote attackers to execute arbitrary
code via a crafted string.
Publish Date : 2014-02-28
CVE-2014-1912
13. A9
Using Components with
Known Vulnerabilities
✤ Changelogs
✤ http://www.cvedetails.com/
✤ http://www.securitylab.ru/
✤ https://twitter.com/CVEnew/
14. OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs
15. OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs
16. OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs
25. A7
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(255), unique=True)
password = db.Column(db.String(255))
active = db.Column(db.Boolean())
confirmed_at = db.Column(db.DateTime())
failed_login_attempts = db.Column(db.Integer(), default=0)
Attack protection
Flask-Security
26. A7
class SecureLoginForm(LoginForm):
captcha = RecaptchaField()
def show_captcha(self):
return self.user and self.user.failed_login_attempts > 4
def validate(self):
self.user = _datastore.get_user(self.email.data)
if not self.user:
return False
if not self.show_captcha():
del self._fields['captcha']
result = super().validate()
if not result:
self.user.failed_login_attempts += 1
else:
self.user.failed_login_attempts = 0
_datastore.put(self.user)
_datastore.commit()
return result
Attack protection
Flask-Security
64. Injection
XML
A1
from lxml import etree
user_xml = '''<?xml version="1.0"?>
<notifications>
<messages>disabled </messages>
<call>enabled </call>
</notifications>
'''
tree = etree.fromstring(user_xml)
for setting in tree.xpath('/notifications /*'):
if setting.text not in ('enabled', 'disabled'):
raise ValueError(
"Incorrect value '{}'".format(value)
)
. . .
65. Injection
XML
A1
from lxml import etree
user_xml = '''<?xml version="1.0"?>
<!DOCTYPE root [ <!ENTITY passwd SYSTEM "file: ///etc/passwd">]>
<notifications>
<messages>&passwd; </messages>
<call>enabled </call>
</notifications>
'''
tree = etree.fromstring(user_xml)
for setting in tree.xpath('/notifications /*'):
if setting.text not in ('enabled', 'disabled'):
raise ValueError(
"Incorrect value ‘{}’".format(value)
)
. . .
66. Injection. XML.A1
from lxml import etree
user_xml = '''<?xml version="1.0"?>
<!DOCTYPE root [ <!ENTITY passwd SYSTEM "file: ///etc/passwd">]>
<notifications>
<messages>&passwd; </messages>
<call>enabled </call>
</notifications>
'''
tree = etree.fromstring(user_xml)
for setting in tree.xpath('/notifications /*'):
if setting.text not in ('enabled', 'disabled'):
raise ValueError(
"Incorrect value ‘{}’".format(value)
)
. . .
Traceback (most recent call last):
File «pycon_example.py", line 53, in <module>
"Incorrect value '{}'".format(setting.text)
ValueError: Incorrect value ' ##
# User Database
#
# Note that this file is consulted directly only when the
system is running
# in single-user mode. At other times this information is
provided by
# Open Directory.
#
# See the opendirectoryd(8) man page for additional
information about
# Open Directory.
##
nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false
root:*:0:0:System Administrator:/var/root:/bin/sh
daemon:*:1:1:System Services:/var/root:/usr/bin/false
67. Injection
XML
A1
from lxml import etree
user_xml = '''<?xml version="1.0"?>
<!DOCTYPE root [ <!ENTITY passwd SYSTEM "file: ///etc/passwd">]>
<notifications>
<messages>&passwd; </messages>
<call>enabled </call>
</notifications>
'''
tree = etree.fromstring(
user_xml, parser=etree.XMLParser(resolve_entities=False)
)
for setting in tree.xpath('/notifications /*'):
if setting.text not in ('enabled', 'disabled'):
raise ValueError(
"Incorrect value '{}'".format(value)
68. Injection. XML.A1
from lxml import etree
user_xml = '''<?xml version="1.0"?>
<!DOCTYPE root [ <!ENTITY passwd SYSTEM "file: ///etc/passwd">]>
<notifications>
<messages>&passwd; </messages>
<call>enabled </call>
</notifications>
'''
tree = etree.fromstring(user_xml)
for setting in tree.xpath('/notifications /*'):
if setting.text not in ('enabled', 'disabled'):
raise ValueError(
"Incorrect value ‘{}’".format(value)
)
. . .
Traceback (most recent call last):
File "pycon_example.py", line 53, in <module>
"Incorrect value '{}'".format(setting.text)
ValueError: Incorrect value 'None'
79. Injection
YAML
A1
Loading YAML
Warning: It is not safe to call yaml.load with
any data received from an untrusted source!
yaml.load is as powerful as pickle.load and so
may call any Python function. Check the
yaml.safe_load function though.
81. Injection
YAML
A1
user_input = '''
key: !!python/name:yaml.__version__
'''
data = yaml.safe_load(user_input)
yaml.constructor.ConstructorError: could not determine a constructor for the tag
'tag:yaml.org,2002:python/name:yaml.__version__'
in "<unicode string>", line 1, column 6:
key: !!python/name:yaml.__version__