Sanitize challenge field to prevent XSS vulnerability

Created on 2 May 2023, over 1 year ago
Updated 2 June 2024, 6 months ago

Problem/Motivation

The Challenge string field isn't sanitized against XSS attacks. Even though this field is admin-only, a user could still be tricked into entering code that performed a wide variety of actions: stealing their session token or login credentials, performing arbitrary actions on the their behalf, and logging their keystrokes.

Steps to reproduce

  1. Log in and go to Configuration > Let's Encrypt challenge.
  2. In the Challenge string field, enter <script>alert(123)</script> and submit.
  3. Go to /.well-known/acme-challenge/1 and you will see an alert, demonstrating the JavaScript executed.

Proposed resolution

Sanitize that field value before it goes into the database, so it can't execute on display.

Remaining tasks

Make a MR with the sanitization code added.

User interface changes

None.

API changes

None.

Data model changes

None.

πŸ› Bug report
Status

Needs work

Version

1.1

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States SamLerner

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @SamLerner
  • πŸ‡ΊπŸ‡ΈUnited States SamLerner
  • Open on Drupal.org β†’
    Core: 10.0.7 + Environment: PHP 7.4 & MySQL 5.7
    last update over 1 year ago
    Waiting for branch to pass
  • @samlerner opened merge request.
  • Status changed to Needs review over 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States SamLerner
  • Status changed to RTBC over 1 year ago
  • πŸ‡§πŸ‡ͺBelgium BramDriesen Belgium πŸ‡§πŸ‡ͺ

    Sure why not. The chance of this happening is slim, but good to have it covered none the less since it's outputting plain user input.

  • πŸ‡ΊπŸ‡ΈUnited States SamLerner

    Agreed, this came up as part of a security audit, so even if normal folks wouldn't find it and exploit it, other security scans might pick up on it.

  • Status changed to Needs work about 1 year ago
  • πŸ‡΅πŸ‡ΉPortugal jcnventura

    Correct me if I'm wrong, but what I believe this code is doing is to escape the challenge, and store it escaped in state, and then get the escaped value from state and again escape it... It works fine as long, as the challenge doesn't include anything that gets escaped.. The moment the challenge includes an escpaed character, let's say

    hello"goodbye

    , it will be stored in state as

    hello"goodbye

    , then retrieved and the challenge to be displayed would be

    hello&quot;goodbye

    . Clearly not what we want. I'm not sure if a quote is a valid challenge character, but I don't see any reason why it would not be.

    Would be way better to use https://api.drupal.org/api/drupal/core%21modules%21editor%21src%21Editor...

  • Open on Drupal.org β†’
    Core: 10.1.4 + Environment: PHP 7.4 & MySQL 5.7
    last update about 1 year ago
    Waiting for branch to pass
  • Status changed to Needs review about 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States SamLerner

    I pushed an update that switches to using Standard::filterXss. I wasn't sure what filter format would make sense to test, since that could vary from site to site, so I just made a dummy one.

  • Status changed to Needs work 6 months ago
  • πŸ‡΅πŸ‡ΉPortugal jcnventura

    The implemention must be the reverse of the current state of the MR. The filterXss must be called ONLY during the setting of the configuration form. That way, no XSS is inserted into the configuration.

    When retrieving the value, it is already XSS-free, so nothing needs to be escaped.

Production build 0.71.5 2024