Development

Introspection, Growth and Passion

Having a moment of introspection this morning, thinking back over the years of how my work has changed – sometimes in pretty dramatic ways. It seems like forever ago that I was fresh out of school and working my first real programming job at a domain host. I worked hard until I was ultimately let go from the role due to some interpersonal issues. Fortunately, the market was good and I found a new role with a natural gas provider relatively quickly. I did a lot of growing there, not only in my skills but just in my understanding of how business gets done. It was while I was there that I got married and soon had to figure out how to juggle work and kids, finally getting it down about the time the second one came around.

All the while, I was still working on my passion – programming and learning how to make “better” applications. I think at the time I didn’t know what “better” meant in the context of PHP applications but I spent a lot of time reading up on the subject and, yes, attending conferences (my first was php|tropics which I still can’t believe my employer paid for to this day). I made friends in the community, both local and national – even some international – that helped me build my skills. They were there when I had questions about how to create something and regularly had books, blog posts and other recommendations for resources to further my understanding of what “better” meant. I was constantly improving and moving up the ranks from junior developer to senior developer then lead developer and, yes, even a manager of a development team (it was weird).

Fast forward a few years to about five years ago. I sat back and looked over my career so far. I really looked at the work that I’d accomplished over the years, how I’d grown in my understanding of what “good code” and well-structured applications meant. I understood some of the higher level development concepts (like SOLID) and how to effectively apply them in my day to day work. I was co-organizaing the local PHP meetup, had started sharing my knowledge at conferences and through books and several articles on a wide range of topics. But I’d hit a problem that Young Me hadn’t thought was possible: I felt like I was stagnating.

I looked at the work I was doing (a security company but doing PHP development, not application security) and, while I was enjoying it and the people I was working with, there was something nagging in the back of my mind. It wondered if this was where things leveled out and the only way up was to a less technical role. I’d always been driven by the tech and exploration, so at the time that was a non-starter. I needed to find something that would fill my need for more tech and more exploration but I didn’t know exactly what.

I looked around at the work I was doing and the industry I was in and realized what I needed. I needed to specialize. I needed new challenges that both appealed to my desire to stay in the tech of things yet provided me with room to explore other things. I’d always had a passion for security (as anyone that knows me can tell you) so it seemed like a good option. I started to do more research and learn everything I could about the current state of application security. I’d had a cursory knowledge of it in the past but I really doubled down, watching recorded talks, reading tons of articles and even giving/writing some of my own (the best way to learn is to teach, right?).

So this was my first pivot. After I muddled through one role that didn’t turn out to be what I was hired to do, I ended up landing an application security job at a larger company. The group I worked for was a smaller acquisition of this company so it still had that “small company” atmosphere. I was still learning as much as I could and was being challenged daily to put this knowledge to the test. I worked with a great team of other security folks and engineering groups in a culture of mutual respect and growth. Unfortunately, some things changed with that role and I ended up leaving, going to my second position as an Application Security Engineer. I wasn’t doing as much development work as I had in the past outside of building some custom testing tooling, but I spent time outside of work scratching that itch.

I’ve been at my current role for over a year now and, while the work is interesting and I am working with a wide variety of tech and learning something new just about every day, I’m starting to feel that same nagging feeling in the back of my head. When I sit down and actually think about what that voice might be telling me, it’s an interesting story. I look back at how I pivoted before. I made use of my years of development background and turned it on its head, focusing on how to use it to understand the structure of applications and how to best work with development teams to improve their overall security.

One of the things that appealed to me the most about the role I’m in is the training program. There was already a program in place, started a year or so before I began there, to internally teach the development groups about application security-related topics. At this point I’d been a speaker and a “teacher” for years in various ways: conference presentations, mentorships, and writing plenty of tutorials and blog posts. I’ve always been excited to share my knowledge with others and delight in seeing that lightbulb go on behind their eyes when they really “get” a concept. I was excited to be able to be a part of that program. I presented the current courses numerous times and even worked up a new “advanced” full-day training to provide even more of an in-depth look at application security for our Engineering staff.

Some things have changed, however, and the team I’m on won’t be involved in the training program as much as before and I’d be lying if I said I wasn’t disappointed. There’s some additional context needed here that might help you understand why this is difficult for me. It has to do with that little voice again. See, a few months back, my excitement about the AppSec training program was really ramping up. I’d given the new course several times and had worked on efforts to help improve the program and processes around it. The excitement was so much so that I finally figured out what that voice was talking about and I applied to graduate school – and was accepted – at the University of Massachusetts (Boston) for a certificate in Instructional Technology Design, focusing on using technology to improve the learning process and experience. It was only after this, however, that things changed in my role and my team was less involved in the program. I won’t get too into it here but you can understand my disappointment. I’d figured out the next pivot that voice was urging on: taking the development background, combining it with the application security perspective and sharing that with others in an interesting, relevant, and effective way.

Being on a different team hasn’t stopped me, though. I still find places to help out where I can and try to make some kind of impact on the program when possible, it’s just not a direct influence. I don’t want all of this to come off as complaining. Despite what my current role’s focus might be, I’m still pushing on, learning as much as I can about learning and development, even if it’s just to apply it to my next conference talk or potential online training sessions. I feel the drive to learn again and it’s refreshing. It has already filled in some blanks for me that I was missing in my own instructional methods and has given me countless more to explore. I’m excited to see where this all will lead me.

I wanted to share my story here, not because I feel like it’s important or that it’s any kind of amazing. I wanted to share it for those out there that might have that little same voice inside their heads wondering “what’s next”. I share it because I want to show that it’s not always about becoming the “best of the best” in a single kind of role. As the saying goes: if you’re the smartest person in the room, you’re in the wrong room. It’s scary to think about change, especially in the tech world where change doesn’t always go so well and things can be unpredictable. Don’t be afraid to take a step back and look at what you’ve accomplished and where you’re headed. Make sure it’s what you want and really think about your future.

I look back on my over almost 20 years of work in technology and think about how far I’ve come in that time. I think about the “what if” of having stayed in that same role I was in years ago and where I’d be now and, honestly, I wouldn’t trade the experience and changes my career has gone through for anything. It has helped me become the person I am and has helped me find my passions along the way and, even now, is driving me on to learn more and grow. I hope that you can find the same kind of excitement in your work and can find what you’re passionate about, regardless of your current role and, most importantly, you don’t ignore that inner voice that could be guiding you towards something where you’ll find joy.

Advertisements

Custom Callbacks with Invoke

In putting the Invoke library to use I noticed something. While I could tell it to check for groups and permissions on the current user and limit HTTP methods on the request, there were more complex things I needed to check that weren’t part of these defaults. Now, I could just extend invoke to include match types for everything I needed (injecting a custom match class based on my needs) but I wanted something a bit more generic that I could use to call my own logic and return the pass/fail result.

So, I added in the “object.callback” match type that allows you to call a static method in your own code and perform the evaluation yourself. Here’s how it works. Say you have this configuration in your routes.yml file:

/foo:
  protected: on
  callback: \App\MyUser::test

This tells Invoke that when the user requests the /foo URL, the protection should kick in. It then goes into the checks portion of the process. This sees the special callback option and looks the class and method to call. In this case, we’ve told it to try calling the test method \App\MyUser. This class needs to be autoloadable so that Invoke can directly call it and its static method. Yep, that’s right – it needs to be a static method but you’ll be provided with everything about the request in the incoming $data variable. Here’s what the method should look like:

public static function test(\Psecio\Invoke\Data $data)
{
  /* perform your evaluation here and return a boolean */
}

In the $data variable there, you’ll have access to the context of the application via some object properties:

  • user: The current InvokeUser instance (ideally where your user lies too)
  • resource: The resource that was requested (includes access to the requested URI)
  • route: This is the route match from Invoke’s configuration the current request matches. This contains the route regex match, the configuration options and any additional parameters passed along

For example, say you needed to get the parameters from the request to do further evaluation. You could fetch them through $data->resource->getParams() and get the associative array back.

Adding these callbacks makes the Invoke system a lot more flexible and allows you to create those custom match types without having to have whole other classes just to perform your checks.

Invoke and Gatekeeper for Route Authentication & Authorization

As a part of a new project I’m working on (personal, not work) I came across a common need to enforce authentication and authorization handling in a bit more automated way based on the URL requested. I looked around for options and didn’t really find many that could be implemented somewhat simply but I did like the way Symfony defines their YAML to enforce auth* on the various endpoints. I set out to make something similar but a little simpler and ended up making Invoke.

It’s a super simplified version of the YAML-based routing and only has functionality for checking groups and permissions right now, but that’s not what I really wanted to talk about in this post. Invoke is fun and all, but I wanted to show how I’ve integrated it with another more robust tool I’ve written, Gatekeeper. The goal of Gatekeeper is to make a simple drop-in authentication system for applications to take care of a lot of the boilerplate user management needs. It comes with the usual CRUD handling for users, groups and permissions (RBAC) and also supports password resets, security questions and “remember me” functionality. Again, Gatekeeper is a cool library but it’s not the primary focus here. I wanted to integrate the two libraries so I could let each do what they do best – Invoke to check the current user against a set of criteria and Gatekeeper to provide the data for this validation.

Invoke lets you hook in your own users via a `UserInterface` that you can implement in your own application. In this case Gatekeeper has a concept of users too, but they don’t exactly mesh with what Invoke is expecting. So, let’s make an Invoke-compatible user object that it can use for it’s checks. This is the real key to the integration:

<?php
use \Psecio\Gatekeeper\Gatekeeper as Gatekeeper;

class InvokeUser implements \Psecio\Invoke\UserInterface
{
  private $details = array();

  public function __construct(array $details)
  {
    $this->details = $details;
  }

  public function getGroups()
  {
    $groupSet = array();
    $groups = Gatekeeper::findUserById($this->details['id'])->groups;
    foreach ($groups as $group) {
      $groupSet[] = new InvokeGroup($group);
    }
    return $groupSet;
  }

  public function getPermissions()
  {
    $permSet = array();
    $permissions = Gatekeeper::findUserById($this->details['id'])->permissions;
    foreach ($permissions as $permission) {
      $permSet[] = new InvokePermission($permission);
    }
    return $permSet;
  }
}
?>

Then, we’ll define the Invoke configuration in a YAML document:

event/add:
  protected: on
  groups: [test]
  permissions: [perm1]

In this case we’re telling Invoke that when it sees the requested URL of `/event/add` it should check a few things:

  • That the user is authenticated (protected: on)
  • That the user has a group with the “name” attribute of “test”
  • That the user has a permissions with the “name” attribute of “perm1”

If the user passes all of these checks, they’re good to go. Here’s how that would look in the execution of the Invoke code:

<?php

$en = new \Psecio\Invoke\Enforcer(__DIR__.'/config/routes.yml');

// If you're already using Gatekeeper for user management, you
// can just use this:
$userData = Gatekeeper::findUserById(1)->toArray();

// Otherwise you can push in your own user data
$userData = array(
  'username' => 'ccornutt',
  'id' => 1,
  'email' => 'ccornutt@phpdeveloper.org'
);

$allowed = $en->isAuthorized(
  new Confer\InvokeUser($userData),
  new \Psecio\Invoke\Resource()
);

if ($allowed === false) {
  // They're not allowed on this resource, forward to an error!
}

?>

The Invoke Resource by default looks at the current REQUEST_URI value so no options are needed when it’s created.

I’ve found this a pretty simple way to integrate these two libraries while still maintaining the correct separation of concerns enough to let each tool do their job. I’m always welcome to feedback on both projects or, of course, PRs if you find something that needs improving or a bug to fix.

Here’s more information about each of them:

Development Security isn’t an Add-on

Thanks to O’Reilly’s “DRM Day” promotion yesterday, I picked up a copy of a book I’ve been meaning to but could justify because a) full price of the ebook is around $25 USD and b) it was written back in 2003 – almost ten years old! The book, “Secure Coding: Principles and Practice” is more of an overview of things to think about when it comes to secure development and less about specific language-related tips. What’s interesting to me is that, despite the book being 10 years old, it seems like the same challenges they were facing then, we’re still facing now.

Even the introduction reinforces something I’ve been trying to advocate in the PHP community for a while now – security is not an “add on” that you can drop in at the end of the development process. Security must be a part of the planning and architecture of your applications from the beginning. If you “go back and secure things” you’re doing it wrong. Now, this doesn’t mean you have to have some kind of security review process retrofitted into your SDLC. I know of lots of teams that have their workflow down and are cranking out the code and features like there’s no tomorrow. How does a team like this start “thinking secure” without having to add a lot of extra overhead? It’s pretty easy really – all it really takes is a shift in mindset.

When most developers I know start out on problems, they ask themselves questions to figure out how to start in on their solution. They wonder about things like the “best way to do it” or “the most efficient way” to get the job done. Their minds start filling up with object structure and SOLID principles, trying to find the best solution (and maybe even technologies) for the job. To start thinking secure, all it takes is one more question:

How can I break this?

Easy, right? Well, like anything else in development, one question always leads to at least 10 more. This one simple question sets you down the right path, though. It’s too easy to get focused on making things work and writing up unit tests that pass when everything’s good. I want to challenge you as a developer to do one thing in your next project. I want you to take a step back from the code – maybe grab a fellow developer to help – and look at the application from the outside and determine what could be exploited and where (the “attack surface“). A lot of times this is easier when you’re not neck deep in the code, so if you have doubts, find an outsider.

Here’s some related websec.io articles I hope can help get you in the right state of mind as you work to integrate secure principles into your development. There’s lots of other topics in there that devs would find useful, but this will get you started:

Let’s all help make the integration of security and development a thing of the past. Then, ten years down the line, people wil be reading books from 2013 and wonder what it was like “before”. 🙂

“It Depends”

In my research and writings that I’ve already done, I’ve noticed something about trying to share helpful security advice to fellow developers – you can provide all of the code examples and describe the threats all you want, but the problem really boils down to two words:

“It depends”

Much like other development-related issues, there’s a lot of things you have to take into consideration when thinking about the security of your application. Code security by itself is good, and there’s some best practices for that that have been shared all over the web. Unfortunately, this only paints a small part of the picture. Web applications, by their nature, are really complex systems composed of multiple pieces of software all running together to make this useful, functional service for its consumers. If you’re a PHP developer, there’s things you can do to help prevent common attacks (like XSS, CSRF or SQL injection to name some popular ones), but unless you look at the bigger picture, you’re getting a false sense of security.

“But I’m only responsible for the code!” you say. You like the idea that your code can be as secure as possible by filtering output, escaping user input and using defensive coding techniques. You commit your code, run your tests and happily go about your business, thinking things are good. Unfortunately, if you don’t consider the ecosystem your application lives in, chances are you missed something.

I’m not talking about code challenges here – preventing things like XSS or SQL injections is relatively easy (as long as you know what to do). The problems I’m talking about are things that may be true for one environment but not for another – things like:

  • Working with multiple databases and storing their credentials securely
  • Effective logging to a remote syslog server
  • Potentially protecting your data from a physical intrusion
  • Working with sensitive data
  • Bridging authentication/authorization across applications
  • Concurrency issues coming from multiple installations of the same application

While a lot of these kinds of concerns revolve around the architecture of the application, developers still need to keep them in mind when creating their applications. At the very least, you need to keep these kinds of concerns in mind when writing your code. Like anything else, there’s ways to structure the code to make things like this simpler to change. The trick is to keep things loosely coupled enough to make life simpler down the road.

Innovation’s Not The “Ah-Hah!”

After reading through his “Confessions of a Public Speaker” (as a beginning speaker, I learned some good things from this one – I’d suggest it if you do any kind of speaking) I was anxious to check out some of Scott Berkun’s other books. The topics of some of the others didn’t really appeal to me, but the one that’s caught my attention recently is his “Myths of Innovation” book. I’m maybe a third of the way through it right now, and there’s one thing that keeps resonating in my mind as I go through it. In a previous chapter, he makes the point that innovation, despite what the history books and popular culture would have us assume – it’s less of an “Ah-hah!” and more of a “Finally!”.

See, most of the common stories of innovators out there leave out something that’s very important – the reference frame of their lives. They don’t provide a larger picture of who someone is (like Einstein or Newton) and how all of their work, everything they’ve done in their career led up to the discoveries that they’re known for.

I think this is important to remember as software developers, too. All of us start projects and never finish them, it’s just a fact of life in the world of a coder. We find something that we either think is the “Next Big Idea” or something that we’ll find amazingly useful and latch onto it, giving it our all for a week, maybe a month. Nine times out of ten, though, that project falls by the wayside. Now, don’t get me wrong, there’s some folks out there that do a great job with anything they touch, but for the average developer, it’s all about hacking away at the latest “shiny”.

Sometimes it’s about the technology (“everyone’s learning Backbone.js, why shouldn’t I?”) and other times there’s a bit of pride that kicks in (“I could do this so much better if…”) but there’s always one thing to remember. It doesn’t matter if the project you’re working on goes anywhere. Remember this. Just like some of the great innovators of the past, it takes a lot of dedication and work to get to be the “Ah-hah Guy” that wows the world with something new and amazing. Don’t forget that the code of the Next Great App isn’t just going to fly from your fingertips.

Work hard at your craft and it will pay off. Maybe not in fame and glory, maybe in making real, useful contributions to the culture and technology around you. Don’t stop trying to innovate, don’t focus on the failures and, above all, keep learning and keep doing.

Book Review: “Code Simplicity”

Last night I finished my latest read from O’Reiily, Code Simplicity – The Science of Software Development. I spotted the book the other day when O’Reilly was running a special on a few books and the ebook was cheap so I figured it couldn’t hurt to give it a try. After all, the “science” part in the title made it sound like there might be some hidden truths that could be applied anywhere in development. Unfortunately, most of the book just ended up being more of a rambling journey though things that most software developers that have any years of experience (even the bad ones) would already know.

The author spent a good bit of the book dedicated to definitions and explanations about various practices and ideas in development, as if he thought that maybe the audience reading the book wasn’t savvy on the topic. The first few chapters also included several sections about the book itself – why it was relevant and mentions of a “science” that never seemed to fully resolve. Granted, trying to make a “science” (more a set of laws than just best practices) out of something so varied as software development is a pretty difficult task, but I felt like the author tried a little too hard to make his case for the book and less time actually defining something that could have been interesting.

All this being said, if you don’t worry too much about him trying to propose a “science” to it all, there were some good best practices reminders in here for developers of any language:

  • Don’t rewrite, rework – a reminder that, despite it seeming easier to chuck the whole system and start over with the knowledge you now have, you’d do better in the long run to change things from the inside out, a piece at a time (hint: unit tests make a world of difference here)
  • Know the problem before writing the solution – listen and understand the problem before you start with even one piece of code. If you don’t fully understand the problem, you’ll end up with half-assed software that only does part of what was needed.
  • Think specific, not general – if you immediately jump to the “well, if I use a plugin architecture for this part…” chances are you’ve already added too much complexity. Think small first – make it work, then make it better (I’m a big fan of iterative development)
  • Use more experienced developers as a sounding board – chances are, if someone’s been in the development biz longer than you, they’ve come across your situation before. Sometimes you have to seek out that person on a specific topic, but don’t just forge ahead blindly. At the very least, try to find blog posts or articles that you can use as a guide.
  • Don’t forget that time is important too – most developers (me included) easily forget that time is a factor in their development. No, I’m not talking about the actual time to write the code or the looming deadline to finish it by. I’m talking more about the time you’ll need to do research, try things out or even consult with fellow developers. Time put into something to gain knowledge is an investment too…don’t forget to remember the value of it.

There were other points made throughout the book, some more relevant than others, but I wish the author had spent less time focusing on definitions and more on expanding the sections with some more practical advice. This (relatively short) book probably could have been summed up in a small series of blog posts and been just fine.

Book: Code Simplicity – The Science of Software Development
Publisher: O’Reilly
Author: Max Kanat-Alexander
Pages: 92