

535 ways to reload the page with JavaScript - clu3
http://www.phpied.com/files/location-location/location-location.html

======
patio11
Yet another demonstration, if you needed it, on why blacklisting user input to
avoid code injection is highly unlikely to succeed. There are many ways to
skin a cat, and you only need to miss one.

You can also assume that the bad guys start with a list similar to this _and_
tools to semi-randomly perturb their inputs until they find the right combo of
hocus-locus to get past your filter and then "neutralized" by your regular
expression magic into functioning exploit code.

(n.b. I'm talking about more interesting attacker goals than forcing a reload,
obviously.)

~~~
Cushman
True as that may be, this doesn't really demonstrate that— it's just 535
different ways to access `location`. A regex would trivially disable every
one. Of the things on that list.

~~~
teej
"Some people, when confronted with a problem, think "I know, I'll use regular
expressions." Now they have two problems."

Show me your trivial regex solution to this problem and I'll show you how to
break it.

~~~
Cushman
I'm not saying there's a trivial regex solution to XSS, I'm saying there's a
trivial regex solution to disable every one of these so-called "ways" of
reloading the page: s/[\\.\\[=]//g will do the trick.

I mean, s/location//g will do the trick too, but I was aiming a little more
generic.

~~~
mike-cardwell
eval(unescape("%64%6F%63%75%6D%65%6E%74%2E%6C%6F%63%61%74%69%6F%6E%2E%68%72%65%66%3D%27%68%74%74%70%73%3A%2F%2F%67%72%65%70%75%6C%61%72%2E%63%6F%6D%2F%27"))

~~~
Cushman
...and if that were on this list of ways to reload a page in JavaScript that
I'm talking about, it would be relevant here.

Look, just _read_ what I'm saying. I swear I know what I'm talking about, and
I _swear_ I'm not saying you can reliably sanitize JavaScript with a regex.
Really.

This must be like the FizzBuzz thing— programmers just can't resist a
challenge, even if it is explicitly marked as not being a challenge.

And thanks for the hscroll :P

~~~
mike-cardwell
hscroll? Here on Firefox 5, it wraps nicely...

~~~
Cushman
Huh— I'm on Chrome 13. Just one of those things, I guess.

~~~
Groxx
/me inspect element -> delete node

/me happy

Odd, that FF wraps... maybe I'll look into it later today, I kinda wonder why.

------
Groxx
I was hoping for a bit more cleverness... that's (at least very nearly) just a
combination of:

    
    
      location=              | combined with
      location.href=         |   
      location.assign()      |   location
      location.replace()     |   location.href
      -----------------------------------------
      location.reload()
    

and things that mean exactly the same thing. As others here have pointed out,
why no meta tags? Form submissions? Surely there's another way or two as well.
The lack of creativity in this list is rather astonishing - if it were sorted,
it'd be merely annoying because of the blatant repetition.

------
Animus7
I really see only two ways here:

1) one of hundreds of equivalent syntaxes for the AST that assigns to
location, and

2) location.reload()

So if we're going to play this game and these count as different, why not
encode the identifiers in hex notation? Or replace the identifiers with lambda
calls to compute them? Or eval()?

Seems like if these 535 ways count, so should the other infinity of them.

~~~
Cushman
That's not completely true— location.replace() and location.assign() do
slightly different things. But, yeah, this is basically 535 different ways to
_spell_ location = location.

And not even very interesting ones. window.window _is_ window, so you can just
go nuts with the chaining. So is window.self, window.top, window.frames...
window.self.top.frames.location = frames.top.self.window.location? Now we're
talkin'.

~~~
sjs
Yeah, not very exciting. Once you go down that road you pass by window['l' +
'ocation'] on the way to window['loc' + (''+![])[!![]+![]] + (''+!![])[-![]] +
'ion'] and so on. I would have completed it but it's 2:30 and I'm tired.

~~~
karl_nerd
sorry to bother you sir but could you tell me what that is called and maybe
where i find out more about it?

~~~
karl_nerd
ok found this good old one <http://news.ycombinator.com/item?id=2129745>

~~~
sjs
l33t searching skills, I couldn't find it. That's where I learned this
technique.

------
bherms
Interesting to see so many ways to do it, but what's missing is explanations
of pros and cons of the different approaches (though I'm sure there probably
aren't many differences). Why not just stick with one then?

~~~
barrkel
I read it as more poking fun at the combination of redundancy in the DOM API
combined with redundancy in Javascript.

------
vladd
Is there any way which doesn't break the back navigation button (since upon
pressing back the JavaScript statement will execute again, causing an
immediate change of location and jumping forward again in the history)?

I thought about checking whether history.forward is empty as a condition for
changing the location, but I don't think you're allowed to do that check...

Alternatives such as meta refreshes and non-JavaScript solutions are cool ways
to solve this, but for POST calls it remains an issue...

~~~
pornel
For POST you should use POST-redirect-GET pattern with status 303.

You can change URL in JS without creating history entry with
location.replace().

------
kree10
Several years back I was on a job where the boss wanted to allow virtually any
user-provided HTML/CSS/JS in a content area, while preventing redirects.

No implementation ever happened of course, but my first thought was, what
would happen if we did a "<script>delete(window.location);</script>" near the
top of the template?

Answer: nothing. But what would the implications be if browsers allowed it?

~~~
ryanpetrich
Some browsers allow __defineGetter__ and __defineSetter__ to replace native
properties such as window.location

~~~
kree10
Interesting. I did a few tests and it seems Chrome will let me override
window.location with __defineSetter__() but not document.location, while
Safari was the other way around. Firefox 3.x won't let me redefine either one
("TypeError: redeclaration of var location").

------
program
Given that "window" is the top level object in JavaScript:

location === window.location === self.location

and that objects are also associative arrays:

oneObject.aMethod === oneObject['aMethod'] === oneObject['aMet' + 'hod']

you can write infinite variant of the same function call.

------
bobds
There's a whole lot more of these actually. Here are a couple off the top of
my head:

    
    
      - Meta refresh tags could be one.
    
      - Creating a form on-the-fly and submitting it via Javascript.

------
n1ck4n
Could any js ninjas briefly explain what's the actual secret/js philosophy
behind all these methods?

~~~
alanstorm
File under: Unintended Consequences. Also, Postel's law could probably be
tricked into admitting itself as an accomplice.

1\. Browser based Javascript provides a location object for managing and
accessing the current browser location, and this location object is available
as a global variable.

2\. Browser based Javascript also provides a special case in the
interpreter/processer/etc., where setting the location object equal to itself
will reload the current page. This is also true for certain properties of the
location object (href)

3a. There is also a more conventional reload method on the location object
which accepts either a location object or string href. Also, many of the "go
to this URL methods" exposed to Javascript will interpret "go to the url I'm
at" as a request to reload the page. Many of these methods will accepts a
location object, or a string representation of a URL as a paramater.

3b. location.href is a string representation of a URL

3\. There are many ways to access global variables in Javascript. There are
many ways to assign a value in javascript. There are many ways to call a
method in javascript.

4\. All of the above can be combined into lots (likely more than the 535) of
ways to achieve the same thing.

------
andyford
I can hear it now... "but how do I do it in jQuery?!"

------
vijaydev
From <http://ycombinator.com/newsguidelines.html>:

If the original title begins with a number or number + gratuitous adjective,
we'd appreciate it if you'd crop it. E.g. translate "10 Ways To Do X" to "How
To Do X," and "14 Amazing Ys" to "Ys." Exception: when the number is
meaningful, e.g. "The 5 Platonic Solids."

~~~
alexobenauer
I think in this case the number is meaningful, because the point of the list
isn't to show us X amount of ways to actually refresh a page with javascript,
but rather to highlight the (slightly humorous) vast number of ways it can be
done, due to the ambiguity and redundancy found in Javascript (and in the
DOM).

I would have guessed that this number would be high, but definitely not in the
500's.

~~~
Cushman
`window.window === window`, so that number is actually in the infinities.

