Hello Djangonauts,

This suggestion is following from discussions of the security issue
which was resolved in today's release. In essence, the issue is that
language codes are optionally used as prefixes in URLs, and for this
use they also become part of regular expressions used by the URL
resolution mechanisms. So, if an attacker manages to convince the
server to use a "language code" which encodes a pathologically complex
regex, the server can be DOS'd. The solution was to modify the
regex-inclusion part to regex-escape the language code -- ensuring
that language codes are never interpreted, in this role, as anything
other than a simple chain of single characters. This is the proper
security fix: Prevents the problem where it could manifest, with
minimal effects elsewhere. 

But looking forward, I think we should reconsider the fact that
django.utils.translation.activate() will just activate whatever
language code it is given. We do have a setting, LANGUAGES, which
defines a list of the languages (and codes) supported by our site. Why
should activate() accept anything that is not in this list?

Two points have been raised in support of the current behavior: The
existence of custom languages, and of fallback language codes (that is,
e.g where the user asks for zh-hk and gets, instead, zh-hant). But in
my opinion, they do not justify it:

- A custom language should be included in settings.LANGUAGES if it is
  to be supported; otherwise, e.g. makemessages will not even handle
  its translation file.

- When a language with a fallback is requested, the site should really
  activate the fallback language, not pretend to activate the requested
  one while actually using the fallback. As an example, if "en-us" is
  used as a fallback for "en-gb", and the URL has "en-gb" in it, then a
  British user would rightly be offended by all the American spelling
  they would see. The site should be honest enough to say "yes, you
  asked for en-gb, but we fell back to en-us; sorry, that's the best we
  have for you".

Note that there are all sorts of functions that check if a language
code is valid. For example, django.views.i18n.set_language() checks if
a translation for the languages exists in the project or its apps (but
not, AFAICT, the setting). d.u.translation.get_language_from_request()
and get_language_from_path() do check the LANGUAGES setting. It is
likely that including the check in activate() will do some double work.
And yet, we found ourselves introducing the security fix.

(I should note that this suggestion was also, independently, raised by
Benjamin who reported the vulnerability)

Opinions, suggestions, and explanations of the value I miss in allowing
activate() to take random language codes welcome.

Thanks,
        Shai.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/20221004170511.4342ebc7.shai%40platonix.com.
  • Sug... Shai Berger
    • ... אורי
      • ... 'Adam Johnson' via Django developers (Contributions to Django itself)

Reply via email to