<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: OWASP DevSlop</title>
    <description>The latest articles on DEV Community by OWASP DevSlop (@devslop).</description>
    <link>https://dev.to/devslop</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F1545%2F196defea-1efb-4662-ab6c-d8e2e2257f29.jpeg</url>
      <title>DEV Community: OWASP DevSlop</title>
      <link>https://dev.to/devslop</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/devslop"/>
    <language>en</language>
    <item>
      <title>Pixi-CRS goes to the Cloud - Part 6 : Summary and Comparison</title>
      <dc:creator>Franziska Bühler</dc:creator>
      <pubDate>Wed, 28 Oct 2020 14:59:30 +0000</pubDate>
      <link>https://dev.to/devslop/pixi-crs-goes-to-the-cloud-part-6-summary-and-comparison-25p4</link>
      <guid>https://dev.to/devslop/pixi-crs-goes-to-the-cloud-part-6-summary-and-comparison-25p4</guid>
      <description>&lt;p&gt;This is the last blog post of the "Pixi-CRS goes to the Cloud" series.&lt;br&gt;
In this blog post, we will sum up and compare the five Pixi-CRS pipelines we built: CircleCI, Amazon Web Services, Azure, Google Cloud Platform and GitHub Actions.&lt;/p&gt;

&lt;p&gt;OWASP DevSlop's goal was to migrate Pixi-CRS to the cloud and we've been successful! &lt;/p&gt;

&lt;h2&gt;
  
  
  Comparison of the 5 Pixi-CRS Pipelines
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;-&lt;/th&gt;
&lt;th&gt;CircleCI&lt;/th&gt;
&lt;th&gt;AWS&lt;/th&gt;
&lt;th&gt;Azure&lt;/th&gt;
&lt;th&gt;GCP&lt;/th&gt;
&lt;th&gt;GitHub Actions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tool Name&lt;/td&gt;
&lt;td&gt;Jobs&lt;/td&gt;
&lt;td&gt;CodeBuild&lt;/td&gt;
&lt;td&gt;Azure DevOps Pipelines&lt;/td&gt;
&lt;td&gt;Cloud Build&lt;/td&gt;
&lt;td&gt;Actions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code File&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/.circleci/config.yml"&gt;.circleci/config.yml&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/buildspec.yml"&gt;buildspec.yml&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/azure-pipelines.yml"&gt;azure-pipelines.yml&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/cloudbuild.yaml"&gt;cloudbuild.yaml&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/.github/workflows/pixi-crs-ci.yml"&gt;.github/workflows/pixi-crs-ci.yml&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Start of CRS&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/.circleci/config.yml#L47"&gt;docker run&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/buildspec.yml#L29"&gt;docker-compose up --env-file&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/azure-pipelines.yml#L22"&gt;docker-compose with FileArgs&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/cloudbuild.yaml#L10"&gt;docker-compose up --env-file&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/.github/workflows/pixi-crs-ci.yml#L24"&gt;docker-compose up --env-file&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Start of Pixi&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/.circleci/config.yml#L29"&gt;docker-compose up&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/buildspec.yml#L29"&gt;docker-compose up&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/azure-pipelines.yml#L22"&gt;docker-compose&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/cloudbuild.yaml#L10"&gt;docker-compose up&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/.github/workflows/pixi-crs-ci.yml#L24"&gt;docker-compose up&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CRS Tuning&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/.circleci/config.yml#L65"&gt;docker cp&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/docker-compose.yaml#L44"&gt;volumes&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/docker-compose.yaml#L44"&gt;volumes&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/docker-compose.yaml#L44"&gt;volumes&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/docker-compose.yaml#L44"&gt;volumes&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Testcafe Tests&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/.circleci/config.yml#L84"&gt;docker run testcafe/testcafe&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/buildspec.yml#L13"&gt;npm install testcafe&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/azure-pipelines.yml#L38"&gt;docker run testcafe/testcafe&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/cloudbuild.yaml#L29"&gt;docker run testcafe/testcafe&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/.github/workflows/pixi-crs-ci.yml#L29"&gt;docker run testcafe/testcafe&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test Endpoint Pixi&lt;/td&gt;
&lt;td&gt;&lt;a href="http://172.17.0.1:8000/"&gt;http://172.17.0.1:8000/&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://localhost:8000/"&gt;http://localhost:8000/&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://172.17.0.1:8000/"&gt;http://172.17.0.1:8000/&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://172.17.0.1:8000/"&gt;http://172.17.0.1:8000/&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://172.17.0.1:8000/"&gt;http://172.17.0.1:8000/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test Endpoint CRS&lt;/td&gt;
&lt;td&gt;&lt;a href="http://172.17.0.2/"&gt;http://172.17.0.2/&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://localhost/"&gt;http://localhost/&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://172.17.0.1:8080/"&gt;http://172.17.0.1:8080/&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://172.17.0.1:8080/"&gt;http://172.17.0.1:8080/&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://172.17.0.1:8080/"&gt;http://172.17.0.1:8080/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pipeline Trigger&lt;/td&gt;
&lt;td&gt;GitHub Webhook&lt;/td&gt;
&lt;td&gt;Set "Primary source webhook events"&lt;/td&gt;
&lt;td&gt;trigger: -master in azure-pipelines.yml&lt;/td&gt;
&lt;td&gt;Set "trigger"&lt;/td&gt;
&lt;td&gt;on: [push, pull_request] in .github/workflows/pixi-crs-ci.yml&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In the table above, I compare cloud providers and pure CI tools. This comparison is a little problematic because the cloud providers and CI tools do not have quite the same strengths. CI tools are strongly designed for the continuous integration part and the cloud providers offer a lot around it.&lt;br&gt;
However, while writing the code, I had more trouble with some pipelines than other pipelines:&lt;/p&gt;

&lt;p&gt;The pure CI tool CircleCI is easy to configure and the code is easy to read. The only drawback was that I had to mount volumes in a container with a workaround.&lt;br&gt;
The AWS buildspec.yml is also easy to configure and easy to read. Of all three cloud providers, this was the easiest code to write for me. Here I couldn't mount any volumes either, and I had to install Testcafe instead of using it as a Docker container.&lt;br&gt;
The Azure Pipeline azure-pipelines.yml and the GCP cloudbuild.yaml was a bit more tricky to write. This code is less intuitive and you have to look up the options.&lt;br&gt;
The GitHub actions were easier again and I was able to use large parts of the CI code from CircleCI and AWS.&lt;/p&gt;

&lt;p&gt;This is a personal comparison and maybe I am not familiar with all of the possibilities that the code offers. And maybe more options are now possible than when I wrote the pipeline code.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;p&gt;For me, it was super fun to get to know the three cloud providers and GitHub Actions and to learn how to write pipeline code for all of them.&lt;/p&gt;

&lt;p&gt;I know there are different ways to implement solutions. I also wanted to try them out. Besides the fact that I sometimes needed to search for another option to implement a pipeline step, I enjoyed trying out different approaches. So, the pipelines can differ. &lt;br&gt;
Maybe there are better ways to implement something. Pull Requests and contributions against &lt;a href="https://github.com/DevSlop/pixi-crs"&gt;Pixi-CRS&lt;/a&gt; or feedback are always very welcome :-)&lt;/p&gt;

&lt;p&gt;Thank you OWASP DevSlop for giving me the opportunity to play with these cloud providers and to learn new stuff!&lt;br&gt;
I hope that the pipelines provided and idea behind them, namely to test a WAF early in the delivery pipeline, or the provided code, will help some of you!&lt;/p&gt;

</description>
      <category>waf</category>
      <category>crs</category>
      <category>pixi</category>
      <category>devsecops</category>
    </item>
    <item>
      <title>Pixi-CRS goes to the Cloud - Part 5 : GitHub Actions</title>
      <dc:creator>Franziska Bühler</dc:creator>
      <pubDate>Tue, 20 Oct 2020 07:43:31 +0000</pubDate>
      <link>https://dev.to/devslop/pixi-crs-goes-to-the-cloud-part-5-github-actions-1ppe</link>
      <guid>https://dev.to/devslop/pixi-crs-goes-to-the-cloud-part-5-github-actions-1ppe</guid>
      <description>&lt;p&gt;The fourth pipeline I implemented Pixi-CRS in was GitHub Actions (GHA): &lt;a href="https://github.com/features/actions"&gt;https://github.com/features/actions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is the fifth blog post in the "Pixi-CRS goes to the Cloud" series.&lt;/p&gt;

&lt;p&gt;This is how Pixi-CRS looks on GitHub Actions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--urEUjk63--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/htnn8ftqznf8v03pc0cg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--urEUjk63--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/htnn8ftqznf8v03pc0cg.png" alt="Pixi-CRS as GitHub Actions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pixi-CRS Pipeline Code
&lt;/h2&gt;

&lt;p&gt;GitHub Actions is not a cloud provider like I described in the earlier blog posts in this series. GitHub Actions is "only" a CI / CD pipeline, but very easy to configure and therefore very lightweight. I like that!&lt;br&gt;
The code behind the pipeline can be found &lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/.github/workflows/pixi-crs-ci.yml"&gt;here&lt;/a&gt;. &lt;br&gt;
GitHub Actions are written in yaml files inside the ./github/workflows subdirectory of the repository. It's pretty easy to get started with GitHub Actions. No need to configure anything. Adding a yaml file in the named directory is enough and the Actions can be run.&lt;/p&gt;

&lt;p&gt;Let's have a closer look at our ./github/workflows/pixi-crs-ci.yml file.&lt;/p&gt;

&lt;p&gt;I will explain the different steps below. But I also give explanations in the comments in the provided yaml file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Pixi-CRS CI Pipeline&lt;/span&gt;

&lt;span class="c1"&gt;# Trigger the workflow on push&lt;/span&gt;
&lt;span class="c1"&gt;# and pull requests&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Start Pixi and the CRS&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@master&lt;/span&gt;

&lt;span class="c1"&gt;#      - name: Debugging &lt;/span&gt;
&lt;span class="c1"&gt;#        run: pwd&lt;/span&gt;
&lt;span class="c1"&gt;#      - name: Debugging &lt;/span&gt;
&lt;span class="c1"&gt;#        run: ls&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Starting Pixi and CRS with docker-compose up&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker-compose -f docker-compose.yaml --env-file compose-gcp.env up -d&lt;/span&gt;

        &lt;span class="c1"&gt;# Application Tests with Testcafe&lt;/span&gt;
        &lt;span class="c1"&gt;# skip-js-errors because of: Uncaught Error: Bootstrap tooltips require Tether&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Testcafe Tests Pixi without and with CRS&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker run --volume /home/runner/work/pixi-crs/pixi-crs/testcafe/tests_container_ip:/tests --rm testcafe/testcafe --skip-js-errors 'chromium:headless --no-sandbox'&lt;/span&gt;

        &lt;span class="c1"&gt;# Show Full error.log&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Show ModSecurity logs&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker exec crs cat /var/log/apache2/error.log&lt;/span&gt;

        &lt;span class="c1"&gt;# ModSecurity Log Analysis:&lt;/span&gt;
        &lt;span class="c1"&gt;# Fail if ModSecurity log is not empty&lt;/span&gt;
        &lt;span class="c1"&gt;# Show ModSecurity logs of Testcafe Tests&lt;/span&gt;
        &lt;span class="c1"&gt;# If not empty -&amp;gt; Repair your application OR&lt;/span&gt;
        &lt;span class="c1"&gt;#              -&amp;gt; ModSecurity Tuning:&lt;/span&gt;
        &lt;span class="c1"&gt;# See https://www.netnea.com/cms/apache-tutorial-8_handling-false-positives-modsecurity-core-rule-set/ OR&lt;/span&gt;
        &lt;span class="c1"&gt;#              -&amp;gt; GitHub issue: https://github.com/SpiderLabs/owasp-modsecurity-crs&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Fail if ModSecurity logs are not empty&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;if docker exec crs cat /var/log/apache2/error.log | grep ModSecurity | grep -vi MyEvilWAFTest | grep -v 949110 | grep -v 980130 | grep msg; then echo "False Positive Found! Aborting!" &amp;amp;&amp;amp; exit 1 ; else echo "ModSecurity Logs empty. This is good!"; fi&lt;/span&gt;

        &lt;span class="c1"&gt;# Fail if ModSecurity log does not contain WAF Test String "MyEvilWAFTest"&lt;/span&gt;
        &lt;span class="c1"&gt;# That means CRS is not working properly or test was aborted.&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Fail if WAF Test String is missing in ModSecurity logs&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;if docker exec crs cat /var/log/apache2/error.log | grep ModSecurity | grep MyEvilWAFTest; then echo "WAF Test String Found. This is good!"; else echo "WAF Test String not Found! Aborting!" &amp;amp;&amp;amp; exit 1; fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pipeline Steps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Start Pixi and the CRS
&lt;/h3&gt;

&lt;p&gt;We start Pixi and the CRS with one docker-compose up command and provide an --env-file. We don't need to install Docker or docker-compose, since it's already there. &lt;/p&gt;

&lt;h3&gt;
  
  
  Testcafe tests
&lt;/h3&gt;

&lt;p&gt;Now that the CRS and Pixi are running, we perform the Testcafe tests. This time we can run the tests with the testcafe/testcafe Docker container. The tests can be mounted easily into this container. &lt;br&gt;
Again, first, we test Pixi directly, then we test Pixi through the CRS. We also test the CRS itself with a malicious string. We want to ensure that the WAF blocks it.&lt;/p&gt;

&lt;p&gt;For our tests, we call Pixi via &lt;a href="http://172.17.0.1:8000"&gt;http://172.17.0.1:8000&lt;/a&gt; and the CRS via &lt;a href="http://172.17.0.1:8080"&gt;http://172.17.0.1:8080&lt;/a&gt;  because we call them from inside the Testcafe Docker container.&lt;/p&gt;

&lt;p&gt;And this is how the Testcafe test output looks:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dnqfas5x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/faky2lhay0r4jq8il4gg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dnqfas5x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/faky2lhay0r4jq8il4gg.png" alt="TestCafe Output GitHub Actions"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Check results
&lt;/h3&gt;

&lt;p&gt;In the end, we check the results. We take a look at the ModSecurity log inside the CRS Docker container.&lt;br&gt;
This is an important step that ensures that we did not have any false positives with our legitimate tests. In addition, we ensure that our malicious test was logged.&lt;/p&gt;
&lt;h2&gt;
  
  
  Trigger
&lt;/h2&gt;

&lt;p&gt;Because Pixi-CRS is a CI pipeline and we want to run our GitHub Actions after every push and pull request, we need to configure a trigger. &lt;br&gt;
I added this in &lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/.github/workflows/pixi-crs-ci.yml#L5"&gt;our ./github/workflows/pixi-crs-ci.yml file&lt;/a&gt; by adding the following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Trigger the workflow on push&lt;/span&gt;
&lt;span class="c1"&gt;# and pull requests&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Things to mention
&lt;/h2&gt;

&lt;p&gt;Pixi-CRS is a CI Pipeline and I did not configure the CD part.&lt;br&gt;
In this blog, post I only wanted to show the CI part. &lt;/p&gt;

&lt;h2&gt;
  
  
  Next blog post
&lt;/h2&gt;

&lt;p&gt;In the next and final blog post of this series I will sum up and compare all five available Pixi-CRS pipelines on CircleCI, Amazon Web Services, Azure DevOps, Google Cloud Platform and GitHub Actions.&lt;/p&gt;

</description>
      <category>waf</category>
      <category>crs</category>
      <category>pixi</category>
      <category>gha</category>
    </item>
    <item>
      <title>Pixi-CRS goes to the Cloud - Part 4 : Google Cloud Platform</title>
      <dc:creator>Franziska Bühler</dc:creator>
      <pubDate>Tue, 13 Oct 2020 06:41:13 +0000</pubDate>
      <link>https://dev.to/devslop/pixi-crs-goes-to-the-cloud-part-4-google-cloud-platform-260e</link>
      <guid>https://dev.to/devslop/pixi-crs-goes-to-the-cloud-part-4-google-cloud-platform-260e</guid>
      <description>&lt;p&gt;The third cloud provider I moved Pixi-CRS to was Google Cloud Platform (GCP): &lt;a href="https://console.cloud.google.com/"&gt;https://console.cloud.google.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the fourth blog post in the series "Pixi-CRS goes to the Cloud".&lt;/p&gt;

&lt;p&gt;This is how Pixi-CRS looks on Google Cloud Platform:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qqdbw58O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hu12j1mneenwfxf4mpsi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qqdbw58O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hu12j1mneenwfxf4mpsi.png" alt="Pixi-CRS on Google Cloud Platform"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the image above, we see that the Pixi-CRS CI Pipeline on GCP is configured as a GCP Cloud Build.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pixi-CRS Pipeline Code
&lt;/h2&gt;

&lt;p&gt;The code behind the pipeline can be found &lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/cloudbuild.yaml"&gt;here&lt;/a&gt;. &lt;br&gt;
GCP Cloud Build code is written in a cloudbuild.yaml file in the root directory of the repository. It's pretty easy to create a new Cloud Build on GCP. First, I had to create a project and "Enable Cloud Build". &lt;/p&gt;

&lt;p&gt;Let's take a closer look at this cloudbuild.yaml file.&lt;/p&gt;

&lt;p&gt;I will explain the different steps below. But I also give explanations in the comments in the provided yaml file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Google Cloud cloudbuild.yaml&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="c1"&gt;# Start the OWASP ModSecurity Core Rule Set and Pixi with its DB with docker-compose&lt;/span&gt;
&lt;span class="c1"&gt;# OWASP ModSecurity Core Rule Set Container (Apache Reverse Proxy)&lt;/span&gt;
&lt;span class="c1"&gt;# owasp/modsecurity-crs&lt;/span&gt;
&lt;span class="c1"&gt;# See https://coreruleset.org/&lt;/span&gt;
&lt;span class="c1"&gt;# ModSecurity Tuning:&lt;/span&gt;
&lt;span class="c1"&gt;# See https://www.netnea.com/cms/apache-tutorial-8_handling-false-positives-modsecurity-core-rule-set/&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Starting&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Pixi&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;CRS&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;docker-compose&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;up'&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;docker/compose:1.26.2'&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;--env-file'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/workspace/compose-gcp.env'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;up'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;-d'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Debugging possibilities&lt;/span&gt;
&lt;span class="c1"&gt;#- name: 'ubuntu'&lt;/span&gt;
&lt;span class="c1"&gt;#  args: [ "touch", "foo" ]&lt;/span&gt;
&lt;span class="c1"&gt;#- name: 'ubuntu'&lt;/span&gt;
&lt;span class="c1"&gt;#  args: [ "ls", "-l", "/workspace/testcafe/tests_container_ip" ]&lt;/span&gt;
&lt;span class="c1"&gt;#- name: 'ubuntu'&lt;/span&gt;
&lt;span class="c1"&gt;#  args: [ "pwd" ]&lt;/span&gt;
&lt;span class="c1"&gt;# Debugging with curl&lt;/span&gt;
&lt;span class="c1"&gt;#- name: 'curlimages/curl:7.69.0'&lt;/span&gt;
&lt;span class="c1"&gt;#  args: [ "-v", "http://172.17.0.1:8000/register"]&lt;/span&gt;
&lt;span class="c1"&gt;#- name: 'curlimages/curl:7.69.0'&lt;/span&gt;
&lt;span class="c1"&gt;#  args: [ "-v", "http://172.17.0.1:8080/register"]&lt;/span&gt;

&lt;span class="c1"&gt;# Application Tests with Testcafe&lt;/span&gt;
&lt;span class="c1"&gt;# skip-js-errors because of: Uncaught Error: Bootstrap tooltips require Tether&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Run&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Testcafe&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Tests:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Pixi&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;without&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;CRS'&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;gcr.io/cloud-builders/docker'&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;run"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--volume"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/workspace/testcafe/tests_container_ip:/tests"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--rm"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;testcafe/testcafe"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chromium:headless&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;--no-sandbox"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--skip-js-errors"&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Copy ModSecurity Logs:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Copy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ModSecurity&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;logs'&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;gcr.io/cloud-builders/docker'&lt;/span&gt;
 &lt;span class="c1"&gt;# args: [ "exec", "crs", "cat /var/log/apache2/error.log | grep ModSecurity" ]&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cp"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;crs:/var/log/apache2/error.log"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/workspace/error.log"&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Show ModSecurity Logs&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Show&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ModSecurity&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;logs'&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ubuntu'&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cat"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/workspace/error.log"&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# ModSecurity Log Analysis:&lt;/span&gt;
&lt;span class="c1"&gt;# Fail if ModSecurity log does not contain WAF Test String "MyEvilWAFTest"&lt;/span&gt;
&lt;span class="c1"&gt;# That means CRS is not working properly or test was aborted.&lt;/span&gt;

&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Fail&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;if&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ModSecurity&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;log&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;does&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;not&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;contain&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;WAF&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Test&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;String'&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;gcr.io/cloud-builders/gcloud'&lt;/span&gt;
  &lt;span class="na"&gt;entrypoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bash"&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-c"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;cat /workspace/error.log | grep -q MyEvilWAFTest&lt;/span&gt;
&lt;span class="c1"&gt;# Fail if ModSecurity log is not empty&lt;/span&gt;
&lt;span class="c1"&gt;# Show ModSecurity logs of Testcafe Tests&lt;/span&gt;
&lt;span class="c1"&gt;# If not empty -&amp;gt; Repair your application OR&lt;/span&gt;
&lt;span class="c1"&gt;#              -&amp;gt; ModSecurity Tuning:&lt;/span&gt;
&lt;span class="c1"&gt;# See https://www.netnea.com/cms/apache-tutorial-8_handling-false-positives-modsecurity-core-rule-set/ OR&lt;/span&gt;
&lt;span class="c1"&gt;#              -&amp;gt; GitHub issue: https://github.com/SpiderLabs/owasp-modsecurity-crs&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Fail&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;if&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ModSecurity&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;log&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;not&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;empty'&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;gcr.io/cloud-builders/gcloud'&lt;/span&gt;
  &lt;span class="na"&gt;entrypoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bash"&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-c"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;"cat /workspace/error.log grep ModSecurity | grep error | grep -vi MyEvilWAFTest | grep -v 949110 | grep -v 980130 &amp;amp;&amp;amp; exit 1 || exit 0"&lt;/span&gt;
&lt;span class="c1"&gt;#- id: 'Fail if ModSecurity log is not empty'&lt;/span&gt;
&lt;span class="c1"&gt;#  name: 'gcr.io/cloud-builders/docker'&lt;/span&gt;
&lt;span class="c1"&gt;#  args: [ 'exec', 'crs', 'cat /var/log/apache2/error.log | grep ModSecurity | grep error | grep -vi "MyEvilWAFTest" | grep -v "949110" | grep -vi "980130" &amp;amp;&amp;amp; exit 1 || exit 0' ]&lt;/span&gt;


&lt;span class="c1"&gt;# Debugging docker&lt;/span&gt;
&lt;span class="c1"&gt;#- id: 'Docker'&lt;/span&gt;
&lt;span class="c1"&gt;#  name: 'gcr.io/cloud-builders/docker'&lt;/span&gt;
&lt;span class="c1"&gt;#  args: [ "ps" ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Pipeline Steps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Start Pixi and the CRS
&lt;/h3&gt;

&lt;p&gt;We start Pixi and the CRS with one docker-compose up command and provide an --env-file. We don't need to install Docker or docker-compose, since we use the docker/compose image. &lt;/p&gt;

&lt;h3&gt;
  
  
  Testcafe tests
&lt;/h3&gt;

&lt;p&gt;Now that the CRS and Pixi are running, we perform the Testcafe tests. This time we can run the tests with the testcafe/testcafe Docker container. The tests can be mounted easily into this container. &lt;br&gt;
Again, first, we test Pixi directly, then we test Pixi through the CRS. We also test the CRS itself with a malicious string. We want to ensure that the WAF blocks it.&lt;/p&gt;

&lt;p&gt;For our tests, we call Pixi via &lt;a href="http://172.17.0.1:8000"&gt;http://172.17.0.1:8000&lt;/a&gt; and the CRS via &lt;a href="http://172.17.0.1:8080"&gt;http://172.17.0.1:8080&lt;/a&gt;  because we call them from inside the Testcafe Docker container.&lt;/p&gt;

&lt;p&gt;And this is how the Testcafe test output looks:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Xra3JPSd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ld2rrls51egdjdg78kjl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xra3JPSd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ld2rrls51egdjdg78kjl.png" alt="Testcafe Output GCP"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Check results
&lt;/h3&gt;

&lt;p&gt;In the end, we check the results. We have a look at the ModSecurity log inside the CRS Docker container.&lt;br&gt;
This ensures that we did not have any false positives with our legitimate tests. In addition, we ensure that our malicious test was logged.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trigger
&lt;/h2&gt;

&lt;p&gt;Because Pixi-CRS is a CI pipeline and we want to run our GCP Cloud Build after every push into the repository, we need to configure a trigger on push events. &lt;br&gt;
I added this via the option Cloud Build &amp;gt; Triggers &amp;gt; Create Trigger.&lt;/p&gt;

&lt;h2&gt;
  
  
  Things to mention
&lt;/h2&gt;

&lt;p&gt;Pixi-CRS is a CI Pipeline and I did not configure the CD part.&lt;br&gt;
In this blog post, I only wanted to show the CI part. And I'm also aware that a lot more Google Cloud Platform options are available. But for this blog post, I wanted to keep it simple and concentrate on the Pixi-CRS CI part.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next blog post
&lt;/h2&gt;

&lt;p&gt;In the next blog post in this series, I will implement the Pixi-CRS CI Pipeline in GitHub Actions.&lt;/p&gt;

</description>
      <category>waf</category>
      <category>crs</category>
      <category>pixi</category>
      <category>gcp</category>
    </item>
    <item>
      <title>Pixi-CRS goes to the Cloud - Part 3 : Microsoft Azure DevOps</title>
      <dc:creator>Franziska Bühler</dc:creator>
      <pubDate>Tue, 06 Oct 2020 08:40:40 +0000</pubDate>
      <link>https://dev.to/devslop/pixi-crs-goes-to-the-cloud-part-3-microsoft-azure-devops-gni</link>
      <guid>https://dev.to/devslop/pixi-crs-goes-to-the-cloud-part-3-microsoft-azure-devops-gni</guid>
      <description>&lt;p&gt;The second cloud provider to which I moved Pixi-CRS was Microsoft Azure DevOps: &lt;a href="https://dev.azure.com/" rel="noopener noreferrer"&gt;https://dev.azure.com/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is the third blog post in the "Pixi-CRS goes to the Cloud" series.&lt;/p&gt;

&lt;p&gt;This is how Pixi-CRS looks on the Microsoft Azure DevOps Pipeline:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzid1enzmohw8jn5bd4go.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzid1enzmohw8jn5bd4go.png" alt="Pixi-CRS on Azure DevOps"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the image above, we see that the Pixi-CRS CI Pipeline on Azure DevOps is configured as Azure DevOps &amp;gt; Pixi-CRS &amp;gt; Pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pixi-CRS Pipeline Code
&lt;/h2&gt;

&lt;p&gt;The code behind the pipeline can be found &lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/azure-pipelines.yml" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;br&gt;
Azure DevOps pipeline code is written in azure-pipeline.yml files in the root directory of the repository. It's quite easy to create a new pipeline project on Azure DevOps. &lt;/p&gt;

&lt;p&gt;Let's take a closer look at this azure-pipelines.yml file.&lt;/p&gt;

&lt;p&gt;I will explain the different steps below. But I also give explanations in the comments in the provided yaml file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Azure DevOps azure-pipelines.yml&lt;/span&gt;

&lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="c1"&gt;# Branch to trigger&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;

&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="c1"&gt;# Start the OWASP ModSecurity Core Rule Set and Pixi with its DB with docker-compose&lt;/span&gt;
&lt;span class="c1"&gt;# OWASP ModSecurity Core Rule Set Container (Apache Reverse Proxy)&lt;/span&gt;
&lt;span class="c1"&gt;# owasp/modsecurity-crs&lt;/span&gt;
&lt;span class="c1"&gt;# See https://coreruleset.org/&lt;/span&gt;
&lt;span class="c1"&gt;# ModSecurity Tuning:&lt;/span&gt;
&lt;span class="c1"&gt;# See https://www.netnea.com/cms/apache-tutorial-8_handling-false-positives-modsecurity-core-rule-set/&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;StartContainersAndTests&lt;/span&gt;
  &lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;job&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;BuildJob&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# Debugging&lt;/span&gt;
      &lt;span class="c1"&gt;# - script: pwd&lt;/span&gt;
      &lt;span class="c1"&gt;# - script: ls&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DockerCompose@0&lt;/span&gt;
        &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Start Pixi and CRS&lt;/span&gt;
        &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;containerregistrytype&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Container&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Registry'&lt;/span&gt;
          &lt;span class="na"&gt;dockerComposeFile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;**/docker-compose.yaml'&lt;/span&gt;
          &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Run&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Docker&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Compose&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;command'&lt;/span&gt;
          &lt;span class="na"&gt;dockerComposeFileArgs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;CRSPORTHTTP=8080&lt;/span&gt;
            &lt;span class="s"&gt;PROXYLOCATION=http://app:8000/&lt;/span&gt;
          &lt;span class="na"&gt;dockerComposeCommand&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;up&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-d'&lt;/span&gt;

      &lt;span class="c1"&gt;# Application Tests with Testcafe&lt;/span&gt;
      &lt;span class="c1"&gt;# skip-js-errors because of: Uncaught Error: Bootstrap tooltips require Tether&lt;/span&gt;
      &lt;span class="c1"&gt;# Another way: https://devexpress.github.io/testcafe/documentation/continuous-integration/azure-devops.html&lt;/span&gt;
      &lt;span class="c1"&gt;# Debugging&lt;/span&gt;
      &lt;span class="c1"&gt;#- script: docker ps&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker run --volume /home/vsts/work/1/s/testcafe/tests_container_ip/:/tests testcafe/testcafe --skip-js-errors 'chromium:headless --no-sandbox'&lt;/span&gt;
        &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Testcafe Tests without and with CRS&lt;/span&gt;

      &lt;span class="c1"&gt;# Show Full error.log&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker exec crs cat /var/log/apache2/error.log&lt;/span&gt;
        &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Show ModSecurity logs&lt;/span&gt;

      &lt;span class="c1"&gt;# ModSecurity Log Analysis:&lt;/span&gt;
      &lt;span class="c1"&gt;# Fail if ModSecurity log is not empty&lt;/span&gt;
      &lt;span class="c1"&gt;# Show ModSecurity logs of Testcafe Tests&lt;/span&gt;
      &lt;span class="c1"&gt;# If not empty -&amp;gt; Repair your application OR&lt;/span&gt;
      &lt;span class="c1"&gt;#              -&amp;gt; ModSecurity Tuning:&lt;/span&gt;
      &lt;span class="c1"&gt;# See https://www.netnea.com/cms/apache-tutorial-8_handling-false-positives-modsecurity-core-rule-set/ OR&lt;/span&gt;
      &lt;span class="c1"&gt;#              -&amp;gt; GitHub issue: https://github.com/SpiderLabs/owasp-modsecurity-crs&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;if docker exec crs cat /var/log/apache2/error.log | grep ModSecurity | grep -vi MyEvilWAFTest | grep -v 949110 | grep -v 980130 | grep msg; then echo "False Positive Found! Aborting!" &amp;amp;&amp;amp; exit 1 ; else echo "ModSecurity Logs empty. This is good!"; fi&lt;/span&gt;
        &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Fail if ModSecurity logs are not empty&lt;/span&gt;

      &lt;span class="c1"&gt;# Fail if ModSecurity log does not contain WAF Test String "MyEvilWAFTest"&lt;/span&gt;
      &lt;span class="c1"&gt;# That means CRS is not working properly or test was aborted.&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;if docker exec crs cat /var/log/apache2/error.log | grep ModSecurity | grep MyEvilWAFTest; then echo "WAF Test String Found. This is good!"; else echo "WAF Test String not Found! Aborting!" &amp;amp;&amp;amp; exit 1; fi&lt;/span&gt;
        &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Fail if WAF Test String is missing in ModSecurity logs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pipeline Steps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Start Pixi and the CRS
&lt;/h3&gt;

&lt;p&gt;We start Pixi and the CRS with one docker-compose up command. We don't need to install Docker or docker-compose, it's already provided. But we need to configure a few things like the dockerComposeFileArgs, for example. &lt;br&gt;
Then we start Pixi and the CRS with the dockerComposeCommand "up -d".&lt;/p&gt;

&lt;h3&gt;
  
  
  Testcafe tests
&lt;/h3&gt;

&lt;p&gt;Now that the CRS and Pixi are running, we perform the Testcafe tests. This time we can run the tests with the testcafe/testcafe Docker container. The tests can be mounted easily into this container. &lt;br&gt;
Again, first, we test Pixi directly, then we test Pixi through the CRS. We also test the CRS itself with a malicious string. We want to ensure that the WAF blocks it.&lt;/p&gt;

&lt;p&gt;For our tests, we call Pixi via &lt;a href="http://172.17.0.1:8000" rel="noopener noreferrer"&gt;http://172.17.0.1:8000&lt;/a&gt; and the CRS via &lt;a href="http://172.17.0.1:8080" rel="noopener noreferrer"&gt;http://172.17.0.1:8080&lt;/a&gt;  because we call them from inside the Testcafe Docker container.&lt;/p&gt;

&lt;p&gt;And this is how the Testcafe test output looks:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fi3tz5gbwwbu5bw2ifsu5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fi3tz5gbwwbu5bw2ifsu5.png" alt="Testcafe Output on Azure DevOps"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Check results
&lt;/h3&gt;

&lt;p&gt;In the end, we check the results. We take a look at the ModSecurity log inside the CRS Docker container.&lt;br&gt;
This is an important step that ensures that we did not have any false positives with our legitimate tests. In addition, we ensure that our malicious test was logged.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trigger
&lt;/h2&gt;

&lt;p&gt;Because Pixi-CRS is a CI pipeline and we want to run our Azure DevOps pipeline project after every push into the repository, we need to configure a trigger on push events. &lt;br&gt;
I added this via the "trigger: -master" entry in the azure-pipeline.yml file. &lt;/p&gt;

&lt;h2&gt;
  
  
  Things to mention
&lt;/h2&gt;

&lt;p&gt;Pixi-CRS is a CI Pipeline and I did not configure the CD part.&lt;br&gt;
In this blog post, I only wanted to show the CI part. And I'm also aware that a lot more Azure DevOps options are available. But for this blog post, I wanted to keep it simple and concentrate on the Pixi-CRS CI part.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next blog post
&lt;/h2&gt;

&lt;p&gt;In the next blog post, we will learn the Pixi-CRS pipeline on Google Cloud Platform.&lt;/p&gt;

</description>
      <category>waf</category>
      <category>crs</category>
      <category>pixi</category>
      <category>azure</category>
    </item>
    <item>
      <title>Pixi-CRS goes to the Cloud - Part 2 : Amazon Web Services</title>
      <dc:creator>Franziska Bühler</dc:creator>
      <pubDate>Wed, 30 Sep 2020 05:02:03 +0000</pubDate>
      <link>https://dev.to/devslop/pixi-crs-goes-to-the-cloud-part-2-amazon-web-services-2cgb</link>
      <guid>https://dev.to/devslop/pixi-crs-goes-to-the-cloud-part-2-amazon-web-services-2cgb</guid>
      <description>&lt;p&gt;Let's start with the first Pixi-CRS Pipeline in the Cloud, namely on AWS: &lt;a href="https://aws.amazon.com/console/" rel="noopener noreferrer"&gt;https://aws.amazon.com/console/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is the second blog post in the "Pixi-CRS goes to the Cloud" series. The intro blog post of this series can be found &lt;a href="https://dev.to/devslop/pixi-crs-goes-to-the-cloud-part-1-intro-14ip"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is how Pixi-CRS looks on Amazon Web Services:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyd94gxx5qwcaftdbhn5h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyd94gxx5qwcaftdbhn5h.png" alt="Pixi-CRS AWS CodeBuild"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the image above, we see that the Pixi-CRS CI Pipeline on AWS was added as Developer Tools &amp;gt; CodeBuild &amp;gt; Build project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pixi-CRS Pipeline Code
&lt;/h2&gt;

&lt;p&gt;The code behind the pipeline can be found &lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/buildspec.yml" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;br&gt;
AWS pipeline code is written in buildspec.yml files in the root directory of the repository. It's pretty easy to create a new build project inside AWS. We just need to provide a "Project Name", a source repository, choose the option "Use a buildspec file" and enable logs.&lt;/p&gt;

&lt;p&gt;Let's have a closer look at this buildspec.yml. &lt;/p&gt;

&lt;p&gt;I will explain the different steps below. But I also give explanations in the comments in the provided yaml file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# AWS buildspec.yml&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.2&lt;/span&gt;
&lt;span class="na"&gt;phases&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;install&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runtime-versions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;19&lt;/span&gt;

  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# We install testcafe. We don't run it in Docker, because volumes can not be mounted!&lt;/span&gt;
      &lt;span class="c1"&gt;# They probably could be mounted in a docker-compose, but let's run testcafe another way...&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm install -g testcafe&lt;/span&gt;
      &lt;span class="c1"&gt;# Start the OWASP ModSecurity Core Rule Set and Pixi with its DB with docker-compose&lt;/span&gt;
      &lt;span class="c1"&gt;# OWASP ModSecurity Core Rule Set Container (Apache Reverse Proxy)&lt;/span&gt;
      &lt;span class="c1"&gt;# owasp/modsecurity-crs&lt;/span&gt;
      &lt;span class="c1"&gt;# See https://coreruleset.org/&lt;/span&gt;
      &lt;span class="c1"&gt;# ModSecurity Tuning:&lt;/span&gt;
      &lt;span class="c1"&gt;# See https://www.netnea.com/cms/apache-tutorial-8_handling-false-positives-modsecurity-core-rule-set/&lt;/span&gt;

      &lt;span class="c1"&gt;# We have to install a higher version of docker-compose manually&lt;/span&gt;
      &lt;span class="c1"&gt;# so that --env-file is available&lt;/span&gt;
      &lt;span class="c1"&gt;# Unfortunately -e does not work, even with a higer docker-compose version&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;curl -L https://github.com/docker/compose/releases/download/1.26.2/docker-compose-`uname -s`-`uname -m` &amp;gt; ~/docker-compose&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;chmod +x ~/docker-compose&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mv ~/docker-compose /usr/local/bin/docker-compose&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker-compose -v&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;cat compose-aws.env&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker-compose --env-file compose-aws.env up -d&lt;/span&gt;

      &lt;span class="c1"&gt;# Application Tests with Testcafe&lt;/span&gt;
      &lt;span class="c1"&gt;# skip-js-errors because of: Uncaught Error: Bootstrap tooltips require Tether&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;testcafe "chrome:headless" testcafe/tests_localhost/test.js --skip-js-errors&lt;/span&gt;
      &lt;span class="c1"&gt;# Application Tests with CRS with Testcafe&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;testcafe "chrome:headless" testcafe/tests_localhost/testcrs.js --skip-js-errors&lt;/span&gt;
      &lt;span class="c1"&gt;# WAF Tests with malicous request to test WAF itself&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;testcafe "chrome:headless" testcafe/tests_localhost/testwaf.js --skip-js-errors&lt;/span&gt;

  &lt;span class="na"&gt;post_build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# Fail if ModSecurity log is not empty&lt;/span&gt;
      &lt;span class="c1"&gt;# Show ModSecurity logs of Testcafe Tests&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker exec crs cat /var/log/apache2/error.log | grep ModSecurity | grep error | grep -vi "MyEvilWAFTest" | grep -v "949110" | grep -vi "980130" &amp;amp;&amp;amp; echo "False Positive Found. Check Logs. Aborting!" &amp;amp;&amp;amp; exit 1 || exit &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;

      &lt;span class="c1"&gt;# If not empty -&amp;gt; Repair your application OR&lt;/span&gt;
      &lt;span class="c1"&gt;#              -&amp;gt; ModSecurity Tuning:&lt;/span&gt;
      &lt;span class="c1"&gt;# See https://www.netnea.com/cms/apache-tutorial-8_handling-false-positives-modsecurity-core-rule-set/ OR&lt;/span&gt;
      &lt;span class="c1"&gt;#              -&amp;gt; GitHub issue: https://github.com/SpiderLabs/owasp-modsecurity-crs&lt;/span&gt;

      &lt;span class="c1"&gt;# Fail if ModSecurity log does not contain WAF Test String "MyEvilWAFTest"&lt;/span&gt;
      &lt;span class="c1"&gt;# That means CRS is not working properly or test was aborted.&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker exec crs cat /var/log/apache2/error.log | grep -q MyEvilWAFTest&lt;/span&gt;

      &lt;span class="c1"&gt;# Show ModSecurity Full Logs:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker exec crs cat /var/log/apache2/error.log | grep ModSecurity | grep msg&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to read a full description of the CircleCI Pixi-CRS pipeline, you should have a look at this &lt;a href="https://dev.to/devslop/devslop-s-pixi-crs-pipeline-4bie"&gt;blog post&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pipeline Steps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Installing Testcafe
&lt;/h3&gt;

&lt;p&gt;This is the only pipeline that uses an installation of Testcafe. All other pipelines will use Testcafe in the testcafe/testcafe Docker container.&lt;br&gt;
We use an installation of Testcafe because, at the time of this writing, I was not able to mount volumes into Docker containers on AWS, and Testcafe Docker uses volumes to mount the tests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; testcafe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Installing docker-compose
&lt;/h3&gt;

&lt;p&gt;Docker-compose is already available in the base image we use. However, we use a newer version of docker-compose because we want to use the argument --env-file. &lt;/p&gt;

&lt;h3&gt;
  
  
  Start Pixi and the CRS
&lt;/h3&gt;

&lt;p&gt;We start Pixi and the CRS with one docker-compose up command. We provide an env-file that configures the listening port of the CRS container and the backend of the CRS container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose &lt;span class="nt"&gt;--env-file&lt;/span&gt; compose-aws.env up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Testcafe tests
&lt;/h3&gt;

&lt;p&gt;Now that the CRS and Pixi are running, we perform the Testcafe tests. First, we test Pixi directly, then we test Pixi through the CRS. We also test the CRS itself with a malicious string. We want to be sure that the WAF will block it.&lt;/p&gt;

&lt;p&gt;For our tests, we call Pixi via &lt;a href="http://localhost:8000" rel="noopener noreferrer"&gt;http://localhost:8000&lt;/a&gt; and the CRS via &lt;a href="http://localhost" rel="noopener noreferrer"&gt;http://localhost&lt;/a&gt;  because we installed testcafe and we now call the exposed Pixi and the CRS ports on localhost.&lt;/p&gt;

&lt;p&gt;And this is how the Testcafe test output looks:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk7ksbiu0wmxv63wnz3lf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk7ksbiu0wmxv63wnz3lf.png" alt="Testcafe Output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Check results
&lt;/h3&gt;

&lt;p&gt;In the end, we check the results. We take a look at the ModSecurity log inside the CRS Docker container.&lt;br&gt;
This is the important step that ensures that we did not get any false positives with our legitimate tests. &lt;br&gt;
In addition, we ensure that our malicious test was logged.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trigger
&lt;/h2&gt;

&lt;p&gt;Because Pixi-CRS is a CI pipeline and we want to run our CodeBuild project after every push into the repository, we need to configure a trigger on push events. &lt;br&gt;
This can be done in: Developer Tools &amp;gt; CodeBuild &amp;gt; Build projects &amp;gt; Pixi-CRS &amp;gt; Edit Source &amp;gt; Webhook. I want to trigger a build every time a code change is pushed to the Pixi-CRS GitHub repository.&lt;br&gt;
I also see this webhook in GitHub then.&lt;/p&gt;

&lt;h2&gt;
  
  
  Things to mention
&lt;/h2&gt;

&lt;p&gt;I didn't configure an AWS CodeDeploy or an AWS CodePipeline. These would be the next steps to deploy Pixi-CRS somewhere and also have Continuous Deployment. In this blog post, I only wanted to show the CI part. And I'm also aware that a lot more AWS options are available. But for this blog post, I wanted to keep it simple and concentrate on the Pixi-CRS CI part.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next blog post
&lt;/h2&gt;

&lt;p&gt;In the next blog post, we will get to know the Pixi-CRS pipeline on the Azure DevOps Pipeline.&lt;/p&gt;

</description>
      <category>waf</category>
      <category>pixi</category>
      <category>crs</category>
      <category>aws</category>
    </item>
    <item>
      <title>Pixi-CRS goes to the Cloud - Part 1: Intro</title>
      <dc:creator>Franziska Bühler</dc:creator>
      <pubDate>Tue, 22 Sep 2020 11:30:01 +0000</pubDate>
      <link>https://dev.to/devslop/pixi-crs-goes-to-the-cloud-part-1-intro-14ip</link>
      <guid>https://dev.to/devslop/pixi-crs-goes-to-the-cloud-part-1-intro-14ip</guid>
      <description>

&lt;p&gt;Some of you may have heard of DevSlop's Pixi-CRS pipeline.&lt;br&gt;
This Continuous Integration (CI) pipeline ensures that developers receive feedback early and often on their Web Application Firewall (WAF) and their application behind the WAF.&lt;br&gt;
The first Pixi-CRS pipeline was built on CircleCI.&lt;/p&gt;

&lt;p&gt;DevSlop's goal is to learn about and teach security. And, of course, we also want to learn about pipelines and security in the cloud!&lt;br&gt;
So, implementing the Pixi-CRS pipeline on cloud providers (such as Google Cloud Platform (GCP), Amazon Web Services (AWS) and Microsoft Azure) and as a GitHub Action was obvious.&lt;/p&gt;

&lt;p&gt;But first, let's take a step back and see what problem the Pixi-CRS pipeline solves for us.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Web Application Firewall?
&lt;/h2&gt;

&lt;p&gt;Of course, a web application should be implemented securely. But we never have a guarantee that the code is 100 per cent secure. &lt;br&gt;
A Web Application Firewall (WAF) is an additional layer of defense in front of a web application against attacks. It's not a silver bullet against all attacks, but it makes it harder to exploit an existing vulnerability in a web application. A WAF logs and inspects the HTTP traffic and blocks malicious traffic based on patterns or rules.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Faimoqiyr2lnjne3na0c5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Faimoqiyr2lnjne3na0c5.png" alt="Web Application Firewall"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A very popular and widely used Web Application Firewall is ModSecurity with the &lt;a href="https://coreruleset.org" rel="noopener noreferrer"&gt;OWASP ModSecurity Core Rule Set&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe11pcl95l3w0he0kpzqw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe11pcl95l3w0he0kpzqw.png" alt="The OWASP ModSecurity Core Rule Set"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Pixi?
&lt;/h2&gt;

&lt;p&gt;Pixi is one &lt;a href="https://devslop.co/pages/modules.html" rel="noopener noreferrer"&gt;module in the OWASP DevSlop&lt;/a&gt; project. It is an intentionally vulnerable web application and API for learning about web application security. More information can be found &lt;a href="https://dev.to/devslop/how-the-owasp-modsecurity-core-rule-set-protects-the-vulnerable-web-application-pixi-by-owasp-devslop-n4d"&gt;in one of my earlier blog posts&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1bem8wxajtcl67davan8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1bem8wxajtcl67davan8.png" alt="Pixi"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As the name suggests, Pixi-CRS is a combination of Pixi and the Core Rule Set.&lt;br&gt;
What I particularly like about Pixi-CRS is that it combines two OWASP projects ❤: OWASP DevSlop and the OWASP ModSecurity Core Rule Set.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;Web Application Firewalls can have so-called false positives. A false positive is a legitimate HTTP request or response that smells a bit like an attack, but is actually not an attack. These false positives can hurt in production if they prevent legitimate users from using the web application properly.&lt;/p&gt;

&lt;p&gt;These false positives hurt even more in a DevOps environment where everything is fully automated and well-tested. In the end, a WAF is added to production without testing it! That's too late! The operator will probably turn off the WAF so that the user can work again. And that's very bad.&lt;/p&gt;

&lt;p&gt;False positives can be tuned away, but to do this, they have to be discovered first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution: Testing in CI Pipeline
&lt;/h2&gt;

&lt;p&gt;If we have automated web application tests, end-to-end or UI tests in a CI Pipeline, we should add the WAF to those tests. And that's exactly what the Pixi-CRS pipeline does.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Continuous Integration?
&lt;/h3&gt;

&lt;p&gt;Continuous Integration and Continuous Delivery together form Continuous Deployment. Continuous Deployment means that code changes are merged, built, tested and shipped to production very often.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pixi-CRS CI Pipeline
&lt;/h3&gt;

&lt;p&gt;The Pixi-CRS Pipeline is a Continuous Integration (CI) Pipeline that focuses on building and testing. &lt;br&gt;
Every code change triggers a CI pipeline that performs the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start Pixi in a Docker container&lt;/li&gt;
&lt;li&gt;Start the WAF ModSecurity with the CRS in a Docker container in front of Pixi&lt;/li&gt;
&lt;li&gt;Loads ModSecurity Tuning rules (in case we have already eliminated false positives)&lt;/li&gt;
&lt;li&gt;Application tests directly against Pixi&lt;/li&gt;
&lt;li&gt;Application tests through the WAF against Pixi&lt;/li&gt;
&lt;li&gt;WAF test with a malicious string&lt;/li&gt;
&lt;li&gt;Test if WAF Logs from legitimate tests are empty&lt;/li&gt;
&lt;li&gt;Test if our malicious test string was logged &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If no false positives occurred and the application tests were successful, the code change can be merged into master. We provide early feedback to the developer on false positives. This means that we always have Pixi in a deployable and runable state, even with a WAF (the CRS) in front of it.&lt;br&gt;
Pixi-CRS does not have a CD portion and is currently not deployed anywhere.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pixi-CRS Tests
&lt;/h3&gt;

&lt;p&gt;The Pixi-CRS pipeline has web application tests that are used to test Pixi. The tests do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Register a user in Pixi&lt;/li&gt;
&lt;li&gt;Log in as this user&lt;/li&gt;
&lt;li&gt;Searches for a string in Pixi's search box&lt;/li&gt;
&lt;li&gt;Clicks "About"&lt;/li&gt;
&lt;li&gt;Clicks "My Profile" and changes Name&lt;/li&gt;
&lt;li&gt;Log out the user&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pixi-CRS goes to the Cloud
&lt;/h3&gt;

&lt;p&gt;The first Pixi-CRS pipeline was built on CircleCI. A detailed description of this pipeline can be found &lt;a href="https://dev.to/devslop/devslop-s-pixi-crs-pipeline-4bie"&gt;in one of my earlier blog posts&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And now Pixi-CRS is going to the cloud.&lt;br&gt;
We wanted to learn if we could also implement Pixi-CRS on Google Cloud Platform, Amazon Web Services, Azure Pipelines and GitHub Actions.&lt;br&gt;
And we've been successful!&lt;/p&gt;

&lt;p&gt;This was an intro blog post about the new Pixi-CRS cloud pipelines and beginning of a series. &lt;br&gt;
In the next blog posts, I will show what Pixi-CRS looks like in the cloud: on Amazon Web Services, Google Cloud Platform, Azure Pipelines and as GitHub Actions...&lt;/p&gt;

</description>
      <category>waf</category>
      <category>crs</category>
      <category>pixi</category>
      <category>devsecops</category>
    </item>
    <item>
      <title>Jobs in Information Security (InfoSec)</title>
      <dc:creator>Tanya Janca</dc:creator>
      <pubDate>Fri, 27 Dec 2019 05:11:17 +0000</pubDate>
      <link>https://dev.to/devslop/jobs-in-information-security-infosec-kmb</link>
      <guid>https://dev.to/devslop/jobs-in-information-security-infosec-kmb</guid>
      <description>&lt;p&gt;**This article is for beginners, not experts. :-D&lt;/p&gt;

&lt;p&gt;Almost all of the people who respond to my &lt;strong&gt;#CyberMentoringMonday&lt;/strong&gt; tweets each week say that they want to "get into InfoSec" or "become a Pentester"; they rarely choose any other jobs or are more specific than that. I believe the reason for this is that they are not aware of all the different areas within the field of Information Security (InfoSec for short, and "Cyber" for those outside of our industry). I can sympathize; I was in the same position when I joined. I knew three Penetration Testers and lots of Risk Analysts and I had no clue that there were several other areas that may interest me or even existed. I knew I didn't want to be a Risk Analyst, so I thought the only other option was PenTester. Now I know that is not at all true. This blog post will detail several other areas within the field of Information Security in hopes that newcomers to our field can find their niche more easily. It will not be exhaustive, but I'll do my best.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ftgtu677y6bgketjws3wk.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ftgtu677y6bgketjws3wk.jpeg" title="Image by Henry Jiang of Oppenheimer &amp;amp; Co." alt="Image by Henry Jiang of Oppenheimer &amp;amp; Co."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  &lt;a href="http://www.sccongress.com/new-york/henry-jiang/author/40883/" rel="noopener noreferrer"&gt;Image by Henry Jiang of Oppenheimer &amp;amp; Co.&lt;/a&gt;
&lt;/h6&gt;

&lt;p&gt;&lt;em&gt;The above image shows 8 different potential areas within the field of Information Security according to the author, Henry Jiang; Governance, Risk, Career Development, User Education, Standards, Threat Intelligence, Security Architecture and Security Operations.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Since I come from the software development side of IT, and have done almost exclusively coding, my view is going to be extremely biased. With that in mind, the first area you may want to consider is &lt;strong&gt;Application Security&lt;/strong&gt; (AppSec); any and all work towards ensuring that software is secure. This is the field that I work in, so it will have the most detail. There are all sorts of jobs within this field, but the most well-known is the web app pentester (sometimes called an ethical hacker); a person who does security testing on software. Such a person is often a consultant, but can also work in large companies. They test one system, intensively, perform a lot of manual testing, and then move on. &lt;/p&gt;

&lt;h4&gt;
  
  
  Jobs in Application Security:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Application Security Engineer&lt;/strong&gt; - you do a mix of all the things listed under AppSec and you are generally a full-time employee. This includes making customer tools, launching a security champion program, writing guidelines, and anything else that will help ensure the security of your organization's apps. I personally consider this the sweet spot, as I get to do changing and interesting work, and see the security posture improve over time. It is, however, usually a more senior role.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Threat Modeller&lt;/strong&gt;, working with developers, business representatives and the security team (that's you in this scenario) to find and document potential threats to your software, then create plans to test for and fix the issues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vulnerability Assessment&lt;/strong&gt;: running lots of scans, all the time, of everything. You can scan the network too. Ideally you will do more than this, to assess the security of the systems in your care, but it depends on where you work. This position is often an employee position and you tend to have prolonged relationships with the systems and teams you assess.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vulnerability Management&lt;/strong&gt;: Keeping Track of the vulnerabilities that all the tools and people find, reporting to management about it, and planning from a higher level. For instance; attempting to wipe out an entire bug class, implementing new tools because you see a deficiency, resource planning, etc. This is an employee position usually, and often a manager role or team lead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure Code Reviewer&lt;/strong&gt;: reading lots of code, using SAST (static application security testing) tools and SCA (Software Composition Analysis - are our 3rd party components secure?), finding vulnerabilities in written code and helping developers fix it. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DevSecOps Engineer&lt;/strong&gt;: an AppSec engineer working in a DevOps environment. Same goal, different tactics. Adding security checks to pipelines, figuring out how to secure containers and anything else your DevOps engineers are up to.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer Education&lt;/strong&gt;: this is usually a consultant role, but sometimes for large companies someone can do this full time. The person teachers the developers to write secure code, the architects to design secure apps, threat modelling, and any other topic they can think of that will help ensure their mandate (secure apps). This person is likely also to training the security champions. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Governance&lt;/strong&gt;: writing policies, guidelines, standards, etc, to ensure your apps are secure. This job is usually someone that does all the governance stuff for your org and the person is working with the AppSec team to get the details right, OR this person is likely a consultant because this is not an activity that needs to be re-done constantly. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Incident Response&lt;/strong&gt;: this area includes jobs as an incident manager (you boss everyone around and make sure the incident goes as smoothly as possible), and investigations (Forensics/DFIR). Investigating incidents related to insecure software is a topic I personally find thrilling; detective work is exciting! But with the stress it causes, it's not for everyone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Testing&lt;/strong&gt;: sometimes called Penetration Testing, sometimes called Red Teaming, sometimes not officially recognized as a job because management isn't "ready" to admit they need this yet. This person tests the software (and sometimes networks) to ensure they are secure. This includes manual testing, using lots of tools, and trying to break things without causing a huge mess. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Design Review&lt;/strong&gt;: This is called a "Security Archtect" but AppSec folks are often asked to review designs for potential security flaws. If asked, say yes! It's super fun and always educational. Bonus; it's a good way to build trust between security and the developers.
In AppSec you will also be asked to do a range of other things because that's how life is. Potential asks; install this giant AppSec tool and figure out how it works, create a proof of concept for an exploit to show everyone that it is/is not a problem, create a proof of value with a new AppSec tool we are considering acquiring, get all the developers to log their apps like 'so' in order for the SIEM can read the results, research how to do something securely when you have no idea how to do that thing at all, etc. Like I said, it's &lt;em&gt;super fun&lt;/em&gt;!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fjp2l7qrhrhx3hhuqg550.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fjp2l7qrhrhx3hhuqg550.jpg" title="ISACA Victoria, Dec 2019" alt="ISACA Victoria, Dec 2019"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  ISACA Victoria, Dec 2019
&lt;/h6&gt;

&lt;p&gt;&lt;strong&gt;SOC Analyst/Threat Hunter&lt;/strong&gt;: SOC analysts interpret output from the monitoring tools to try to tell if something bad is happening, while threat hunters go looking for trouble. This is mostly network based, and I'm not good at networks, otherwise I would have been all over this when I moved into security. The idea of threat hunting (using data and patterns to spot problems), is very appealing to my metric-adoring brain. Note: SOC Analysist is a junior or intermediate position and threat hunter is not a junior position, but if you want to get into InfoSec they are basically always hiring for SOC Analysts, at almost every company.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security Architect&lt;/strong&gt; (apps, cloud, network): Security architects ensure that designs are secure. This can mean reviewing a deployment, network or application design, adding recommendations, or even creating the design themselves from scratch. This tends to be a more senior role.&lt;br&gt;
Risk Analyst: Evaluate systems to identify and measure risk to the business, then offer recommendations on how to mitigate or when to accept the risks. This tends to be coupled closely with Compliance, and Auditing, which I won't describe here because I am shamefully under-educated in this area.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security Policy Writer&lt;/strong&gt;: Writing policies about security, such as how long network passwords need to be, that all public-facing web apps must be available via HTTPS, and that only TLS 1.2 and higher are acceptable on your network. Deciding, writing, socializing and enforcing these policies are all part of this role.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Malware Analyst/Reverse Engineer&lt;/strong&gt;: Someone needs to look at malware and figure out how it works, and sometimes people need to write exploits (for legitimate reasons, such as to prove that something is indeed vulnerable, or… You need to ask them). If you enjoy puzzles and really low level programming (such as ARM, assembler, etc), this job might be for you. But be careful; playing with malware at home is dangerous.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chief Information Security Officer&lt;/strong&gt; (CISO or CSO): 'The boss" of security. This person (hopefully) has a seat at the executive table, directs all security aspects for a company, and is the person held responsible, for better or for worse. If you enjoy running programs, managing things from a high level, and making a big difference, this might be a role for you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blue Team/Defender/Security Engineer&lt;/strong&gt; (enterprise security/implements security tools): The people that keep us safe! These people install tools, run the tools, monitor, patch, and freak out when people download and install things to their desktops without asking. They perform security operations, making sure all the things happen. While those in the SOC (Security operations centre), monitor everything that's happening and respond when there are problems.&lt;/p&gt;

&lt;p&gt;There are many, many, many jobs within the field of Information Security, please feel free to list some of the ones that I missed in the comments below. I hope this information helps more of you join our industry, because we need all the help we can get!&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;For this and more, check out my book, &lt;a href="https://aliceandboblearn.com/" rel="noopener noreferrer"&gt;Alice and Bob Learn Application Security&lt;/a&gt; and my online training academy, &lt;a href="https://academy.wehackpurple.com" rel="noopener noreferrer"&gt;We Hack Purple&lt;/a&gt;!&lt;/strong&gt;
&lt;/h2&gt;

</description>
      <category>beginners</category>
      <category>security</category>
      <category>career</category>
      <category>infosec</category>
    </item>
    <item>
      <title>DevSlop's Pixi-CRS Pipeline</title>
      <dc:creator>Franziska Bühler</dc:creator>
      <pubDate>Thu, 19 Dec 2019 09:25:46 +0000</pubDate>
      <link>https://dev.to/devslop/devslop-s-pixi-crs-pipeline-4bie</link>
      <guid>https://dev.to/devslop/devslop-s-pixi-crs-pipeline-4bie</guid>
      <description>&lt;p&gt;A Web Application Firewall (WAF) raises concerns that it does not fit into the DevOps methodology. The problem is that when a WAF is added to production, the impact on the application is tested too late. The application developer gets extremely late feedback and the WAF could break the application. This can lead to production issues.&lt;/p&gt;

&lt;p&gt;But what if a WAF is involved in the DevOps process very early on and not just at the end, at production?&lt;/p&gt;

&lt;p&gt;The whole DevOps process only makes sense when all components are part of it! A service can only be successfully complemented by a WAF if the WAF is part of the pipeline from the beginning. I will show how to integrate a WAF, specifically ModSecurity with the Core Rule Set, and its testing into continuous integration. The CI-pipeline called Pixi-CRS is one of DevSlop's modules.&lt;/p&gt;

&lt;p&gt;For those of you who want to learn more about the web application Pixi and its known vulnerabilities, read my &lt;a href="https://dev.to/devslop/how-the-owasp-modsecurity-core-rule-set-protects-the-vulnerable-web-application-pixi-by-owasp-devslop-n4d"&gt;former blog post&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;Despite the fact that the number of false positives has been massively reduced in CRS3, there is still the possibility that legitimate traffic from a legitimate user might trigger a CRS rule. This means the user receives a ‘403 – Forbidden’ message and can’t use the full application functionality. She or he gets blocked.&lt;/p&gt;

&lt;p&gt;This problem is even worse in a DevOps culture. Everything is fully automated and well-tested and in the end, we add a WAF to production and kill the whole positive experience: When production issues arise, it is often too late to find and correct the problems. Instead, an operator is likely to disable the WAF and never re-enable it again. This is because operators have a lot of other work to do and security is not always the top priority.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;The solution is to insert the WAF / CRS very early in the DevOps process and give the developers and operators early feedback:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If we automate application tests, we must add the CRS to these tests. All tests have to succeed first without, then with the CRS! Additionally, no CRS rule should be triggered by the tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each commit of the application code into the repository triggers a continuous integration run. This launches the application, starts the WAF and runs the application tests.&lt;br&gt;
We are thus testing an application with the CRS after every commit of the code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We always want to have the application in a deployable and runnable state with the CRS.&lt;br&gt;
This way, we know that our current app version’s traffic is not blocked by the CRS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We guarantee this by testing the application and the CRS in a production-like environment. There can always be false positives. We can remove them by tuning the rules via the configuration.&lt;br&gt;
If we have to perform these adjustments to the CRS, we already have our configuration for production because we tested it in a production-like environment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The application should not go to release until it is fully tested with the CRS!&lt;br&gt;
An application whose legitimate traffic triggers a rule should not go into production until the error is fixed either. With every false positive, we need to decide if it is something we can fix in the application, or if the CRS needs to be tuned.&lt;br&gt;
This way, the application’s traffic is tested with the CRS and we don’t have to fear production issues later on.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  CRS Docker Container
&lt;/h2&gt;

&lt;p&gt;As you can read at &lt;a href="https://coreruleset.org/installation" rel="noopener noreferrer"&gt;https://coreruleset.org/installation&lt;/a&gt;, it only takes a few steps to install the Core Rule Set. And it gets even easier if you use it in a Docker Container.&lt;/p&gt;

&lt;p&gt;The official CRS Docker image has a reverse proxy configuration to put it in front of a web application and various configurable CRS variables. With this container, the CRS can be very quickly and easily integrated into automated tests.&lt;/p&gt;

&lt;p&gt;Here is how to run the container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-dt&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;PARANOIA&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nv"&gt;ANOMALYIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5 &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;ANOMALYOUT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4 &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;PROXYLOCATION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://172.17.0.1:8000/ &lt;span class="se"&gt;\&lt;/span&gt;
owasp/modsecurity-crs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Among others, the following environment variables are configurable:&lt;/p&gt;

&lt;p&gt;PARANOIA: paranoia_level&lt;br&gt;
ANOMALYIN: inbound_anomaly_score_threshold&lt;br&gt;
ANOMALYOUT: outbound_anomaly_score_threshold&lt;br&gt;
PROXYLOCATION: IP address and TCP port of application backend&lt;/p&gt;

&lt;p&gt;Explanations of the individual parameters can be found in the main CRS configuration file crs-setup.conf (current version: &lt;a href="https://github.com/SpiderLabs/owasp-modsecurity-crs/blob/v3.3/dev/crs-setup.conf.example" rel="noopener noreferrer"&gt;https://github.com/SpiderLabs/owasp-modsecurity-crs/blob/v3.3/dev/crs-setup.conf.example&lt;/a&gt;) or as part of the tutorial series about ModSecurity and CRS at netnea.&lt;/p&gt;
&lt;h2&gt;
  
  
  Proof of Concept: DevSlop's Pixi-CRS pipeline
&lt;/h2&gt;

&lt;p&gt;I have implemented a proof of concept in CircleCI. This Pixi-CRS pipeline (&lt;a href="https://github.com/DevSlop/pixi-crs" rel="noopener noreferrer"&gt;https://github.com/DevSlop/pixi-crs&lt;/a&gt;) is one of DevSlop's modules. Of course, the continuous integration can also be implemented on TravisCI, Jenkins, and so on. Then I used TestCafe to write the application tests. It’s a Node.js tool for performing end-to-end tests.&lt;/p&gt;

&lt;p&gt;In the basic setup, we have application tests that are performed against the application. Naturally, these application tests should succeed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ft8km1qd37xlj429lbot8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ft8km1qd37xlj429lbot8.png" alt="Setup"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a next step, we put CRS in front of the same application in order to funnel the same tests through the WAF. We expect the application tests to still succeed and the log to remain empty. This would confirm that no CRS rule were triggered by the tests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fb6ps01wn0cnrq2v6un79.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fb6ps01wn0cnrq2v6un79.png" alt="Setup with CRS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each of these components runs in a separate Docker container.&lt;/p&gt;

&lt;p&gt;The time taken to pull and start the Core Rule Set container and to run the application tests are only a small part (approx. 1 minute and 30 seconds in this PoC) of the overall testing process (approx. 3 minutes and 30 seconds in my example).&lt;/p&gt;

&lt;p&gt;The message here is: We do not waste a lot of time but get a lot of extra security.&lt;/p&gt;
&lt;h2&gt;
  
  
  CI Configuration
&lt;/h2&gt;

&lt;p&gt;In summary, the CircleCI configuration .circleci/config.yml consists of the following steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .circleci/config.yml&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;circleci/node:stretch&lt;/span&gt;
      &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="na"&gt;-run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
             &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies&lt;/span&gt;
             &lt;span class="s"&gt;...&lt;/span&gt;
         &lt;span class="s"&gt;-run&lt;/span&gt;
             &lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install Docker Compose&lt;/span&gt;
             &lt;span class="s"&gt;...&lt;/span&gt;
         &lt;span class="s"&gt;-setup_remote_docker&lt;/span&gt;
         &lt;span class="s"&gt;-checkout&lt;/span&gt;
         &lt;span class="na"&gt;-run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
             &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Start App Container Pixi&lt;/span&gt;
             &lt;span class="s"&gt;...&lt;/span&gt;
         &lt;span class="na"&gt;-run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
             &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Start OWASP ModSecurity CRS Container in front of application for application tests&lt;/span&gt;
             &lt;span class="c1"&gt;#http://172.17.0.2:443&lt;/span&gt;
             &lt;span class="c1"&gt;#we set inbound and outbound anomaly score to 1, no tolerance&lt;/span&gt;
             &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
                &lt;span class="s"&gt;docker pull owasp/modsecurity-crs:v3.2-modsec2-apache &amp;amp;&amp;amp; \&lt;/span&gt;
                &lt;span class="s"&gt;docker run -dt --name apachecrstc -e PARANOIA=2 \&lt;/span&gt;
                &lt;span class="s"&gt;-e ALLOWED_METHODS='GET HEAD POST OPTIONS PUT' -e \&lt;/span&gt;
                &lt;span class="s"&gt;ANOMALYIN=1 -e ANOMALYOUT=1 -e PROXYLOCATION=http://172.17.0.1:8000/ \&lt;/span&gt;
                &lt;span class="s"&gt;--expose 80 owasp/modsecurity-crs:v3.2-modsec2-apache&lt;/span&gt;
         &lt;span class="na"&gt;-run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
             &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ModSecurity Tuning - Load rule exclusions&lt;/span&gt;
             &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
                &lt;span class="s"&gt;printf '# Rule 942450 (msg: SQL Hex Encoding Identified) triggers,\n' &amp;gt; tmp.conf&lt;/span&gt;
                &lt;span class="s"&gt;printf '# because of random characters in the session cookie.\n' &amp;gt;&amp;gt; tmp.conf&lt;/span&gt;
                &lt;span class="s"&gt;printf '\nSecRuleUpdateTargetById 942450 "!REQUEST_COOKIES:session"\n' &amp;gt;&amp;gt; tmp.conf&lt;/span&gt;
                &lt;span class="s"&gt;# CRS container for application tests:&lt;/span&gt;
                &lt;span class="s"&gt;docker cp tmp.conf apachecrstc:/etc/httpd/modsecurity.d/owasp-crs/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf;&lt;/span&gt;
                &lt;span class="s"&gt;docker exec apachecrstc /usr/sbin/httpd -k graceful&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
             &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Application Tests with Testcafe&lt;/span&gt;
             &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
                &lt;span class="s"&gt;# https://circleci.com/docs/2.0/building-docker-images/#mounting-folders&lt;/span&gt;
                &lt;span class="s"&gt;# creating dummy container which will hold a volume with config&lt;/span&gt;
                &lt;span class="s"&gt;docker create -v /tests --name configs alpine:latest /bin/true&lt;/span&gt;
                &lt;span class="s"&gt;# copying config file into this volume&lt;/span&gt;
                &lt;span class="s"&gt;docker cp /home/circleci/project/testcafe/tests/test.js configs:/tests&lt;/span&gt;
                &lt;span class="s"&gt;# starting application container using this volume&lt;/span&gt;
                &lt;span class="s"&gt;docker pull testcafe/testcafe&lt;/span&gt;
                &lt;span class="s"&gt;docker run --volumes-from configs:rw --name testcafe -it testcafe/testcafe 'chromium:headless --no-sandbox' /tests/test.js&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
             &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Application Tests with CRS with Testcafe&lt;/span&gt;
             &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
                &lt;span class="s"&gt;docker cp /home/circleci/project/testcafe/tests/testcrs.js configs:/tests&lt;/span&gt;
                &lt;span class="s"&gt;docker run --volumes-from configs:rw --name testcafecrs -it testcafe/testcafe 'chromium:headless --no-sandbox' /tests/testcrs.js&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
             &lt;span class="c1"&gt;# Fail if ModSecurity log is not empty&lt;/span&gt;
             &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Show ModSecurity logs of Testcafe Tests&lt;/span&gt;
             &lt;span class="s"&gt;...&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# Fail if ModSecurity log does not contain WAF Test String "My evil WAF Test"&lt;/span&gt;
            &lt;span class="c1"&gt;# '&amp;lt;script&amp;gt;alert("My evil WAF Test")&amp;lt;/script&amp;gt;'&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Search for WAF Test String "My evil WAF Test" in ModSecurity logs&lt;/span&gt;
            &lt;span class="s"&gt;...&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For all details see Pixi-CRS on GitHub:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/.circleci/config.yml" rel="noopener noreferrer"&gt;https://github.com/DevSlop/pixi-crs/blob/master/.circleci/config.yml&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s go through the steps and take a closer look:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step “Spin up Environment”
&lt;/h3&gt;

&lt;p&gt;First, we have to tell CircleCI which image to use for the primary Docker Container. That is where all of the following steps are performed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Steps “Install dependencies”, “Install Docker Compose” and “setup_remote_docker”
&lt;/h3&gt;

&lt;p&gt;Then we want CircleCI to install some dependencies, docker-compose and docker.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step “checkout”
&lt;/h3&gt;

&lt;p&gt;The configuration .circleci/config.yml is in the root of the application repository. And in step ‘checkout’, CircleCI checks out the application code, where the .circleci/config.yml resides.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step “Start App Container”
&lt;/h3&gt;

&lt;p&gt;In the next step, we start the application Pixi in a container.&lt;/p&gt;

&lt;p&gt;Step “Start OWASP ModSecurity CRS Container in front of application for application tests”&lt;/p&gt;

&lt;p&gt;Then we start our CRS container in front of the application we have just started above.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step “ModSecurity Tuning – Load rule exclusions”
&lt;/h3&gt;

&lt;p&gt;In this step, we have the ability to tune the ModSecurity / CRS setup. We exclude certain rules or we hide certain parameters from the set of over 150 rules to avoid false positives and to keep the logfile empty.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step “Application Tests with Testcafe”
&lt;/h3&gt;

&lt;p&gt;Here, we perform the application tests against the TCP port of the application container. We do this to be sure that the application and the application tests are working. We want to distinguish failed application tests caused by the application itself from false positives introduced by CRS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step “Application Tests with CRS with Testcafe”
&lt;/h3&gt;

&lt;p&gt;We repeat the application tests, but this time via the WAF / CRS. This is done by pointing the tests against the TCP port of the CRS container. Of course, these tests must be successful, too. In addition to the existing application tests, we add a WAF test to be sure that the CRS really triggers: We send an Cross Site Scripting (XSS) payload to a search form and expect the CRS to block the attack.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step “Show ModSecurity logs of Testcafe Tests”
&lt;/h3&gt;

&lt;p&gt;In the end, we check the results: The ModSecurity log should be empty. This means that no CRS rule was triggered by the standard application tests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step “Search for WAF Test String “My evil WAF Test” in ModSecurity logs
&lt;/h3&gt;

&lt;p&gt;We also test that our intentionally added XSS string appears in the log. If it does not appear, either the tests have been aborted or the CRS did not work properly and we should look into this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpcndc19cl2xo04x1kjre.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpcndc19cl2xo04x1kjre.png" alt="CircleCIRun"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the image above, we don't see any problem. That means this application can be released. &lt;br&gt;
The message here is: If and when every step is successful and the application works behind the CRS, then the application can go into production!&lt;/p&gt;

&lt;h2&gt;
  
  
  Recommendations for Production
&lt;/h2&gt;

&lt;p&gt;This PoC covers the continuous integration part. But of course, it could be extended to an entire deployment pipeline.&lt;/p&gt;

&lt;p&gt;To do all this in production, I recommend the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The more tests you write, the better!&lt;br&gt;
But at least test your login process. I often see false positives in cookies and cookie names in production, if, for example, special characters or random strings are used.&lt;br&gt;
Click through your entire application. Testing all GET and POST arguments covers a broad part of the application. I also often see problems there.&lt;br&gt;
The broader the tests are, the better the chance to get all possible false positives caused by the application’s legitimate traffic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Perform your tests during continuous integration with a very low inbound and outbound anomaly threshold.&lt;br&gt;
We want to see and alert every false positive.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If there are false positives in production (lack of tests?), then write a test for every issue discovered this way. This makes sure the false positives goes away.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each new feature of the application should be covered by a test. Of course, this should always be the case, but it’s even more important with CRS in place.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You will probably have to adapt the CRS Docker container to fit into your organization.&lt;br&gt;
Take the CI pipeline and the Docker container of this PoC and customize it for your organization. This PoC is meant to give you free samples of how to implement a pipeline with a WAF in it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;The backend application I tested in this PoC is the Pixi application from the &lt;a href="https://www.owasp.org/index.php/OWASP_DevSlop_Project" rel="noopener noreferrer"&gt;OWASP project DevSlop&lt;/a&gt;.&lt;br&gt;
The OWASP DevSlop project consists of several modules, all aimed at either presenting proof-of-concept DevSecOps pipelines, or insecure implementations of DevOps to teach better practices.&lt;/p&gt;

&lt;p&gt;The CircleCI configuration can be found on &lt;a href="https://github.com/DevSlop/pixi-crs/blob/master/.circleci/config.yml" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. Please take this example and customize it for your organization.&lt;/p&gt;

&lt;p&gt;The CRS Docker image can be found at &lt;a href="https://hub.docker.com/r/owasp/modsecurity-crs/" rel="noopener noreferrer"&gt;DockerHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One of the triggers of the idea behind this blog post is the book &lt;a href="https://www.manning.com/books/securing-devops" rel="noopener noreferrer"&gt;‘Securing DevOps’ by Julien Vehent&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://netnea.com/apache-tutorials" rel="noopener noreferrer"&gt;ModSecurity Guides by Christian Folini&lt;/a&gt; provide the basic knowledge to understand the concepts and inner working of CRS and ModSecurity.&lt;/p&gt;

&lt;p&gt;This is a crosspost from &lt;a href="https://coreruleset.org" rel="noopener noreferrer"&gt;https://coreruleset.org&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>crs</category>
      <category>waf</category>
      <category>pixi</category>
      <category>pixicrs</category>
    </item>
    <item>
      <title>How the OWASP ModSecurity Core Rule Set protects the vulnerable web application Pixi by OWASP DevSlop</title>
      <dc:creator>Franziska Bühler</dc:creator>
      <pubDate>Sun, 01 Dec 2019 06:56:16 +0000</pubDate>
      <link>https://dev.to/devslop/how-the-owasp-modsecurity-core-rule-set-protects-the-vulnerable-web-application-pixi-by-owasp-devslop-n4d</link>
      <guid>https://dev.to/devslop/how-the-owasp-modsecurity-core-rule-set-protects-the-vulnerable-web-application-pixi-by-owasp-devslop-n4d</guid>
      <description>&lt;p&gt;How could the functionality of a WAF be better demonstrated than with a vulnerable web application?&lt;/p&gt;

&lt;p&gt;In this blog post I introduce Pixi, an intentionally vulnerable web application by the OWASP project DevSlop. I show its known vulnerabilities and examine how the OWASP ModSecurity Core Rule Set (CRS) protects against these vulnerabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Pixi?
&lt;/h2&gt;

&lt;p&gt;Pixi is a deliberately vulnerable web application that is part of the OWASP DevSlop project. It's a hacker playground written by Nicole Becher. Most of you may know the &lt;a href="https://youtube.com/owaspdevslop" rel="noopener noreferrer"&gt;DevSlop YouTube shows&lt;/a&gt; with Tanya Janca and Nancy Gariché.&lt;/p&gt;

&lt;p&gt;The good news is, the vulnerable web application Pixi can be protected with the Core Rule Set in a very effective way!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the OWASP ModSecurity Core Rule Set?
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://coreruleset.org/" rel="noopener noreferrer"&gt;CRS&lt;/a&gt; is a rule set for a Web Application Firewall (WAF) such as ModSecurity. Its purpose is to defend against common web application attacks. It's the first line of defense in front of a (potential vulnerable) web application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;To start Pixi and the CRS in front of it, I use the official &lt;a href="https://github.com/SpiderLabs/owasp-modsecurity-crs/blob/v3.2.0/util/docker/docker-compose.yaml" rel="noopener noreferrer"&gt;docker-compose.yaml&lt;/a&gt; provided by the Core Rule Set and I add the Pixi part below the CRS part:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# This docker-compose file starts owasp/modsecurity-crs&lt;/span&gt;

version: "3"

services:

  crs:
    image: owasp/modsecurity-crs
    ports:
      - "80:80"
      # only available if SETTLS was enabled:
      - "443:443"

    environment:
      - SERVERNAME=localhost

      &lt;span class="c"&gt;#############################################&lt;/span&gt;
      &lt;span class="c"&gt;# CRS Variables&lt;/span&gt;
      &lt;span class="c"&gt;#############################################&lt;/span&gt;
      &lt;span class="c"&gt;# Paranoia Level&lt;/span&gt;
      - PARANOIA=1
      &lt;span class="c"&gt;# Inbound and Outbound Anomaly Score Threshold&lt;/span&gt;
      - ANOMALYIN=5
      - ANOMALYOUT=4
      &lt;span class="c"&gt;# Executing Paranoia Level&lt;/span&gt;
      &lt;span class="c"&gt;# - EXECUTING_PARANOIA=2&lt;/span&gt;

      &lt;span class="c"&gt;#######################################################&lt;/span&gt;
      &lt;span class="c"&gt;# Reverse Proxy mode&lt;/span&gt;
      &lt;span class="c"&gt;# (only available if SETPROXY was enabled during the&lt;/span&gt;
      &lt;span class="c"&gt;# parent ModSecurity image)&lt;/span&gt;
      &lt;span class="c"&gt;#######################################################&lt;/span&gt;
      &lt;span class="c"&gt;# PROXYLOCATION: Application Backend of Reverse Proxy&lt;/span&gt;
      - PROXYLOCATION=http://app:8000/

  db:
    image: deadrobots/pixi:datastore
    container_name: pixidb
    expose:
      - "27017"
      - "28017"

  app:
    image: deadrobots/pixi:app
    ports:
      - "127.0.0.1:8000:8000"
      - "127.0.0.1:8090:8090"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The image owasp/modsecurity-crs is the new official OWASP ModSecurity Core Rule Set container image. It supports the TLS and PROXY mode per default.&lt;br&gt;
We use the standard installation, the Paranoia Level 1 and an inbound anomaly threshold of 5 and outbound anomaly threshold of 4. The backend, Pixi, runs on port 8000 and we set the PROXYLOCATION env var to the service app with port 8000. The CRS Reverse Proxy listens on port 80 and 443.&lt;/p&gt;

&lt;p&gt;I will use port 80 for demonstration, but it’s very easy to mount a valid TLS server certificate into the container and provide proper TLS.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pixis Vulnerabilities
&lt;/h2&gt;

&lt;p&gt;Let’s now dive into Pixi’s weaknesses:&lt;/p&gt;
&lt;h3&gt;
  
  
  Authentication bypass
&lt;/h3&gt;

&lt;p&gt;With a simple Mongo DB injection, the authentication can be bypassed. For further reading about this class of vulnerabilities, see &lt;a href="https://www.owasp.org/index.php/Testing_for_NoSQL_injection" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Unfortunately, I can not show this vulnerability. As soon as I replay this request in ZAP (&lt;a href="https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project" rel="noopener noreferrer"&gt;OWASP Zed Attack Proxy&lt;/a&gt;) the application Pixi dies. You could say it’s a remote DoS on top of the authentication problem. One more reason the use CRS to protect us from this problem!&lt;/p&gt;

&lt;p&gt;When I replay the request through the CRS, Pixi doesn’t die anymore, because CRS blocks the request at Paranoia Level 1:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5ryzthvzwyqj8nzqncwz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5ryzthvzwyqj8nzqncwz.png" alt="Authentication Bypass: ZAP Request Editor"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Frgvo5btqv1qpccromnlu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Frgvo5btqv1qpccromnlu.png" alt="Authentication Bypass: ZAP Response"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The logfile tells us that the MongoDB injection was detected (id: 942290). It says that the access was denied (id: 949110) and that the Inbound Anomaly Score of the request at PL1 was 5 (id: 980130). The last two log file entries (id: 949110 and 980130) always occur with a blocked request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;Mon Sep 09 07:40:47.839300 2019] &lt;span class="o"&gt;[&lt;/span&gt;:error] &lt;span class="o"&gt;[&lt;/span&gt;pid 44:tid 139999475324672] 
&lt;span class="o"&gt;[&lt;/span&gt;client 192.168.0.1:59602] &lt;span class="o"&gt;[&lt;/span&gt;client 192.168.0.1] ModSecurity: Warning. 
Pattern match “&lt;span class="o"&gt;(&lt;/span&gt;?i:&lt;span class="o"&gt;(&lt;/span&gt;?:&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;?:ne|eq|lte?|gte?|n?
&lt;span class="k"&gt;in&lt;/span&gt;|mod|all|size|exists|type|slice|x?or|div|like|between|and&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="o"&gt;]))&lt;/span&gt;” at 
ARGS_NAMES:pass[&lt;span class="nv"&gt;$ne&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;file “/etc/modsecurity.d/owasp-crs/rules/REQUEST-
942-APPLICATION-ATTACK-SQLI.conf”] &lt;span class="o"&gt;[&lt;/span&gt;line “367”] &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; “942290”] &lt;span class="o"&gt;[&lt;/span&gt;msg “Finds 
basic MongoDB SQL injection attempts”] &lt;span class="o"&gt;[&lt;/span&gt;data “Matched Data: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$ne&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; found 
within ARGS_NAMES:pass[&lt;span class="nv"&gt;$ne&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: pass[&lt;span class="nv"&gt;$ne&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;”] &lt;span class="o"&gt;[&lt;/span&gt;severity “CRITICAL”] &lt;span class="o"&gt;[&lt;/span&gt;ver 
“OWASP_CRS/3.2.0”] &lt;span class="o"&gt;[&lt;/span&gt;tag “application-multi”] &lt;span class="o"&gt;[&lt;/span&gt;tag “language-multi”] &lt;span class="o"&gt;[&lt;/span&gt;tag 
“platform-multi”] &lt;span class="o"&gt;[&lt;/span&gt;tag “attack-sqli”] &lt;span class="o"&gt;[&lt;/span&gt;tag “OWASP_CRS”] &lt;span class="o"&gt;[&lt;/span&gt;tag 
“OWASP_CRS/WEB_ATTACK/SQL_INJECTION”] &lt;span class="o"&gt;[&lt;/span&gt;tag “WASCTC/WASC-19”] &lt;span class="o"&gt;[&lt;/span&gt;tag 
“OWASP_TOP_10/A1”] &lt;span class="o"&gt;[&lt;/span&gt;tag “OWASP_AppSensor/CIE1”] &lt;span class="o"&gt;[&lt;/span&gt;tag “PCI/6.5.2”] 
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;hostname&lt;/span&gt; “localhost”] &lt;span class="o"&gt;[&lt;/span&gt;uri “/login”] &lt;span class="o"&gt;[&lt;/span&gt;unique_id “XXYB-
5tiXQGQt80jpPMnxgAAAJc”], referer: http://localhost:80/login


&lt;span class="o"&gt;[&lt;/span&gt;Mon Sep 09 07:40:47.845881 2019] &lt;span class="o"&gt;[&lt;/span&gt;:error] &lt;span class="o"&gt;[&lt;/span&gt;pid 44:tid 139999475324672] 
&lt;span class="o"&gt;[&lt;/span&gt;client 192.168.0.1:59602] &lt;span class="o"&gt;[&lt;/span&gt;client 192.168.0.1] ModSecurity: Access 
denied with code 403 &lt;span class="o"&gt;(&lt;/span&gt;phase 2&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; Operator GE matched 5 at 
TX:anomaly_score. &lt;span class="o"&gt;[&lt;/span&gt;file “/etc/modsecurity.d/owasp-crs/rules/REQUEST-949-
BLOCKING-EVALUATION.conf”] &lt;span class="o"&gt;[&lt;/span&gt;line “91”] &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; “949110”] &lt;span class="o"&gt;[&lt;/span&gt;msg “Inbound 
Anomaly Score Exceeded &lt;span class="o"&gt;(&lt;/span&gt;Total Score: 5&lt;span class="o"&gt;)&lt;/span&gt;”] &lt;span class="o"&gt;[&lt;/span&gt;severity “CRITICAL”] &lt;span class="o"&gt;[&lt;/span&gt;tag 
“application-multi”] &lt;span class="o"&gt;[&lt;/span&gt;tag “language-multi”] &lt;span class="o"&gt;[&lt;/span&gt;tag “platform-multi”] &lt;span class="o"&gt;[&lt;/span&gt;tag 
“attack-generic”] &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;hostname&lt;/span&gt; “localhost”] &lt;span class="o"&gt;[&lt;/span&gt;uri “/login”] &lt;span class="o"&gt;[&lt;/span&gt;unique_id “XXYB-
5tiXQGQt80jpPMnxgAAAJc”], referer: http://localhost:80/login


&lt;span class="o"&gt;[&lt;/span&gt;Mon Sep 09 07:40:47.849314 2019] &lt;span class="o"&gt;[&lt;/span&gt;:error] &lt;span class="o"&gt;[&lt;/span&gt;pid 44:tid 139999475324672] 
&lt;span class="o"&gt;[&lt;/span&gt;client 192.168.0.1:59602] &lt;span class="o"&gt;[&lt;/span&gt;client 192.168.0.1] ModSecurity: Warning. 
Operator GE matched 5 at TX:inbound_anomaly_score. &lt;span class="o"&gt;[&lt;/span&gt;file 
“/etc/modsecurity.d/owasp-crs/rules/RESPONSE-980-CORRELATION.conf”] &lt;span class="o"&gt;[&lt;/span&gt;line 
“86”] &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; “980130”] &lt;span class="o"&gt;[&lt;/span&gt;msg “Inbound Anomaly Score Exceeded &lt;span class="o"&gt;(&lt;/span&gt;Total Inbound 
Score: 5 – &lt;span class="nv"&gt;SQLI&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5,XSS&lt;span class="o"&gt;=&lt;/span&gt;0,RFI&lt;span class="o"&gt;=&lt;/span&gt;0,LFI&lt;span class="o"&gt;=&lt;/span&gt;0,RCE&lt;span class="o"&gt;=&lt;/span&gt;0,PHPI&lt;span class="o"&gt;=&lt;/span&gt;0,HTTP&lt;span class="o"&gt;=&lt;/span&gt;0,SESS&lt;span class="o"&gt;=&lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt;: 
individual paranoia level scores: 5, 0, 0, 0“] &lt;span class="o"&gt;[&lt;/span&gt;tag “event-correlation”] 
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;hostname&lt;/span&gt; “localhost”] &lt;span class="o"&gt;[&lt;/span&gt;uri “/login”] &lt;span class="o"&gt;[&lt;/span&gt;unique_id “XXYB-
5tiXQGQt80jpPMnxgAAAJc”], referer: http://localhost:80/login

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the logfiles are a bit hard to read, I will shorten the output of the next vulnerabilities and use Christian Folini’s alias melidmsg. For further information about his aliases, see &lt;a href="https://www.netnea.com/cms/apache-tutorials/" rel="noopener noreferrer"&gt;Christian’s tutorials&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Angular Constructor Injection
&lt;/h3&gt;

&lt;p&gt;Under special circumstances an Angular template injection is possible. This can happen when client side security checks are disabled (that must not be disabled). For further reading, please see &lt;a href="http://blog.portswigger.net/2016/01/xss-without-html-client-side-template.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So let’s see what Pixi does with this command in the login mask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;alert(1)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)()}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fmpk7x85w4z25db8lws61.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fmpk7x85w4z25db8lws61.png" alt="Angular Template Injection"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fwcb3sz3khc5ue93uhan2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fwcb3sz3khc5ue93uhan2.png" alt="Angular Template Injection: Popup"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ooops, we showed a popup window through XSS!&lt;/p&gt;

&lt;p&gt;So let’s see what the Core Rule Set does with this command:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnyp63xheax6aehqnph10.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnyp63xheax6aehqnph10.png" alt="Angular Template Injection: Popup at PL1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The CRS at Paranoia Level 1 does not detect this Angular injection. Why could this happen?&lt;/p&gt;

&lt;p&gt;That’s possible because the CRS is not meant to protect us from every exploit at Paranoia Level 1.&lt;/p&gt;

&lt;p&gt;There are 4 Paranoia Levels available. If our web application is critical and if we want to assure that our web application is well protected we should consider raising the Paranoia Level. This will enable additional rules giving you a rule set with better coverage. But unfortunately also with more false positives.&lt;/p&gt;

&lt;p&gt;Let’s do this and see what the CRS does at PL2:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fbq042gotjumoj9dpi6w6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fbq042gotjumoj9dpi6w6.png" alt="Angular Template Injection: CRS blocks at PL2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The request is now blocked and the log confirms this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;my-alert-error.log | melidmsg
941380 AngularJS client side template injection detected
942370 Detects classic SQL injection probings 2/3
942430 Restricted SQL Character Anomaly Detection &lt;span class="o"&gt;(&lt;/span&gt;args&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="c"&gt;# of special characters exceeded (12)&lt;/span&gt;
949110 Inbound Anomaly Score Exceeded &lt;span class="o"&gt;(&lt;/span&gt;Total Score: 13&lt;span class="o"&gt;)&lt;/span&gt;
980130 Inbound Anomaly Score Exceeded &lt;span class="o"&gt;(&lt;/span&gt;Total Inbound Score: 13 - &lt;span class="nv"&gt;SQLI&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8,XSS&lt;span class="o"&gt;=&lt;/span&gt;5,RFI&lt;span class="o"&gt;=&lt;/span&gt;0,LFI&lt;span class="o"&gt;=&lt;/span&gt;0,RCE&lt;span class="o"&gt;=&lt;/span&gt;0,PHPI&lt;span class="o"&gt;=&lt;/span&gt;0,HTTP&lt;span class="o"&gt;=&lt;/span&gt;0,SESS&lt;span class="o"&gt;=&lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt;: individual paranoia level scores: 0, 13, 0, 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An Angular template injection was discovered. That’s correct! By the way the rule 941380 is one of many new rules in CRS 3.2.&lt;/p&gt;

&lt;p&gt;And also two SQLi rules triggered. That’s possible, because the SQL Injection is the most covered vulnerability and the detection is very strong there. Therefore very often SQLi rules, especially at higher PLs, also trigger. But that’s not a problem as far as they protect us and as far as they do not generate False Positives. If they protect us, they are very welcome.&lt;/p&gt;

&lt;h3&gt;
  
  
  XSS on search field
&lt;/h3&gt;

&lt;p&gt;The next vulnerability is a XSS weakness in the search field.&lt;/p&gt;

&lt;p&gt;The following string entered in the search field shows a popup, that demonstrates us the XSS weakness:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;xss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fbbphke9xpywklgz01slu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fbbphke9xpywklgz01slu.png" alt="Cross Site Scripting in Search Field"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Core Rule Set at PL1 blocks this XSS test request:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fo24n7iym5bn1dpo5p2js.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fo24n7iym5bn1dpo5p2js.png" alt="Cross Site Scripting: CRS blocks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the logs we see that three XSS rules were triggered by this request and we got a Inbound Anomaly Score of 15 at PL1!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;my-alert-error.log | melidmsg
941100 XSS Attack Detected via libinjection
941110 XSS Filter - Category 1: Script Tag Vector
941160 NoScript XSS InjectionChecker: HTML Injection
949110 Inbound Anomaly Score Exceeded &lt;span class="o"&gt;(&lt;/span&gt;Total Score: 15&lt;span class="o"&gt;)&lt;/span&gt;
980130 Inbound Anomaly Score Exceeded &lt;span class="o"&gt;(&lt;/span&gt;Total Inbound Score: 15 - &lt;span class="nv"&gt;SQLI&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0,XSS&lt;span class="o"&gt;=&lt;/span&gt;15,RFI&lt;span class="o"&gt;=&lt;/span&gt;0,LFI&lt;span class="o"&gt;=&lt;/span&gt;0,RCE&lt;span class="o"&gt;=&lt;/span&gt;0,PHPI&lt;span class="o"&gt;=&lt;/span&gt;0,HTTP&lt;span class="o"&gt;=&lt;/span&gt;0,SESS&lt;span class="o"&gt;=&lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt;: individual paranoia level scores: 15, 0, 0, 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verbose Errors
&lt;/h3&gt;

&lt;p&gt;When not logged in as an admin of the application, the access to the admin path throws an HTTP 500 error. This error reveals some information about the application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fbscxrate5h8xhpwzl7kd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fbscxrate5h8xhpwzl7kd.png" alt="Verbose Errors in Admin Page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When accessing the secret page, the error even shows a hint to a server.conf file:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5pidlst5hndqthn9a27o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5pidlst5hndqthn9a27o.png" alt="Verbose Errors in Secret Page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When running at PL1 this response error remains undetected but not at PL2:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fmcw10bui7rksiuv5il7r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fmcw10bui7rksiuv5il7r.png" alt="Verbose Errors in Admin Page are blocked at PL2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0g2q1teidhb1kcdxi4ed.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0g2q1teidhb1kcdxi4ed.png" alt="Verbose Errors in Secret Page are blocked at PL2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the logs we see that the response code 500 was blocked at PL2 due to potential information leakage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;my-alert-error.log | melidmsg
950100 The Application Returned a 500-Level Status Code
959100 Outbound Anomaly Score Exceeded &lt;span class="o"&gt;(&lt;/span&gt;Total Score: 4&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"]
980140 Outbound Anomaly Score Exceeded (score 4): individual paranoia level scores: 0, 4, 0, 0
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Insecure Direct Object Reference
&lt;/h3&gt;

&lt;p&gt;In the error message above we saw that there must be a server.conf. So let’s access the file and see what it reveals to us:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fiw6v1etqwpv2r0fnhm8s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fiw6v1etqwpv2r0fnhm8s.png" alt="server.conf reveals session_secret"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The server.conf even shows a session_secret. That is very awful!&lt;/p&gt;

&lt;p&gt;Does the Core Rule Set protect us?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Feaajmhkb9ctmhcy9hkhx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Feaajmhkb9ctmhcy9hkhx.png" alt="server.conf is blocked at PL1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The log confirms that a request to a .conf file is potentially dangerous:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;my-alert-error.log | melidmsg
920440 URL file extension is restricted by policy
949110 Inbound Anomaly Score Exceeded &lt;span class="o"&gt;(&lt;/span&gt;Total Score: 5&lt;span class="o"&gt;)&lt;/span&gt;
980130 Total Inbound Score: 5 - &lt;span class="nv"&gt;SQLI&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0,XSS&lt;span class="o"&gt;=&lt;/span&gt;0,RFI&lt;span class="o"&gt;=&lt;/span&gt;0,LFI&lt;span class="o"&gt;=&lt;/span&gt;0,RCE&lt;span class="o"&gt;=&lt;/span&gt;0,PHPI&lt;span class="o"&gt;=&lt;/span&gt;0,HTTP&lt;span class="o"&gt;=&lt;/span&gt;0,SESS&lt;span class="o"&gt;=&lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt;: individual paranoia level scores: 5, 0, 0, 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The triggered rule 920440 at PL1 blocks potentially dangerous file extensions. The extension .conf is part of this list. Of course, these file extensions can be configured. But the standard installation protects us. With the CRS in front of Pixi this session_secret will never be exposed!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The CRS standard installation at PL1 already protects us from a bunch of vulnerabilites. But to be protected from more vulnerabilities and exploits a higher Paranoia Level is highly recommended.&lt;/p&gt;

&lt;p&gt;In the examples above the highest Paranoia Level I had to configure was PL2 and there are even PL 3 and PL4!&lt;/p&gt;

&lt;p&gt;This is a crosspost from &lt;a href="https://coreruleset.org" rel="noopener noreferrer"&gt;https://coreruleset.org&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>waf</category>
      <category>pixi</category>
      <category>crs</category>
      <category>modsecurity</category>
    </item>
    <item>
      <title>2FAnotifier and multi-factor authentication</title>
      <dc:creator>Tanya Janca</dc:creator>
      <pubDate>Tue, 27 Aug 2019 20:23:12 +0000</pubDate>
      <link>https://dev.to/devslop/2fanotifier-and-multi-factor-authentication-1i6d</link>
      <guid>https://dev.to/devslop/2fanotifier-and-multi-factor-authentication-1i6d</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/shehackspurple"&gt;Tanya Janca&lt;/a&gt;, one of the &lt;a href="https://twitter.com/Owasp_DevSlop"&gt;OWASP DevSlop Project Leaders&lt;/a&gt;, is currently obsessed with convincing people to enable multi-factor authentication on all of their important accounts. To this end, she created a video that shows users how to install a browser plugin called &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/2fa-notifier/"&gt;"2FAnotifier"&lt;/a&gt;, which will alert users if a site offers the option to use multi-factors of authentication on your user account.  &lt;/p&gt;

&lt;p&gt;If you want to know more about what MFA is and why it's important, please read Tanya's post here; &lt;a href="https://aka.ms/MFAally"&gt;Multi-Factor Authentication (MFA)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ySfOpGi51Mk"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For this and more, check out my book, &lt;a href="https://aliceandboblearn.com/"&gt;Alice and Bob Learn Application Security&lt;/a&gt; and my online training academy, &lt;a href="https://academy.wehackpurple.com"&gt;We Hack Purple&lt;/a&gt;!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>authentication</category>
    </item>
    <item>
      <title>Global AppSec 2019 - Tel Aviv</title>
      <dc:creator>Tanya Janca</dc:creator>
      <pubDate>Mon, 03 Jun 2019 18:41:15 +0000</pubDate>
      <link>https://dev.to/devslop/global-appsec-2019-tel-aviv-4gmj</link>
      <guid>https://dev.to/devslop/global-appsec-2019-tel-aviv-4gmj</guid>
      <description>&lt;p&gt;&lt;a href="https://twitter.com/nanzgtweets"&gt;Nancy Gariché&lt;/a&gt; and I (&lt;a href="https://dev.to/shehackspurple"&gt;Tanya Janca&lt;/a&gt;),  traveled to Tel Aviv, Israel to speak at &lt;a href="https://globalappsectelaviv2019.sched.com/"&gt;Global AppSec&lt;/a&gt;, the international &lt;a href="https://owasp.org/"&gt;OWASP&lt;/a&gt; conference, which serves as the foundation's main income generating event.  The conference concentrates on the topic of application security, which includes DevSecOps, white hat hacking, code review, and so much more.  It was prefaced with formal training.&lt;/p&gt;

&lt;p&gt;It is no secret that OWASP's AppSec conferences are my favorite, as OWASP is my main professional community that I participate in, so you are not likely to be surprised when I write about how great it was...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fsY_rfz4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/0qio1x46tnm36wz1oatk.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fsY_rfz4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/0qio1x46tnm36wz1oatk.jpeg" alt="Tanya Janca and Nancy Gariché on stage at Global AppSec" title="Tanya Janca and Nancy Gariché on stage at Global AppSec"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I took the training course &lt;a href="https://globalappsectelaviv2019.sched.com/event/MCmH/an-introduction-to-hacking-blockchain-applications-and-smart-contracts"&gt;"An Introduction to Hacking Blockchain Applications and Smart Contracts"&lt;/a&gt;, with trainer &lt;a href="https://twitter.com/MickAyzenberg"&gt;Mick Ayzenberg&lt;/a&gt;.  I absolutely loved the training, even though I arrived a bit late Mick made sure I was caught up over lunch on the first day.  We created our own crypto currency, learned very basic solidity, learned common security vulnerabilities in blockchain (including reentrancy), participated in a custom smart contract CTF, and so much more.  Mick is a fantastic teacher; patient, knowledgeable, fun and very open to feedback so that he can improve.  No wonder he's so good!&lt;/p&gt;

&lt;p&gt;During the training, and throughout the entire conference, we were provided with tasty and high-quality Israeli food: humus, breads, dates, chocolates, fruit, vegetables, cheeses, grilled meats, etc.  I'm a huge fan of Israeli food, and I was not disappointed; I've rarely been so well fed at a conference. A+ on food!&lt;/p&gt;

&lt;p&gt;Unfortunately I really wasn't feeling well for much of the conference: head colds don't care that I'm at work and doing important stuff, which resulted in me missing the entire first day of the conference as well as several social opportunities.  :-/&lt;/p&gt;

&lt;p&gt;That said; I still got to see a bunch of kick-ass talks.&lt;/p&gt;

&lt;p&gt;Day 2 started with a &lt;a href="https://globalappsectelaviv2019.sched.com/event/OB1X/the-evolving-community-of-appsec"&gt;keynote&lt;/a&gt; by &lt;a href="https://twitter.com/astha_singhal"&gt;Astha Singhal&lt;/a&gt;, the head of the AppSec team at Netflix.  I happen to think Astha's a pretty awesome human, and you might want to know she's hiring for some cool positions; &lt;a href="https://jobs.netflix.com/jobs/869263"&gt;Security Partner&lt;/a&gt; and &lt;a href="https://jobs.netflix.com/jobs/869545"&gt;Security Software Engineer, Application Security&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I skipped the talk "How Online Dating Made Me Better At Threat Modeling" by &lt;a href="https://twitter.com/isaiahsarju"&gt;Isaiah Sarju&lt;/a&gt;, but only because I had already seen it at B-Sides Vancouver.  It was a great talk, if you have a chance to see a video of it I suggest checking it out.  Also, even though Isaiah is a new speaker, he's great on stage; funny, thoughtful and very well spoken.  I can't wait to see what his next talk will be about.&lt;/p&gt;

&lt;p&gt;The talk I saw instead was "&lt;a href="https://globalappsectelaviv2019.sched.com/event/NEXd/defending-cloud-infrastructures-with-cloud-security-suite"&gt;Defending Cloud Infrastructures with Cloud Security Suite&lt;/a&gt;" by &lt;a href="https://twitter.com/jayeshsch"&gt;Jayesh Chauhan&lt;/a&gt;; it was really good.  His tool that he created for auditing all of the 3 major cloud providers is amazing, I can hardly believe it's free!  I definitely plan to try it out.  Also, he happens to be in charge of the &lt;a href="https://cloud-village.org/"&gt;DefCon Cloud Village&lt;/a&gt;, and the CFP is still open in case you were wondering. (Of course I applied!)&lt;/p&gt;

&lt;p&gt;Right before my talk with Nancy was "&lt;a href="https://globalappsectelaviv2019.sched.com/event/NsS9/can-we-automate-security"&gt;Can We Automate Security?&lt;/a&gt;" by &lt;a href="https://twitter.com/DivineOps"&gt;Sasha Rosenbaum&lt;/a&gt;. Sasha &lt;strong&gt;just&lt;/strong&gt; started at Microsoft a month ago, and already she's on stage being awesome.  I was disappointed I didn't get a chance to see her entire talk since Nancy and I were last-minute prepping, but since I work with her now I'm pretty sure she will share her slides with me that detail the inner workings of DevSecOps at Microsoft.  :-D&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GFCerYSj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/8j13jfsagziwwtjdtfam.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GFCerYSj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/8j13jfsagziwwtjdtfam.jpeg" alt="Tanya Janca and Nancy Gariché on stage at Global AppSec" title="Tanya Janca and Nancy Gariché on stage at Global AppSec"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then came my big talk with Nancy, "&lt;a href="https://globalappsectelaviv2019.sched.com/event/NF62/devsecops-with-owasp-devslop"&gt;DevSecOps with OWASP DevSlop&lt;/a&gt;".  We demoed the "Patty" module of our OWASP project &lt;a href="https://devslop.co"&gt;DevSlop&lt;/a&gt;, an &lt;a href="https://azure.microsoft.com/services/devops/pipelines/?WT.mc_id=devto-blog-tajanca"&gt;Azure Pipelines&lt;/a&gt; DevSecOps pipeline, which included; SonarCloud, White Source Bolt, &lt;a href="https://azure.microsoft.com/en-us/services/key-vault/?WT.mc_id=devto-blog-tajanca"&gt;Azure Key Vault&lt;/a&gt;, &lt;a href="https://secdevtools.azurewebsites.net/helpcredscan.html?WT.mc_id=devto-blog-tajanca"&gt;Cred Scan&lt;/a&gt;, OWASP Zap, and more.  Most of our talk was demo after demo, but we also talked about about our project, OWASP, and what DevSecOps actually is.  If I do say so myself: we were great!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Phz0iV7p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/v6az2hdzvgs32s5sugbz.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Phz0iV7p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/v6az2hdzvgs32s5sugbz.jpeg" alt="Tanya Janca and Nancy Gariché on stage at Global AppSec" title="Tanya Janca and Nancy Gariché on stage at Global AppSec"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The last talk I got to see was "&lt;a href="https://globalappsectelaviv2019.sched.com/event/NsKt/owasp-serverless-top-10"&gt;OWASP Serverless Top 10&lt;/a&gt;" by &lt;a href="https://twitter.com/_nu11p0inter"&gt;Tal Melamed&lt;/a&gt;.  Tal is the leader of the &lt;a href="https://www.owasp.org/index.php/OWASP_Serverless_Top_10_Project"&gt;OWASP Top Ten Serverless project&lt;/a&gt; and also someone who I have waited a long time to meet in person; it was worth the wait. We've been submitting talks together, trying to spread the word of serverless security together. If you haven't checked out his project, maybe you should?&lt;/p&gt;

&lt;p&gt;At this point I went back to my hotel room and fell asleep for the next 18+ hours.  Head colds have no mercy!&lt;/p&gt;

&lt;p&gt;I also had the chance to connect with several people who I rarely get to see in person, and what follows are various images from the trip that were already shared publicly on Twitter, so I hope it's okay that I am sharing them here as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4GITpKtT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ll6lyl04sismnnyb6ywx.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4GITpKtT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ll6lyl04sismnnyb6ywx.jpeg" alt="It has become a tradition for Anne Gauthier, and I to take photos with other female OWASP Leaders at each global event, I think this might be our 5th event together! " title="It has become a tradition for Anne Gauthier, and I to take photos with other female OWASP Leaders at each global event, I think this might be our 5th event together! "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It has become a tradition for &lt;a href="https://twitter.com/Anne__Gauthier"&gt;Anne Gauthier&lt;/a&gt;, leader of &lt;a href="https://www.owasp.org/index.php/Montr%C3%A9al"&gt;OWASP Montréal&lt;/a&gt;, and I to take photos with other female OWASP Leaders at each global event, I think this might be our 5th event together! Right to left: Nancy Gariché, Vandana Verma, Tanya Janca and Anne Gauthier.  It should be noted that Anne Gauthier is leading a campaign to &lt;a href="https://twitter.com/owaspmontreal/status/1133819381786529792"&gt;host #GlobalAppSec in Montréal, Canada in 2020&lt;/a&gt;.  You can help her and the Montréal chapter by showing your support on social media, messaging OWASP directly or retweeting and/or liking &lt;a href="https://twitter.com/owaspmontreal/status/1133819381786529792"&gt;this tweet&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OINeQZzI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2xs5clhkf2qj5gyh7eu7.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OINeQZzI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2xs5clhkf2qj5gyh7eu7.jpeg" alt="Nancy and I with [Shira Shamban](https://twitter.com/ShambanIT), the chair of the speaker selection committee." title="Nancy and I with [Shira Shamban](https://twitter.com/ShambanIT), the chair of the speaker selection committee."&gt;&lt;/a&gt;&lt;br&gt;
Nancy and I with &lt;a href="https://twitter.com/ShambanIT"&gt;Shira Shamban&lt;/a&gt;, the chair of the speaker selection committee.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3m2rnAW_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/5h1zzvbp26il9fj2fjjx.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3m2rnAW_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/5h1zzvbp26il9fj2fjjx.jpeg" alt="[Vandana Verma](https://twitter.com/InfosecVandana) and I.  She travelled all the way from India!  It was so wonderful to see her in person again, it had been too long." title="[Vandana Verma](https://twitter.com/InfosecVandana) and I.  She travelled all the way from India!  It was so wonderful to see her in person again, it had been too long."&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/InfosecVandana"&gt;Vandana Verma&lt;/a&gt; and I.  She travelled all the way from India!  It was so wonderful to see her in person again, it had been too long. Vandana taught a penetration testing course which was offered for free to women.  She's also the Bangalore OWASP Chapter Leader, active member of WIA (Women in AppSec), InfoSec Kids and InfoSec Girls leader, and WoSEC Bangalore Chapter leader.  What can't this woman do?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9JpyGvRg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ctna9vl3rmrd81astatq.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9JpyGvRg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ctna9vl3rmrd81astatq.jpeg" alt="Nancy Gariché, Dominique Righetto, and I" title="Nancy Gariché, Dominique Righetto, and I"&gt;&lt;/a&gt;&lt;br&gt;
Nancy Gariché, &lt;a href="https://twitter.com/righettod"&gt;Dominique Righetto&lt;/a&gt;, and I.  Dominique is one of the project leaders of the &lt;a href="https://www.owasp.org/index.php/OWASP_Cheat_Sheet_Series"&gt;OWASP Cheat Sheets Project&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pne9-ZSU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/h9b0fgsgr9gu2p8muct0.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pne9-ZSU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/h9b0fgsgr9gu2p8muct0.jpeg" alt="Final Photo: Astha Singhal, Anne Gauthier, Vandana Verma, Nancy Gariché and Tanya Janca" title="Final Photo: Astha Singhal, Anne Gauthier, Vandana Verma, Nancy Gariché and Tanya Janca"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Final Photo: Astha Singhal, Anne Gauthier, Vandana Verma, Nancy Gariché and Tanya Janca&lt;/p&gt;

&lt;p&gt;Thank you for reading, and BIG THANKS to the huge number of volunteers who worked for months to make this wonderful event possible.&lt;/p&gt;

</description>
      <category>owasp</category>
      <category>conference</category>
      <category>security</category>
      <category>speaking</category>
    </item>
    <item>
      <title>Security Headers for ASP.Net and .Net CORE</title>
      <dc:creator>Tanya Janca</dc:creator>
      <pubDate>Sat, 23 Mar 2019 23:51:08 +0000</pubDate>
      <link>https://dev.to/devslop/security-headers-for-aspnet-and-net-core-b36</link>
      <guid>https://dev.to/devslop/security-headers-for-aspnet-and-net-core-b36</guid>
      <description>&lt;p&gt;For those who do not follow &lt;a href="https://twitter.com/shehackspurple" rel="noopener noreferrer"&gt;myself&lt;/a&gt; or &lt;a href="https://twitter.com/bufrasch" rel="noopener noreferrer"&gt;Franziska Bühler&lt;/a&gt;, we have an open source project together called &lt;a href="https://devslop.co" rel="noopener noreferrer"&gt;OWASP DevSlop&lt;/a&gt; in which we explore DevSecOps through writing vulnerable apps, creating pipelines, publishing proof of concepts, and documenting what we’ve learned on our &lt;a href="https://aka/ms/DevSlopShow" rel="noopener noreferrer"&gt;YouTube Channel&lt;/a&gt; and our blogs. In this article we will explore adding security headers to our proof of concept website, DevSlop.co. This blog post is closely related to Franziska’s post &lt;a href="https://medium.com/@franbuehler/owasp-devslops-journey-to-tls-and-security-headers-aa892f1ac851" rel="noopener noreferrer"&gt;OWASP DevSlop’s journey to TLS and Security Headers&lt;/a&gt;. If you like this one, read hers too. :)&lt;/p&gt;

&lt;p&gt;Franziska Bühler and I installed several security headers during the OWASP DevSlop Show in Episode &lt;a href="https://www.youtube.com/watch?v=-il28nDFgBg&amp;amp;t=3s" rel="noopener noreferrer"&gt;2&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=6-mqK3jr6Jg&amp;amp;t=3s&amp;amp;list=PLI9RITMnVbyg-OEn2vbsDnzWi9jGd6_5u&amp;amp;index=5" rel="noopener noreferrer"&gt;2.1&lt;/a&gt; and &lt;a href="https://www.youtube.com/watch?v=uJeUodTRCEs" rel="noopener noreferrer"&gt;2.2&lt;/a&gt;. Unfortunately we found out that .Net Core apps don’t have a web.config, so the next time we published it wiped out the beautiful security headers we had added. Although that is not good news, it was another chance to learn, and it gave me great excuse to finally write my &lt;strong&gt;Security Headers&lt;/strong&gt; blog post that I have been promising. Here we go!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fhy9wb6dmqphd0xz4ys6o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fhy9wb6dmqphd0xz4ys6o.png" alt="Our web.config looked so…. Empty."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just now, I added back the headers but I added them to the startup.cs file in my .Net Core app, which you can &lt;a href="https://www.youtube.com/watch?v=uJeUodTRCEs" rel="noopener noreferrer"&gt;watch here&lt;/a&gt;. Special thanks to &lt;a href="https://damienbod.com/2018/02/08/adding-http-headers-to-improve-security-in-an-asp-net-mvc-core-application/" rel="noopener noreferrer"&gt;Damien Bod&lt;/a&gt; for help with the &lt;a href="https://docs.microsoft.com/en-ca/dotnet/core/?WT.mc_id=SheHacksPurple-Blog-tajanca" rel="noopener noreferrer"&gt;.Net Core twist&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want in-depth details about what we did on the show and what each security header means, you should &lt;a href="https://medium.com/@franbuehler/owasp-devslops-journey-to-tls-and-security-headers-aa892f1ac851" rel="noopener noreferrer"&gt;read Franziska’s blog post&lt;/a&gt;. She explains every step, and if you are trying to add security headers for the first time to your web.config (&lt;a href="https://docs.microsoft.com/en-ca/dotnet/standard/?WT.mc_id=SheHacksPurple-Blog-tajanca" rel="noopener noreferrer"&gt;ASP.Net&lt;/a&gt;, not &lt;a href="https://docs.microsoft.com/en-ca/dotnet/core/?WT.mc_id=SheHacksPurple-Blog-tajanca" rel="noopener noreferrer"&gt;.Net CORE&lt;/a&gt;), you should definitely read it.&lt;/p&gt;

&lt;p&gt;The new code for ASP.Net in your web.config looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;**&amp;lt;! — Start Security Headers -&amp;gt;**
&amp;lt;httpProtocol&amp;gt;
 &amp;lt;customHeaders&amp;gt;
 &amp;lt;add name=”X-XSS-Protection” value=”1; mode=block”/&amp;gt;
 &amp;lt;add name=”Content-Security-Policy” value=”default-src ‘self’”/&amp;gt;
 &amp;lt;add name=”X-frame-options” value=”SAMEORIGIN”/&amp;gt;
 &amp;lt;add name=”X-Content-Type-Options” value=”nosniff”/&amp;gt;
 &amp;lt;add name=”Referrer-Policy” value=”strict-origin-when-cross-origin”/&amp;gt;
 &amp;lt;remove name=”X-Powered-By”/&amp;gt;
 &amp;lt;/customHeaders&amp;gt;
 &amp;lt;/httpProtocol&amp;gt;
**&amp;lt;! — End Security Headers -&amp;gt;**
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fofvzgoxzoqyxclab4oqi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fofvzgoxzoqyxclab4oqi.png" alt="Our new-and-improved Web.Config!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the new code for my startup.cs (.Net CORE), looks like this (Thank you Damien Bod):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;//Security headers make me happy&lt;/strong&gt;&lt;br&gt;
app.UseHsts(hsts =&amp;gt; hsts.MaxAge(365).IncludeSubdomains());&lt;br&gt;
app.UseXContentTypeOptions();&lt;br&gt;
app.UseReferrerPolicy(opts =&amp;gt; opts.NoReferrer());&lt;br&gt;
app.UseXXssProtection(options =&amp;gt; options.EnabledWithBlockMode());&lt;br&gt;
app.UseXfo(options =&amp;gt; options.Deny());&lt;br&gt;
app.UseCsp(opts =&amp;gt; opts&lt;br&gt;
.BlockAllMixedContent()&lt;br&gt;
.StyleSources(s =&amp;gt; s.Self())&lt;br&gt;
.StyleSources(s =&amp;gt; s.UnsafeInline())&lt;br&gt;
.FontSources(s =&amp;gt; s.Self())&lt;br&gt;
.FormActions(s =&amp;gt; s.Self())&lt;br&gt;
.FrameAncestors(s =&amp;gt; s.Self())&lt;br&gt;
.ImageSources(s =&amp;gt; s.Self())&lt;br&gt;
.ScriptSources(s =&amp;gt; s.Self())&lt;br&gt;
);&lt;br&gt;
 &lt;strong&gt;//End Security Headers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fzsbe9pmu9bb2iwqioskd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fzsbe9pmu9bb2iwqioskd.png" alt="Behold, our beautiful security headers!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In future episodes we will also add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Secure settings for our cookies&lt;/li&gt;
&lt;li&gt;X-Permitted-Cross-Domain-Policies: none&lt;/li&gt;
&lt;li&gt;Expect-CT: (not currently supported by our provider)&lt;/li&gt;
&lt;li&gt;Feature-Policy: camera ‘none’; microphone ‘none’; speaker ‘self’; vibrate ‘none’; geolocation ‘none’; accelerometer ‘none’; ambient-light-sensor ‘none’; autoplay ‘none’; encrypted-media ‘none’; gyroscope ‘none’; magnetometer ‘none’; midi ‘none’; payment ‘none’; picture-in-picture ‘none’; usb ‘none’; vr ‘none’; fullscreen *;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more information on all of these security headers, I strongly suggest you read the &lt;a href="https://www.owasp.org/index.php/OWASP_Secure_Headers_Project#xpcdp" rel="noopener noreferrer"&gt;OWASP Security Headers Guidance&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We now have good marks from all of the important places, &lt;a href="https://securityheaders.com" rel="noopener noreferrer"&gt;https://securityheaders.com&lt;/a&gt;, &lt;a href="https://www.ssllabs.com" rel="noopener noreferrer"&gt;https://www.ssllabs.com&lt;/a&gt; and &lt;a href="http://hardenize.com" rel="noopener noreferrer"&gt;http://hardenize.com)&lt;/a&gt;, but hope to improve our score even further.&lt;/p&gt;

&lt;p&gt;For more information, watch our show on &lt;a href="https://aka.ms/DevSlopShow" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;!&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3g3boahgnpvon4qlj916.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3g3boahgnpvon4qlj916.png" alt="SSLLabs for the win!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  Please use every security header that is available and applicable to you.
&lt;/h5&gt;

</description>
      <category>securityheaders</category>
      <category>dotnet</category>
      <category>infosec</category>
      <category>appsec</category>
    </item>
  </channel>
</rss>
