Pregunta

  

Editar: desde entonces he encontrado y publicado una solución eficiente y elegante que transforma IDs como 3141592 en cadenas como vJST y al revés. Está disponible para PHP aquí:

     

https://github.com/delight-im/PHP-IDs

     

Al proporcionar algunos antecedentes, utiliza el hashing multiplicativo de Knuth seguido de una conversión de base para generar ID únicos, reversibles y no secuenciales.

Problema :

Tengo páginas dinámicas en PHP donde el contenido se muestra de acuerdo con la identificación dada. La identificación siempre se envía a través de un parámetro GET: page.php? Id = X Esto causa un problema: los visitantes del sitio pueden enumerar los identificadores y simplemente recorrer las diferentes páginas de contenido. Esto no debería ser posible, por supuesto.

¿Cómo podría resolverse esto?

Mi enfoque es codificar todos los identificadores en enlaces y formularios que se usan como parámetro GET más adelante. Al comienzo de cada página, la identificación dada se decodifica en el " real " id que se usa en la base de datos. ¿Es este un buen enfoque? ¿Elegirías otra forma?

Posible solución de mi enfoque:

Convertiría la identificación de entero a un entero base 38 y reemplazaría los dígitos por caracteres de una lista dada. Usaría estos caracteres para la identificación de cadena codificada:

a-z 0-9 - _

¿Usarías también otros personajes? Para estos personajes mi script sería este:

function id2secure($old_number) {
    $alphabet_en = array(0=>'1', 1=>'3', 2=>'5', 3=>'7', 4=>'9', 5=>'0', 6=>'2', 7=>'4', 8=>'6', 9=>'8', 10=>'a', 11=>'c', 12=>'e', 13=>'g', 14=>'i', 15=>'k', 16=>'m', 17=>'o', 18=>'q', 19=>'s', 20=>'u', 21=>'w', 22=>'y', 23=>'b', 24=>'d', 25=>'f', 26=>'h', 27=>'j', 28=>'l', 29=>'n', 30=>'p', 31=>'r', 32=>'t', 33=>'v', 34=>'x', 35=>'z', 36=>'-', 37=>'_');
    $new_number = '';
    while ($old_number > 0) {
        $rest = $old_number%38;
        if (!isset($alphabet_en[$rest])) { return FALSE; }
        $new_number .= $alphabet_en[$rest];
        $old_number = floor($old_number/38);
    }
    $new_number = strrev($new_number);
    return $new_number;
}

Pregunta adicional:

¿Cuál sería la función inversa para mi función?

Espero que me puedan ayudar. ¡Gracias!

¿Fue útil?

Solución

¿Pueden los usuarios acceder a las páginas a través del sitio web? Si la respuesta es sí, entonces debería preguntarse si esto es realmente un problema o no.

Si no es así, el problema es que no está asegurando sus páginas o, para decirlo de otra manera: depende de la oscuridad para la seguridad, lo cual nunca es un buen movimiento.

¿Mi consejo? Asegure sus páginas para que solo los usuarios correctos puedan acceder a ellas o no se preocupe por eso.

Si realmente debe preocuparse por eso, simplemente pase un campo adicional que debe ser correcto para la página dada. No construiría esto a partir de la identificación. Quizás genere otro número o un GUID cuando cree la entrada de página en la base de datos. Si ambos campos no son correctos, no muestre la página.

Olvídate de la simple sustitución de caracteres y otras ingenuas técnicas de ofuscación. Son una pérdida de tiempo.

Editar: si busca ID no secuenciales de la misma longitud, considere usar UUID en lugar de claves primarias de incremento automático. Básicamente esto se hace a nivel de aplicación:

  • Cambie su clave principal a char (36);
  • En su declaración de inserción, debe configurar la clave y completarla con la función UUID () de MySQL.

Eche un vistazo a a UUID o no a UUID? y UUID como clave principal . Hay una degradación del rendimiento debido a esto (específicamente porque está utilizando caracteres en lugar de enteros para las búsquedas), pero a menos que tenga un gran (más de 1 millón de filas) o datos, probablemente no será un problema en la práctica.

Otros consejos

Utilice un algoritmo de suma de comprobación como Luhn :

$id = 1337;

Utilice un algoritmo de suma de comprobación como Luhn :

$id = Luhn_Verify(

Utilice un algoritmo de suma de comprobación como Luhn :

$id = 1337;

Utilice un algoritmo de suma de comprobación como Luhn :

<*>

EDITAR: olvidé mencionarlo, pero al usar este método puede verificar si una ID es válida sin siquiera tener que consultar la base de datos, por ejemplo:

<*>GET['id'] = Luhn($id, 3); // 1337518, adds 3 checkdigits

Utilice un algoritmo de suma de comprobación como Luhn :

<*>

EDITAR: olvidé mencionarlo, pero al usar este método puede verificar si una ID es válida sin siquiera tener que consultar la base de datos, por ejemplo:

<*>GET['id'] = Luhn_Verify(

Utilice un algoritmo de suma de comprobación como Luhn :

<*>

EDITAR: olvidé mencionarlo, pero al usar este método puede verificar si una ID es válida sin siquiera tener que consultar la base de datos, por ejemplo:

<*>GET['id'], 3); // 1337, returns the original number of false if validation fails echo

Utilice un algoritmo de suma de comprobación como Luhn :

<*>

EDITAR: olvidé mencionarlo, pero al usar este método puede verificar si una ID es válida sin siquiera tener que consultar la base de datos, por ejemplo:

<*>GET['id']; // 1337

EDITAR: olvidé mencionarlo, pero al usar este método puede verificar si una ID es válida sin siquiera tener que consultar la base de datos, por ejemplo:

<*>GET['id'], 3); if ($id === false) { // someone is trying to guess the ID } else { // $id is valid, do the DB stuff here }

EDITAR: olvidé mencionarlo, pero al usar este método puede verificar si una ID es válida sin siquiera tener que consultar la base de datos, por ejemplo:

<*>GET['id'] = Luhn($id, 3); // 1337518, adds 3 checkdigits

Utilice un algoritmo de suma de comprobación como Luhn :

<*>

EDITAR: olvidé mencionarlo, pero al usar este método puede verificar si una ID es válida sin siquiera tener que consultar la base de datos, por ejemplo:

<*>GET['id'] = Luhn_Verify(

Utilice un algoritmo de suma de comprobación como Luhn :

<*>

EDITAR: olvidé mencionarlo, pero al usar este método puede verificar si una ID es válida sin siquiera tener que consultar la base de datos, por ejemplo:

<*>GET['id'], 3); // 1337, returns the original number of false if validation fails echo

Utilice un algoritmo de suma de comprobación como Luhn :

<*>

EDITAR: olvidé mencionarlo, pero al usar este método puede verificar si una ID es válida sin siquiera tener que consultar la base de datos, por ejemplo:

<*>GET['id']; // 1337

EDITAR: olvidé mencionarlo, pero al usar este método puede verificar si una ID es válida sin siquiera tener que consultar la base de datos, por ejemplo:

<*>

Todavía será posible recorrer sus páginas secuencialmente, aunque sería más difícil adivinar el patrón. Mientras el patrón raíz sea secuencial, eventualmente tendrá un problema (suponiendo que en realidad sea un problema en primer lugar, y no solo algo de lo que no le guste la idea).

Puede usar números aleatorios para las ID. Eso evitaría adivinar fácilmente los ID de las páginas y el orden de las páginas (de nuevo, si eso es importante).

También puede usar Hashids para codificar / decodificar sus ID.

  

Este código fue escrito con la intención de colocar los identificadores creados en lugares visibles, como la URL.

  

Hashids es una pequeña biblioteca de código abierto que genera identificadores cortos, únicos y no secuenciales a partir de números.
  Convierte números como 347 en cadenas como "yr8", o una matriz de números como [27, 986] en "3kTMd".
  También puedes decodificar esos identificadores. Esto es útil para agrupar varios parámetros en uno o simplemente usarlos como UID cortos.

No me preocuparía por este '' problema '', pero de todos modos utilicé en uno de mis proyectos ese método:

Después de guardar una nueva página en la base de datos, generé md5 de (record_id + page_title) y lo puse en el campo especial pagecode . Luego accedí a las páginas por ese código de página en lugar de id. Y es mejor indexar el campo pagecode en la base de datos.

  

Los visitantes del sitio pueden enumerar los identificadores   y simplemente caminar por todos los   diferentes páginas de contenido Esta   no debería ser posible, por supuesto.

No estoy seguro de por qué esto debería ser un problema: las personas pueden ver una lista de todas las páginas (públicas, indexadas por Googlebot) en un sitio web simplemente escribiendo site: domain.com en Google, y repítelos si lo desean. Cambiar el índice único que usa no cambiará eso.

Pero si realmente no desea que los visitantes accedan a sus páginas directamente, una solución rápida simple es usar POST en lugar de GET.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top