How to not do chat apps

In this post I’ll be talking about XSS. For anyone wondering what is XSS I think you should watch this video from Computerphile about it : https://www.youtube.com/embed/L5l9lSnNMxg

This list will probably help you understand how easily it can be performed (I’ll provide a solution against XSS at the end in the form of a Javascript function).

For this list I searched “chat” on the Glitch search engine and found some projects where it’s possible to do XSS.

Chat App IO - https://glitch.com/~chat-app-io

It’s possible to do it by sending a message and also with your nickname (you can set it with the button on the top of the page)

Chatter - https://chatter.glitch.me/chat#general

You can do it with messages but nicknames does not work BUT it makes the website not work correctly because there will be an “html tag jam” instead of the normal website.



There isn’t that many chat apps that aren’t remixes of an example by socket.io where HTML was handled correctly. So I’ll probably add more to this list as time passes so people can try that out, because it will allow you, the reader, to learn how to not do chat apps.

To counter XSS, you have to ensure every bit of data generated by a user is not detected as executable. To do that, there’s one simple way : The characters used to start and end tags have equivalents, it means that graphically they are the same, but they’re not able to start/end an html tag. Since you’ll need to replace this characters quite a lot of time (when displaying usernames, user-generated text, etc…) when building chat apps, here’s a function that will handle it for you. It returns text that wont be detected as HTML in any way.

function nohtml(message){
return message.replace(/</ig, '&lt;').replace(/>/ig, '&gt;');
}

This function replaces < to the symbol called “lesser than”, and > to the symbol “greater than” and returns the result string.

6 Likes

Don’t forget SQL injections too.

Javascript also provides a function called escape for this which might be useful if html changes or adds a new character(which won’t happen in a long time but nice to be future proof).
Also for sql injection just use a well-known library like endb and if there’s an issue you can blame the library. If you do write your own library don’t concatanate sql strings there’s another method to do it where you put ,s or something and then the library subsitutes it in with your actual string with it being escaped.

Yes, there’s also that but I can’t demonstrate it on Glitch unless I make a sandbox project where I authorize everyone to do it SQL injections. That’s why I did not talk about that.

I also recommend looking into OWASP top 10 security vulnerabilities. They explain what they are, how to do them and how to prevent them.

1 Like

Many drivers nowadays have built in methods for devs which allow them to completely eliminate SQL injections.

1 Like

PHP: What if we made SQL injections easier?

2 Likes

Can’t you just format the data, to completely plain text? I always put messages with .innerText instead of .innerHTML.

No, when displaying a new message you need to manipulate the innerHTML with HTML DOM, which makes it so all messages that include HTML will inevitably be detected and ran. Replacing the symbol makes it so it’s not able to start/end a tag, you can’t mess with the website’s DOM this way and no one will be able to place malicious scripts.

You don’t need to use .innerHTML, I can just do this:

var messagesList = document.getElementById("messages-list");
// When someone messages, this will be called when server tells us
function onMessage(message) {
  var messageItem = document.createElement("div");
  messageItem.classList.add("message");
  messageItem.innerText = (message.content).toString();
  messagesList.appendChild(messageItem);
}
// Just an test
onMessage({
  content: '<script>window.location.reload();</script>'
});

image

Can you do XSS? If yes, then how?

1 Like

It’s not a matter of type of value, it’s a matter of the characters used. innerHTML will makes it so the characters are detected regardless of what type it is. .appendChild also executes the code in innerText if it’s in a script tag :

const tag = document.createElement("script");
tag.innerText = `console.log('Inner Text Used')`;
document.body.appendChild(tag); //executes code

Source : https://stackoverflow.com/a/52707305

But yes, innerHTML looks secure as it doesn’t make the code executable.

1 Like

However I am not putting this into <script>

1 Like