1

I'm having issues setting up a proper way of escaping strings and sanitizing data sent from the server to the client.

I've tried the encodeURI function built within Javascript, however the names in my chat look very chunky having %'s in them etc.

function sendChat(data){
  var message = `<div class="message flex">
    <div class="image flex flex-v flex-h">
      <img src="${ data.avatar }">
    </div>

    <div class="content">
      <div class="name flex">
        <div>
          ${ data.username }
        </div>

        <div class="level">
          ${ data.level }
        </div>
      </div>

      <div class="text">
        ${ data.message }
      </div>
    </div>
  </div>`;

  $('.chat .box').append(message);
 }

Whenever a user puts in alert('hi') as an text message it is obviously sent to the the client and converted into proper js, however to prevent this I'd like to sanitize the data without it looking funky, is there any proper function to use so I can still safely sanitize the data without it looking scuffed..?

Borda
  • 139
  • 1
  • 10
  • What do you mean by look chunky? Where is it looking"funny"? In code, you may not be able to get around that. To the end user, does it not get decoded properly? Is the encoding on the server, and the files on the server set properly? Can you show an example of what you're trying to avoid (the issue you are seeing), and what you would like to have/see instead? Thank you for clarifying the issue. Also, take a peek at the suggested link, there are some good ideas for handling data there. – SherylHohman Feb 17 '19 at 03:10
  • When a username like `Alpha 1` is sent, it's shown as `Alpha%201` (or some other number than 20, not sure what a space is interpreted as. Anyhow I'll check out the link. – Borda Feb 17 '19 at 12:46

3 Answers3

0

use this

var StrippedString = OriginalString.replace(/(<([^>]+)>)/ig,"");

ALPHA
  • 1,135
  • 1
  • 8
  • 18
0

I ended up using;

String.prototype.escape = function() {
    var tagsToReplace = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;'
    };
    return this.replace(/[&<>]/g, function(tag) {
        return tagsToReplace[tag] || tag;
    });
};

to sanitizing data on the frontend.

Answer was found under Fastest method to escape HTML tags as HTML entities?

Borda
  • 139
  • 1
  • 10
0

A very safe way would be to build the message in jquery since you are already using it, like so (just a quick sketch - I appologise for the readability in advance):

 function sendChat(data) {

    var image = $('<img></img>').attr('src', data.avatar);
    var imageContainer = $('<div></div>').addClass('iange flex flex-v flex-h').append(image)
    var username = $('<div></div>').text(data.username);
    var level = $('<div></div>').text(data.level);
    var name = $('<div></div>').addClass('name flex').append(username).append(level);
    var text = $('<div></div>').text(data.message);
    var content = $('<div></div>').addClass('content').append(name).append(text)


    var message = $('<div></div>').addClass('message flex')
        .append(imageContainer).append(content);
    $('.chat .box').append(message);
}

While this is less readable, it is slightly more secure as you don't have to re-invent the sanitization and use the time-tested jquery implementation instead. For example, in your code an attacker could probably still hijack the src attribute of the avatar by convincing the system that their avatar is:

;\" onerror=\"\alert('hi')"

The best solution however would be to use a templating engine as these will sanitize it for you AND be readable at the same time. An example using mustache.js:

function sendChatMustache(data) {
    var message = 
         `<div class="message flex">
            <div class="image flex flex-v flex-h">
              <img src="{{avatar}}">
            </div>

            <div class="content">
              <div class="name flex">
                <div>
                  {{username}}
                </div>

                <div class="level">
                  {{level}}
                </div>
              </div>

              <div class="text">
                {{message}}
              </div>
            </div>
          </div>`;

    var html = Mustache.to_html(message, data);

    $('.chat .box').append(html);
}
Jakub Judas
  • 737
  • 6
  • 16
  • Yeah, I do like it to be readable though, and for the templating issue, I'm using SocketIO to have data update live. – Borda Feb 17 '19 at 15:13
  • A JavaScript templating engine should not prevent you from live updating your data any more than your current solution does. However, it might be Overkill if the project is small – Jakub Judas Feb 17 '19 at 16:20
  • I'm already using EJS for handling non-live data, however still for some data I will be using AJAX and still would need to sanitize data, correct? – Borda Feb 17 '19 at 16:28
  • Not necessarily - a client templating engine should be able to do it for you - I'll try to expand my answer with an example later today. – Jakub Judas Feb 17 '19 at 16:39
  • @Borda I have added an example with mustache.js - the output is automatically sanitized, so that is one less thing to worry about. – Jakub Judas Feb 17 '19 at 19:45