Escaping data in PHP pages

What does it mean to “escape” data that is put into a web page?

By escape I mean formatting the data in such a way that it doesn’t interfere with any of the code or markup of a web page. For example, let’s say a user entered their first name like so into a text input box

<b>Mary</b>

If the web page redisplays this data after the form is submitted, and it doesn’t escape it, then it will be rendered something like

<p>First Name: <b>Mary</b></p>

which will display as

First Name: Mary

instead of as

First Name: <b>Mary</b>

That is, as a web developer you want to display to the user exactly what they provided. The way to make sure you display to the user exactly what they provided is to escape any characters that could be interpreted as part of the web page markup, like so

First Name: &lt;b&gt;Mary&lt;/b&gt;

which will render as

First Name: <b>Mary</b>

Why is it important to escape data included in a web page?

There are two main problems that can arise when data isn’t escaped in a web page. We’ve already looked at one, namely that characters that are part of the markup or programming language (as we’ll see with JavaScript later) can mess up that actual markup or program code. So for the sake of correctness, data included in the web page must be escaped.

The second problem is that failure to escape data in a web page can make possible various kinds of security attacks. Keeping with our example, suppose a user entered as their first name

Mary<script>alert("Hijacked!");</script>

Displaying this directly in a web page would result in that script being executed. And the JavaScript so injected could do lots of nefarious things, such as reading a user’s cookies.

What are the different ways of escaping data?

There are several different ways in which data is added to a web page, and they require different techniques to properly escape them. I’ll cover three cases in this blog:

  • HTML data
  • JavaScript strings and JSON
  • URL components

For each of these I’ll show how to escape these in PHP (specifically when using Laravel), but the techniques here are applicable to other languages and frameworks. Most languages and frameworks will have similar utilities to escape web page data.

How to escape HTML data

For the most part what we need to do is replace the following characters

  • < to &lt;
  • > to &gt;
  • ” to &quot;
  • & to &amp;
  • etc.

In a Laravel controller you can escape data to be put into a web page with the htmlspecialchars. In a Blade template you can escape data by using triple curly braces, for example, {{{ $first_name }}}.

To go along with the example we started with, here’s how to write the Blade template to display the first name:

<p>First Name: {{{ $first_name }}}</p>

If you are dynamically generating a web page using JavaScript then you also need to be careful when creating DOM elements. Don’t use .innerHTML because that won’t escape any HTML special characters. There’s a simple way to handle data that you want to put into the DOM that may have special HTML characters and that is to use the special .textContent property of the DOM element.

var p = document.createElement('p');
p.textContent = '<b>Mary</b>';
// then append the p somewhere in the DOM

You can do the same in jQuery with the .text() function.

How to escape JavaScript strings and JSON data

With JavaScript strings you want to make sure that you escape quote characters in the string. If the user’s first name value is Mary" and you put this directly into a JavaScript string like so

<script>
var firstName = "{{ $first_name }}";
</script>

it will get rendered as

<script>
var firstName = "Mary"";
</script>

which is invalid JavaScript. The double quote in the $first_name variable prematurely terminates the JavaScript string.

In PHP, the way to deal with this is to use the json_encode method. You can use this for JavaScript strings:

<script>
var firstName = "{{ json_encode($first_name) }}";
</script>

You can also use it to encoding PHP data structures like arrays to JSON:

<script>
var userData = "{{ json_encode($userdata) }}";
</script>

How to escape values placed in URLs

When placing data into a URL, care has to be taken to encode any characters that are special to URLs such as

  • forward slash (/)
  • ampersand (&)
  • question mark (?)
  • etc.

URL encoding is the process of converting these special characters using something called percent-encoding. For example / gets encoded as %2F. Notice that this encoding format is different from the HTML encoding above so you’ll need different functions and techniques to do percent-encoding.

Let’s say you have a $project_name variable with the value This&that project and you want to create a link with the project name in it:

<a href="/projects?name={{ $project_name }}">Go to {{{ $project_name }}}</a>

This renders as

<a href="/projects?name=This&that project">Go to This&that project</a>

But this won’t work. When someone clicks on the link the server will interpret the URLs parameters like so

  • name=This is the first parameter name and value
  • that project is another parameter without a value

Instead use urlencode to properly encode the URL data.

<a href="/projects?name={{ urlencode($project_name) }}">Go to {{{ $project_name }}}</a>

This renders as

<a href="/projects?name=This%26that%20project">Go to This&that project</a>

The server will interpret these URL parameters as

  • name=This&that project as the sole name value pair

If you are constructing URLs in JavaScript code, use encodeURIComponent to do percent-encoding on URL data.

Resources

ECSS Symposium – CILogon and Keycloak

Note: I originally wrote this back in April but forgot to publish it. The presentation below was given on April 18, 2017.

At work, the beginning of this week was busy for me as I prepared for the ECSS Symposium. ECSS stands for Extended Collaborative Support Services and it is a way for XSEDE users to get expert help with running scientific applications on XSEDE resources. I talked about our recent work integrating CILogon with Keycloak and how we use it to secure access to Airavata services. My presentation is the second one and it starts about 24 minutes in:

The Philosopher’s Handbook

Bought the book The Philosopher’s Handbook by Stanley Rosen (editor) today at Barnes & Noble. It is a kind of introduction to philosophy organized in 6 sections corresponding to the following 6 divisions of philosophy:

  • social and political philosophy
  • philosophy of religion
  • aesthetics
  • metaphysics
  • epistemology
  • philosophy of science

Each section starts with an introduction by an expert in that particular branch of philosophy and then follows with a selection of readings from famous philosophers on the topic.

Today I read the introduction by Stanley Rosen. I’ll try to sum it up. Dr. Rosen begins with Socrates and defines philosophy as the pursuit of knowledge about what it means to live the good life. However, this approach to philosophy has been under attack in more recent years from two fronts: first, from science which posits a reduction of human impulses to merely the result of biological, chemical, physical forces, and second from cultural relativism which sees the values of different cultures as relevant for only those cultures, only understandable within those cultures.

Put differently, within science we can ask questions about natural phenomena and explore various hypotheses. Different practitioners can propose theories or attempt to confirm or falsify the theories of others. Can we do something similar with questions like “What does it mean to live a good life?” This is the fundamental question the author raises in the introduction. Likewise, do the answers to questions of this sort necessarily only make sense within the context of the cultures within which the questions are entertained?

The presentation of these questions is engaging but my head is kind of spinning and I’m not sure how to answer these questions. Are there fundamental universal truths about what the good life is and how to best live it? Can we know these truths with the same certainty that we know the gravitational constant? I’m intrigued and look forward to reading the rest of the book. I’ve been wanting for some time to read a good introduction to philosophy. My feeling is that this book won’t have breadth of coverage, but with the excerpts from classic texts I expect it to make several deep dives and be a starting point for further investigations.

Facebook’s BSD+PATENTS license no longer Apache compatible

So Apache has decided that the PATENTS grant in the ReactJS license is incompatible with the Apache license. The ReactJS PATENTS grant is mutually exclusive: you are granted use of patents that may be used by ReactJS but the moment you sue Facebook for any patent infringement your grant to the ReactJS patents is revoked.

The PATENTS grant seems both fairly innocuous, reasonable but also understandable how this could be interpreted as being incompatible with the Apache license.

Apparently what started this discussion is a question about the user of RocksDB, some sort of persistent key-value storage (of which I had never heard before all of this). Some good news: the RocksDB team has already merged a pull request that makes the project dual-licensed: GPL 2.0 or Apache licensed.

There is an open issue in the ReactJS Github to consider making the same change. Here’s hoping they do.

This is particularly relevant to me because I’ve been planning to use ReactJS with Django for the upcoming new PGA implementation for Apache Airavata. If this PATENTS situation isn’t resolved what options would we have in Airavata?

  • Preact or some other React compatible library. That would allow us to use the React API and if the PATENTS situation gets eventually resolved then perhaps we could even move back to use React.
  • VueJS. I’ve heard great things about VueJS and from what I’ve seen it looks good. Like React it keeps things simple, indeed it is probably simpler and easier for newcomers. This would be another good alternative.

More discussion on HN.

LA Trip, Day 3

Monday, December 5, 2016

The third day of our family vacation to Los Angeles.

Breakfast

Still a little jet lagged, we wake up by 6:30. We’re staying in a Fairfield Inn that has a food court area and we go there to buy breakfast sandwiches.  We eat the sandwiches in our room.

We a little anxious to get to Disneyland, but it doesn’t open until 9am. So we’re twiddling our thumbs…

Disneyland!

We arrive at the baggage check outside of Disneyland (and California Adventure). It takes a while to get through baggage check. Seems like a lot of family have loaded up their strollers like a pack mule, so there is a lot for the security staff to check.  When we get to baggage check we breeze through since the Tracy and the girls only have one bag each and I have nothing.

We’re in line waiting to get into Disneyland by 8:15. At 8:30 they start letting folks in. Since this is our first day, they take our pictures and associate them with our paper passes (no magic bands!).  On subsequent days they will just scan our passes and visually check to make sure that we’re the same people.

The park doesn’t actually open until 9am. While we wait we get our “first visit” buttons on main street. We also stopped to look at these beautiful moving displays in some of the windows.  They display scenes from Disney movies and every once in a while they rotate around and the scene completely changes. My picture won’t do it justice but here’s a scene from Princess and the Frog:

Princess and the Frog

The rope drops at 9am separating Main Street from Tomorrowland. First ride, Hyperspace mountain! Ceilidh has been looking forward to this for months. At one point she was convinced they wouldn’t have the Hyperspace overlay during our trip and instead it would be just plain Space Mountain, but fortunately they still have the Hyperspace overlay.

Excited to go on Hyperspace Mountain!

Next is the Buzz Lightyear ride. We find this version more enjoyable than the Disney World one. You have more range of motion because the guns aren’t attached to the cart.  I, of course, got the high score out of our family 😉

Before lunch we checked out Autopia, which is like Disney World’s Tomorrowland Speedway. Then Mr Toad’s Wild Ride, the Matterhorn and Star Tours.  Unfortunately the Matterhorn temporarily shut down just after we got into the bobsleds.  We enjoyed seeing BB-8 from The Force Awakens in the Star Tours ride.

Keira’s first driver’s license
Sadly, seconds later they ask us to get off

We then hiked over to California Adventure for lunch. I’m trying to remember now, I think Keira and I got pizza but Ceilidh and Tracy went to get corn dogs.  From where we were sitting we could see most of the latin themed parade out front.  We also picked up Radiator Springs fast passes that we would use later that day.

At this point we were pretty tired, but we did go to the Little Mermaid ride before heading back to the hotel to rest.

We crashed pretty hard and when we woke up and got back to California Adventure it was time for dinner so we went to Cocina Cucamonga. Our family loves Mexican food so this little quick serve restaurant really hit the spot.  Generally I really enjoyed the food at Disneyland.

After dinner we rode Toy Story Mania, Radiator Springs Racers and Luigi’s Rollickin’ Roadsters.  We ended the day by getting churros and watching the fireworks back in Magic Kingdom.

Don’t wanna brag, but that’s my score on the right
The girls at Radiator Springs

LA Trip, Day 2

Sunday, December 4, 2016

The second day of our family vacation to Los Angeles.

Breakfast

Since we’re still jet lagged we wake up early. The hotel breakfast doesn’t start until 7, so to tide us over, Ceilidh and I walk to a nearby Yum Yum Donuts shop. We each got a donut and I think the consensus is that the chocolate glazed twist donuts were the best of the bunch.

Afterwards we went downstairs for the hotel breakfast. It was good too. I had the biscuits and sausage gravy.

Pacific Coast Highway

This morning we want to see the ocean. So we plan to drive north and take the Pacific Coast Highway (PCH) south and eventually we’ll arrive at Santa Monica Pier.

Not long after getting on the PCH we find a beautiful, quiet place to pull over and watch the ocean waves crash against the rocks. It was very relaxing and peaceful. We took pictures and also just enjoyed the scenery for a while.  This was our first stop but little did we know that it would become our favorite spot along the PCH. No other spot was so beautiful and peaceful.

It’s hypnotic, really

We continued driving up the coast, looking for another good spot to pull over. However, what we found was that the coast quickly gets more densely populated, so we didn’t have much luck.  But the view was nice.

Santa Monica Pier

And we make it to the Santa Monica Pier.  First stop is the bathroom 🙂 Then, since we ate breakfast so early, we’re hungry. Fortunately the restaurant we planned to eat at, Rusty’s, opened at 11:30, about the time we got there.

Rusty’s is good eats. It’s decked out with a lot of surf boards. In the corner is a small stage and looks like they have live music on most nights.

I’m so glad to have a beer

After Rusty’s we walk around and take in the sights of the pier.  There are several street performers playing music as well as vendors making pieces of art.  Keira buys a piece of art that is a picture of dolphins painted on a small piece of glass.  We also just spent some time looking out over the water.

Ceilidh, wearing her “I (heart) LA” sweatshirt
The pier

Keira and I decide we want to wade into the water for a little while. It’s a little chilly so Tracy and Ceilidh decide to sit this one out.  Keira and I take off our shoes and find a same place to put them and then we start to walk into the water. The idea is to just wade in the water and to not get wet since we need to get back in the car and keep driving soon. However it’s not too long until the water rolls in and Keira tries to quickly backpedal away from the rising water. She trips and falls down, getting her pants all wet. It was a pretty funny moment for us. I take off my jacket and she wraps it around her waist.  Then we get back into the water, this time a little wiser about how to deal with the waves rolling in.

Soon after we get back in the car and head to our Fairfield Inn, which is just across the street from Disneyland.

Downtown Disney

As is our tradition whenever we go to Disney World, the night before actually going into the parks we got check out Downtown Disney.  We get a bite to eat at Earl of Sandwich. I got the Original 1762 which is a hot roast beef with cheese and horseradish sauce. It is so savory and spicy, so good.

The girls in front of a Christmas tree at Downtown Disney

And then the shopping begins. All of the Christie girls love shopping and I like helping them find cute things to buy.  Ceilidh finds a stuffed Eeyore that she instantly falls in love with. Usually she would wait until she also sees what other things she might want to buy that are in the park, but she absolutely adores this Eeyore, love at first sight, so she buys it right then and there.

He’s so cute!

Atonement

This week I finished reading Atonement by Ian McEwan. I recommend it as it is very well written. The story is set in London, in the 1930’s and 1940’s. Cecilia is a young woman, trying to figure out what adulthood means. Her younger sister Briony is on the cusp of adolescence. Due to a misunderstanding Briony wrongly accuses Cecilia’s lover, Robbie, of a crime. Prison and then war separate Cecilia and Robbie as they try to sustain a long distance relationship. Meanwhile Briony struggles with guilt and uncertainty, and what she can possibly do to atone for her error.

LA Trip, Day 1

The Christie family spent a week in Los Angeles, seeing the sights and going to Disneyland.

Saturday, December 3rd, 2016

Flight to LAX

We wake up at 4am. Although we haven’t slept much everyone is in good spirits and full of energy. We eat breakfast sandwiches that Tracy has prepared beforehand. We load up the car and set off for the Indianapolis airport.

When we get to the airport we park in the garage. We check in at Southwest. We have two checked bags and then Tracy and I each have one carry on, but the girls have two each since they also have their backpacks.

Getting through security was thankfully very smooth. For the most part we got to go through as a family. We get to the gate by 6:30, but our flight isn’t until 8:30, so we have some time to kill.

This is the girls’ first flight, so there are some nerves and excitement. We luck out and the flight isn’t full. The place seats 3 on each side of the row, so we put the girls on the window seats with Tracy and I on the aisle seats, and with a seat between us.

In general we find the Southwest flight very pleasant. It helps that the plane isn’t full. We have plenty of leg room. We appreciate the free snacks and drinks. And the girls like watching the free Disney channel TV.

Ceilidh on an airplane
A little nervous

 

Keira on airplane
A little uncertain…
Ceilidh relaxing on plane
What nerves? I’m ready to chill out 🙂
Ceilidh sleeping on airplane
Catching some zzz’s

When we get to LAX we pick up a Dodge rental car from National. Now it’s time to start exploring LA.

Bob’s Big Boy

We’re hungry because the flight was four hours long, so our first stop is Bob’s Big Boy. Supposedly there is a table here where the Beatles ate one time, but it’s too busy to request sitting at it. The burgers, shakes and sodas are great!

 

The girls posing next to the Big Boy statue
We’re so hungry we could eat this statue!
Hamburger, fries and cherry Coke at Bob's Big Boy
And let me tell you what, that cherry Coke was delicious!

Walk of Fame

For our next stop we decide to go to the Walk of Fame and see if we can find the stars of some of our favorite actors and musicians.

This was a bit of a miss for us. The girls were not a little freaked out by the Chinese Christian group that was marching around with a bullhorn and loud speakers, loudly exonerating passersby that they need to convert. There were also all the usual vendors hawking their wares and the costumed characters trying to solicit donations for having their picture taken.

However, it was mostly a positive experience. We found several favorite stars. Probably our favorite part was the Chinese Theater which was less hectic and we got to see footprints and handprints of more favorite stars.

Star Wars footprints at the Chinese Theater in Hollywood

And then we were pooped…

After the Walk of Fame we checked into our hotel to get some rest and relaxation. We ended up taking a nap that lasted 2.5 hours! Even after the nap we were all feeling a little low-key, so we decided to stay in, order pizza and just chill out.