Prevent XSS attacks with string replace method in JavaScript - javascript

I am writing an application where the user can add messages, they are saved in the firebase, and displayed on the page. I am using the following method to protect html injection:
function testHtml(str){
return str.replace(/</g, '<').replace(/>/g, '>');
}
And I output the text as follows:
$("#save").click(function(){
let text = $("#text").val(); //user input
text = testHtml(text);
$("#resultDiv").append(text);
});
I want to know if this method is safe? Are there any workarounds? If so, which ones? I use this filtering method when displaying messages. Many thanks for considering my request.

Related

Javascript converts XML characters to &LT and &GT

I am currently using DYMO Label Printing software to print labels. I have previously had the label XML template stored as plain text and it worked fine. But recently I have decided to move to a more dynamic approach so that labels can be edited and modified directly from the database.
So I am currently storing the XML label templates in a simple SQL database table. I set up the viewmodel that contains the XML information, and then access it in Javascript when printing in the View itself.
I previously just tried this:
try {
var labelXml = "#Viewmodel.XMLString"; //Open XML from Viewmodel directly
var labelD = dymo.label.framework.openLabelXml(labelXml);
}
catch(err) {
alert("Couldn't load label");
return;
}
And that did not work.
I did some research and also tried this (placing viewmodel in "text/plain") and then accessing it above.
<script>
try {
var labelXml = $('#label_XML').text();
var labelD = dymo.label.framework.openLabelXml(labelXml);
}
catch(err) {
alert("Couldn't load label");
return;
}
</script>
<script id="label_XML" type="text/plain">
#Viewmodel.XML
</script>
Both of these methods result in this: (<> replaced with &lt and &gt)
How can I simply access a XML string in the database from the viewmodel while avoiding any unwanted conversions? Thanks.
Using #Html.Raw results in this problem:
The first line is read correctly but with each line break it reads as code instead of text. I put the original #Html.Raw in quotes, is there a way to prevent it from attempting to read it as code as shown above?
It looks like you are struggling with HTML Encoding. Have you tried using #Html.Raw(Viewmodel.XML)? That helper should prevent MVC from HTML encoding the content.
Depending on where that XML content comes from, you might be creating an XSS risk, so be careful how you use Html.Raw and consider reading more about it if it does solve this problem for you Is there a risk in using #Html.Raw?

Special letters displaying as HTML entities in form

I'm trying to send information (name and email) from one form to another form on another page. The problem is that when the information is sent to the second form, any special letters (like å, ä, ö etc.) are displayed as HTML entities (ö becomes &ouml). I'm a beginner coder and did not build the form that sends the information myself, but I believe it's sent with jQuery. The form is validated, serialized and then decoded before it's sent to the other page. Code is below:
/*Form Submit*/
$('#button').click(function(){
if (validateForm()) {
var data = $("#form-signup").serialize();
var dataDecoded = decodeURI(data);
var regUrl = 'mypage.com/registration' + '&' + dataDecoded;
$("#link").attr("href", regUrl);
if (($('#checkBox').is(':checked'))) {
$('#checkBox').css('outline', 'none');
return true;
} else {
$('#checkBox').css('outline', '1px solid red');
$('#checkbox-message').next().addClass('checkbox-error');
$('#checkbox-message').next().text('Please Tick the Agree to Terms of Use');
return false;
}
}
});
In console all letters and special characters look alright, as well as in the URL on the second page. The URL becomes something like:
mypage.com/registration?&firstName=Björn&lastName=Björngård&email=bjorn%40mail.com.
But in the actual form the name displays like: Bj&amp';ouml';rn Bj&amp';ouml';rng&amp';aring';rd. (Without the ') . Email displays correct.
Any idea if the problem is with sending the information or receiving?
Thanks in advance!
Use the function :
unescape(Your_String_Here);
its a pure JavaScript function url decodes any value
see this
Update
Check this as well:
var parser = new DOMParser;
var dom = parser.parseFromString(your_string);
var decodedString = dom.body.textContent;
alert(decodedString);

Send a user to a certain URL depending on his text field input

Basically I want the ff. done:
User inputs a text in my text field. If his text matches a text in my "list," he is sent to a certain URL once he hits the submit button.
I found a similar code on this site but his is just one specific text value. [ Get input text field from HTML into JavaScript and go to URL ]
I want mine to determine the user's text input from a list I provide. My list will have a lot of texts/urls and it will continue to grow, so manually inputting values into the script won't work for me.. I want to be able to edit the list (possibly in an admin panel or something?) instead of the js code.
Example:
input text: aaaa, go to URL1
input text: mmne, go to URL2
input text: lhfj, go to URL3
input text: tigf, go to URL4
input text: gred, go to URL5
Can anyone help me with this please? Thanks!
Hope this helps you
var Something =$("#TextBoxID").val();
if(Something == "aaaa")
{
window.location.href = 'URL1'; //Will take you to URL1
}
......
......
if you want to configure the list on an admin console you need to have some kind of server side technology like php (or node.js if you want to keep using javascript). You need to think of where this data will be stored. A possibility would be fetching the list of text/url pairs using ajax (e.g. with jQuery) and storing the data in some database or in your case also a plain text file probably would suffice. The functionality you are looking for is not possible with plain HTML and JavaScript on cient side.
Use a function like this, if you store your URLs on the client side (HTML/JS page):
function determineAndGoToURL(text) {
var url = "#";
switch(text) {
case "aaaa":
url="www.google.com";
break;
case "bbbb":
url = "www.bing.com";
break;
default:
url = "www.yahoo.com";
break;
}
window.location.href = "http://" + url;
}
If you have an updated list of URLs on the server side, get them from server-side to client side, and iterate over them with a for statement.
I'd suggest, you'd get them from the server as JSON, and use JSON.parse(text) to create an object out of them, and then iterate.

Make sure user doesn't put in malicious html in code

I'm using a textarea to get input from the user and display it on the screen. How can I make sure that if they put in something like
<h1>YAY, I hacked in</h1>
I only display it as it is, and it doesn't display as an <h1>. There must be a function for this. Help? :D
As I commented, if you're about to send that data to a server, you should use one of the various XML Parsers available and strip + validate the input.
If you however, need to purely validate on the client, I suggest you use document.implementation.createHTMLDocument, which creates an fully fledged DOM Object on the stack. You can then operate in there and return your validated data.
Example:
function validate( input ) {
var doc = document.implementation.createHTMLDocument( "validate" );
doc.body.innerHTML = input;
return [].map.call( doc.body.querySelectorAll( '*' ), function( node ) {
return node.textContent;
}).join('') || doc.body.textContent;
}
call it like
validate( "<script>EVIL!</script>" );
You need to address this on the server side. If you filter with JavaScript at form submission time, the user can subvert your filter by creating their own page, using telnet, by disabling JavaScript, using the Chrome/FF/IE console, etc. And if you filter at display time, you haven't mitigated anything, you've only moved the breakin-point around on the page.
In PHP, for instance, if you wish to just dump the raw characters out with none of the user's formatting, you can use:
print htmlentities($user_submitted_data, ENT_NOQUOTES, 'utf-8');
In .NET:
someControl.innerHTML = Server.HtmlEncode(userSubmittedData);
If you're trying to sanitize the content client-side for immediate/preview display, this should be sufficient:
out.innerHTML = user_data.replace(/</g, "<").replace(/>/g, ">");

Using jQuery on a string containing HTML

I'm trying to make a field similar to the facebook share box where you can enter a url and it gives you data about the page, title, pictures, etc. I have set up a server side service to get the html from the page as a string and am trying to just get the page title. I tried this:
function getLinkData(link) {
link = '/Home/GetStringFromURL?url=' + link;
$.ajax({
url: link,
success: function (data) {
$('#result').html($(data).find('title').html());
$('#result').fadeIn('slow');
}
});
}
which doesn't work, however the following does:
$(data).appendTo('#result')
var title = $('#result').find('title').html();
$('#result').html(title);
$('#result').fadeIn('slow');
but I don't want to write all the HTML to the page as in some case it redirects and does all sorts of nasty things. Any ideas?
Thanks
Ben
Try using filter rather than find:
$('#result').html($(data).filter('title').html());
To do this with jQuery, .filter is what you need (as lonesomeday pointed out):
$("#result").text($(data).filter("title").text());
However do not insert the HTML of the foreign document into your page. This will leave your site open to XSS attacks.
As has been pointed out, this depends on the browser's innerHTML implementation, so it does not work consistently.
Even better is to do all the relevant HTML processing on the server. Sending only the relevant information to your JS will make the client code vastly simpler and faster. You can whitelist safe/desired tags/attributes without ever worrying about dangerous ish getting sent to your users. Processing the HTML on the server will not slow down your site. Your language already has excellent HTML parsers, why not use them?.
When you place an entire HTML document into a jQuery object, all but the content of the <body> gets stripped away.
If all you need is the content of the <title>, you could try a simple regex:
var title = /<title>([^<]+)<\/title>/.exec(dat)[ 1 ];
alert(title);
Or using .split():
var title = dat.split( '<title>' )[1].split( '</title>' )[0];
alert(title);
The alternative is to look for the title yourself. Fortunately, unlike most parse your own html questions, finding the title is very easy because it doesn;t allow any nested elements. Look in the string for something like <title>(.*)</title> and you should be set.
(yes yes yes I know never use regex on html, but this is an exceptionally simple case)

Categories