"%3Cscript" vs "<script" - javascript

Every once in a while, I'll see an HTML code snippet with:
%3Cscript
where the %3C replaces the <. Is this because the code was auto-generated or needs to display properly in an editor or was it coded that way explicitly for some reason and needs to keep that form on the HTML webpage? In case it is helpful here is the full beginning of the line of code I was questioning:
document.write(unescape('('%3Cscript
Wouldn't the line of code work just fine it you replaced the %3C with a <?

The unescape() Javascript function converts the %3C back to < before it gets written into the document. This is apparently an attempt to avoid triggering scanners that might see the literal <script tag in the source and misinterpret what it means.

When writing javascript in a script tag embedded in html, the sequence </script> cannot appear anywhere in the script because it will end the script tag:
<script type="text/javascript">
var a = "<script>alert('hello world');</script>";
</script>
Is more or less treated as:
<script type="text/javascript">
var a = "<script>alert('hello world');
</script>
";
<script></script>
In the eyes of the html parser.
Like mplungjan said, this is convoluted way and one can simply <\/script> in a javascript string literal to make it work:
<script type="text/javascript">
var a = "<script>alert('hello world');<\/script>";
</script>
This is not related to document.write technically at all, it's just that document.write is a common place where you need "</script>" in javascript string literal.
Also note that "<script>" is indeed totally fine as is. It's just the "</script>" that's the problem which you have cut out from the code.

As mentioned, possible attempt to fool scanners.
A more useful and important one is the
<\/script> or '...<scr'+'ipt>' needed to not end the current script block when document.writing a script inline

Related

inject JS code into a textarea

I am trying to show some JS code in a textarea. The code is generated with JS so I am injecting it into the textarea with JS. However, using the <script> tags, causes the script to execute. I thought using < would solve this, but this is simply displaying < instead of <.
Any suggestions how I can do this?
$('myTextarea').set('value', '<script>alert('do something');</script>');
Just separate the script tag into two.
$('myTextarea').val('<script>alert("do something");</scr'+'ipt>');
The next </script> after the opening <script> block closes the script block; whether it's contained with a JS string or not.
To fix you can either split the </script> like so;
$('myTextarea').set('value', '<script>alert('do something');</scr' + 'ipt>');
Or like this (less common, but works, and probably more correct);
$('myTextarea').set('value', '<script>alert('do something');<\/script>');
Furthermore, you also need to fix your quotes;
$('myTextarea').set('value', '<script>alert(\'do something\');<\/script>');
You can see this now working here: http://jsfiddle.net/pK9SK/

Unescaping ampersand characters in javascript

I'm having trouble properly displaying values that contain escaped characters (i.e. apostrophes are stored as \' and not ' and brackets are > and < rather than > and <).
Items stored in my database have the characters (' < >) escaped to (\' < >), respectively. When I try to dynamically add them to the page with JavaScript, they print out in the escaped form in Firefox, rather than returning to their normal values like in IE (< is being printed to the HTML rather just <).
<html>
<head>
<script type="text/javascript">
$(document).ready(function() {
var str = ">";
$(document.body).html(str);
});
</script>
</head>
<body>
</body>
</html>
I know that if I simply do a replace, I can print correctly, but by doing so, I'm allowing the injection of HTML code, which is why I escaped the string in the first place.
ADDED:
Firstly, I apologize about the mistakes in my initial post. After closer examination, in the instances where I am using $().html(), the strings are printing correctly. The times where they aren't printing correctly are when I am using code like below.
var str = ">";
$('#inputField').val(str);
In this instance, the text ">" is shown, rather than ">". Is there something I can do to fix this?
You need to decode them like this:
$('#myText').val($("<div/>").html(str).text());
Demo: http://jsfiddle.net/QUbmK/
You can move the decode part to function too and call that instead:
function jDecode(str) {
return $("<div/>").html(str).text();
}
$('#myText').val(jDecode(str));
First off, you can't run the code you have in your example. document.body is not ready for manipulation in the HEAD tag. You have to run that after the document has loaded. If I put your code in a safe place to run, it works fine as you can see here.
So ... there must be more to your situation than the simple example you show here. You can see your simple example works fine here when the code is put in the right place:
http://jsfiddle.net/jfriend00/RDSNz/
That doesn't happen, at least not with jQuery. If you do, literally: $(document.body).html('<div>'), you will get <div> printed to the screen, not a div tag. If you're doing something not listed in your question:
either use .text() instead of .html() or replace all & with &:
$(document.body).text(str);
$(document.body).html(str.replace(/&/g, '&'))

How do I get Aptana/Firefox to execute my JavaScript rather than show the code?

I'm extremely new to coding and I'm reading a book on it. And I think I have the basics down on this little test project I'm doing, but whenever I test the page I just see the code I used. Here's the entirety of my code.
<script type = "text/javascript">;
//<![CDATA[
// from concat.html
var person = "" ;
person = prompt( "What is your name?") ;
alert("Hi there, ") + person + "!");
//]]>
</script>
Honestly I don't know what the CDATA is for or what concat.html is.
How can I get Firefox to run my JavaScript rather than just show the code?
Try wrapping it in <html> to make the whole page get treated as HTML. Does the file have a .js extention, by any chance?
CDATA is to distinguish code from markup.
Put it in an HTML file.
So, first, save it as scriptname.html - you're embedding JavaScript within an HTML file.
Next, make it valid html - add <html> to the top and </html> to the bottom. And <head> and <body> tags where appropriate - if you don't know what those are, head over to any HTML site to look them up (www.diveintohtml5.org is nice, if you can follow it.)
Better install Firebug plugin for Firefox or use other browser's Javascript console. It will allow you to run your code
http://www.w3resource.com/web-development-tools/execute-JavaScript-on-the-fly-with-Firebug.php

What is the purpose of this JavaScript?

I was playing around with a Python-based HTML parser and parsed Stackoverflow. The parser puked on a line with
HTMLParser.HTMLParseError: bad end tag: "</'+'scr'+'ipt>", at line 649, column 29
The error points to the following lines of javascript in the site's source:
<script type="text/javascript">
document.write('<s'+'cript lang' + 'uage="jav' + 'ascript" src=" [...] ">');
document.write('</'+'scr'+'ipt>');
</script>
([...] replace a long link, which is removed for simplicity)
Out of curiosity, is there a specific reason for what looks to me like artificial 'obfuscation' of the code, i.e. why use the document.write method to concatenate all the chopped up strings?
I think it's to fight adblockers.
... + 'uage="jav' + 'ascript" src="http://ads.stackoverflow.com
It has been written in that way to avoid the browser thinks it's the closing tag for <script>, which would cause some problems.
When the HTML parser encounters document.write('</script>');, it thinks it has found the end of the enclosing <script> tag. Breaking the tag up stops the parser from recognising the closing tag.
The other way I've seen this achieved is by escaping the slash, i.e. document.write('<\/script>');.
The correct way to do this is either:
Enclose the body of the script in a <![CDATA[ ... ]]> block (if serving XHTML), or
Put the script in an external file, or
Use the DOM API instead (i.e. create a script node and append that to the document head)
Perhaps its there to stop programs that search specifically for script tags. Ad blockers, for example, look for script tags and object tags.

Javascript external script loading strangeness

I'm maintaining a legacy javascript application which has its components split into 4 JS files.
They are "Default.aspx", "set1.aspx", "set2.aspx" and "set3.aspx". The ASPX pages writes out compressed JS from multiple (all-different) source files belonged to their respective set and set content-type header to "text/javascript".
The application is invoked by adding a reference to the first set and creating the main entry object.
<script src="/app/default.aspx" type="text/javascript"></script>
<script type="text/javascript>
var ax;
// <body onload="OnLoad()">
function OnLoad() {
ax = new MyApp(document.getElementById("axTargetDiv"));
}
</script>
At the end of the first set of scripts (default.aspx) is the following exact code:
function Script(src) {
document.write('<script src="' + src + '" type="text/javascript"></script>');
}
Script("set1.aspx?v=" + Settings.Version);
Which loads the second set of scripts (set1.aspx). And this works without any errors in all major browsers (IE6-8 Firefox Safari Opera Chrome).
However, as I've been working on this script for quiet sometime, I'd like to simplify function calls in a lot of places and mistakenly inlined the above Script function, resulting in the following code:
document.write('<script src="set1.aspx?v=' + Settings.Version + '" type="text/javascript"></script>');
Which, when tested with a test page, now throws the following error in all browsers:
MyApp is not defined.
This happens at the line: ax = new MyApp(... as Visual Studio JS debugger and Firebug reports it.
I've tried various methods in the first 4 answers posted to this question to no avail. The only thing that will enable MyApp to loads successfully is only by putting the actual "add script" code inside a function (i.e. the document.write('script') line):
If I put the document.write line inside a function, it works, otherwise, it doesn't. What's happening?
Splitting and/or escaping the script text does not work.
To see the problem, look at that top line in its script element:
<script type="text/javascript">
document.write('<script src="set1.aspx?v=1234" type="text/javascript"></script>');
</script>
So an HTML parser comes along and sees the opening <script> tag. Inside <script>, normal <tag> parsing is disabled (in SGML terms, the element has CDATA content). To find where the script block ends, the HTML parser looks for the matching close-tag </script>.
The first one it finds is the one inside the string literal. An HTML parser can't know that it's inside a string literal, because HTML parsers don't know anything about JavaScript syntax, they only know about CDATA. So what you are actually saying is:
<script type="text/javascript">
document.write('<script src="set1.aspx?v=1234" type="text/javascript">
</script>
That is, an unclosed string literal and an unfinished function call. These result in JavaScript errors and the desired script tag is never written.
A common attempt to solve the problem is:
document.write('...</scr' + 'ipt>');
This is still technically wrong (and won't validate). This is because in SGML, the character sequence that ends a CDATA element is not actually ‘</tagname>’ but just ‘</’ — a sequence that is still present in the line above. Browsers generally are more forgiving and in practice will allow it.
Probably the best solution is to escape the sequence. There are a few possibilities, but the simplest is to use JavaScript string literal escapes ('\xNN'):
document.write('\x3Cscript src="set1.aspx?v=1234\x26w=5678" type="text/javascript"\x3E\x3C/script\x3E');
The above escapes all ‘<’, ‘>’ and ‘&’ characters, which not only stops the ‘</’ sequence appearing in the string, but also allows it to be inserted into an XHTML script block without causing errors.
(In XHTML, there's no such thing as a CDATA element, so these characters would have the same meaning as if included in normal content, and a string '<script>' inside a script block would actually create a nested script element! It's possible to allow <>& in an XHTML script block by using a <![CDATA[ section, but it's a bit ugly and usually better to avoid using those characters in inline script.)
1) Assure that you do not try to reference MyApp before the script is "actually" included in your page.
2) Try breaking the word "script" in your inline loader like this:
<script type="text/javascript">
document.write('<scr' + 'ipt src="set1.aspx?v=1234" type="text/javascript"></scr' + 'ipt>');
</script>
Alternatively, use this syntax which i borrowed from google analytics code and have been able to use successfully:
<script type="text/javascript">
document.write(unescape("%3Cscript src='set1.aspx?v=1234' type='text/javascript'%3E%3C/script%3E"));
</script>
You could also try:
var script = document.createElement("script");
script.src = "set1.aspx?v=1234";
script.type = "text/javascript";
document.getElementsByTagName("head")[0].appendChild(script);
Steve
If you could use JQuery you could use the following:
$.getScript("set1.aspx?v=1234");
This loads the script into the global javascript context.
Make sure you set contenttype of the response to "text/javascript".
Hope this helps...

Categories