No se puede descargar el archivo adjunto js

Estoy recibiendo exactamente el mismo error que en esta pregunta, es decir, puedo subir archivos JS después de permitirlo en la configuración, pero cuando intento descargarlos, la URL en el navegador cambia a la URL del archivo JS y se muestra el mensaje: “El cambio que solicitaste fue rechazado”.

Entorno:
Discourse en Docker ejecutándose detrás de Nginx (Nginx está usando SSL).

Registros del contenedor de Discourse:

    Started GET "p5ePkm5OoKveknnMjyArlS4PPwS.js" for 192.168.32.1 at 2021-02-22 05:48:52 +0000
    Processing by UploadsController#show_short as JS
      Parameters: {"base62"=>"p5ePkm5OoKveknnMjyArlS4PPwS", "extension"=>"js"}
    Sent file afcdf626f9db8d54a1fb5e8ebcab0ea214d9226a.js (2.2ms)
    Security warning: an embedded <script> tag on another site requested protected JavaScript. If you know what you're doing, go ahead and disable forgery protection on this action to permit cross-origin JavaScript embedding.
    Completed 422 Unprocessable Entity in 59ms (ActiveRecord: 0.0ms | Allocations: 17414)
    ActionController::InvalidCrossOriginRequest (Security warning: an embedded <script> tag on another site requested protected JavaScript. If you know what you're doing, go ahead and disable forgery protection on this action to permit cross-origin JavaScript embedding.)
    /opt/bitnami/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.3.1/lib/action_controller/metal/request_forgery_protection.rb:266:in `verify_same_origin_request'

Registros de Nginx:

    10.164.0.103 - - [22/Feb/2021:05:51:11 +0000] "GET /uploads/short-url/p5ePkm5OoKveknnMjyArlS4PPwS.js HTTP/2.0" 422 781 "getting-started-with-sftp-module/292" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36"

¡Agradecería cualquier ayuda o indicación!

2 Me gusta

¿Permite que los usuarios adjunten archivos *.js a sus publicaciones? ¿Tiene una necesidad legítima de que sus usuarios adjunten archivos de JavaScript? Solo queremos confirmarlo absolutamente antes de continuar.

1 me gusta

¡Gracias por la respuesta rápida!
Sí, es una discusión de preguntas y respuestas sobre programación, por lo que adjuntar archivos de código *.js es un caso de uso legítimo.

2 Me gusta

¡Hola a todos! Estoy teniendo el mismo problema. Hemos permitido la carga de archivos con la extensión .js, pero nadie puede descargarlos. Aún no hemos encontrado ninguna configuración para solucionar esto. ¿Alguien puede ayudar?

1 me gusta

¿Puedes describir el caso de uso? ¿Por qué es esto necesario?

Hola Jeff

Aunque, ahora copiamos y pegamos el código en la sección de texto de la publicación.
Caso de uso: Tenemos un archivo .js con un código de Kickstarter o una solución a un problema recurrente y queremos compartirlo como un archivo adjunto, para que los usuarios puedan descargarlo y comenzar a usarlo en sus proyectos.

Sin embargo, si cambiamos la extensión del archivo de .js a .txt, nuevamente aparece el mensaje “El cambio que deseaba fue rechazado”. (Esto podría deberse a alguna optimización de almacenamiento en el backend; si el archivo tiene el mismo contenido que un archivo anterior, el nuevo adjunto apunta al archivo previamente subido).
Así que modifiqué un poco el contenido del archivo .js (con extensión .txt) y lo subí de nuevo, y pude descargar el archivo como adjunto.

@codinghorror ¿Existe algún riesgo de seguridad al permitir la descarga de archivos .js?

1 me gusta

Sí; necesitaríamos realizar algunas investigaciones sobre los navegadores para asegurarnos de que el archivo siempre se descargue en el disco y nunca se ejecute.

1 me gusta

Tenemos un foro de desarrolladores en fluiggers.com.br, echa un vistazo… y a menudo compartimos archivos .js.

1 me gusta

Claro, hay muchos problemas de seguridad relacionados con permitir archivos JS, por lo que es algo con lo que debemos tener extrema precaución.

La cabecera Content-Disposition impedirá la ejecución de archivos JS descargados y la estamos configurando correctamente:

attachment; filename="test.js"; filename*=UTF-8''test.js

Funciona para las cargas en S3 y debería funcionar también con las cargas locales, pero parece haber una medida de seguridad nueva (o relativamente reciente) de Rails:

ActionController::InvalidCrossOriginRequest (Advertencia de seguridad: una etiqueta \u003cscript\u003e incrustada en otro sitio solicitó JavaScript protegido. Si sabes lo que estás haciendo, deshabilita la protección contra falsificación en esta acción para permitir la incrustación de JavaScript entre orígenes.)

Debería ser posible solucionarlo…

3 Me gusta

Me encontré con el mismo problema, tenemos un foro de preguntas y respuestas de codificación y necesitamos poder compartir archivos js grandes para descargar.

Tengo el mismo problema en mi comunidad. La gente quiere compartir archivos JS pero al intentar descargarlos, reciben este error:

Extracto del registro de producción de Rails:

Started GET "/uploads/short-url/qDlrltMxEIJ2aYYdt8lZ200E3wA.js" for 94.31.111.247 at 2025-07-09 05:53:30 +0000
Processing by UploadsController#show_short as JS
  Parameters: {"base62"=>"qDlrltMxEIJ2aYYdt8lZ200E3wA", "extension"=>"js"}
Sent file /var/www/discourse/public/uploads/default/original/1X/baab1fc131be960b601467333f5a690b257daeb0.js (0.3ms)
Security warning: an embedded <script> tag on another site requested protected JavaScript. If you know what you're doing, go ahead and disable forgery protection on this action to permit cross-origin JavaScript embedding.
Completed 422 Unprocessable Entity in 17ms (ActiveRecord: 0.0ms (0 queries, 0 cached) | GC: 0.0ms)

Los archivos js están en la lista de extensiones de carga permitidas:

Mismo problema aquí. Tenemos archivos js que se ejecutan en nuestro propio software, nada que pueda hacer algo en un navegador.

Logramos solucionar el problema de descarga de Discourse moviendo todas las cargas a un bucket de S3 y estableciendo s3_use_cdn_url_for_all_uploads en true. Esto esencialmente evita el controlador de URL cortas, que parece ser el obstáculo principal para los archivos js.

En detalle (de mi IA que me guió a través de esto):

  1. Configurar almacenamiento compatible con S3 (por ejemplo, Cloudflare R2)

Discourse no puede servir de forma segura archivos .js desde el disco local. Muévelos a un bucket.

  • Bucket: Crea un bucket privado (por ejemplo, my-discourse-bucket).

  • Claves API: Genera una Clave de Acceso y una Clave Secreta.

2. Configurar un dominio CDN personalizado

En Cloudflare (o tu proveedor), conecta un dominio personalizado a tu bucket (por ejemplo, cdn.example.com). Esto asegura que los archivos se sirvan como activos estáticos mediante una URL directa, evitando el “guardián de seguridad” de Discourse.

3. Actualizar la configuración de Discourse

En Administración → Configuración, configura tus detalles de S3. Crucialmente, habilita lo siguiente para asegurar que Discourse no intente “firmar” las URL con encabezados temporales que puedan romperlas:

  • s3_use_cdn_url_for_all_uploads: Marca esta casilla (Este es el paso más importante).

  • s3_cdn_url: Establece en https://cdn.example.com.

  • s3_region: Usa us-east-1 (para compatibilidad con R2).

4. Migrar cargas existentes (opcional)

Nota: Esto NO funcionó para nosotros por razones desconocidas.

Para arreglar enlaces antiguos en publicaciones existentes, entra en tu contenedor y ejecuta:

Bash

# Dentro de /var/discourse
./launcher enter app
rake uploads:migrate_to_s3
rake posts:rebake

Espero que esto ayude a alguien.