Showing posts with label teaching. Show all posts
Showing posts with label teaching. Show all posts

Monday, November 27, 2023

AskAppSec - Capturing Flags

Deliberate practice proved being invaluable in my own career. The last months showed me once again that this applies to the field of security just as well.

As we can't practice security related skills on just any system without causing harm, we need dedicated spaces to practice safely. Fortunately, there are lots of options readily available out there, way too many to list them all. Hence, here are just a few sites that provide not only great starting points yet also the opportunity to go as deep as you can.

  • OWASP Juice Shop: This is an intentionally vulnerable web app, mimicking a quite common e-commerce scenario. Based on this, you get a set of challenges presented that allow you to try out techniques to find and exploit the present vulnerabilities. It's been my own entry point into practice apps for security and the gamification behind this app in particular really drew me in further.
  • OWASP WebGoat: Another commonly cited OWASP project that offers you a place to practice. In this case, you go through dedicated lessons to learn about vulnerabilities, to see how they work and how they can be mitigated.
  • Hack The Box: This service offers you a huge amount of prepared virtual machines aka "boxes" to practice on safely. I really like their starting point machines that guide you towards the secret aka flag you're trying to find and introduce you to commonly used tools to identify and exploit vulnerabilities.
  • TryHackMe: Another service offering lots and lots of machines to practice on. You have plenty of themed learning paths to learn on with a lot of detailed information to guide you on the way. Both Hack The Box and TryHackMe have big communities active on Discord offering a great support network.
  • PortSwigger's Web Security Academy: The developers of BurpSuite provide a great resource with lots of challenges to solve in order to learn more about web security in general.
  • PentesterLab: The courses offered on this platform include lots of explanation and guide you step by step to learn skills needed for penetration testing. My thanks go to Yianna Paris for introducing me to this service!
Besides these dedicated apps and labs available around the clock, you can also watch out for hosted public capture the flag (CTF) events. I've recently joined one from Huntress and I see several being announced for the upcoming holiday season, like TryHackMe's Advent of Cyber or the SANS Holiday Hack Challenge. Being in security-focused communities and following more security folks on social media really helps to learn about these CTFs. Alternatively, you can check dedicated sites like CTFtime to look out for the next ones coming up.

When practicing in these kinds of spaces on such kinds of challenges, I've experienced the following benefits.

  • Reduce scariness. Dipping your toes into security can by scary indeed. You might not know where to even start, so having these kinds of practice spaces can serve as just the starting point you need. More often than not, they include challenges designed for beginners that offer further explanation and guidance to get you introduced into the space.
  • Grow knowledge. Through these practice apps I usually got introduced to something I didn't know before, be it a concept, a tool, or anything. For example, they also provide a great reason to get to know security focused Unix systems like Kali Linux, Parrot Security or Mobexler and their respective tool boxes.
  • Hone skills. The more we practice, the better our skills get, and the more we can make connections between things we know. More pieces to complete the puzzle, or in our case the next challenge. Creative problem solving is definitely a skill we're practicing here!
  • Build confidence. The more touchpoints we get and the more we seize practice opportunities, the more we can grow our own confidence that we can also figure out the next challenge.
  • Spread awareness. We can use the gained knowledge and skills to raise awareness about vulnerabilities with others. Even better, by practicing together we can increase awareness in real time. These kinds of challenges can help people see what's possible and why we need to defend our systems, protect value and keep harm away.
  • Find joy. Security can be perceived as such a dour and tedious topic. Finding solutions to security challenges, however, can feel very rewarding in itself. Doing challenges together can further help with connecting security with fun and make it more interesting for people to engage with. It can also help to find community and like-minded people to learn and grow with.

All of these advantages I've experienced myself as I've been trying out various vulnerable apps, a bunch of labs offering dedicated challenges, as well as dipping my toes into my first public CTFs. I've also seen them over and over again with conference participants, joining me for many sessions of "capturing flags together" at SoCraTes, FroGS Conf and Agile Testing Days. It's been just the same when hosting practice sessions with colleagues in the past - something I'd like to pick up again in coordination with our current InfoSec team.

So, just practicing within these spaces gives us everything we need, right? Well, unfortunately that sounds too good to be true. There are also downsides to these kinds of challenges. Kudos to Dave van Stein for making me think more about this!

  • Artificial challenges. All these spaces are crafted with a specific goal in mind, usually to educate and provide a safe place to practice. Therefore, challenges are inherently artificial and can't fully represent real-life scenarios.
  • Mindsets differ. Attackers tend to think differently. I mean, they usually don't have the one clear flag to find in a constrained environment to announce their win. Instead, they might gather all kinds of information over a period of time, and based on that build their strategy on whether to exploit identified paths into a system, what to gain from it, and so on. It highly depends on their motivation and goals as well.
  • Uncertainty instead of solutions. For labs and CTFs you'll know when you made the right move, you get a reward. In real life, there's no cheat sheet, there's no walkthrough. Just potential and ambiguity and never being completely sure that whatever you've found (if you've found any at all) is all there is to find.
  • Overly focused on penetration testing. All the sites listed above are mainly offered to practice penetration testing. It's the one hot topic that probably attracts most people, but how often do you actually need those skills? How many jobs are in this area compared to all the others? There are so many more skills needed in the field of security. So where are the challenges on secure coding, or secret storing, or vulnerability evaluation, or threat identification, or incident response, and so on? Well, more practice apps are being built all the time, so some of these do exist already while not always being in the spotlight. And of course, there's official formal training to have as well (though it can come at high costs).
Weighing benefits and downsides against each other, I consider deliberate practice opportunities like the ones listed above still invaluable. We do have to be cautious, though, to put them into perspective and be clear about their goals and limitations.

That leaves me with yet another question: can we practice closer to reality? Here are a few approaches I think we could experiment with. I'd be happy to hear about further options to add to the list.
  • Replay past real incidents. I'm thinking of actual security issues that your own company faced. We could replay these very real scenarios both from an attacker and a defender point of view and hence learn what we can do better - very concretely for our specific situation.
  • Run open thinking exercises. Deliberately practice approaches like threat modelling, attack trees and similar to improve our thinking, within our actual work context to make it as applicable as possible.
  • Host custom-tailored CTFs. Have one person hide a custom flag on your own system for people to find. It might still be an artificial scenario, yet placed in your very real context. This requires quite some preparation of course, like a dedicated environment to practice on and, as usual, explicit consent from all involved parties. The gained insights might still be worth the effort.
Personally, I'm sure I'll continue making good use of the various practice opportunities there are. I'm also considering joining or starting a CTF team to make practice even more deliberate. If anyone's interested or has recommendations for good places to find a welcoming, inclusive and diverse team please let me know.

Now let's bring this question back to the community: what do you do to practice your security skills?

Sunday, May 17, 2020

#SecurityStories: Using OWASP Juice Shop for Teaching

Have you heard of OWASP Juice Shop? It's a project that's very dear to me and helped me massively over the last years.

Johannes Seitz was the first one who introduced me to this intentionally vulnerable application used to practice security testing hands-on. He facilitated an open space session at TestBash Munich 2017 with it, and I got hooked. Dan Billing also used this great application in his tutorial at Agile Testing Days 2018. I personally used Juice Shop for security testing workshops at my own company since beginning of 2019.

What I like about Juice Shop is that it's a full-blown application. It's working, and it's vulnerable. We can safely practice lots of techniques, whether manually or having automation support us. You're also not alone, it offers guidance in case you need it. What I love most of all: it's based on gamification, offering many challenges on various difficulty levels. The first challenge itself is to find the score board to get an overview on which tasks are there and what's your progress! Although I know that attackers would approach a productive application differently, the gamification approach is very appealing to me. It's simply fun and draws me further from one challenge to the next.

This kind of gamification also worked well for the people I've had in my workshops, introducing them to security testing. Challenges can be taking time and be quite frustrating - yet when you finally solve them, the moment of epiphany and heureka is invaluable and very memorable. In these workshops, I've also seen people learn how to make more use of tools when testing, like the browser's developer tools or REST clients. Despite them having used these tools before, Juice Shop triggered them to discover more possibilities and features they weren't aware of yet. Also, people shared lots of knowledge on how applications are built, which assumptions we make, which approaches we take.

My personal challenge this year is to tell #SecurityStories, so I thought of using Juice Shop again for teaching. Parveen Khan is currently on a testing tour and asked me to join her for a session. She knew about my #SecurityStories challenge, so we thought it's a great match to pair on security testing. Once more, Juice Shop it was.
I believe that pairing on Juice Shop challenges (or the like) will result in deepening my own understanding by sharing the concepts and approaches I've learned.
I know I'll have succeeded when my pair learned 3 new things from me.
Just around that time, a new shiny Juice Shop version got released! Perfect. In our pairing session, I helped Parveen set everything up and we also tackled the first challenges together. As I already knew the solutions, I held back with my knowledge not to spoil the experience for her. Instead, I led her through only nudging in certain directions, waiting for her to ask for hints. It worked! The first challenge was the hardest - it's a whole new application to get to know after all. Once getting the grips with Juice Shop, Parveen solved the second chosen challenge a lot faster. It was really fun doing this together with her! At the end, Parveen shared with me what she learned from this experience hat was completely new to her.
  • She knew how to look at information in the browser's developer tools, yet now she learned that she can also do something with it and how powerful these tools really are.
  • She always thought that security testing needs a hacker mindset and JavaScript knowledge and therefore concluded that she can't do that. Now she saw she can take first steps into security testing herself indeed and solve challenges to learn more.
  • She shared she never had much interest to learn about security, despite knowing that it's important. After having fun with Juice Shop, she's now open to learn more.
  • She learned that she could do security testing together with another person to have more eyes on the problem which makes things easier and more interesting.
  • She realized she forced herself to think in a different way, and she will always remember that. It was great to get through the experience without me giving away too much.
So I'd say, my experiment worked out well! This experience taught me once more how useful Juice Shop and security testing in general is to teach knowledge that also helps us in everyday testing life: understanding how applications work, what we need to check for under the hood of a shiny interface, which tools can help us, and more. Security testing is combining so much knowledge, learning about it is super useful for anyone involved in product development. This fit very nicely to my findings from doing security testing workshops at my company.
I could have stopped there when it comes to Juice Shop. However, there's something that bugged me. Despite knowing Juice Shop for quite a while, and frequently using it for teaching purpose, I haven't solved nearly as many challenges myself as I would like to. I decided that now's the time to change this. So here's my next experiment.
I believe that working on Juice Shop challenges, alone or with a pair, will result in increased confidence in my own skills.
I know I'll have succeeded when I've solved all challenges below 5 stars.
This fits well to what I learned during the AppSecDays: I need more hands-on practice. Off to new frontiers! Want to pair with me on this one? Feel free to reach out. 

Sunday, November 3, 2019

On Having Become #CodeConfident

For 2019, I've once more made a pact with my learning partner Toyer Mamoojee. This year my personal challenge was to become code-confident. To learn about my hypothesis, the experiment I designed and who influenced me to embark on this journey, please read the origin story. Now that the challenge is officially over, it's time to look back and forth.

Why This Challenge

Why did I pick this challenge? This question followed me throughout the year. Here are the reasons I discovered on my journey.
  • Programming is a skill that many people benefit from; no matter their role. I think this is the case already now, and presumably even more in the future.
  • Many of my peers in the testing community program every day.
  • People say coding skills are essential for us testers. Even to stay "employable" and get new jobs. Whenever I heard this, I felt I don't belong and that soon enough everyone will see that, too. Even worse, many people consider you only technical when you're able to code. I absolutely don't share these viewpoints, but still felt the need to prove myself that I am not only able to read code but also write code myself. It was about time to conquer this fear of losing my face by showing how much I don't know yet and to see for myself how much I can increase my programming skills in a certain time frame.
  • I feel I „specialize in generalizing“ (as Patrick Prill likes to say) - so I wanted to upskill as a generalist. To strengthen my strength by adding coding to my toolbox.
  • I wanted to be able to help my testing better through automation and tool creation.
  • I wanted to understand our product architecture better, how things work together, where they tend to break, where the risks are.
  • My knowledge is quite broad yet scattered, and never really deep. I have lots of bits and pieces of knowledge and often try to puzzle them together to see the bigger picture. I wanted to see how far I can go with this when it comes to coding. The good thing: I realized I don‘t have to know everything to belong. The main key is to keep yourself aware of your contributions and the value-add you bring, and then to keep going and learning new things, adding to that toolbox you bring.


Continuous Practicing

In the beginning I found the very first steps to be the easiest and the hardest at the same time. If you want to know more, read about my first steps until picking my first coding challenge. As soon as I published my first ever GitHub commit, things started to roll.

As I started out on this coding journey, I soon felt the urge to blog about my experiences and lessons. At the same time I wanted to avoid spending too much effort on blogging and rather put it into practicing. I decided to experiment with a new lightweight blog post type in the form of a coding journal, documenting my raw notes while coding. My hope was was that these kind of posts will serve three goals.
  1. Act as learning journal for myself, making my learning journey visible helping me acknowledge what I achieved
  2. Provide context for anyone who would like to check out my repositories and maybe provide feedback and support
  3. Potentially provide a source of learning and inspiration for anyone else following my journey
So I had finally started, I blogged about my journey - next thing to do was to call for collaborators, people to pair with me hands-on or provide feedback on my code. Once more I learned about the joy of doing things together when you put trust in each other. Compared to my Testing Tour last year, I did a lot on my own as well. However, I wouldn’t be where I am without my wonderful collaborators, so here’s a huge shout out to these great people!
Not mentioned above but never forgotten are my dear teammates supporting, encouraging and teaching me during work time. Thank you.

Besides those that paired with me, this wonderful community was a great factor and motivator on my journey by providing dearly needed encouragement! Like Angie Jones who recognized my growth in her technical workshops - which meant a lot to me! She even triggered me to submit to Test.bash();. Without her I wouldn’t have presented my lessons from this challenge at TestBash Manchster. Also, during the code-related workshops I attended this year I realized people thanked me for helping them - which made me realize I was indeed able to help them!

After getting started with my first challenge, I decided to go from more familiar topics to the least familiar ones for me. So I came up with the following plan.
  1. Start with automated testing through the UI (though these tests might actually be the most complex, starting with something familiar made perfect sense to me);
  2. Then go a level deeper to API testing;
  3. Then to unit testing;
  4. Now cross over to writing features myself, first implement a small backend feature;
  5. Then implement a small frontend feature.
I hoped afterwards I would already be ready to start my proof of concept project.

Last but not least: while working on my challenges, I had to keep an eye on my self-imposed constraints.
  • Pause criteria - play computer games at least once a week
  • No online courses or tutorials - at least not for the actual practice scope
  • Time - at some point I realized I had to speed up, especially for the TestBash Manchester talk
The great news is: I fulfilled the promise to myself to have at least five repositories of practice projects published on GitHub - even in five months!

Time to Tackle the End Game

As I had hoped, I was now ready to build an application myself. I pondered for a long time what I could do as my final proof of concept app. In the end I decided to create a learning journal. An app that would help me tackle my challenges, based on what I learned so far - and other people could use the same approach. A place to define a challenge, a hypothesis, the experiment. A place to track your progress, to evaluate your results.

So this it was! I created “Journey” - a learning journal application. I wanted to use a similar tech stack to what we have at work. In the end not as similar as I intended yet still really useful for practice.

However, there‘s a twist to it. I decided to kick-start the project so I wouldn’t have to deal with the whole setup. I chose a tool called Jhipster which allows you to generate apps from scratch. Great, right? Well, this approach had upsides and downsides to it. First and foremost: I felt guilty, like I cheated by doing this jump start; while being well aware that at work we also used code generators in the beginning of a project, like the Spring Initalizer or the generated snippets by Angular. It was great to already have a running base to work on; yet the project was bloated from the beginning, with features added that I did not need (like user management or auditing). When you start something from scratch, you know everything (or most of it); with this kick-start, I felt I immediately entered a legacy project, I had to learn how things work together. Yet after all it was still valuable for practice and learning! So I decided to move on with it.

Based on the generated code I then introduced my own entities, created views, modeled what I wanted it to do. What you can do with it is you can define your challenge, and you can create journal entries for your challenge, tracking your progress. Just that, serving as proof of concept. The project is absolutely not finished yet. There's so much more to do, and so much more there could be. It would be a great playground to practice all kinds of testing as well. Though my challenge is done, I can still continue work on it - which feels amazing!

Let's Evaluate

First of all: I could prove my hypothesis true. I did practice, I paired up, and in the end I did develop a small product.

Even more: My whole year was under the focus of coding. At conferences I chose courses, workshops, and talks according to my goal. I attended sessions about mutation testing, automation in testing, clean code practices, approval testing, Python for testers, Jest, and more.

The outcome was indeed actual confidence! End of August I finally realized how much I had worked on code at work over the last weeks. I found myself writing unit tests for our new frontend, to help my developers with our safety net here and to understand our product architecture better to see where it breaks. We were experimenting with mutation testing. I even did some refactoring myself! I finally realized it was the result of having become code-confident (past tense!). To illustrate that, for example I found myself having inner dialogs like the following:
"Okay, now I’m tackling the split of this dialog component into two. Or - nah, maybe someone else should do it, they could do it more efficiently. Or maybe we do it together! Pairing is great. Well, let's have a short look at it first. Oh, that looks like more than I thought it would... Well, whatever, let’s try anyways."
And I was able to do it! In addition, by doing so I understood our application a lot better. The thing is: I would have been capable of doing this before already - yet I didn’t dare to do so. I hesitated, found excuses.  Now I am not afraid anymore to try and to learn by doing. I know there’s a lot more to learn - and that’s fine!
All this made me think. I could stop now with confidence - yet what about if I dare even more? Step even more out of my comfort zone? When preparing my TestBash talk about this whole challenge, my original idea was to have no slides at all, just code, walking people through. Well - obviously I still had slides in the end, I did not dare go without them (yet!). Still I wanted to dare even more. So I decided to do some live coding on stage to show my confidence. I considered that this might go horribly wrong - yet at least I would have tried it. I thought, even if I failed I would have succeeded as I would have dared; and I would have learned what not to do in these situations. ;-) So I prepared for it. I chose my proof of concept project Journey as my target app. I chose a super small change to make it less scary, to not take too long, something that would still allow me to narrate what I am doing at the same time. Small steps, right? Also, I chose a frontend change so people could see the impact right away without me having to restart the app. So that's how I did it - and it worked out!

Plenty of Lessons Learned

There are a lot of lessons to take away from this journey. Let's start with the lessons learned when working with code.
  • Learn how to go in small steps. And then even smaller steps.
  • Googling is a real skill - if you know what to look for it will save you lots of time.
  • Read things carefully. Documentation, exceptions, what methods expect - don't skim over them but read them properly! Sometimes you really need to read everything to get the information you need.
  • Keep maintenance in mind. Would a method now take more than three parameters? Then it's time to refactor as it's getting too big to keep it in the head. One method, one purpose; keep it small. Shall we extract a method for a line that's used in two places? It might not be worth the effort, yet should be consistent. The most elegant solution might not be most readable one, find the middle way.
  • Test the tests. I encountered this classic several times: a test that's constantly green but not checking the right thing (or no thing at all). Sigh.
  • Learn IDE shortcuts by heart; especially for all features you constantly use.
When it comes to code review:
  • Get feedback early and incrementally.
  • Don’t take it personal.
  • Learn from it.
  • Thank people for their feedback.
  • Respond to each feedback.
  • Need to discuss? Then rather discuss in person.
  • Stay patient.
  • It’s scary but worth it!
And finally, I also learned a lot on the personal challenge itself.
  • Learning by exploring is really valuable (and very close to our everyday work). I have a hunch, thought, that it might be best combined with some more structured training.
  • In the end it’s all about practice, practice, practice. It's not about doing things perfect from the start, but about daring imperfection and getting feedback to improve.
  • Pair up for success. (Obviously.)
  • Follow your energies and don’t forget to take breaks. Tired days are not helping. For a private project you have the luxury of leaving a problem for a while and follow your energies instead to keep the momentum. After a while you can either come back to the problem or leave it there (if it’s just for practice); at work we often have to push through, yet defocusing can still help there as well.
Overall, I learned a lot! But I also struggled a lot. My biggest struggle increased my empathy for my developers. Not only the kind of work they do as problem solvers, or having your own work reviewed, but especially when it comes to testing.

When developing I caught myself just wanting to make things work and then move on. The sad truth is, I postponed errors. I sometimes did not test a change at all, neither using exploration nor automation. I just wanted to move to the next change and the next and the next… I really should know better and yet did not care! (Still can't believe this. Super embarrassing.) I really had to remind myself of switching between development and testing modes, or rather intertwine them. This is not easy and I will need to continue practicing. Now I know better how they feel and how difficult it can be to not jump to the next feature.


What else?

Besides this challenge: I‘m finally enjoying my hobby again! As I promised to myself, I played a computer game each week since 2018, December 16th. :D Yet honestly, I struggled to achieve even that. I did not play too much each week. The sad truth is, I dearly needed this personal limit to take better care of myself. So, I'm still working on finding a better balance. We should not put our personal lives behind our personal development.

Now that I survived puzzling bits and pieces of knowledge together to create something myself - I can go back to school! :-) I wanted to fill my theoretical knowledge gaps and get a deeper understanding of the languages, or at least revisit the basics. To begin with, I finally did a bunch of more courses offered by the Test Automation University. By doing so, I discovered that I knew a lot of these things already! This kind of confirmation is a really encouraging. Also, this made me revisit some important concepts that I had heard of already yet never really memorized. As a side effect, I know now that these courses are very worth recommending, they are well taught and provide a wealth of easily accessible, free knowledge. If you haven't done so already, check them out.

At work, I continued to contribute in new ways, using and practicing my coding skills a lot more. This feels so good! Especially as researching real problems open up so many opportunities to learn more.

Oh, and I'm sure there will be another personal challenge for 2020! :-) I'm already thinking about it. Yet no matter what I might choose, I already made a decision to continuously offer pairing sessions, on various topics. Over the last years this proved to be extremely beneficial to all parties. In case you're up for it, feel free to check my availability for the next period on Calendly and book a session with me.

In Summary

If you want to go on your own journey and tackle your own challenge, then break it down so it becomes testable and therefore achievable. Explore using the knowledge you already picked up on your way, and practice! Yet always remember: take care of yourself first.

Thursday, October 31, 2019

#CodeConfident: Journey - Part 4

My Journey application went through a couple of further changes. Here's my coding journal for them.

September 26

  • received security vulnerability report from GitHub, upgraded generator-jhipster
    1 generator-jhipster vulnerability found in package.json 3 days ago
    Remediation
    Upgrade generator-jhipster to version 6.3.1 or later. For example:

    "dependencies": {
      "generator-jhipster": ">=6.3.1"
    }
    or…
    "devDependencies": {
      "generator-jhipster": ">=6.3.1"
    }
    Always verify the validity and compatibility of suggestions with your codebase.

    Details
    GHSA-mc84-xr9p-938r More information
    high severity
    Vulnerable versions: < 6.3.1
    Patched version: 6.3.1
    Generated code uses repository configuration that downloads over HTTP instead of HTTPS
    Impact
    Gradle users were using the http://repo.spring.io/plugins-release repositories in plain HTTP, and not HTTPS, so a man-in-the-middle attack was possible at build time.

    Patches
    Maven users should at least upgrade to 6.3.0 while Gradle users should update to 6.3.1.
    If you are not able to upgrade make sure not to use a Maven repository via http in your build file.

    Workarounds
    Replace all custom repository definitions in build.gradle or pom.xml with their https version.

    e.g.

     <repository>
                <id>oss.sonatype.org-snapshot</id>
                <url>https://oss.sonatype.org/content/repositories/snapshots</url> // <-- must be httpS
                <releases>
                    <enabled>false</enabled>
                </releases>
                <snapshots>
                    <enabled>true</enabled>
                </snapshots>
    </repository>
    maven { url "https://repo.spring.io/plugins-release" } // <-- must be httpS
    References
    https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator?vector=AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
    https://max.computer/blog/how-to-take-over-the-computer-of-any-java-or-clojure-or-scala-developer/
    For more information
    If you have any questions or comments about this advisory:

    Open an issue in https://github.com/jhipster/generator-jhipster/issues

October 13

  • activated issue tracking for my GitHub repo, added all open todos I am aware of
  • added the projects option, created a project and added open todos to it to provide a better overview and track progress
  • added contributing.md as guideline how to contribute to the project
  • changed default sorting for journal entries and challenges

October 15

  • Github reported a security alert; upgraded swagger-ui
    1 swagger-ui vulnerability found in package.json 2 hours ago
    Remediation
    Upgrade swagger-ui to version 3.23.11 or later. For example:

    "dependencies": {
      "swagger-ui": ">=3.23.11"
    }
    or…
    "devDependencies": {
      "swagger-ui": ">=3.23.11"
    }
    Always verify the validity and compatibility of suggestions with your codebase.

    Details
    CVE-2019-17495 More information
    high severity
    Vulnerable versions: < 3.23.11
    Patched version: 3.23.11
    A Cascading Style Sheets (CSS) injection vulnerability in Swagger UI before 3.23.11 allows attackers to use the Relative Path Overwrite (RPO) technique to perform CSS-based input field value exfiltration, such as exfiltration of a CSRF token value. In other words, this product intentionally allows the embedding of untrusted JSON data from remote servers, but it was not previously known that <style>@import within the JSON data was a functional attack method.

October 27

  • pairing session with Michael Kutz
  • our goal was still to introduce Lombok to Journey; as preparation for our pairing session, I recreated the situation where we ended last time, using the @Data annotation from Lombok which caused the equalsVerifier test to fail
  • when debugging the failing test again, Michael noticed that Logback threw an exception:
    WARN in net.logstash.logback.appender.LogstashTcpSocketAppender[LOGSTASH] - Log destination localhost/127.0.0.1:5000: connection failed. java.net.ConnectException: Connection refused: connect
    http://logback.qos.ch/codes.html#earlier_fa_collision
    This does not cause a problem for the test as we still have log output in the console, yet is something to investigate for later. Maybe deactivate the file appender in case of running tests.
  • we tracked down the difference between the previous "equals" implementation and the one Lombok provides: Lombok does not consider the need for the object instances to have the same id, in the implementation generated by JHipster, however, they need to have an id defined and that to be the same
  • this triggered thoughts that it might not be wise at all to use @Data annotation for entities; Michael remembered a discussion with a colleague and a related blog post and will investigate further --> here it is! https://developer.jboss.org/wiki/EqualsAndHashCode
  • as side note: Michael shared that any additional dependency introduced for microservices is a risk in itself as dependencies result in frequent maintenance costs on updates
  • we researched whether we could use the @EqualsAndHashCode annotation configured to include or exclude certain fields
    https://projectlombok.org/features/EqualsAndHashCode
  • Michael questioned the design of the generated code of JHipster regarding entities that are also used as business objects; we have DTOs here as well, which can be considered as objects that construct a JSON object from the entity
  • in the end we decided not to risk using @Data as using Lombok here might lead to unwanted side effects like not persisting entities in the database or creating duplicate ones; these kind of problems tend to surface only much later and are hard to figure out; in the end it was good to have a test for it!
  • instead we decided to use the following specific annotations which still replace a lot of boilerplate code: @Getter, @Setter, @ToString
  • for equals and hashCode we kept the original implementation; equals here will only return true in case the instances have the same id persisted in the database
  • the hashCode implementation which sets it to the magic number of 31 is completely obscure to us; the hashCode is used e.g. in a HashSet to check if an object of this type is already present
  • before committing, we reviewed our change set
  • we discussed where to put the Lombok dependency in the Gradle file; the current list of dependencies is provided by JHipster, using a BOM = Bill of Materials; therefore no specific versions are provided for the dependencies, JHipster will take care of getting the latest versions they have available; this is similarly solved in SpringBoot; we decided to add our new dependency at the very end, considering we would find it again quicker and not miss it when skimming over the JHipster dependencies
  • we discussed our previous sample test for the toString method without and with Lombok; this was rather meant as test to showcase how Lombok works, and build trust in this library; as soon as we trust it, such a test is not useful anymore, so it's not meant to be maintained but rather to help our exploration, so we threw it away; the Lombok toString might be implemented differently now, yet this method in general is only meant to provide a human readable representation of the object, while hashCode is meant as interpretable for a machine
  • when committing, we discussed proper commit messages; Michael recommended the following post: https://chris.beams.io/posts/git-commit/ He has trained himself to make use of these recommendations and learned their benefits; we used the same approach here:
    • a) write commit messages as short as possible --> write them in present tense (which is always shorter than past tense), and as imperatives for git
    • b) if you want to provide more information, add an empty line after this "subject" and then write your comments in the third line
    • c) don't write more than 50 characters for the subject or more than 72 characters per line for the rest of the commit message
    • d) start the subject with a capital letter
    • --> IntelliJ settings offer automatic warnings in case such patterns are ignored
  • it's great to reflect on commit messages together with a pair as this helps you become aware of potential ambiguous commits; if a pair cannot formulate a great commit message together, then it might be too big, too early or not ready yet at all; great heuristic!
  • trying to commit, we stumbled across different shortcut settings: per IDE, per operating system, overridden by another program, or using custom ones; for pairing it's great to know the default ones provided by an IDE as well as most people use them
  • Retrospective:
    • I learned a lot again, it's a pleasure to pair with Michael, he takes time and stays patient to explain things well
    • Michael shared it's fun to pair with me, and explaining helps him see where his gaps are, what are only his opinions or more common viewpoints
  • Our pairing session was over, and yet we continued talking for over an hour :) We ended up with a great conversation on the following topics and more:
    • how to structure big test suites, e.g. in teams aiming to cover nearly every bit of code with automated tests
    • what are integration tests, what are service tests, what should they call and what not
    • potential future blog posts, talks, video courses, books
    • Test Automation University
    • public viewing of talks and pairing sessions at work and their discussion afterwards to learn more
    • Agile Testing Days 2019 which starts in a week and where we will meet in person
    • a conference I wasn't aware of yet: SAEC Days
    • paired talks and their specifics; paired workshops and why we should always pair for them
    • exploratory testing and introducing it to developers; how close it is to security testing
    • coaching and career development
    • pairing in general: If Michael sees one person working alone and they are not deleting their emails, then he considers this as waste. They might not know what they do; they need to share their knowledge anyway with the team; if they don't share it's a knowledge silo; feedback like had regarding proper commit messages will be lost as it's mostly not provided at a later point in time; feedback should be timely and constructive anyway and this is a lot easier when pairing. With me, pairing is easy as learning is always my second goal, yet that's not the case with all people. Having people do things alone is always dangerous.
    • code confident: Michael would instantly have me pair in his team and people wouldn't know I'm not a developer. The only difference would be that coding is rather on my breadth than my depth when it comes to my t-shaped skills, which is not bad as pairing is always learning and broadening our skill set. The one most important skill in his opinion when it comes to pairing is curiosity and the thirst for knowledge and I bring that. :D
  • TODO: fix logging configuration for running tests
  • TODO: make use of Lombok in other classes

October 27 (cont)

  • adapted implementation of entities and more to use Lombok as well
  • found some generated integration tests for the user management implementation were broke (already before using Lombok), presumably after one of the latest security fixes --> TODO

October 31

  • pairing with Simon Berner
  • he was also focusing on coding this year, so we had decided to start our session with sharing our experiences and lessons learned, before moving to a hands-on part on Journey
  • when it comes to personal learning challenges, we shared how tempting it is to do too much and loose focus; time is limited and you can only do so much
  • it helped Simon to focus on things he is passionate about, and that he also wants to present at conferences, like the workshop "Git like a Pro" he is soon giving at Let's Test Southafrica
  • he did a sneak peak into everything, learning new things and trying stuff out without any pressure involved
  • we shared our experiences regarding submitting papers at conferences for talks or workshops; we shared how awesome it is that people like Lisa Crispin helps new voices to increase their visibility by pairing up with them; it's hard to kick-start your journey into speaking and this kind of support, sponsorship and encouragement helps immensely
  • we had paired already last year on my Testing Tour, and Simon shared it was a great experience; scary at first to suddenly pair with a stranger, yet now I'm already no stranger anymore and it feels natural to pair; it really helps to share the same interests and work together
  • we talked about the things Simon tried out (check out Simon's GitHub account!); he focused on small examples, learning by doing without having to invest too much time into things; this freedom really helped him
  • sometimes we go to bed frustrated that things don't work as we wanted them to work, and then the next day we catch ourselves thinking: "wait a second..." and we know the solution; you can't force these things to happen, sometimes you need to defocus; despite us asking ourselves "all the others can do it... is it me??", we know that the job is 80% searching, exploring, experimenting, talking with people, and only a tiny part is actual coding
  • we talked about testing, our roles at our companies, how fascinating our job is and how many opportunities it offers; and how often we have to share this with people who are not aware of what this job is about
  • we talked about pairing and mobbing and getting people to give it a try; it's fascinating that with some people this kind of collaboration becomes very natural and you get into a super productive and effective flow; yet with some people you cannot; some people also strongly resist to give things a try, and you cannot force people into something
  • we decided it's time to start the hands-on part
  • I walked him through the Journey project, explaining what JHipster provided when generating the base project, and showed him the project board with the tasks I want to work on
  • Simon instantly went for the top item on the todo list: "journal entries should show the related challenge tag instead of id" I hesitated and warned him this one might be too big for our limited time, yet he said: "why not, let's try it!"
  • we explored the code for the journal entry edit dialog, trying to understand where the challenge ids are coming from and how the drop-down list is populated
  • Simon shared that he really values good documentation, especially in these kind of situations; here we don't have any and also the generated code itself is hard to understand and not self-explanatory
  • Simon shared that when exploring an unknown code base he often deletes things to see where they get used and if they are needed
  • we shared knowledge regarding Visual Studio Code features as it's a newer IDE to both of us; Simon really likes it to be lightweight and having a great ecosystem; he likes IntelliJ for their advanced features like search, yet it's rather the heavy lifter
  • we went slowly step by step, and discovered a method named "trackChallengeById" in the journal update component which returned the id of a challenge; we changed it to return its tag instead, yet this did not do the trick yet; we found the method to be used in the related template, where we also needed to change the call to tag - and it worked!!
  • Retrospective:
    • Lisi: Thank you so much! Especially for the courage of giving this task a try. Amazing. Just within 30 minutes we solved a challenge I spent already many hours on. This clearly shows the benefits of pairing!
    • Simon: This was great! Really happy we could solve it, even when exploring the code for the first time. Let's pair again! 
  • TODO: solve the task for the rest of the views as well :)

Besides that?

I've had the honor to present what I learned on my #CodeConfident challenge at TestBash Manchester - an amazing experience. During the conference's open space, we formed a mob and worked on a coding challenge together. Our goal was to experience this collaborative approach and practice our development skills hands-on together. We made progress but did not manage to finish the challenge in the limited time of the open space. The thing is: I couldn't let go working on the it myself! I did not take notes for this one, and yet I'm still trying to figure out how to upgrade MobTime to latest open Java and JavaFx versions in order to then change it's preset alarm tone (or offer more options). Unfortunately I couldn't get it to run (yet). Still, I learned a bunch on this challenge already - and it's yet another project I'd love to pair (or mob again) on! :)

Monday, September 3, 2018

Testing Tour Stop #18: Mob Exploring with Amitai and codecentric

This stop on my testing tour was really special. Why?
  1. I saw Amitai Schleier again! We had read each other's tweets since longer and first met in real life at the Mob Programming Conference 2018.
  2. Amitai went on a coding tour this summer, joining several companies for one week each to learn together (find more about it on his blog). Most of the tour happened to be in Germany, and the last two days in Munich at codecentric. He knew about my testing tour and imagined us to have a common stop in my home town.
  3. We mobbed. My original hypothesis for my tour was about either pairing or mobbing, however, I only had the chance to pair before.
  4. The people on the mob identified as developers and had no experience with exploratory testing. My tour was about learning from testers, still, this promised to be interesting. I did not join the mob myself but stayed the facilitator. Though my tour was about hands-on testing, with me included, I learned a lot about teaching testing.
  5. My previous stop with Simon Berner was about pairing and mobbing itself. Only a few days later I could put our exchange into practice!
At first I saw this session as guest visit on Amitai's coding tour. Amitai, however, wished for counting it as stop on my testing tour as well. Even though I was not on the mob myself, this indeed felt like a bonus stop on my tour. So be it! :)

Setting the Stage

Amitai and Thorsten Brunzendorf already welcomed me at the entry. We had a nice chat, set up the room intended for our mob and waited for interested people from codecentric to join our session. They came, and even brought a test target we could use where they would value feedback on. Great, I really like to have our sessions to not only have the training effect but also have real-life impact.

After Amitai and I introducing ourselves and sharing some words on our tours, the session started. I decided to have a short introduction round in the mob as well, asking them for their name and core expertise. I knew everybody was identifying as developers, however, it was still very interesting to hear the different backgrounds, interests and specialties. Some people were into DevOps, some preferred backend development, or even tended towards security testing. I was pleasantly surprised to hear most of the group already had mob experience, only two persons didn't. After giving them a short heads-up, I went over to introducing testing, and especially exploratory testing. I presented my preferred definition by Elisabeth Hendrickson, as well as her charter template that I find useful especially for people new to exploration.
"Simultaneously designing and executing tests to learn about the system, using your insights from the last experiment to inform the next."
"Explore (target)
With (resources)
to discover (information)"
(Elisabeth Hendrickson, Explore It!: Reduce Risk and Increase Confidence with Exploratory Testing)
I wanted to keep the basic theory short and have people learn by hands-on testing as soon as possible. I asked the ones who provided the test target to shortly introduce it and afterwards asked the mob to write their charter. They, however, were really unsure what they wanted to focus on as they felt they didn't know the product well enough yet. So I decided to have them do a recon session for the first rotations in the mob, mapping out the system. I also recommended to already jot down notes together as a mob, for example in a mind map. And off they went!

Let the Mob Explore

It was really interesting to observe this mob explore a product most of them saw for the first time. They were unsure about their procedure, trying to align themselves as a group. They jumped all over the place, already finding great issues; not taking notes of them. They started a list of assumptions and wishes they had for the product. And they shared lots of implicit knowledge with each other, just as I have witnessed it in so many mobs before.

After nearly one full round of rotations, I had them stop. I shared some of my observations and provided recommendations. I also asked them whether they now felt ready to write a charter so we could do more focused exploration, using a simple Roman vote for quick decision making: thumbsup - I feel we're ready, thumbsdown - we need more information, thumbs sideways - not sure which way to go. Half of the group voted up, half sideways. I could have used the mostly positive result to have them write a charter now, but decided to have them finish a full round of rotations before asking again. Now all thumbs went up! Chartering didn't come easy to them. I helped them through, trying to not enforce my own suggestions or opinion. They managed to come up with a first charter to start with, providing them the needed focus. Interestingly, they decided to explore user experience with the help of the source code! That promised to be interesting, and it was indeed.
  • They used the code as oracle - great.
  • They looked for existing unit tests - nice.
  • One person shared: "I still don't understand the test, can you shortly walk me through?" - liked that.
  • They fed different values to unit tests, in an attempt to use it for exploration - awesome! Unfortunately, they did not follow up on it, or left a remark for future sessions.
  • They said they should also test the feature from user perspective - exactly! It might be the code they saw was actually never executed, right?
Towards the end of our mob session they started a discussion of whether a certain feature was useful at all. They brainstormed ideas how a different solution might be way more valuable to the user in the end. They questioned the context the product might be used in. Many great points were made.

Retro? Debrief, Discussion, Feedback

On my testing tour sessions, I normally do a short retrospective in the end so we can learn how to improve (I learned their value on my very first stop with Maaret). This time, I did a debrief of the testing session with the mob instead, to have them reflect on certain aspects. It proofed really valuable to get them thinking about what they did. Mental note to myself: I should do that more often for my own testing as well.
  1. What was our mission?
  2. What did we test and what not?
  3. What did we learn?
  4. What feedback can we provide about the product, can we quickly derive it from our notes?
  5. What to focus on as next highest priority with the knowledge we have now? 
The response on the last question was my personal favorite. They wanted to talk with the product owner as next step to see if they were going in the right direction or whether other areas might be more risky.

After a short closing, the mob session was officially over. Still, the group stayed and started an informal discussion. One of the persons who proposed the test target now shared that he didn't want to spoil the session, but the tested product version was outdated already and they had indeed agreed to remove the challenged feature - so the mob's feeling was indeed correct here!

It was great to hear people's experience with testing, mobbing and knowledge sharing. I really enjoyed the conversation to conclude a great session. Afterwards, Amitai shared personal feedback with me. He said he could clearly see I did these sessions very often already. This feedback took me by surprise. I had facilitated several mob sessions since beginning of the year: three in my company, one at a meetup, and three at conferences. So this session had been my eighth only. Amitai shared it was received as really professional and it was exactly what he was hoping for. This showed me I had learned a lot and it also triggered me to reflect. The session had indeed felt good. Maybe because I taught developers new to exploratory testing? Would it have been the same in case they would have been other testers? Still to be answered. This I know for sure: I had shared a lot about testing and testers during the session while people were doing hands-on testing. The mob approach is just an awesome way not only to learn but also to teach testing.
Bonus: Amitai also shared what he learned on his blog as well as recorded a conversation with codecentric sharing their highlights from this stop; including my exploratory testing session! :D