5

In my game, I changed the list of players from canvas to html, due to which a vulnerability appeared that any player can give himself a name into which he can insert js code, for example, <script>alert(1);</script> which will work for all players when the player appears in the player list. The question is, how to make html not work and everything that the player enters is displayed as text? The pre tag in html didn't help me :(

The code for adding a player to the player list:

const drawLeaderboard = function() {
    if (!settings.showLeaderboard || !leaderboard.items) return wjQuery('#leaderboard').css('display', 'none');
    else wjQuery('#leaderboard').css('display', 'block');
    
    
    let text, vip = false,
        isMe = false;
    
    const texts = {
        all: '',
        emoji: ''
    };
    
    for (let i = 0; i < leaderboard.items.length; i++) {
        if (leaderboard.type == 'text')
            text = leaderboard.items[i];
        else
            text = leaderboard.items[i].name,
            isMe = leaderboard.items[i].me,
            vip = leaderboard.items[i].vip;
        
        texts.all += `<div class="item"${isMe ? 'style="color: #faa;"' : ''}>${text.trim()}</div>`;
        texts.emoji += `<div class="item">${vip ? '' : ''}</div>`;
    }
    
    wjQuery('#leaderboard > .content > .items').html(texts.all);
    wjQuery('#leaderboard > .content > .emoji').html(texts.emoji);
}
TopoR
  • 75
  • 6

3 Answers3

1

There are already good answers on this, e.g. this one;

I stole the answer to save you a click ;-)

There are additional answers in this thread that you might also find interesting.


var entityMap = {
  '&': '&amp;',
  '<': '&lt;',
  '>': '&gt;',
  '"': '&quot;',
  "'": '&#39;',
  '/': '&#x2F;',
  '`': '&#x60;',
  '=': '&#x3D;'
};

function escapeHtml (string) {
  return String(string).replace(/[&<>"'`=\/]/g, function (s) {
    return entityMap[s];
  });
}
MarcRo
  • 2,434
  • 1
  • 9
  • 24
1

This is an example of cross site scripting. we can prevent it by encoding HTML entities using regex.

var encodedStr = $('#inputText').replace(/[\u00A0-\u9999<>\&]/g, function(i) {
   return '&#'+i.charCodeAt(0)+';';
});

this encoded string if displayed in html is same as the characters but wouldn't evaluate as javascript

0

You could simply replace all tags with an empty string. See this example:

const regex = /<\/?[a-zA-Z]+>/g;
const input = document.querySelector('input');
const newValue = input.value.replaceAll(regex, '');
console.log(newValue);
<input type="text" value="My name is ... <script>alert('Trying to hack...');</script>">
Reza Saadati
  • 5,018
  • 4
  • 27
  • 64