Online version

Talk detail

They say you have to sanitize or escape user input. But what's that “user input” they talk about? The thing is everything is user input.

Date and event

June 23, 2018, PHP Prague (talk duration 20 minutes, 9 slides)

Slides

Everything is User Input

#1 What's user input? Everything. Trust me, I'll show you.

Label: [<script>alert('XSS');</script>]

#2 There are only two hard things in Computer Science: cache invalidation and naming things, as Phil Karlton once said. I've solved the “naming things” problem by using JavaScript. I mean, name this, name that, everything wants a name so when I have no idea, I use JavaScript. Well, I have to admit I have a different problem now.

The page at https://bitbucket.org says: XSS

#3 Unfortunately there are pages actually executing my “let's use this as a name” JavaScript. Like Bitbucket back in 2014. I've reported this issue, it was promptly fixed, and I made it to the Security Hall of Fame.

<div><script>alert('XSS');</script></div>

#4 This was the name of my SSH key literally echoed back to the HTML and that's why the script was executed by my browser. That's called a Cross-Site Scripting (XSS) attack. Labels, names and generally all form fields are user input. Also company names, and not just XSS.

Recently used devices: <script>alert(1);</script>

#5 These are the devices that have access to my Google Account (check your devices too). See the pattern? By using JavaScript in the name of the device I'm “btw-testing” the services that display the name. Yes, device names are also user input.

Him + her = kid

#6 Now imagine that one day I'll have a kid. Should we call the baby say <script>alert('b4b33')</script>? No, that would be a silly name. We'll call him Bobby, Little Bobby Tables' -- !!!, of course. Human names are also user input.

$_SERVER

#7 The $_SERVER array in PHP is a bit sneaky. Half of the values there are actually coming from the client. Like HTTP headers, check your phpinfo() output (but don't put that info.php file on a production server, I dare you) and see the keys starting with HTTP_ – that's the request headers. But it's not just headers, also PHP_SELF is user input. Just treat everything in $_SERVER as user input.

Check my site in a few tools showing response headers (like browser devtools or just any online tool), you'll like both of my Server and X-Powered-By headers. And my DNS records, too. The talk has a demo where I show what these can be used for.

Moat, high hard walls, limited entry points, guards check identity, watch towers

#8 When designing a security architecture for your app, think about a castle. See the multiple defense layers? Sometimes it's called “Defense in Depth”, sometimes “Castle Approach” but what it means is that you should always keep in mind that one layer of security or one security control will fail, so you should add more. That one failure shouldn't bring the whole system down. If the enemy army is able to get across the moat they still need to overcome the walls and guards and laser towers. If you're interested, I have a different talk about castle approach to XSS, though it's in Czech.

Jakub Vrána: Na konferenci http://devel.cz jsem přednášel o tom, jak v Google o programech dokazujeme, že nemají XSS a některé další zranitelnosti.

#9 This tweet is in Czech, sorry for that. But it's still relevant to the XSS topic. Jakub Vrána of Google recently gave a talk about how they prove that there's no XSS and some other vulnerabilities on their tools. Long story short: if a developer uses a dangerous (and thus forbidden) DOM construct or a method call, their code won't compile. In PHP you can use PHPStan, the static analyzer built by Ondřej Mirtes, and create custom rules that forbid some dangerous methods and constructs in your code. You can also use my disallowed rules for that, we use them on Report URI already.

I hate to repeat myself but please remember, everything is user input.

Česky