[00:00.000 --> 00:03.720] Thank you for waking up early after a night of debauchery here at HOPE. [00:04.480 --> 00:07.160] I'd like to thank the previous speaker for warming the audience up. [00:07.340 --> 00:08.720] That was very enlightening. [00:09.500 --> 00:11.780] I want to give you a heads up ahead of time. [00:11.880 --> 00:18.180] If you're a super advanced leet hacker, as all of us are, you're probably going to find a lot of this talk to be extremely basic. [00:18.580 --> 00:20.600] So hopefully you'll stick around for the jokes. [00:21.240 --> 00:25.840] But, you know, just excuse my lack of leetness in this. [00:27.120 --> 00:29.320] So let me give you a bit of background on me. [00:30.000 --> 00:32.340] I'm Ben Combee, unwired, Ben on Twitter. [00:32.840 --> 00:40.020] My current job is working on JavaScript frameworks for the company formerly known as Palm, currently known as a subsidiary of HP. [00:40.700 --> 00:44.740] Nothing I'm talking about today is speaking on behalf or in favor of my employer. [00:45.080 --> 00:46.760] So just ignore all that. [00:49.360 --> 00:51.140] I do like my employer, though, by the way. [00:51.140 --> 00:52.820] I'm just, you know, not speaking for them. [00:54.620 --> 00:57.680] In my past life, I was a browser developer at Mozilla. [00:57.980 --> 01:01.840] And then I worked on mobile devices and compilers and developer tools. [01:02.060 --> 01:06.160] So I spent a lot of time thinking about how people develop applications. [01:06.640 --> 01:13.780] And in this case, how they're developing for the web and what that means for all the web users out there and how you can find out what they're actually doing. [01:14.840 --> 01:24.260] So I thought what I'd do is I'd take you through four different examples looking at particular websites or applications and then looking at what tools you can use to figure out what they're really doing. [01:25.240 --> 01:29.320] So since we're in New York, my first example is going to be the New York Times. [01:30.660 --> 01:35.920] New York Times, you know, very popular website, millions and millions of hits a day. [01:36.380 --> 01:38.380] Let's see what's really going on when you load a page. [01:38.960 --> 01:43.280] So what I'm going to do is I'm going to tab over to my Google Chrome here. [01:44.080 --> 01:47.320] So this is showing just the New York Times web page as it is this morning. [01:49.800 --> 02:00.580] Now, Google Chrome for the last five or six releases, which probably I think means about three weeks now, has been shipping developer tools built into it that are really quite nice. [02:01.240 --> 02:08.360] The usual way you activate it is you go up to the menu bar and here on the Mac you'd go to View, Developer, Developer Tools. [02:09.800 --> 02:22.220] And this either brings up a separate window or if you go down here to the very bottom, I'm going to use this special zoom technique to go, whoo, click there and then come back out. [02:22.480 --> 02:24.060] It's docked at the bottom of the page. [02:25.160 --> 02:30.740] So, you know, that's kind of an easy, convenient way to get it there, but for our purposes we're going to undock it and see the full thing. [02:31.340 --> 02:41.580] So the Developer Tools lets you do things like look at the actual HTML text and it kind of shows it in this collapsed form where you can dig into it but not see everything at once. [02:42.180 --> 02:43.820] It lets you look at all the resources. [02:43.820 --> 02:46.520] It's basically all of the pieces of the page. [02:46.680 --> 02:54.500] So in this case we have one frame and we have maybe some database associated with it or index DB tables, cookies. [02:55.500 --> 02:57.540] But the key thing we're going to look at here is network. [02:58.100 --> 02:59.900] So what does this network tab do? [03:00.540 --> 03:06.420] Well, whenever you load a web page, you don't just load a single HTML file. [03:06.780 --> 03:16.760] That HTML file links to lots of other resources, whether they be images, scripts, flash movies, sound files, all sorts of stuff. [03:18.460 --> 03:27.440] So this network tab is going to show you every single HTTP transaction that web page makes as you're loading it and even as it's running in your browser as it goes on. [03:28.840 --> 03:33.520] So we brought this up after we already had loaded the New York Times page and we're noticing a few things here. [03:33.880 --> 03:36.580] We're noticing this reference to ping. [03:37.660 --> 03:42.720] So in HTTP parlance, an HTTP get is just a simple request to the server to send back a resource. [03:43.400 --> 03:53.540] HTTP also does post where you're sending information to the server and then it supports methods like put and delete that are mainly used by web geeks that like to write applications in a restful way. [03:55.280 --> 04:02.720] So just sitting here on the page, it's actually continually going and pinging something called static chartbeat.com... [04:02.720 --> 04:04.460] Well, no, that's who's pinging it. [04:04.760 --> 04:07.880] It's pinging a really complicated URL here. [04:08.680 --> 04:13.400] So looking at this URL, the first things we can notice is that there's a lot of information in this. [04:13.660 --> 04:21.740] Even though it's requesting just a single ping image, it's actually sending a huge amount of info about what's going on in that web page, what's going on in your browser. [04:22.820 --> 04:25.620] We also have services here, which is... [04:25.620 --> 04:28.880] looks like that's going to tubemogul.com. [04:29.020 --> 04:30.380] I'm not quite sure who that is. [04:30.840 --> 04:34.480] Well, let's go and reload the New York Times web page and see all the things it loads. [04:34.480 --> 04:40.140] So actually we can do command R from this or we can also do it from developer tools. [04:42.020 --> 04:46.880] So it's going to go and it's immediately showing us just this huge number of resources loaded. [04:49.620 --> 05:03.000] And as the time goes on, here at the very bottom of the screen, let's zoom in on that, we see there's 181 separate requests being made of all sorts of different services just to load up the New York Times web page. [05:03.700 --> 05:06.300] All in all, it's about 164K worth of data. [05:07.500 --> 05:10.780] Up to this point, it's taken 18 seconds to load all this. [05:11.500 --> 05:22.380] And this onload number is basically how much time it takes to get to the point where the web browser thinks the page is actually loaded and it stops showing that circle moving animation and, you know, you can't hit the X anymore. [05:24.320 --> 05:27.260] So what kind of stuff is loaded here on the New York Times site? [05:28.020 --> 05:31.200] We go to the very top, we have, of course, the New York Times web page. [05:31.880 --> 05:40.860] So if we click on that here in the developer tools, it actually shows us the HTTP headers that have been sent by the browser and all the responses that come back. [05:42.380 --> 05:45.520] So those headers, I mean, for the most part, are really boring stuff. [05:45.820 --> 05:47.840] I mean, it's saying, hey, I'm a web browser. [05:47.960 --> 05:53.160] I can accept some HTML text or I can accept some XML text or, you know, all these other things. [05:53.520 --> 05:55.360] Hey, I happen to like English a lot. [05:55.360 --> 05:56.620] You know, things like that. [05:57.640 --> 06:02.880] Kind of most useful for understanding, though, this interaction between the web browser and the website are cookies. [06:03.780 --> 06:11.000] So we're all familiar with the idea that cookies are data that get sent from web servers and get stored in your browser for some period of time. [06:11.420 --> 06:17.380] And whenever a cookie is associated with a particular domain, any request to that domain is going to send a cookie along with it. [06:18.160 --> 06:24.840] Now, fortunately, Chrome gives us kind of a view that decodes this big cookie block and shows all the details in it. [06:25.900 --> 06:28.880] So a lot of the cookies are really boring. [06:29.100 --> 06:31.880] I mean, the most common use of cookies is what's called session cookies. [06:32.200 --> 06:44.420] The idea is that when you go and log in or start a website transaction, the server sends down some unique random string that identifies your particular session of talking to that server. [06:44.680 --> 06:49.000] And so it can do things like save state on your behalf, all that. [06:49.000 --> 06:51.040] But then there are cookies which are tracking cookies. [06:52.000 --> 06:56.320] The ones to look for always are these ones starting with UT or underscore UT. [06:57.320 --> 07:00.740] So to explain what those are, I'm going to switch over to a different web browser. [07:01.260 --> 07:06.020] And this is a page on Google's site about a product called Google Analytics. [07:07.380 --> 07:14.980] I would say well over half the web right now is using some form of Google Analytics, which basically puts a very small script on your page. [07:15.160 --> 07:19.780] And whenever that page loads up, it's going to go and request a few files from Google. [07:20.000 --> 07:23.240] And that lets Google track your movement across the web. [07:24.980 --> 07:28.880] Fortunately, Google, you know, does try to be a little more transparent than a lot of people. [07:29.040 --> 07:35.020] So they have this whole website set up telling you what these cookies are, what they do, even what the cookie names are. [07:35.300 --> 07:38.260] So if you want to find out more about what these are, you can go there. [07:38.980 --> 07:44.380] If you have your browser set to block third-party cookies, some of this data gets blocked but not all of it. [07:44.700 --> 07:52.140] If we go back over to Chrome, we'll notice that this cookie is set on the New York Times web page, not on Google's site. [07:52.680 --> 07:56.340] That means that that cookie wouldn't be blocked by turning off third-party cookies. [07:56.560 --> 07:58.860] It probably would be blocked by turning off JavaScript. [07:58.860 --> 08:03.620] But, you know, that's something which is almost impractical to do on the web today. [08:05.060 --> 08:05.540] Okay. [08:06.000 --> 08:07.240] So back to the headers. [08:08.440 --> 08:11.580] Another useful header that gets sent with every request is refer. [08:11.960 --> 08:16.560] And that's telling the website what site you were looking at when you went to that. [08:17.500 --> 08:21.200] Usually if you type your URL into the address bar, it doesn't set a refer. [08:21.480 --> 08:28.180] But if you click on a link or hit refresh, then it will tell that site where you came from unless you have some extension to turn off refers. [08:29.180 --> 08:31.020] And then we also have user agent. [08:31.540 --> 08:35.840] So pretty much every browser build out there has a unique user agent string. [08:36.060 --> 08:41.320] And this string is kind of a giant pile of debris that's accumulated over time. [08:41.600 --> 08:46.400] And you notice we're using Chrome, but the very first thing it says is, hey, we're using Mozilla version 5. [08:47.500 --> 08:53.980] This is basically because a lot of websites do a lot of stupid things about how they detect particular versions. [08:55.460 --> 08:58.720] And they break if you send things they don't expect. [08:59.580 --> 09:06.940] I was just in a talk yesterday at a JavaScript conference where a guy from Opera was talking about, you know, they put in their user agent string, hey, I'm Opera. [09:07.980 --> 09:12.680] And currently they're syndicating their version as 9.8, even though they released version 12. [09:13.420 --> 09:18.560] The problem is that there are millions of websites out there that only look at the very first character of the version number. [09:18.840 --> 09:27.100] So when they tried going from 9 to 10, all the sites suddenly thought they were Opera version 1 and then started putting, you know, blinking banners and X10 ads. [09:27.100 --> 09:29.420] So, okay. [09:29.840 --> 09:32.080] So this is just kind of an example of what goes through HTTP. [09:32.440 --> 09:34.260] Let's look at what all these other things are. [09:35.100 --> 09:36.860] And we're not going to go through them one by one. [09:36.980 --> 09:38.900] I just want to point out some big categories here. [09:42.180 --> 09:44.300] So, there are things like CSS files. [09:44.500 --> 09:46.440] CSS files are just style sheets. [09:46.740 --> 09:54.980] They describe how elements on the page get laid out or how, you know, that this text has a blue color, this area has a certain amount of padding. [09:54.980 --> 09:56.480] Nothing too bad there. [09:57.060 --> 09:58.640] This is a JavaScript file. [09:58.860 --> 10:01.120] This is from a script tag on the page. [10:02.180 --> 10:05.080] Some JavaScript files are served directly by the New York Times. [10:05.480 --> 10:10.900] But you'll notice this is from js.nyt.com instead of newyorktimes.com. [10:11.680 --> 10:17.800] A lot of websites actually use a separate domain name to serve static content, content that's not dynamic. [10:18.160 --> 10:32.300] The reason for this has to do with this limitation that browsers voluntarily agreed to years ago where they wouldn't try to retrieve too many items from a single domain at one time in order to keep those servers from being overwhelmed. [10:32.920 --> 10:46.300] What that means is now effectively if you're trying to serve a page with lots and lots of elements, you have to set up a lot of different domain names and serve all the different pieces from them in order to get the most bandwidth from the server back to your web browser. [10:47.060 --> 10:50.200] So, I'm not too worried about the newyorktimes.com stuff. [10:51.020 --> 10:53.260] Here we have graphics 8 NY Times. [10:54.000 --> 10:59.700] Now, there's actually a reason why some content gets served from NYT and some gets served from New York Times. [10:59.860 --> 11:01.220] And that has to do with cookies again. [11:01.860 --> 11:11.940] If we go back to the cookies here, you'll see that there's this setting which is kind of not expanded very well called domain. [11:13.740 --> 11:17.000] And when you send a cookie back down, you can actually set a domain. [11:17.440 --> 11:26.400] So, you can say that this applies just to, you know, my site at newyorktimes.com or it applies to anything at newyorktimes.com. [11:26.760 --> 11:34.680] And so, if you want a cookie to be transparently passed between servers, then you need for them to share some root domain name. [11:34.820 --> 11:38.260] But if you don't care about the cookies being passed back and forth, then you can use a different domain. [11:40.780 --> 11:41.180] Okay. [11:41.940 --> 11:48.260] We're not going to hit the New York Times for too long, but there are some very curious things I saw when I was poking at this last night. [11:49.940 --> 11:50.340] Meter. [11:51.620 --> 12:00.280] If any of you remember, I guess it was a couple of years ago, the New York Times started charging for viewing more than, like, 10 or 15 articles on their website in a month. [12:01.120 --> 12:03.660] Meter.js is a JavaScript file that does that. [12:04.060 --> 12:10.920] And effectively, it does it by saving a cookie on your local browser and every time you go to a new article, it increments that number in the cookie. [12:11.180 --> 12:18.220] And when you get to a certain number, that's going to go and suddenly start doing pop-ups on top of you, saying, hey, log in. [12:18.460 --> 12:19.400] Hey, get a subscription. [12:20.520 --> 12:26.380] And if we look here in the developer tools, we'll see this preview actually shows what's in this JavaScript file. [12:27.100 --> 12:27.520] Okay. [12:27.920 --> 12:29.520] So this is why we come to a new tool. [12:30.220 --> 12:31.430] Because this is one... [12:32.060 --> 12:33.720] Well, actually, this isn't a bad line. [12:33.920 --> 12:35.860] There is definitely some lines that are worse than this. [12:36.480 --> 12:37.320] But we... [12:37.320 --> 12:39.040] You know, this is kind of hard for a human to read. [12:39.300 --> 12:43.720] So let's use a website called jsbeautifier.org. [12:44.340 --> 12:47.280] I'm grabbing that all, copying it, switching back to Mozilla. [12:49.680 --> 12:52.720] So jsbeautifier.org exists to unminify JavaScript. [12:53.380 --> 13:00.180] A lot of times if you're watching what goes over the network and looking at these JavaScript files, you're going to see that they're very compact. [13:00.460 --> 13:01.920] They've had all the white space removed. [13:02.260 --> 13:02.900] They've just, you know... [13:03.340 --> 13:06.760] This is actually not done necessarily to keep you from looking at them. [13:06.900 --> 13:11.280] It's done to reduce the size that they are when sent over the network so that web pages are quicker. [13:12.240 --> 13:15.460] So we're going to take this code, paste it into here. [13:16.720 --> 13:18.620] And that was not actually what I wanted to paste. [13:18.780 --> 13:19.340] Let's go back. [13:23.440 --> 13:25.680] Ah, control A is not really long. [13:26.060 --> 13:26.900] Let's try response. [13:33.310 --> 13:33.850] Okay. [13:37.130 --> 13:38.410] Okay, copy that. [13:38.850 --> 13:39.690] Tab over. [13:42.430 --> 13:46.250] Okay, much smaller amount there, but not everything. [13:46.790 --> 13:48.230] Okay, I'll do this for another thing. [13:48.310 --> 13:52.730] But what the jsbeautifier does is it goes and takes this JavaScript code. [13:52.830 --> 13:54.350] Double forward at the beginning to do it. [13:54.810 --> 13:55.350] Okay. [13:56.010 --> 13:56.550] Awesome. [13:57.110 --> 14:00.370] Well, no, because I also need the beginning of the data structure at the front. [14:00.630 --> 14:03.370] I'll grab another bigger script here in a moment and it will work better. [14:06.690 --> 14:10.330] So, what's interesting about this, this actually isn't real JavaScript code. [14:11.190 --> 14:12.590] This is something called JSONP. [14:14.670 --> 14:15.110] JSONP... [14:15.110 --> 14:21.070] Well, to go into background, web pages can request content as part of their code running. [14:21.070 --> 14:23.250] And they use a technique called Ajax. [14:23.990 --> 14:27.290] Ajax originally stood for asynchronous JavaScript and XML. [14:27.730 --> 14:29.910] The XML part isn't used as much anymore. [14:30.090 --> 14:32.970] Now it's JSON format, JavaScript object notation. [14:33.490 --> 14:39.930] The problem is that by default, you can only send Ajax requests back to the server that originally served your web page. [14:41.230 --> 14:45.130] Well, that doesn't work so well for trying to talk to all these third party sites. [14:45.450 --> 14:49.710] So, someone cleverly came up with the idea that, well, you can grab a script from anywhere. [14:50.190 --> 14:53.690] So, why don't we set it up so you add a script tag into your document. [14:53.690 --> 14:57.210] That will then load JavaScript from an external server. [14:57.650 --> 15:01.330] And all that JavaScript is going to do is call a function that you've already defined with all this data. [15:01.830 --> 15:03.210] That's what JSONP is. [15:03.310 --> 15:07.970] And it's a way that you can get around this cross-site request problem. [15:09.070 --> 15:09.550] Okay. [15:10.470 --> 15:12.630] Let's find something really insidious here. [15:13.250 --> 15:14.470] Oh, this looks fun. [15:14.730 --> 15:17.090] This is from krdx.net. [15:17.350 --> 15:18.310] Oh, here we go. [15:18.410 --> 15:19.370] This is what I like. [15:19.450 --> 15:20.830] This is good JavaScript fun here. [15:21.630 --> 15:23.850] This is what I was talking about when I said minify. [15:24.150 --> 15:24.510] This... [15:24.510 --> 15:27.450] I don't think anyone can reliably read that. [15:27.770 --> 15:28.590] But I can. [15:28.790 --> 15:29.970] Using JSBeautifier. [15:30.950 --> 15:31.170] Whee. [15:32.890 --> 15:34.230] All the way to the end. [15:39.870 --> 15:40.390] Yeah. [15:40.690 --> 15:40.810] Okay. [15:41.050 --> 15:47.530] So, this is why when you go to the New York Times site after your cache has been cleared, it actually loads up almost a megabyte worth of data. [15:48.510 --> 15:52.270] A lot of it is giant JavaScript files like this. [15:53.730 --> 15:56.370] So, let's maybe start down there and try the other way. [15:58.670 --> 16:02.530] Control shift A did not work very well because... [16:02.530 --> 16:03.130] Okay. [16:04.810 --> 16:05.510] Here we go. [16:07.650 --> 16:08.090] Okay. [16:08.130 --> 16:10.390] That just took a long time to even paste into Beautify. [16:11.050 --> 16:12.910] So, we are going to get up to the top of there. [16:13.150 --> 16:13.690] I know. [16:13.890 --> 16:14.570] White space. [16:14.770 --> 16:14.930] Beautiful. [16:16.430 --> 16:17.330] And run it. [16:18.410 --> 16:18.850] Okay. [16:18.970 --> 16:20.930] That looks like more like code you could actually read. [16:20.930 --> 16:35.030] And looking through this, I mean, figuring out what this does is going to take a while because a lot of it is just boilerplate code because JavaScript programmers like to use lots of frameworks with lots of extra code to do what they do. [16:36.270 --> 16:44.370] But you can often look for things like references to ads, references to tracking, references to EXC late. [16:44.830 --> 16:45.010] Hmm. [16:45.170 --> 16:46.750] Sounds like some sort of laxative. [16:46.850 --> 16:47.250] I am not sure. [16:48.290 --> 16:48.790] So, yeah. [16:49.430 --> 16:52.210] That is just an example of all the kind of stuff that goes on. [16:52.650 --> 16:54.250] There are a few interesting... [16:54.250 --> 16:54.570] Let's see. [16:54.770 --> 16:55.290] Brightcove. [16:55.990 --> 16:58.430] Brightcove is a provider of video services. [16:59.310 --> 16:59.730] So... [16:59.730 --> 17:02.270] And this is actually a one pixel wide GIF. [17:02.730 --> 17:03.590] So, this is basically... [17:03.590 --> 17:06.970] Brightcove is using this to track the user that is using video on their site. [17:09.310 --> 17:10.250] We will go down. [17:10.510 --> 17:11.670] I mean... [17:11.670 --> 17:12.590] There is lots of stuff. [17:12.790 --> 17:16.310] When I was looking through there, I found more references to Google for analytics. [17:16.850 --> 17:22.470] I saw references to DoubleClick, which is a Google owned ad agency, which is used to serve all those ads. [17:22.830 --> 17:26.950] I think I found references to two or three other ad networks that are being used for various parts of the page. [17:27.930 --> 17:33.510] What I can tell from this is basically the New York Times is primarily concerned with tracking their readers and selling ads to them. [17:33.790 --> 17:35.090] Which, you know, that is how they make their money. [17:37.010 --> 17:38.250] Before I jump... [17:38.250 --> 17:38.870] Well... [17:38.870 --> 17:40.110] I was going to show another tool. [17:40.630 --> 17:43.750] So, this was JSBeautifier, which is great for JavaScript code. [17:44.730 --> 17:46.290] Another tool is JSONLint. [17:46.450 --> 17:49.230] And this is what I use if you just have a JSON data structure. [17:49.570 --> 17:56.830] I actually use this in programming a lot because not only does it expand a minified JSON structure, but it also tells you if you made a mistake. [17:57.170 --> 18:04.270] And so, if you are writing code that sends data back and forth and you happen to leave out a comma or forget to quote something, this will give you the error for that. [18:05.690 --> 18:06.090] Okay. [18:06.950 --> 18:08.250] So, back to Chrome. [18:10.070 --> 18:12.450] Another tool which is very useful. [18:12.650 --> 18:15.230] And I will switch back to the New York Times to show you how this works. [18:16.010 --> 18:20.130] There is an extension that is available for both Firefox and Chrome called Adblock Plus. [18:20.890 --> 18:23.710] This is a heroic effort, a really amazing thing. [18:24.770 --> 18:27.810] And I have it enabled here so that... [18:27.810 --> 18:31.690] Go up to the tool bar and right now it is grayed out saying Adblock Plus is not active. [18:32.410 --> 18:37.330] Let's turn it back on for the site and let's reload the page and see how much less stuff gets loaded. [18:38.450 --> 18:42.490] So, switching back to developer tools, what we have seen is... [18:44.090 --> 18:46.890] 193 requests, about 225k. [18:47.130 --> 18:49.970] Some of those are pings since we loaded the page, but... [18:49.970 --> 18:50.830] Not to worry. [18:51.710 --> 18:51.990] Okay. [18:53.850 --> 18:55.450] Back over here, do a reload. [18:58.500 --> 18:59.680] Wait for this to come up. [18:59.840 --> 19:00.820] Okay, it's finished loading. [19:01.380 --> 19:02.560] Switch back to dev tools. [19:04.240 --> 19:05.760] So, we had as many requests. [19:05.980 --> 19:08.000] We had a little less data transferred. [19:09.340 --> 19:17.100] But what you will see with Adblock Plus is that we are now missing these whole areas up here at the top of the page which are showing ads. [19:17.360 --> 19:19.640] We are missing this flash ad that was over here. [19:20.140 --> 19:21.860] The pages does a lot easier to use. [19:22.220 --> 19:25.440] And in a lot of situations, it means that... [19:26.420 --> 19:26.600] Yeah. [19:26.800 --> 19:31.420] Side effect using developer tools, by the way, is you will find a lot of bad programming out there. [19:32.500 --> 19:36.400] JavaScript code in general is very resilient to errors because it's event driven. [19:36.660 --> 19:41.720] And if you handle an event and throw an exception, well, that's not a problem because another event will come along in a minute. [19:42.280 --> 19:47.420] But if you have the dev tools turned on, then you might want to go down here to this area and... [19:48.420 --> 19:50.820] Let me zoom in so you can see this. [19:52.200 --> 19:56.840] Well, really off the edge of the projector there, there's a little stop sign. [19:56.840 --> 20:00.300] And if you click on it, then it will tell it not to pause on exceptions. [20:00.520 --> 20:07.320] And then you will be able to keep running all that wonderful JavaScript code without having it, you know, stop on the debugger every time. [20:08.600 --> 20:09.000] Okay. [20:10.600 --> 20:12.540] So, that is my first example. [20:12.640 --> 20:13.220] The New York Times. [20:13.560 --> 20:18.340] Before I jump into another example, though, I wanted to point out a few other web pages that we are familiar with. [20:18.900 --> 20:20.600] So let's go over to the next one. [20:20.840 --> 20:22.580] The wonderful HOPE Number Nine website. [20:24.300 --> 20:27.020] Just to do, bring up the developer tools for that one. [20:28.440 --> 20:32.640] HOPE, the website here is much, much better than New York Times as far as the stuff it requests. [20:33.260 --> 20:35.780] So, going to the network tab and doing a reload. [20:36.800 --> 20:39.840] All we are really seeing is it's loading some fonts out of Google. [20:42.680 --> 20:47.100] And there is also some code here to show tweets from Twitter. [20:47.340 --> 20:51.940] Which means that Twitter does have the ability to necessarily track you if you go to the site when you are logged in. [20:51.940 --> 20:53.840] But that's about the only one... [20:53.840 --> 20:54.140] Oh, wait. [20:54.240 --> 20:54.300] No. [20:54.620 --> 20:56.140] Actually, there is that underscore UTM. [20:56.240 --> 20:57.460] They are using Google Analytics too. [20:57.740 --> 21:00.240] So, you know, they know who visits and so does Google. [21:03.020 --> 21:07.400] On a nicer front, let's go to our friends at 2600. [21:10.900 --> 21:12.260] And bring up the dev tools. [21:12.980 --> 21:14.080] That's not what I wanted to do. [21:17.580 --> 21:24.920] The 2600 webpage is old and wonderful and it actually doesn't load very much at all. [21:25.260 --> 21:30.800] The only thing I saw looking at it that was loading was the Google search boxes inside of it. [21:31.480 --> 21:34.580] And so, everything else was just loaded from its own servers. [21:34.960 --> 21:36.300] Good job 2600. [21:36.960 --> 21:37.520] Okay. [21:39.100 --> 21:40.960] So, back to my slides. [21:41.860 --> 21:44.160] Just to recap the tools we talked about there. [21:44.300 --> 21:45.280] The Chrome developer tools. [21:45.500 --> 21:46.100] Built into Chrome. [21:46.260 --> 21:50.000] Everyone has Chrome on their desktop, laptop. [21:50.640 --> 21:52.240] Chromebook has access to this. [21:52.480 --> 21:56.140] If you are using Chrome on Android, the developer tools aren't quite there. [21:56.140 --> 22:01.320] But Google has basically set up their dev tools to allow remote debugging. [22:01.540 --> 22:03.560] So, you can actually run Chrome on your desktop. [22:03.740 --> 22:04.960] Run it on an Android device. [22:05.480 --> 22:09.100] And then connect to the Android device and do all the same kind of inspecting. [22:09.220 --> 22:11.060] But you are actually looking at what is happening on the device. [22:12.220 --> 22:13.220] JS Beautify. [22:13.400 --> 22:14.100] JSON Lint. [22:14.260 --> 22:15.160] And then Adblock Plus. [22:16.080 --> 22:17.000] That's number one. [22:17.900 --> 22:18.940] Let's look at number two. [22:19.300 --> 22:19.800] Facebook. [22:20.700 --> 22:26.060] The giant collection of irrelevant information that we all or many of us enjoy all the time. [22:26.660 --> 22:27.460] I am guilty. [22:27.780 --> 22:28.380] I do Facebook. [22:31.060 --> 22:33.740] So, going over to our nice Facebook. [22:33.960 --> 22:35.440] I am looking at it here in Mozilla. [22:36.200 --> 22:37.040] In Firefox. [22:37.620 --> 22:39.620] Show off what Firefox dev tools can do. [22:39.860 --> 22:46.020] So, as of like a few generations ago, Firefox developer tools basically was a JavaScript console. [22:47.500 --> 22:50.660] They have done a lot of work on letting you visualize the way a web page. [22:50.820 --> 22:55.460] So, I am going to give you a tip on what will make you look like the latest hacker to all your friends. [22:56.400 --> 22:56.760] Okay. [22:57.080 --> 22:58.020] So, I am going... [22:58.020 --> 22:59.080] I am here in the middle of the page. [22:59.240 --> 23:01.460] I right click on it and I do inspect element. [23:02.720 --> 23:06.160] So, this by itself is just kind of neat because I have highlighted something. [23:06.460 --> 23:09.160] And I can see, oh, this is an HTML span. [23:09.160 --> 23:11.520] It has this CSS class message body on it. [23:12.140 --> 23:17.880] But if you go down to the very bottom of the page, which, you know what, I have to be out of full screen mode for this to work. [23:17.880 --> 23:19.180] So, let's do that. [23:22.250 --> 23:22.690] Okay. [23:23.410 --> 23:24.270] So, inspect. [23:26.250 --> 23:27.850] You will see this toolbar at the bottom. [23:27.990 --> 23:31.770] This shows you, kind of, lets you pop up things like viewing the HTML of the page. [23:32.030 --> 23:34.110] View the CSS stuff that is applied. [23:34.450 --> 23:36.550] And then they have this thing called 3D view. [23:36.990 --> 23:40.230] This is totally out of Jurassic Park, I know UNIX. [23:40.230 --> 23:41.470] So, I am going to click on it. [23:42.270 --> 23:44.430] And then all of a sudden... [23:46.250 --> 23:47.190] And even better. [23:58.910 --> 24:01.950] So, there actually is a practical reason for them doing this. [24:02.350 --> 24:07.850] It lets you really easily visualize how all of these HTML elements are stacked on top of each other. [24:07.970 --> 24:10.070] How you have divs inside of divs inside of divs. [24:10.370 --> 24:18.470] And you can see things like if you messed up in your HTML text and didn't, you know, ended something early and so it didn't continue on the page. [24:18.610 --> 24:19.250] You can tell that. [24:19.830 --> 24:23.790] But it is also just, you know, ooh, I am looking at the web from the side. [24:28.130 --> 24:30.250] So, I wanted to make sure you all knew about that. [24:31.190 --> 24:31.910] It is awesome. [24:33.210 --> 24:39.250] Now, from the developer tools here, one of the great things you can do with this is you can play around with the actual content. [24:40.910 --> 24:44.650] Like, okay, my friend Asa here wants to know, how do I remove trending articles? [24:45.750 --> 24:47.310] You know, that is kind of annoying. [24:48.010 --> 24:49.650] I don't like the use of the word trending. [24:50.510 --> 24:52.290] So, I can go into the HTML view here. [24:56.110 --> 25:00.030] And, well, I can't actually change the text of this. [25:00.330 --> 25:03.490] I can go to something like this image ahead of it. [25:03.650 --> 25:04.550] Let's find here. [25:04.850 --> 25:06.510] Inspect his little URL face. [25:07.490 --> 25:09.870] And I can go and I can change the attribute. [25:10.050 --> 25:11.970] So, I can change this and just get rid of source. [25:13.990 --> 25:15.470] Now, he doesn't have an appearance anymore. [25:16.130 --> 25:18.850] You can imagine the fun you can have going to someone's Facebook page. [25:19.370 --> 25:20.830] Now, this doesn't change anything on the server. [25:20.990 --> 25:24.910] But you, like, go there, change some pictures in the middle of the feed and then bring someone over. [25:25.070 --> 25:27.290] Hey, look at what this person did with this other person. [25:27.450 --> 25:27.930] It is awesome. [25:30.190 --> 25:38.510] The practical side of this, though, is if you are actually doing web development, you can tell a lot of stuff about these styles and you can go and edit styles and see how they affect things. [25:38.610 --> 25:41.550] I mean, it is super useful when you are actually building web pages. [25:42.830 --> 25:46.870] Looking at Facebook here, we want to look... [25:46.870 --> 25:53.790] If we want to get the same kind of information in Firefox we did in Chrome about all the stuff that gets loaded, that is not yet available in the built-in dev tools. [25:54.190 --> 25:59.450] But there is this extension called Firebug, which I will jump over here to the page on it. [26:00.130 --> 26:04.630] Firebug is kind of the original super awesome web developer tool. [26:04.630 --> 26:10.050] And it is what has inspired all the development tool work that the browser vendors themselves have done. [26:10.430 --> 26:12.090] So I have Firebug installed. [26:12.410 --> 26:22.530] And if I go up to Tools, View, Firebug, then I kind of have a very similar thing. [26:22.650 --> 26:25.730] Here is like the JavaScript console showing me all the stuff that has been fetched. [26:25.870 --> 26:29.390] If I go to the Net tab, then it shows me all the things. [26:29.930 --> 26:34.470] What I was noticing when I was looking at Facebook last night is that Facebook is very monolithic. [26:35.070 --> 26:41.210] What I mean by that is that Facebook is basically going and fetching everything from its own servers. [26:41.390 --> 26:42.190] It doesn't go out to Google. [26:42.350 --> 26:44.290] It doesn't go out to Yahoo, Microsoft, anyone. [26:44.850 --> 26:46.110] Facebook doesn't give a whatever. [26:47.150 --> 26:48.610] It does it all itself. [26:48.990 --> 26:52.790] So it's tracking all this information, but basically only on Facebook's own domains. [26:54.470 --> 26:56.470] So there wasn't a lot super interesting here. [26:57.590 --> 26:58.730] Nice things about this. [26:58.730 --> 27:03.430] So the network panel will, like, show you just HTML files that got loaded, just CSS. [27:04.750 --> 27:08.490] XHR is those requests made from the page itself after the page has been loaded. [27:09.550 --> 27:17.910] If you like to do things like save Swift files, you can go here and see the URLs of all the Flash files that were loaded in the page, all the images here. [27:18.310 --> 27:20.830] And, oh, you get nice little previews as you go down. [27:21.030 --> 27:23.010] So it's like someone has a Dr. Horrible picture. [27:23.010 --> 27:23.870] Awesome. [27:25.690 --> 27:26.970] Firebug, free extension. [27:27.330 --> 27:33.150] You can go to addons.firefox or addonsmozilla.com and download it or just go to getfirebug.com. [27:34.410 --> 27:34.930] Okay. [27:36.030 --> 27:38.210] So switching back to my slides again. [27:39.870 --> 27:41.710] So that's what you can do with Firefox. [27:42.090 --> 27:43.890] I mean, I find both of them very useful. [27:44.090 --> 27:52.410] Chrome is a bit quicker to get into things, but I found the debugging capabilities in Firefox and just the ability to change up styles to be super useful. [27:53.250 --> 27:53.690] Okay. [27:54.330 --> 27:55.690] So number three, TweetDeck. [27:56.990 --> 27:58.270] TweetDeck is not... [27:58.270 --> 28:01.110] I mean, you can use it over the web, but TweetDeck is an actual application. [28:01.410 --> 28:05.810] It uses the web protocols to talk to Twitter to do all these various searches and things for you. [28:06.950 --> 28:08.590] But it's not running in the browser. [28:08.830 --> 28:10.210] So how do we figure out what it's doing? [28:10.950 --> 28:13.210] Well, here's where we get to use a few tools. [28:14.070 --> 28:17.670] First one is one which a lot of you are familiar with called Wireshark. [28:19.330 --> 28:21.310] Wireshark is this cross-platform tool. [28:21.310 --> 28:23.250] It runs on Linux, on Windows, on Mac. [28:23.610 --> 28:29.590] And it basically sits and reads all the network traffic going from your computer to other computers on the network. [28:30.210 --> 28:37.450] So if we tell it to start and go over the Ethernet interface, then let's go and start up TweetDeck. [28:40.170 --> 28:41.630] So TweetDeck is going to load up. [28:41.750 --> 28:45.030] It's going to show my Twitter timeline, some things from Facebook, so on. [28:46.030 --> 28:47.010] Let's put that away. [28:48.030 --> 28:52.150] Here in Wireshark, we've actually gone and we see all this traffic that's been going out. [28:53.230 --> 28:56.250] So looking at it, if we sort... well, let's stop the capture. [28:56.530 --> 29:05.430] If we sort by protocol, then the HTTP stuff is the stuff that's been sent in the clear, back and forth from the application, or from other things running on this PC. [29:06.550 --> 29:11.430] We also end up having a lot of traffic like this, which is HTTPS. [29:12.490 --> 29:16.730] Fortunately, TweetDeck uses a secure version of HTTP to talk between it and Twitter. [29:18.530 --> 29:27.670] And Wireshark can snoop on the unencrypted traffic, but when it comes to the encrypted stuff, it can basically tell you who you're talking to, but it can't tell you what's in that conversation. [29:28.250 --> 29:37.530] So if you, like, go and look at a HTTP transaction, then it's telling you, hey, here's how it starts, and oh, it's a JPEG file that's being sent over the network. [29:38.110 --> 29:46.410] But if we go to something HTTPS, then it can basically tell us a little bit about what's going on, but it can't do any decryption. [29:47.130 --> 29:57.330] So Wireshark is great for figuring out what, you know, servers, programs are talking to, but we need something else if we want to actually discover what the conversation is between TweetDeck and Twitter. [29:58.130 --> 30:00.050] So let's quit Wireshark. [30:02.270 --> 30:08.210] And another program, this one is actually shareware rather than open software called CharlesProxy. [30:08.890 --> 30:11.770] But it's one of the best pieces of shareware I've used. [30:12.330 --> 30:22.790] So what CharlesProxy does is it sets up a SSL proxy on your local machine, and it also goes and installs its own certificate that you can toggle on and off into your web browsers. [30:22.790 --> 30:27.530] And for the Mac, it actually hooks it into the system certificate store. [30:28.190 --> 30:37.090] That means that if a web app tries to do an HTTPS transaction, it's actually going to end up talking to the CharlesProxy, which sits in the middle and logs everything. [30:38.010 --> 30:42.050] So now let's go back to TweetDeck and quit it and restart it. [30:43.550 --> 30:44.910] Making sure that I am recording. [30:46.130 --> 30:47.750] Now you have to do a little configuration. [30:47.850 --> 30:50.610] You have to tell it that you want to accept traffic from all domains. [30:50.610 --> 30:56.950] You have to make sure that you have the certificates installed correctly or else TweetDeck will complain about this. [30:57.430 --> 31:01.770] But now when we go to CharlesProxy, we see all these requests and notice they're HTTPS requests. [31:02.430 --> 31:07.630] So if we look at this, we can actually go and see, okay, it's actually doing this request. [31:07.930 --> 31:09.010] Here's a lot of the timing. [31:09.630 --> 31:12.330] Here's what it sent to grab the encrypted file. [31:12.630 --> 31:14.190] Here's the response that came back. [31:14.770 --> 31:27.410] And so you can use this to do a lot of discovery, like not just finding out what public API something like TweetDeck is using, but also private APIs or things like session keys, special... [31:27.410 --> 31:33.910] A lot of web URL or web APIs use special client keys that identify what particular client. [31:34.150 --> 31:39.990] And they use that so that if some client, you know, does bad things in the future, they can turn it off at the server. [31:39.990 --> 31:42.930] Or they can also limit how much that client accesses it. [31:44.230 --> 31:44.630] So... [31:45.450 --> 31:47.630] You'll notice it's also pulling a lot of other information. [31:47.830 --> 31:51.190] Oh, this is just noticing the fact that I stole the New York Times open in the background. [31:51.490 --> 31:53.030] So nothing to worry about there. [31:53.610 --> 31:55.750] APITwitter.com is kind of the most interesting one. [31:56.550 --> 31:58.010] Okay, you have verified credentials. [31:58.370 --> 32:00.050] So something to check on that. [32:01.870 --> 32:04.810] These all are requests to get lists of contacts. [32:05.190 --> 32:07.650] Ah, here's a case where we can use that wonderful JSON lent. [32:07.650 --> 32:09.010] Copy all that. [32:09.190 --> 32:10.030] Back to Firefox. [32:10.950 --> 32:13.410] Back to JSON lent here. [32:15.610 --> 32:17.190] Paste and validate. [32:20.310 --> 32:22.250] And after just a moment... [32:22.250 --> 32:29.410] Okay, now we have all this data that got sent in that secure stream just shown in a nice, easily viewable format. [32:30.090 --> 32:33.690] And I will be invalidating all my sessions immediately after this talk. [32:35.970 --> 32:37.810] So, that's Charles Proxy. [32:37.990 --> 32:38.930] Very useful tool. [32:39.350 --> 32:40.450] Worthwhile to register. [32:40.990 --> 32:44.750] You can do 30 days free, but it pops up kind of annoying things while it's running. [32:45.910 --> 32:51.130] And it also is nice that Charles Proxy will go and... [32:51.770 --> 32:54.170] It unhooks itself when you shut it down. [32:54.470 --> 32:57.830] So, you know, it's only going to intercept transactions while it's actually running. [32:59.070 --> 32:59.530] Okay. [33:00.410 --> 33:02.170] One more example here. [33:02.710 --> 33:03.050] Just... [33:03.050 --> 33:04.210] Here's the tools that we used. [33:05.150 --> 33:05.470] GitHub. [33:06.630 --> 33:07.770] I'm a software developer. [33:08.130 --> 33:11.110] My day job is managing a big open-source project. [33:11.470 --> 33:18.430] So, a lot of what I do during the day is use GitHub to not just deal with my own code I've written, but also review code other people have written. [33:18.990 --> 33:21.090] So, let's go back to Firefox here. [33:23.390 --> 33:25.270] And bring up my GitHub. [33:30.600 --> 33:31.080] Okay. [33:33.000 --> 33:33.480] So... [33:33.480 --> 33:33.920] Yeah. [33:34.100 --> 33:34.660] Here's my... [33:34.660 --> 33:36.300] Here's my GitHub page. [33:37.420 --> 33:41.980] One of the open-source projects I'm heavily involved with is this thing called the Enyo JavaScript framework. [33:43.360 --> 33:46.660] So, let me switch over to viewing things as Enyo. [33:48.640 --> 33:53.120] And we have this widget library called Onyx, which I clicked on the wrong one. [33:55.120 --> 34:04.820] And if you've done anything in GitHub, one way that people collaborate is by taking your repository of code, working on it, and then sending you a pull request for a change you want to do. [34:05.640 --> 34:08.300] So, I have an open pull request from my friend Kevin. [34:08.720 --> 34:12.300] He wants me to, you know, review this code and update it. [34:13.320 --> 34:15.120] So, I do a lot of this code review. [34:16.120 --> 34:16.520] And... [34:18.080 --> 34:19.800] The GitHub interface is fine for it. [34:19.880 --> 34:21.500] It actually will automatically do a lot of things. [34:22.360 --> 34:24.660] And there's this merge pull request down here. [34:25.560 --> 34:27.560] Actually, before I do that, let me... [34:28.620 --> 34:30.760] disable GreaseMonkey, because I'm going to talk about GreaseMonkey. [34:30.900 --> 34:32.600] If you haven't used GreaseMonkey, it's really great. [34:33.100 --> 34:33.420] Okay. [34:33.680 --> 34:35.440] So, I've reloaded the page without GreaseMonkey. [34:35.440 --> 34:40.620] If I hit merge pull request, it's going to show me, oh, here's kind of the description of it. [34:41.320 --> 34:50.500] And the way our project is running, every time I do something, I have to add a line that says, reviewed by blah, blah, blah, my name, my email address. [34:50.820 --> 34:51.740] That gets tedious. [34:53.460 --> 35:01.300] So, what I decided to do was use GreaseMonkey, which is this plug-in add-on for Firefox that lets you do things called user scripts. [35:01.300 --> 35:08.280] The idea behind GreaseMonkey is that you can set up a bunch of JavaScript files that will be loaded conditionally depending on what page you're on. [35:09.020 --> 35:13.220] And the user script is code you've written or code that you pulled from someone else. [35:13.460 --> 35:21.440] And that can go and modify what's on the page, add new features, hide things, show things, just change the whole web experience. [35:21.820 --> 35:34.620] This is one of the things I really love about the web, because if I wanted to add a feature to GitHub, I can send a mail to their developers, maybe get a response a few days later saying, hey, that sounds great, we'll put it on our list to handle sometime in the future, [35:35.120 --> 35:36.460] or maybe they'll ignore me. [35:36.960 --> 35:44.820] But since this is all based on the web platform and we have access and know what's going on, we can actually write our own code that extends these websites for us. [35:45.760 --> 35:49.660] So I'm going to turn GreaseMonkey back on and reload this page. [35:52.020 --> 35:57.520] So what I did is I made a user script here which adds a reviewed by button. [35:57.660 --> 36:01.760] And so if I tap that, there's my reviewed by message stuck immediately into the text. [36:02.620 --> 36:04.020] So let's see how I did that. [36:06.720 --> 36:08.700] GreaseMonkey lets you create new user scripts. [36:08.800 --> 36:09.800] I have two loaded here. [36:10.080 --> 36:11.820] This is the one that I wrote. [36:11.820 --> 36:18.840] This is MrScript which is about 6,000 lines of JavaScript that modify the Kingdom of Loathing online game to be a little easier to work with. [36:20.180 --> 36:21.320] But let's look at this one. [36:23.680 --> 36:25.360] So bring it up here in the text editor. [36:25.500 --> 36:26.680] Let me make that a little larger. [36:28.580 --> 36:31.300] So what I'm just doing here is I'm using a little bit of jQuery. [36:31.700 --> 36:35.240] I've gone and I'm looking for that merge request button. [36:35.680 --> 36:37.820] And I've added a special behavior to it. [36:37.920 --> 36:41.100] So when it gets clicked on, it's going to then run this code inside here. [36:41.960 --> 36:47.400] This code does a set time out because I want this to run a little bit in the future. [36:47.940 --> 36:51.580] When you actually are clicking on the button, it hasn't created all those other pieces yet. [36:51.740 --> 36:56.060] But if I wait 10 milliseconds, then the new buttons that I want to hook onto will be there. [36:56.600 --> 37:01.900] So I wait 10 milliseconds and then I'm going to create my new little reviewed by button. [37:02.120 --> 37:06.280] I'm going to put a click handler on it that adds my, you know, special line to it. [37:06.280 --> 37:09.380] And then I'm going to stick it after that button. [37:10.300 --> 37:14.100] This does have a little bug that I noticed last night that I haven't actually fixed yet. [37:14.500 --> 37:20.480] If I hit cancel and then hit merge pull request again, I have two reviewed by buttons. [37:20.820 --> 37:25.760] And I can keep doing that because I didn't actually check to see that I didn't have that already. [37:26.100 --> 37:27.440] I can live with that. [37:27.720 --> 37:29.000] I might fix it one day. [37:31.440 --> 37:32.140] That's right. [37:32.320 --> 37:32.720] That's right. [37:34.620 --> 37:38.580] So, I mean, if you're a programmer, you can easily create your own user scripts. [37:38.820 --> 37:47.700] And the way I figured out where I wanted to put it was actually using those Firefox dev tools to look and see what the classes were, what all the DOM attributes were for the items on the page. [37:48.160 --> 37:52.300] The good news is that you don't have to do this just to take advantage of them. [37:52.620 --> 37:58.340] There's this great website, userscripts.org, that has thousands of scripts that other people have contributed. [37:59.100 --> 38:06.620] If we look here, the most popular scripts tend to be ones that let you download videos from YouTube for some reason. [38:06.840 --> 38:07.920] People really like doing that. [38:08.780 --> 38:13.040] But there's things like a Netflix queue sorter to let you view your movies in your own order. [38:14.840 --> 38:21.040] Lots of stuff for gaming sites for, you know, cheaty reasons or enabling reasons. [38:22.200 --> 38:33.380] So, people have kind of already gone and done a lot of the work for you out there and finding all these annoyances and pages or just places where they want to customize that the website owners didn't think of and writing scripts for it. [38:34.900 --> 38:36.980] There are certain things user scripts can't do. [38:37.160 --> 38:39.420] They're not very effective in modifying Flash content. [38:39.620 --> 38:46.000] But the good news is that the web is generally moving away from Flash and more towards HTML, JavaScript code. [38:47.460 --> 38:50.580] And there's a lot of security work that's been done around Grease Monkey. [38:51.600 --> 39:00.180] One of the early problems they found is that the original version would let scripts running on the web page detect that the user had added scripts to the page. [39:00.520 --> 39:06.160] And this suddenly led to this kind of war between pages that didn't want to be modified and the users that wanted to modify them. [39:06.780 --> 39:11.420] Where a script would be sitting around and, like, would notice, oh, wait, this was added by Grease Monkey. [39:11.600 --> 39:15.540] I'm going to go stomp on that or change my ID so it can't modify things anymore. [39:16.660 --> 39:25.060] Grease Monkey is actually running all the user script code in a special sandbox where it only has access across a barrier to what's on the web page. [39:25.240 --> 39:28.400] And the web page can't reach back into the Grease Monkey stuff at all. [39:29.420 --> 39:31.420] Now, this isn't just limited to Firefox. [39:32.180 --> 39:34.100] Chrome supports user scripts as well. [39:34.360 --> 39:36.320] It actually has it built directly into the browser. [39:36.540 --> 39:37.420] You don't have to get an add-on. [39:37.900 --> 39:39.360] You just find one of these files. [39:40.200 --> 39:41.260] Let's look at this one. [39:43.280 --> 39:49.480] So if we downloaded this one or clicked install, then it would load a file. [39:49.980 --> 39:54.620] You can't really see it, but it's called 35183.user.js. [39:55.680 --> 40:00.260] And Chrome is smart enough to know that things named user.js at the end or user scripts. [40:00.780 --> 40:07.920] And so if you clicked on that from Chrome, it would prompt you, hey, do you want to install this script and have it and they have a whole management interface through their add-ons method. [40:08.740 --> 40:10.560] So, user scripts, awesome tool. [40:10.980 --> 40:12.160] Definitely worth checking out. [40:16.920 --> 40:19.840] So, the good news is that those are the examples. [40:20.040 --> 40:24.000] I'm actually giving you the gift of extra time for lunch or extra time to go see other panels. [40:24.000 --> 40:28.060] But before I cut off, are there any questions for the audience about this kind of thing? [40:31.610 --> 40:32.690] Yes, up here on the front. [40:32.790 --> 40:35.090] One more time, what was that tool to see the Internet from the side? [40:35.330 --> 40:36.730] Oh, that's... yes. [40:38.210 --> 40:41.830] That is built into Firefox, I think, 13 and later. [40:42.390 --> 40:52.630] So, if you're in Firefox, just right-click on an item, do inspect an element, and then you can turn off the views on the side by these buttons on the bottom. [40:52.630 --> 40:54.610] But then the button here is 3D view. [40:55.370 --> 40:58.090] So, 3D view, and whee! [40:58.390 --> 40:59.650] The Internet is rotating. [41:03.670 --> 41:04.270] Yeah. [41:04.850 --> 41:05.670] Anything else? [41:06.510 --> 41:07.850] Thank you all very much. [41:08.130 --> 41:08.210] Oh.