Se necesita una bomba de tiempo en la aplicación ASP.NET
security time-bomb (23)
"No parece probable que paguen por ello, por lo que a nuestro jefe le gustaría que introduzcamos una bomba de tiempo".
Un empresario incompetente le está pidiendo que implemente una solución técnica a un problema comercial. Si su cliente no va a pagar, su Jefe debe lidiar con la situación como un adulto y no está jugando con bombas lógicas como un hacker de secundaria.
No es ético, probablemente sea ilegal, pero sobre todo es simplemente estúpido.
Desarrollamos una aplicación ASP.NET a medida para usar en la intranet de nuestros clientes. Parece que es poco probable que lo paguen, por lo que a nuestro jefe le gustaría que le introduzcamos una bomba de tiempo.
[Editar:] ¡Las respuestas técnicas solo por favor! Si esta es una buena idea (o legal) es una pregunta para CEOoverflow.com ;-)
Todas las páginas de la aplicación heredan de una clase llamada ApplicationBasePage y tienen un manejo de errores consistente, así que estoy pensando que lanzar una excepción al principio del ciclo de vida de ApplicationBasePage será una manera fácil de hacer que la aplicación no se pueda usar. Aunque estoy abierto a otras ideas que puedas tener.
Mi pregunta es: ¿cómo y dónde deberíamos almacenar la fecha en que caducará la aplicación?
Algunos puntos a tener en cuenta:
- La aplicación está instalada en un solo servidor en las oficinas del cliente.
- Los datos de la aplicación se guardan en una base de datos de SQL Server 2005 que se encuentra en el mismo servidor. La base de datos fue diseñada por nosotros y no se usa para nada más.
- La aplicación solo es accesible en su intranet: no hay acceso a la aplicación a través de Internet.
- Actualmente tenemos acceso de escritorio remoto a su servidor, pero esperaríamos perder eso si las cosas se ponen feas.
- La aplicación está escrita en .NET 2.0.
- La seguridad es manejada por FormsAuthentication.
- Necesitamos poder apagar la bomba de tiempo o cambiar fácilmente la fecha de activación (supongamos que todavía tenemos acceso remoto al escritorio para hacer esto).
- El servidor normalmente puede acceder a Internet, pero sería mejor no confiar en esto.
- La bomba de tiempo solo bloqueará a los usuarios: no destruirá ningún dato.
- A menos que se desencadene, el cliente nunca debe estar al tanto de la existencia de la bomba de tiempo.
- Su informático estará feliz hurgando en la web.config o en la base de datos. Él no es un programador, pero no tiene miedo de cambiar las cosas "solo para ver qué pasa". Descompilar o aplicar ingeniería inversa a la aplicación estaría más allá de sus capacidades.
Para obtener crédito adicional, ¿cuánto crees que está bien confiar en la seguridad a través de la oscuridad en este caso?
[ Editar: ]
- La aplicación hace muchas cosas dependientes de fechas críticas para el negocio, por lo que podemos estar seguros de que no cambiarán el reloj en su servidor ya que esto haría que la aplicación sea peor que inútil.
¿Su servidor web tiene acceso a internet? Es posible que desee utilizar un servicio web para activar la bomba de tiempo, además de otros métodos, ya que el sysadmin astuto puede estar dispuesto a configurar el reloj en el servidor hace unos años.
A sabiendas, la introducción de una "bomba de tiempo" como esa es ciertamente ilegal. Tu jefe no es el primero en considerarlo y no será el último. Su mejor opción es detener la implementación de la producción hasta que se realice un pago.
Bueno, aquí hay algunas cosas en las que puedo pensar
- Ponga una bomba lógica que dependa de que una de sus personas inicie sesión, de modo que dentro de un cierto número de días de la última aplicación de inicio de sesión se apaga.
- Para usar un bloqueo basado en la fecha y almacenar la fecha en una tabla en el servidor SQL. Pero encripte el valor almacenado utilizando un algoritmo estándar que utiliza una sal enterrada en su código. De esta forma evitará exponer la fecha a sys-admin.
- Utilizando el método anterior, almacene un valor entero grande desde el que realice una cuenta regresiva tan pronto como la aplicación cargue en IIS, una vez que llegue a cero elimine el valor en el archivo db y bloquee la aplicación, deberá restablecer el valor utilizando su encriptación. para trabajar de nuevo
- La seguridad por oscuridad está bien si esta aplicación, pero si desea comercializar esto como un producto, entonces necesitaría algún tipo de encriptación.
Ninguno de estos son infalibles, sin embargo ...
Descargo de responsabilidad: no soy ningún tipo de experto legal, respondí esto desde un punto de vista técnico solo. Yo personalmente no haría esto, ya que creo que es moralmente ambiguo.
Como muchos otros aquí, yo diría que no lo hagas. No sé si es ilegal, pero simplemente no se siente bien. Las empresas deben basarse en la confianza y la discusión abierta debe tener prioridad sobre tales esquemas.
Habla de tus preocupaciones y congela el desarrollo, si es necesario. ¡Supongo que quieren el producto después de todo!
Dejando a un lado los problemas éticos, si le preocupa que se haya pirateado la implementación de su número de serie, ¿por qué no usar un certificado X509? Si, por ejemplo, tiene una caja de Windows con el servidor de certificados instalado, puede exponer una lista de revocación de certificados en Internet.
Emita a cada cliente un certificado de identificación del cliente (bonificación si está suministrando la verificación de actualizaciones a un servidor central; ahora puede usar HTTPS cliente / servidor sin preocuparse por las contraseñas).
Si el cliente no paga, entonces revoque el certificado. En el inicio de la aplicación simplemente carga el certificado y verifica su validez ...
Dos pensamientos:
1) Yo alojaría la aplicación fuera del sitio hasta que paguen o hasta que depositen el dinero en custodia. Si dicen que no funciona y no pagarán, no les importará si desactiva el acceso mientras se resuelve el acuerdo, ¿o sí?
2) Hemos hecho algo similar a esto antes. Pasamos mucho más tiempo considerando que cualquier posible "bomba de tiempo" sería 100% a prueba de balas para que no se disparara accidentalmente antes de la fecha de corte, o en algún momento accidentalmente después de haber sido "desactivada". Por ejemplo, puede ser mejor eliminar el código en lugar de simplemente cambiar un indicador de "Prueba" a "Uso ilimitado".
Es posible que desee advertir a su jefe que si su cliente sufre alguna pérdida monetaria (incluida la pérdida de clientes), su empresa será responsable de esa pérdida y, probablemente, de las sanciones, además de los honorarios legales de su empresa. Y, si la empresa no sobrevive la demanda y el acuerdo, se quedará sin trabajo.
Lo pensaría dos veces antes de seguir con esto si fuera tú.
Esto es bastante secreto, pero podría simplemente escribir una tarea programada que ejecute un programa que sane todas las contraseñas. No arruina ningún dato, y mientras tenga acceso puede deshabilitar la tarea de programación. Además, si sucede algo en el que desea devolverles la información, sería tan fácil como desaprobar ... desalar ... las contraseñas.
Como con muchos otros, me gustaría tener reservas sobre la implementación de esto.
Esto suena como un trabajo para un abogado.
Aparte de eso, usaría un archivo de configuración simple que contiene la fecha de vencimiento. Luego, almacene un hash cifrado RSA de esa fecha en el archivo de configuración, también. Si actualiza la fecha de caducidad, simplemente actualice el hash cifrado también. La aplicación lee la fecha de forma regular y descifra el hash con la clave RSA pública y luego verifica el hash. Si reproducen la fecha, el hash cifrado o la clave pública, la aplicación deja de funcionar.
Estoy de acuerdo con el comentario sobre llamarlo como una versión de prueba y dejarlo caducar. En uno de nuestros productos, un sistema de publicación web, tenemos una clase de página común que verificará la clave de licencia de los usuarios y, si no es válida, imprimiremos un mensaje en la parte superior de todas las páginas. El mensaje es muy visible pero no afecta la forma en que funciona el programa.
Para hacer el control, almacenamos una "clave de registro" en el archivo web.config. Comparamos esto con una clave que calculamos, y el algoritmo para calcularlo se almacena en un ensamblaje por separado. Si las claves coinciden, suponemos que el producto tiene licencia.
Para nuestro uso, solo proporcionamos un nombre de cliente para el algoritmo de calculcación de la clave de registro, pero es posible que desee agregar un número de versión o alguna otra fecha. La clave de registro se genera calculando un hash MD5 del nombre suministrado combinado con un código secred (algunos bytes aleatorios en una matriz).
Esto de ninguna manera es a prueba de tontos o muy sólido, pero es simple y ha sido suficiente para nuestro uso.
Los problemas técnicos son manejados por programadores, los problemas de negocios son manejados por abogados. Su jefe necesita usar la herramienta adecuada para el trabajo.
Mueva un poco de lógica a un servicio web en sus propios servidores. Deje que la aplicación del cliente dependa de ese servicio web. Tiene una buena razón para mover esa lógica, como "Es nuestra actividad principal, así que tenemos que controlar eso", hacer ese cambio como parte de una "nueva versión" del programa.
Renueve el contrato con el cliente con una nueva sección que indique que si no pagan, se desconectará su servicio web.
Si no quieren firmar el contrato, no quieren hacer negocios con usted y usted puede desconectar el servicio web por ellos, si firman, aceptan los nuevos términos.
Esta es realmente la única forma de hacerlo si quieres estar seguro de que no pueden usarla si no pagan. De lo contrario, tienes que transmitir sobre demandarlos o amenazas como esa.
No ponga su nombre en todo lo que haga y elimine todos los comentarios existentes que tengan su nombre en ellos. Si va a ser legal y su nombre está en el programa, su jefe podría arrojarlo fácilmente debajo del autobús y decir que no tenía nada que hacer con él. Me volvería a considerar seriamente seguir esta dirección. Sé que es decisión de la gerencia, pero si estás haciendo el trabajo que fácilmente podría volver a morderte.
No puedo hablar sobre los problemas legales.
Técnicamente, supuse que podrías hacer esto. Haga un par de claves y use la clave privada para encriptar un archivo con una fecha de vencimiento. Su aplicación usará una clave pública para descifrar el archivo con la fecha de vencimiento. Cada vez que se ejecuta el programa, se muestra de manera prominente algo así como "quedan 57 días hasta que expire la licencia. Yada, yada". De esta forma, tienen una advertencia continua de que la aplicación dejará de funcionar.
En cuanto a corromper cualquier dato después de la caducidad, no lo haría. Creo que cifraría algunos elementos clave en los datos que requieren la aplicación para descifrar.
Sin embargo, es difícil sortear un administrador de sistemas que retrasará el reloj. Pero, si tiene una conexión neta, puede tenerlo "teléfono a casa" para obtener la clave, y no funcionar en absoluto si no puede obtenerla.
No soy abogado, pero aquí está mi punto de vista: si afirman que el programa no funciona y es inutilizable, entonces no pueden argumentar más tarde que ''funciona menos'' y lo consideran responsable de los daños a menos que ya hayan hecho pagos parciales por lo funciona.
Me gustaría obtener su queja por escrito antes de probar cualquiera de las sugerencias aquí. (Añadiría que la ruta de "prueba gratuita" parece más segura)
Realmente no veo ningún escenario donde esto termine bien. Si le preocupa que le paguen (y presumiblemente están preocupados por pagar una aplicación antes de que se la entreguen), ¿qué tal establecer algún tipo de depósito en garantía? Ponen el pago en depósito con provisiones mutuamente acordadas para liberar el dinero, y luego continúan trabajando sabiendo que el dinero se ha dejado de lado hasta que terminen.
Si desea que la fecha esté en el servidor y no en Internet, parece que su única apuesta es la seguridad a través de la oscuridad. Sin embargo, esto es sensato: no querría que la aplicación verifique en Internet cada vez que se inicia la fecha y muera cuando hay una mala conexión a Internet.
El método más fácil es guardar la fecha en el ensamblaje como una variable. Si tiene miedo de la simple descompilación, cifre y almacene también la clave en el ensamblaje. Si cree que le gustaría cambiar la fecha en el futuro, guárdela en DB / web.config (encriptada, por supuesto). Para el cifrado puede usar cualquier cosa desde base64 a la criptografía de clave pública. Obviamente eso no obstaculizará la descompilación seria de su código ... pero es bueno para los principiantes.
En una nota lateral, ¿la ''bomba lógica'' te recuerda a Swordfish también?
Si el cliente tiene todas las piezas del software, no puede evitarlo por completo.
La única forma adecuada es hacer que la aplicación dependa de algún componente que posea, por ejemplo, podría requerir una activación después de un tiempo, o un ping a su servidor web.
Esto se puede lograr tomando la fecha de instalación y usándola como una especie de clave sal / criptográfica y encriptando todos los datos con ella. A continuación, puede comparar contra la fecha de instalación. Si el cliente se atornilla con él (ajustando el reloj), lo notará ya que tiene la fecha de instalación original. Si cambian la fecha, eso también cambiará la clave criptográfica y, por lo tanto, los datos ya no podrán descifrarse.
Todavía hay una forma de evitarlo, pero con cualquier solución basada en el tiempo de alguna manera necesita mantener la fecha de instalación como una base para comparar, y debe hacer que esto sea seguro, de ahí la idea de usar en algún tipo de cifrado para proteger todos los datos con él.
Un par de puntos a considerar:
¿Esto es legal? Suponiendo que no planee revelar este Huevo de Pascua, "a menos que se desencadene, el cliente nunca debe estar al tanto de la existencia de la bomba de tiempo ", es posible que tenga problemas legales ...
Si el cliente tiene acceso a la fuente, no puedo imaginar cómo podría incluir algo que no pudieran contratar para que lo eliminara un desarrollador. Incluso si el técnico de TI no es un desarrollador, no está más allá de su capacidad contratar a otro desarrollador para realizar ingeniería inversa del código.
Por último, mal karma ... Si realmente está trabajando con un cliente en quien no cree que confíe para pagar realmente, ¿entonces por qué trabajar con ellos? Esperaría que quisiera poner todo sobre la mesa y obtener un compromiso total del cliente antes de realizar el trabajo. Si el cliente se niega a comprometerse a pagar, yo caminaría ...
Implementaré algún tipo de método en un dll compilado que almacene en el directorio bin. Llámalo algo distinto de timebomb.dll
.
A continuación, debe tener un método en este dll que devuelva verdadero o falso:
public bool hasTimeExpired() {
//Pseudocode
DateTime expires = new DateTime(Janurary 10, 2009);
return ( DateTime.Now() >= expires );
}
Simplemente compruebe el método hasTimeExpired () en el Inicio de la aplicación (global.ascx ??) o en ciertas páginas de códigos, dependiendo de cómo quiera manejar el mensaje de vencimiento.
El dll en el directorio bin sería fácil de reemplazar con una nueva versión compilada cuando quisieras apagar el timebomb o extender el tiempo. Tendría que ser descompilado para determinar la fecha de vencimiento y sería fácil eludirlo si descubren cómo funciona, pero como dijiste, el administrador en cuestión probablemente no haría esto.
Aparte de esto, realmente necesita trabajar con un abogado, pero a veces un bloqueo en un software prestado como este es más efectivo y más barato que un abogado.
¡Gracias por todas tus respuestas!
No hicimos exactamente lo que sugirió una persona, pero usamos ideas de varios de ustedes.
En primer lugar, dejamos de llamarlo bomba de tiempo y, en su lugar, lo llamamos licencia. Como el software está (posiblemente) incompleto en este momento, y como el cliente no lo ha pagado, podemos llamarlo una versión de prueba que expira. Esto (probablemente) nos hace pasar la mayor parte de un campo minado legal, y (como señaló zsharp) si afirman que el producto es de calidad inferior, realmente no pueden quejarse si no pueden usarlo.
De todos modos, la implementación técnica es la siguiente:
Queríamos que la fecha de caducidad se ocultara donde no se tropezara, y si se notaba, estar en una forma que no sería fácilmente modificable. También tenía que estar en algún lugar del que pudiéramos estar seguros de que no se vería afectado inadvertidamente, a pesar de que está en un servidor sobre el que no tenemos tanto control.
Entonces, encriptamos la fecha de caducidad y la colocamos en una Propiedad Extendida en la base de datos que usa la aplicación, dándole un nombre apropiadamente engañoso.
La aplicación comprueba la clave al inicio, estableciendo un indicador booleano estático en verdadero si la aplicación no ha expirado. Cada página del sitio verifica este indicador y devuelve al usuario a la página de error si el indicador es falso.
Estamos contentos con esta solución por los siguientes motivos:
- Es fácil para nosotros cambiar la fecha de caducidad de la aplicación.
- No hay confianza en que se pueda acceder a Internet, ni a nada más allá de su servidor.
- La protección sobrevivirá a las copias de seguridad y restauraciones, o la aplicación se moverá a otra casilla.
Cuando los argumentos se han detenido, nos han pagado y todos somos amigos otra vez, la próxima actualización a su aplicación no tendrá el control en absoluto, asegurando que esta pieza olvidada de código no se active accidentalmente en algún momento. señalar años después (¡gracias, Kristen!).
Haga la ruta del antivirus, realice una llamada externa para "Actualizaciones". Si no obtiene las actualizaciones, la aplicación deja de funcionar si no pagan, deje de darles actualizaciones.
Creo que es la solución incorrecta al problema, pero entiendo que su trabajo es hacer lo que le dicen.