javascript - Eliminar archivo usando Coldfusion a través de jQuery ajax

CorePress2024-01-24  11

Estoy intentando eliminar archivos de imagen, después de completar los datos sobre el archivo en un modal.

Mi jQuery se ve así:

const deleteMedia = () => {
    const url = '../../includes/delete-media.cfc?method=deleteMedia';
    $(document).on('click', '.confirm-delete', () => {
        const fileName = $('.modal-wrapper').find('.file-name').text();
        $.ajax({
            url,
            type: 'POST',
            data: 'fileName=' + fileName,
            dataType: 'json',
            success(data) {
                console.log(data);
            },
            error(status) {
                console.log(status.statusText);
            }
        });
        return false;
    });
};

export default deleteMedia;

Y mi archivo Coldfusion delete-media.cfc:

<cffunction name="deleteMedia" access="remote" returnType="any" returnformat="json">
    <cfargument name="fileName" >
    <cfset requestBody = toString( getHttpRequestData().content ) />
    <!--- Double-check to make sure it's a JSON value. --->
    <cfif isJSON( requestBody )>
        <cfset VARIABLES.DeleteFileName = deserializeJSON( requestBody )>
        <cffile
            action = "delete"
            file = "C:\pathToSite\img\#variables.DeleteFileName#"
        >
        <cfdump var="#variables.DeleteFileName#">
    </cfif>
</cffunction>

Esto envía fileName = fileName como datos cuando reviso el panel Red y devuelve un 200, aunque no puedo ver el contenido del cfdump.

Estoy bien con la Fórmula E, no tan entusiasmado con la CF, supongo que mi CF es demasiado compleja pero tampoco hace lo que espero que haga. Intenté hacer referencia a algunas cosas que escribí hace un tiempo, además de esto:

¿Cómo utilizar Ajax para pasar variables de Javascript a Coldfusion?

Y esto:

Pasar y devolver ColdFusion Structure a través de JQuery

¿Alguna idea?

Sí, CFML es bastante de la vieja escuela. Lo primero que pensé es que no es necesario utilizar un .cfc. Simplifique el punto final y conviértalo en un archivo .cfm. Devuelva lo que quiera al front-end generando SerializeJSON(myReturnStruct) y luego puede depurar mirando los datos devueltos en su devolución de llamada de éxito de Ajax o puede usar WriteLog(). No debería necesitar realizar una llamada a getHttpRequestData(). Todos los campos de su formulario estarán en el alcance del formulario en su punto final. Buena suerte.

Redtopia

27 de marzo de 2021 a las 12:46

El enfoque que solía adoptar antes de jubilarme era comenzar haciendo que el código CF funcionara en un archivo independiente. Luego lo pondría en un cfc y lo haría funcionar al llamar a la función desde CF. Llamarlo desde JS sería el último paso. Por cierto, cuando llames al código CF desde JS, nunca verás el contenido de un cfdump.

- Dan Bracuk

27/03/2021 a las 14:31

Gracias. De hecho, fui a cffiddle.org para hacer un poco de depuración.

- lharby

27/03/2021 a las 15:22

1

No estoy de acuerdo con la afirmación de que esto no debería manejarse con un CFC. Al contrario, creo que debería utilizarse absolutamente un CFC. Usar a.cfm para una llamada AJAx es "de la vieja escuela"

- Scott Stroz

27/03/2021 a las 18:32

@ScottStroz, ¿puedes describir la diferencia?

- lharby

28 de marzo de 2021 a las 10:37



------------------------------------

Sí, sigue siendo problemático que estés pasando un nombre de archivo como parte de la solicitud. Alguien puede entrar y causar estragos en sus archivos. ¿Está verificando que el archivo en cuestión debería ser accesible incluso para el usuario que inició sesión? ¿Qué pasa si pasan el valor del archivo de otra persona? Esto también parece vulnerable a un ataque de recorrido de ruta. Si pasa `filename=../../someReallyImportaintFile', ¿se eliminará? owasp.org/www-community/attacks/Path_Traversal

Si se trata de un sitio personal y no de negocios, probablemente no haya mucho de qué preocuparse. Si este fuera el sitio de un cliente, estaríamás preocupado.

En Windows, tengo Steam instalado aquí:

`D:\Steam\`. 

Puedo abrir esta ruta en el Explorador de Windows:

`D:\Steam\bin`. 

Yo también puedo abrir este camino,

`D:\Steam\bin\..\config`

que enumera D:\Steam\config

Si pesco con

`deleteFileName=..\..\Windows\some\folder\someFile` 

Es posible que pueda eliminar archivos de su directorio de Windows si los permisos de su servidor no están configurados para evitar que CF elimine algo en el servidor.

Su usuario de CF no debe ser la cuenta de administrador del servidor. Existen guías de bloqueo que pueden ayudar a prevenir todo tipo de ataques de seguridad.

Lo ideal sería almacenar una lista de sus archivos en una tabla de base de datos y luego hacer referencia a un ID de archivo como parámetro de solicitud de eliminación.

$(document).on('click', '.confirm-delete', () => {
    $.ajax({
        url,
        type: 'POST',
        data: 'fileID=' + $('#SomeHiddenField').val(),
        success(data) {
            console.log(data);
            hideOverlay();
        },
        error(status) {
            console.log(status.statusText);
        }
    });
});

Luego, en el servidor, en el mejor de los casos verificas

¿El usuario ha iniciado sesión? ¿Tienen acceso a t?su expediente? ¿Tienen permiso para eliminar este archivo? Eliminar el archivo físico Marque el registro como eliminado con la hora en que fue eliminado y por quién.

1

Gracias por esto, todavía lo estoy digiriendo. Me gustaría adoptar estas políticas incluso si solo accedo a una parte de mi sitio a la que solo yo puedo acceder.

- lharby

28/03/2021 a las 16:26



------------------------------------

OK, siguiendo el comentario de Redtopia, creé esto:

<cfset requestBody = toString( getHttpRequestData().content ) />
<!--- Double-check to make sure fileName exists. --->
<cfif len(requestBody)>
    <cfset deleteFileName = requestBody.split("=")[2] />
    <cfoutput>#deleteFileName#</cfoutput>
    <cffile
        action = "delete"
        file = "C:\pathToSite\img\#deleteFileName#"
    >
<cfelse>
    <cfoutput>fileName not correct</cfoutput>
</cfif>

Luego, en mi llamada ajax, eliminé el tipo de datos json.

$(document).on('click', '.confirm-delete', () => {
    const fileName = $('.modal-wrapper').find('.file-name').text();
    $.ajax({
        url,
        type: 'POST',
        data: 'fileName=' + fileName,
        success(data) {
            console.log(data);
            hideOverlay();
        },
        error(status) {
            console.log(status.statusText);
        }
    });
});

¡Parece funcionar bien!

4

2

Sí, sigue siendo problemático que estés pasando un nombre de archivo como parte de la solicitud. Alguien puede entrar y causar estragos en sus archivos. ¿Está verificando que el archivo en cuestión debería ser accesible incluso para el usuario que inició sesión? ¿Qué pasa si pasan el valor del archivo de otra persona? Esto también parece vulnerable a un camino tataque transversal. Si pasa `filename=../../someReallyImportaintFile', ¿se eliminará? owasp.org/www-community/attacks/Path_Traversal

-Adrián J. Moreno

27/03/2021 a las 15:37

Está en una parte de mi sitio que tiene contraseña y solo yo tengo acceso. Sin embargo, soy todo oídos si hay formas mejores o más seguras de lograr lo que quiero. Lo que estaba haciendo antes de esto era cargar o eliminar vía ftp, así que esto es una gran mejora.

- lharby

27/03/2021 a las 16:30

1

La ruta del archivo en file = "C:\pathToSite\img\#deleteFileName#" Lo he truncado, en realidad apunta a un directorio específico en mi servidor, pero ¿está sugiriendo que si alguien recorre el árbol y adivina una carpeta y un nombre de archivo, podría eliminarlo? No entiendo cómo alguien puede manipular la ruta del archivo en cfml al que no pueden acceder si se envía desde el servidor, a menos que me falte algo. No sé mucho sobre piratería.

- lharby

27/03/2021 a las 16:47

1

@lharby Dado que esto proviene del servidor CF, se realizará como usuario de CF. Si CF puede acceder a un directorio, entonces los archivos de ese directorio se pueden manipular. A menos que limite el acceso a la cuenta CF. Cuando se trata de manipulación de archivos, es importante tener en cuenta el contexto desde el que se realiza la acción y los permisos permitidos para ese contexto. Además, si hay una parte de su sitio protegida con contraseña, no puede confiar en el hecho de que usted es el único que tiene la contraseña, o que siempre será usted quien use esa contraseña. La defensa en profundidad sigue siendo un buen concepto.

-Shawn

1 de abril de 2021 a las 13:46

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare