How is this XSS attack working? - javascript

SPOILER ALERT: This question contains an answer to one of the problems from the Google's XSS Challenge! Please stop reading further if you're not interested in knowing the answer right now.
I'm able to get pass the level 4 of the challenge, however, I still don't know how exactly the exploit is working. The following is the code from Google's XSS challenge - Level 4:
<!doctype html>
<html>
<head>
<!-- Internal game scripts/styles, mostly boring stuff -->
<script src="/static/game-frame.js"></script>
<link rel="stylesheet" href="/static/game-frame-styles.css" />
<script>
function startTimer(seconds) {
seconds = parseInt(seconds) || 3;
setTimeout(function() {
window.confirm("Time is up!");
window.history.back();
}, seconds * 1000);
}
</script>
</head>
<body id="level4">
<img src="/static/logos/level4.png" />
<br>
<img src="/static/loading.gif" onload="startTimer('{{ timer }}');" />
<br>
<div id="message">Your timer will execute in {{ timer }} seconds.</div>
</body>
</html>
Basically, they are using Django framework (which uses a bunch of security measure against XSS). The variable timer carries the input from the user. The goal of this activity is to alert a message by sending a payload which can bypass Django's XSS security.
I'm able to alert a message using one of the following payloads:
');alert('xss
OR
3') || alert('1
I'm able to clear the level using the above payloads but I'm still not sure where exactly the alert() method is being called? In the onload handler OR within the startTimer() method?
I'm confused because if I check the source HTML of the page after submitting the payload, Django is encoding the payload:
<html>
<head>
<!-- Internal game scripts/styles, mostly boring stuff -->
<script src="/static/game-frame.js"></script>
<link rel="stylesheet" href="/static/game-frame-styles.css" />
<script>
function startTimer(seconds) {
seconds = parseInt(seconds) || 3;
setTimeout(function() {
window.confirm("Time is up!");
window.history.back();
}, seconds * 1000);
}
</script>
</head>
<body id="level4">
<img src="/static/logos/level4.png" />
<br>
<img src="/static/loading.gif" onload="startTimer('');alert('xss');" />
<br>
<div id="message">Your timer will execute in ');alert('xss seconds.</div>
</body>
</html>

What seems to be confusing you is the mix of two different languages: HTML and JavaScript. ' is HTML. It's translated to the ' character when displayed and when interpreted as JavaScript. That means, from the JavaScript interpreter's point of view, there's no difference between ' and '. The code onload="startTimer('');alert('xss');" is effectively the same as onload="startTimer('');alert('xss');" even though at the first glance it looks like something that shouldn't work.

I see why the XSS worked! One of the section in the OWASP XSS cheat sheet says:
HTML entity encoding is okay for untrusted data that you put in the
body of the HTML document, such as inside a tag. It even sort of
works for untrusted data that goes into attributes, particularly if
you're religious about using quotes around your attributes. But HTML
entity encoding doesn't work if you're putting untrusted data inside a
tag anywhere, or an event handler attribute like onmouseover,
or inside CSS, or in a URL. So even if you use an HTML entity encoding
method everywhere, you are still most likely vulnerable to XSS. You
MUST use the escape syntax for the part of the HTML document you're
putting untrusted data into. That's what the rules below are all
about.
In this case, the user input is being fed into an event handler, which will treat it as a JS instead of HTML. And, the input is being escaped in HTML context (not in JS context). Therefore, JS will treat startTimer('3') || alert('1'); as startTimer('') || alert('1'); and will simply run this script.
PS: JS escaping might have prevented the attack.

Related

Javascript not functioning properly on my whole system

SOLVED: So the problem was that the program broke at when I declared userInput but that was already declared in the js file that I initialized right before this app.js file. Once I changed the name it seems to be better now, thanks all! :D
So i've started a JS tutorial and all the code is doing weird things and not executing in the proper order no matter how many times I close and reopen the program.
I am working on a calculator program from the tutorial so i've copied the code how it appears.
Here is the file structure:
Here is my index.html (notice the script tags at the end of the body)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Basics</title>
<link
href="https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="assets/styles/app.css" />
</head>
<body>
<header>
<h1>The Unconventional Calculators</h1>
</header>
<section id="calculator">
<input type="number" id="input-number" />
<div id="calc-actions">
<button type="button" id="btn-add">+</button>
<button type="button" id="btn-subtract">-</button>
<button type="button" id="btn-multiply">*</button>
<button type="button" id="btn-divide">/</button>
</div>
</section>
<section id="results">
<h2 id="current-calculation">0</h2>
<h2>Result: <span id="current-result">0</span></h2>
</section>
<script src="assets/scripts/vendor.js"></script>
<script src="assets/scripts/app.js"></script>
</body>
</html>
I put the script tags at the end of the body so the site content is generated first but it still runs the script first sometimes, and only when I refresh enough times does it stop. Weird...
app.js
let currentResult = 10;
currentResult = currentResult + 10 * 3;
let calculationDescription = `${currentResult} (0 + 10)`
outputResult(currentResult, calculationDescription)
alert("hello")
And then when I press Ok on the alert
Only then does the calculation get done. Which is strange because the calculation is written to be executed BEFORE the alert (The calculation did appear a few times while the alert was active, but only 15 seconds later, it doesn't even do that anymore)
When I add..
const userInput = 123;
let result;
After the alert in app.js, the alert stops running entirely!
This makes no sense to me. I wanted to have some js code after the alert so I can put in another alert but this file is making it seem like the alert MUST be the last thing in a js file OR there can only be approx 5 lines in a js file.
Also, the css in the project wasn't working until I moved the entire project from my downloads folder to my desktop (and removed the 5 parent folder hierarchy over it) and there the css did work...
Any idea what can be causing this mess, or is my computer just cursed?
Assumptions:
I've saved the code so it is fully updated
I am using VScode
Running from my OneDrive folder on Windows 10
You essentially asked three questions here:
Why do I see result of my calculation only after closing the alert?
Why does adding const userInput = 123; let result; after the alert prevent the alert from showing up at all?
Why is my CSS not working in some circumstances?
Let me answer all:
Answer to Question 1: Order of execution
The code does execute in order. You can see that if you use the devtools debugger to step through it line by line. What's tripping you up is when the browser redraws page content, as this happens at the end of a tick, when there is no more code to be run in that tick. Rerendering the page instantly whenever something on it gets changed would be very slow (and could induce flicker, depending on what it is that you are updating).
So what happens is this:
Your calculation result is set as content of your element. (But you don't see it yet since the page hasn't been redrawn yet.)
Your alert shows up.
You close the alert.
The call to the alert function returns and the code continues.
No more code is there to run (at least synchronously), and the page is redrawn. (Now you see the changed content.)
In the rare cases where the calculation did show up 15 seconds later, it was probably that something else, something external (such as maybe resizing the window) triggered a redraw despite the alert still being open.
alert isn't the best way to get output anyway, for several reasons: it also obscures a lot of information about more complex data types because it coerces everything to a string, and you cannot easily trace the source of the alert or log the exact time it was shown - all of which are things that console.log would do better.
Answer to Question 2: Why adding code can break everything
Most likely you were introducing a syntax error at that point. For example you may have already declared userInput or result previously, and adding that code made the whole file invalid with a SyntaxError: Identifier 'result' has already been declared or the like, so it wouldn't execute at all.
That's because when a script file (or a <script> tag content) is loaded, it's first parsed (at which point you can encounter "compile-time errors" such as a SyntaxError) and only then it's executed (and then you can encounter "runtime errors" such as a ReferenceError). If you add a single bad character at the very end of your file that's causing a SyntaxError during parsing, the whole file will no longer run.
You would see this error and where it originates from if you'd look into the console tab of your devtools.
In general, I can only recommend learning how to use devtools rather sooner than later: https://www.youtube.com/watch?v=Y3u2groOG-A
Answer to Question 3: Missing styles
It's hard to tell with the information given. Again, a good start would be to check in your devtools for errors in regards to loading the CSS file (in console and network tabs). Also, in case you are using a file:// URI, I'd recommend switching to a local HTTP server instead. Many things behave differently with file:// URIs compared to http:///https://.

HTML will not execute JavaScript functions

I am trying to get a very simple javascript project going, but I cannot get any function to execute. Here is a simple example. It is obviously just an example. I have tried everything I can think of to get the browser to recognize that I am trying to call a function that has been defined, but it never does anything but just display the text, rather than call anything. In the below example, I simply get a page with the text: "varTimesTwo(3);"
<!DOCtype html>
<html>
<body>
<script>
function varTimesTwo(oneVar){
return (oneVar * 2)
}
</script>
varTimesTwo(3);
</body>
</html>
your code is wrong, you have to place varTimesTwo(3); inside the script tag, like this:
<!DOCtype html>
<html>
<body>
<script>
function varTimesTwo(oneVar){
return (oneVar * 2)
}
varTimesTwo(3);
</script>
</body>
</html>
Keep all JavaScript code in the script tags, or better yet, in a file
separate from the html file using <script src="myjsfile.js"></script>
You can use document.write(string) to write a string to the document.
This string is treated as HTML so you need to use <p>text</p> or <br> to get line breaks.
<!DOCtype html>
<html>
<body>
<script>
function varTimesTwo(oneVar){
return (oneVar * 2)
}
document.write("3 times two is "+varTimesTwo(3));
</script>
</body>
</html>
Alternatively, you can use window.alert(string) or simply alert(string) to pop up an alert box. But if you have turned off pop-ups in the browser, these will not pop up.
<!DOCtype html>
<html>
<body>
<script>
function varTimesTwo(oneVar){
return (oneVar * 2)
}
alert("3 times two is "+varTimesTwo(3));
</script>
</body>
</html>
console.log(string) writes to the debugging console, which you can see on many browsers with either control-shift-J or F12.
The javascript debugging console is also useful for learning javascript without messing with input and output. Anything you type in the JS console is immediately executed, so you can define functions there and play with them without having to write additional code to write the output or read input.
Finally, these techniques are insufficient for most websites as they are actually used. Instead, what is done is to define an html container element and change the text or html that is inside. jQuery provides a browser-independent method of manipulating the document to change items on the page.

Eval already loaded script tag

I have the following code
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
<script type='text/javascript' src="js.js" id="scripter"></script>
</head>
<body>
<button>AGAIN</button>
</body>
</html>
The included js has as set of statements whichg gets executed as soon as the page load.
* NOTE : it does not contain any function and dont want to contain any function.
On click of the button AGAIN i want to eval the entire script once again. Any possible ways this can be done ??
Trying to get the script contents of the script included so that I can eval it.
Any possible ways this can be achieved ??
OR
Some other method to achieve the same ??
Thanks.
For people downvoting this : I know those are what functions are for, hence specified note specifically. Maybe I should have asked the latter part of the question directly wtihout giving much details. Is it possible for me to access the scripts content that gets included in a page ??
It can be achieved by setting <script>'s src attribute to the same with a random get variable like
scriptTag.src = scriptTag.src + "?r=" + Math.random();
which will cause the browser to load the entire file again and that's usually not a good idea, but that's how it could be done
I dont know how big that JS file of yours is but - if its possible - you can write that file as
$someVariable = ' Whole Javascript code in quotes';
And whenever you want to run the code again just call eval($someVariable).
Now you might have a question for me. How is it gunna run at the very first time.
just add following line at the end of your JS file.
eval($someVariable);

AJAX returning a javascript to be parsed results in loss of page contents

So I've been working recently on a script to obfuscate client-side code for protecting intellectual property without interfering with the appearance or interactivity of the resulting page. The process is as follows:
HTTP request comes in, .htaccess redirects (.*) to parse_request.php
parse_request.php creates a "phpURLParser" class whose class variables are essentially copies of the $_SERVER variables
phpURLParser looks at the requested path, and sometimes the host, referer, or other server-side information to determine how to react. There are several possible responses
a. The requested object was a .js or .css file. Pass the file to the YUI Compressor and send the output
b. The requested object is an image or application. Pass the file with no change
c. The requested object contains HTML. Replace every ASCII character with its 2-digit hexadecimal equivalent and send the following javascript:
<script type="text/javascript">
var x="~lots of hex~";
var y="";
for(i=0; i<x.length; i+=2){
y += unescape('%'+x.substr(i,2));
}
document.write(y);
</script>
So the website is replaced by a lot of hex and a small javascript to return the hex to its original form. I have an example of this setup at examples.chikachu.com/colorbox/example1 (I didn't code ColorBox, it's a free jQuery tool that I chose to use since it allowed me to test several different javascript features and make sure they all worked)
Now for the problem:
As it turns out, this works 99% of the time. But AJAX makes it angry. Clicking one of the AJAX examples (under "Other Content Types") will look like it redirects you to a new page. Looking in the address bar or viewing the page source will prove that you're still on the same page, however. Using the Inspect Element tool in Chrome (or Firebug in Firefox) will reveal that the contents of the webpage were entirely replaced by the contents of the AJAX request.
If I modify parse_request.php slightly to allow the file requested by the AJAX to be passed through unharmed, everything works. No problem. So for some reason my script which replaces the string of hex with its meaningful HTML counterpart is overwriting the entire website instead of nicely inserting itself within the confines of a <div> object.
Essentially here's the expected non-obfuscated HTML:
<html>
<head>
...
</head>
<body>
<div id="colorbox">
<INSERT AJAX HERE>
</div>
...
</body>
</html>
With only the AJAX obfuscated, I expect the following:
<html>
<head>
...
</head>
<body>
<div id="colorbox">
<script type="text/javascript">
var x="asdfasdfasdfasdf";
var y="";
for(i=0; i<x.length; i+=2){
y += unescape('%'+x.substr(i,2));
}
document.write(y);
</script>
</div>
...
</body>
</html>
I expect that the document.write() line here will write y at the location of the javascript (within the <div>). If I'm mistaken and that's not how document.write() works, I still expect it to write y at the end of the document. Instead, the entire document is replaced by y. Why is this, and what's my solution?
Answer to your last question:
Calling
document.write('my_precious_html_code');
will append or override text on page depending when it was called (before or after onLoad event). You shouldn't use it any script. Read more about it here: http://javascript.crockford.com/script.html
General answer:
Obfuscating HTML code doesn't make any sense. Just like protecting images by disabling right mouse button in late '90. It took me less then 3 sec to "crack" your obfuscated code and get beautifully formatted HTML. Also your site is rendered in quirks mode which is probably something you don't want.
Try something like this:
<html>
<head>
...
</head>
<body>
<div id="colorbox">
<div id="MYAJAXCONTENT">
</div>
<INSERT AJAX HERE>
</div>
...
</body>
</html>
<html>
<head>
...
</head>
<body>
<div id="colorbox">
<script type="text/javascript">
var x="asdfasdfasdfasdf";
var y="";
for(i=0; i<x.length; i+=2){
y += unescape('%'+x.substr(i,2));
}
document.getElementById('MYAJAXCONTENT').innerHTML = y;
// for the jQuery psychos out there
// $('#MYAJAXCONTENT').html(y);
</script>
</div>
...
</body>
</html>

How does the location of a script tag in a page affect a JavaScript function that is defined in it?

I read that you should define your JavaScript functions in the <head> tag, but how does the location of the <script> (whether in the <head>, <body>, or any other tag) affect a JavaScript function.
Specifically, how does it affect the scope of the function and where you can call it from?
Telling people to add <SCRIPT> only in the head sounds like a reasonable thing to do, but as others have said there are many reasons why this isn't recommended or even practical - mainly speed and the way that HTML pages are generated dynamically.
This is what the HTML 4 spec says :
The SCRIPT element places a script
within a document. This element may
appear any number of times in the HEAD
or BODY of an HTML document.
And some sample HTML. Doesn't it look pretty all formatted here :)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<HTML>
<HEAD>
<TITLE>A document with SCRIPT</TITLE>
<META http-equiv="Content-Script-Type" content="text/tcl">
<SCRIPT type="text/vbscript" src="http://someplace.com/progs/vbcalc">
</SCRIPT>
</HEAD>
<BODY>
<SCRIPT type="text/javascript">
...some JavaScript...
</SCRIPT>
</BODY>
</HTML>
And something to look forward to in HTML 5 :
New async attribute in <SCRIPT> :
Note: There are ways [sic] a script can be
executed:
The async attribute is "true": The
script will be executed asynchrously
with the rest of the page, so the
script will be executed while the page
continues the parsing.
The async attribute is "false", but
the defer attribute is "true": The
script will be executed when the page
is finished with the parsing.
The normal rules of play still stand; don't use stuff before it's defined. :)
Also, take note that the 'put everything at the bottom' advice isn't the only rule in the book - in some cases it may not be feasible and in other cases it may make more sense to put the script elsewhere.
The main reason for putting a script at the bottom of a document is for performance, scripts, unlike other HTTP requests, do not load in parallel, meaning they'll slow down the loading of the rest of your page. Another reason for putting scripts at the bottom is so you don't have to use any 'DOM ready' functions. Since the script tag is below all elements the DOM will be ready for manipulation!
EDIT: Read this: http://developer.yahoo.com/performance/rules.html#js_bottom
One of the aspects of placement is performance. See this fine article within the YSlow discussion for why it's sometimes recommended you put them at the bottom of the document.
As for issues of scope, the usual visibility rules for Javascript (vars defined inside or outside of functions, local, global, closures, etc.) are not affected so far as I know.
Position of script tag does matter.
If you bind a Function with document Element then the document element has to be loaded first before we implement function. suppose getTeachers() is function in getTeachers.js file.
This will give you an error:
<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Unit Teachers</title>
<head>
<script type="text/javascript" src="getTeachers.js"></script>
<script type="text/javascript">
document.getElementById("buttonId").onclick=function(){getResults()};
</script>
</head>
<body>
<form>
<input type = "button" id="buttonId" value = "Press for Results" /><br />
</form>
<span id="results" /></span>
</body>
</html>
It gives error before head is loaded first and it cannot find element with id specified.
The below code is correction:
<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Unit Teachers</title>
<head>
<script type="text/javascript" src="getTeachers.js"></script>
</head>
<body>
<form>
<input type = "button" id="buttonId" value = "Press for Results" /><br />
</form>
<script type="text/javascript">
document.getElementById("buttonId").onclick=function(){getResults()};
</script>
<span id="results" /></span>
</body>
</html>
If your script refers to an ID on the page and the page has not been rendered (i.e. script is before HTML, or your script is executed with onload, rather then the DOM is ready) you can also get an error.
It doesn't. Most programming framework scatter scripts all throughout the page. I've only rarely seen problems because of that (and only from older browsers).
If you pull Javascripts in through XMLHttpRequest, like Diodeus said, it probably won't work. In my case, there was no error, the browser just ignores the new script(s).
I ended up using this, not terribly elegant but works for me so far:
http://zeta-puppis.com/2006/03/07/javascript-script-execution-in-innerhtml-the-revenge/
How to use execJS: http://zeta-puppis.com/2006/02/23/javascript-script-execution-in-innerhtml/
Note: Watch out for < in this line: for(var i=0;i<st.length; i++)
If you have an inline script (outside functions) located before functions it may call, you may get an error because they may not be not available yet. Not saying it is always going to happen, just that it may depending on browser type or version.
Javascript's scoping rules are similar to perl - you can call any function at the current or any higher scope level. The only restriction is that the function has to be defined at the time you call it. The position in the source is irrelevant - only the position in time matters.
You should avoid putting scripts in the <head> if possible as it slows down page display (see the link Alan posted).

Categories

Resources