feat(obs): nommer chaque requete, et rendre les pages d erreur audibles
OBS-005. Un 500 dans errors.log et les six lignes de app.log qui y menent n etaient relies que par leur horodatage — ce qui n est pas une relation des que le serveur traite plus d une requete a la fois. Et un utilisateur qui dit « ca a plante quand j ai clique sur enregistrer » ne donnait a personne de quoi chercher. Chaque requete recoit un identifiant, porte par toutes les lignes de journal qu elle produit, renvoye en X-Request-Id, et affiche sur la page 500 comme reference a citer. Il est **genere**, jamais lu depuis un en-tete entrant. Accepter celui du client serait pratique pour tracer a travers nginx, et permettrait aussi a n importe qui d ecrire du texte arbitraire — retours a la ligne compris — dans le fichier de journal. C est ainsi qu un journal cesse d etre une preuve. Il n y a de toute facon aucun proxy de confiance tant qu OPS-002 est ouvert. Le test correspondant assure sur l alphabet plutot qu en envoyant un retour a la ligne : le client de test de Werkzeug refuse d emettre un tel en-tete, donc l attaque ne peut meme pas etre construite par la, ce qui ne prouverait rien sur l application. **Defaut trouve en chemin, et repare.** Les cinq gabarits d erreur remplissent le bloc `content`, qui n existait que dans la branche authentifiee de la mise en page. Un visiteur deconnecte tombant sur une erreur — donc typiquement sur la page de connexion — recevait le logo, le selecteur de langue, et **aucun message**. Le code de statut etait bon, les journaux etaient bons, la page etait vide. Le <title> disait quand meme « 404 », ce qui explique en grande partie que personne ne l ait vu. Le bloc est desormais rendu dans les deux branches via self.content(), Jinja refusant deux blocs de meme nom. Un seul cote du if s execute, donc jamais de double rendu — et c est assure, pas suppose. 550 tests.
This commit is contained in:
@@ -8,6 +8,12 @@
|
||||
</div>
|
||||
<h2>{{ _('500 — Internal Server Error') }}</h2>
|
||||
<p>{{ _('Something went wrong on our end. The error has been logged and will be investigated. Please try again later.') }}</p>
|
||||
{# The reference is what makes a report actionable: it names one request
|
||||
in errors.log. It identifies nothing else — no session, no account —
|
||||
so there is nothing to protect here (OBS-005). #}
|
||||
{% if request_id and request_id != '-' %}
|
||||
<p class="text-muted small">{{ _('Reference to quote if you report this:') }} <code>{{ request_id }}</code></p>
|
||||
{% endif %}
|
||||
<a href="{{ url_for('main.dashboard') if current_user.is_authenticated else url_for('auth.login') }}" class="btn btn-primary">
|
||||
<i class="fas fa-redo-alt"></i> {{ _('Try Again') }}
|
||||
</a>
|
||||
|
||||
@@ -201,6 +201,20 @@
|
||||
<div class="auth-language">
|
||||
{% include "layouts/_language_switcher.html" %}
|
||||
</div>
|
||||
{# The same `content` block as the signed-in branch, rendered
|
||||
here too — `self.content()` rather than a second
|
||||
`{% block %}`, which Jinja refuses.
|
||||
|
||||
The error pages (400, 403, 404, 429, 500) all fill `content`,
|
||||
and it existed only inside the `is_authenticated` branch: a
|
||||
signed-out visitor hitting any of them got the logo, the
|
||||
language switcher and no message whatsoever. The <title> still
|
||||
said "404", which is most of why nobody noticed.
|
||||
|
||||
Only one branch of the `if` runs, so this never double-renders.
|
||||
Sign-in pages fill `auth_content` instead and leave this
|
||||
empty. #}
|
||||
{{ self.content() }}
|
||||
{% block auth_content %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user