Changeset - aa51aca7fd1a
[Not reviewed]
stable
0 3 0
Valentin Kleibel - 19 months ago 2024-08-26 21:13:06
valentin@vrvis.at
Grafted from: 8daf3500d52f
controller: Handle UnicodeDecodeError from webob decoding invalid URLs

webob will try to utf-8 decode all %-encoded bytes in URL-parameters, but will
not handle Unicode erors ... and neither did Kallithea. Visiting a URL like
http://localhost:5000/?%AD would thus give an unhandled exception showing
"Internal Server Error" to the user, and logging the full traceback and:

WebApp Error: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xad in position 0: invalid start byte

This has been seen a lot recently from attackers probing for a php
vulnerability
https://devco.re/blog/2024/06/06/security-alert-cve-2024-4577-php-cgi-argument-injection-vulnerability-en/ .

Now handle these exceptions more nicely and reject with "400 Bad Request".
3 files changed with 11 insertions and 1 deletions:
0 comments (0 inline, 0 general)
CONTRIBUTORS
Show inline comments
 
List of contributors to Kallithea project:
 

	
 
    Mads Kiilerich <mads@kiilerich.com> 2016-2024
 
    Aristotelis Stageiritis <aristotelis79@gmail.com> 2024
 
    Poesty Li <poesty7450@gmail.com> 2024
 
    Valentin Kleibel <valentin@vrvis.at> 2024
 
    Manuel Jacob <me@manueljacob.de> 2019-2020 2022-2023
 
    Mathias De Mare <mathias.de_mare@nokia.com> 2023
 
    qy117121 <mixuan121@gmail.com> 2023
 
    Asterios Dimitriou <steve@pci.gr> 2016-2017 2020 2022
 
    Étienne Gilli <etienne@gilli.io> 2020-2022
 
    Jaime Marquínez Ferrándiz <weblate@jregistros.fastmail.net> 2022
 
    Louis Bertrand <louis.bertrand@durhamcollege.ca> 2022
 
    toras9000 <toras9000@gmail.com> 2022
 
    yzqzss <yzqzss@othing.xyz> 2022
 
    МАН69К <weblate@mah69k.net> 2022
 
    Thomas De Schampheleire <thomas.de_schampheleire@nokia.com> 2014-2021
 
    ssantos <ssantos@web.de> 2018-2021
 
    Private <adamantine.sword@gmail.com> 2019-2021
 
    fresh <fresh190@protonmail.com> 2020-2021
 
    robertus <robertuss12@gmail.com> 2020-2021
 
    Eugenia Russell <eugenia.russell2019@gmail.com> 2021
 
    Michalis <michalisntovas@yahoo.gr> 2021
 
    vs <vsuhachev@yandex.ru> 2021
 
    Александр <akonn7@mail.ru> 2021
 
    Allan Nordhøy <epost@anotheragency.no> 2017-2020
 
    Anton Schur <tonich.sh@gmail.com> 2017 2020
 
    Artem <kovalevartem.ru@gmail.com> 2020
 
    David Ignjić <ignjic@gmail.com> 2020
 
    Dennis Fink <dennis.fink@c3l.lu> 2020
kallithea/controllers/base.py
Show inline comments
 
@@ -435,50 +435,58 @@ class BaseController(TGController):
 
                user_info = auth_modules.authenticate('', '', request.environ)
 
            except UserCreationError as e:
 
                webutils.flash(e, 'error', logf=log.error)
 
            else:
 
                if user_info is not None:
 
                    username = user_info['username']
 
                    user = db.User.get_by_username(username, case_insensitive=True)
 
                    return log_in_user(user, remember=False, is_external_auth=True, ip_addr=ip_addr)
 

	
 
        # User is default user (if active) or anonymous
 
        default_user = db.User.get_default_user()
 
        authuser = AuthUser.make(dbuser=default_user, ip_addr=ip_addr)
 
        if authuser is None: # fall back to anonymous
 
            authuser = AuthUser(dbuser=default_user) # TODO: somehow use .make?
 
        return authuser
 

	
 
    @staticmethod
 
    def _basic_security_checks():
 
        """Perform basic security/sanity checks before processing the request."""
 

	
 
        # Only allow the following HTTP request methods.
 
        if request.method not in ['GET', 'HEAD', 'POST']:
 
            raise webob.exc.HTTPMethodNotAllowed()
 

	
 
        try:
 
            params = request.params
 
        except UnicodeDecodeError as e:
 
            # webobj will leak UnicodeDecodeError when decoding invalid
 
            # URLencoded byte sequences in parameters
 
            log.error('Error decoding request parameters: %s' % e)
 
            raise webob.exc.HTTPBadRequest()
 

	
 
        # Also verify the _method override - no longer allowed.
 
        if request.params.get('_method') is None:
 
        if params.get('_method') is None:
 
            pass # no override, no problem
 
        else:
 
            raise webob.exc.HTTPMethodNotAllowed()
 

	
 
        # Make sure CSRF token never appears in the URL. If so, invalidate it.
 
        if webutils.session_csrf_secret_name in request.GET:
 
            log.error('CSRF key leak detected')
 
            session.pop(webutils.session_csrf_secret_name, None)
 
            session.save()
 
            webutils.flash(_('CSRF token leak has been detected - all form tokens have been expired'),
 
                    category='error')
 

	
 
        # WebOb already ignores request payload parameters for anything other
 
        # than POST/PUT, but double-check since other Kallithea code relies on
 
        # this assumption.
 
        if request.method not in ['POST', 'PUT'] and request.POST:
 
            log.error('%r request with payload parameters; WebOb should have stopped this', request.method)
 
            raise webob.exc.HTTPBadRequest()
 

	
 
    def __call__(self, environ, context):
 
        try:
 
            ip_addr = get_ip_addr(environ)
 
            self._basic_security_checks()
 

	
kallithea/templates/about.html
Show inline comments
 
@@ -6,48 +6,49 @@
 
<%block name="header_menu">
 
    ${self.menu('about')}
 
</%block>
 
<%def name="main()">
 

	
 
<div class="panel panel-primary">
 
  <div class="panel-heading">
 
    <h5 class="panel-title">${_('About')} Kallithea</h5>
 
  </div>
 

	
 
  <div class="panel-body panel-about">
 
  <p><a href="https://kallithea-scm.org/">Kallithea</a> is a project of the
 
  <a href="http://sfconservancy.org/">Software Freedom Conservancy, Inc.</a>
 
  and is released under the terms of the
 
  <a href="http://www.gnu.org/copyleft/gpl.html">GNU General Public License,
 
  v 3.0 (GPLv3)</a>.</p>
 

	
 
  <p>Kallithea is copyrighted by various authors, including but not
 
  necessarily limited to the following:</p>
 
  <ul>
 

	
 
  <li>Copyright &copy; 2012&ndash;2024, Mads Kiilerich</li>
 
  <li>Copyright &copy; 2024, Aristotelis Stageiritis</li>
 
  <li>Copyright &copy; 2024, Poesty Li</li>
 
  <li>Copyright &copy; 2024, Valentin Kleibel</li>
 
  <li>Copyright &copy; 2019&ndash;2020, 2022&ndash;2023, Manuel Jacob</li>
 
  <li>Copyright &copy; 2023, Mathias De Mare</li>
 
  <li>Copyright &copy; 2023, qy117121</li>
 
  <li>Copyright &copy; 2015&ndash;2017, 2019&ndash;2022, Étienne Gilli</li>
 
  <li>Copyright &copy; 2016&ndash;2017, 2020, 2022, Asterios Dimitriou</li>
 
  <li>Copyright &copy; 2022, Jaime Marquínez Ferrándiz</li>
 
  <li>Copyright &copy; 2022, Louis Bertrand</li>
 
  <li>Copyright &copy; 2022, toras9000</li>
 
  <li>Copyright &copy; 2022, yzqzss</li>
 
  <li>Copyright &copy; 2022, МАН69К</li>
 
  <li>Copyright &copy; 2014&ndash;2021, Thomas De Schampheleire</li>
 
  <li>Copyright &copy; 2018&ndash;2021, ssantos</li>
 
  <li>Copyright &copy; 2019&ndash;2021, Private</li>
 
  <li>Copyright &copy; 2020&ndash;2021, fresh</li>
 
  <li>Copyright &copy; 2020&ndash;2021, robertus</li>
 
  <li>Copyright &copy; 2021, Eugenia Russell</li>
 
  <li>Copyright &copy; 2021, Michalis</li>
 
  <li>Copyright &copy; 2021, vs</li>
 
  <li>Copyright &copy; 2021, Александр</li>
 
  <li>Copyright &copy; 2017&ndash;2020, Allan Nordhøy</li>
 
  <li>Copyright &copy; 2017, 2020, Anton Schur</li>
 
  <li>Copyright &copy; 2020, Artem</li>
 
  <li>Copyright &copy; 2020, David Ignjić</li>
 
  <li>Copyright &copy; 2020, Dennis Fink</li>
0 comments (0 inline, 0 general)