Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
azconger authored Mar 4, 2024
2 parents 3879154 + 495edb8 commit b55767a
Show file tree
Hide file tree
Showing 52 changed files with 4,949 additions and 30 deletions.
61 changes: 61 additions & 0 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: "CodeQL"

on:
push:
branches: [ "main" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "main" ]
schedule:
- cron: '28 12 * * 2'

jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write

strategy:
fail-fast: false
matrix:
language: [ 'java' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support

steps:
- name: Checkout repository
uses: actions/checkout@v3

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.

# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality


# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2

# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun

# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.

# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
56 changes: 30 additions & 26 deletions .github/workflows/hawkscan.yml
Original file line number Diff line number Diff line change
@@ -1,32 +1,36 @@
name: HawkScan
on:
repository_dispatch:
types: [integration-initial-test]
push:
branches:
- main
pull_request:
branches:
- main
jobs:
hawkscan:
name: HawkScan
runs-on: ubuntu-latest
build-and-scan:
name: Build and Scan
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Create ${{ github.event.client_payload.repoName }} app directory
run: mkdir -p common/build/integrationTests/hawkscan-action/apps/${{ github.event.client_payload.repoName }}
- name: Navigate to ${{ github.event.client_payload.repoName }} app directory
run: cd common/build/integrationTests/hawkscan-action/apps/${{ github.event.client_payload.repoName }}
- name: Checkout vulny repo
run: git clone https://github.com/${{ github.event.client_payload.repoOrg }}/${{ github.event.client_payload.repoName }}.git
- name: Run ${{ github.event.client_payload.repoName }}
run: docker-compose up -d
- name: Navigate to repo root directory
run: cd /home/runner/work/${{ github.event.client_payload.repoName }}/${{ github.event.client_payload.repoName }}
- name: Run HawkScan
id: run-hawkscan
uses: stackhawk/hawkscan-action@main
- name: Check out code
uses: actions/checkout@v2

- name: Setup Java and Gradle cache
uses: actions/setup-java@v2
with:
distribution: 'adopt' # See 'Supported distributions' for available options
java-version: '11'
cache: gradle

- name: Build the app
run: ./gradlew build

- name: Test the app
run: ./gradlew test

- name: Run the app
run: ./gradlew bootRun &

- name: Test with HawkScan
uses: stackhawk/[email protected]
with:
apiKey: ${{ secrets.HAWK_API_KEY }}
configurationFiles: ${{ github.event.client_payload.configFile }}
sourceURL: ${{ github.event.client_payload.hawkscanSourceUrl }}
version: ${{ github.event.client_payload.hawkscanVersion }}
verbose: ${{ github.event.client_payload.verbose }}
env:
# APPLICATION_ID: ${{ github.event.client_payload.appId }}
APP_ID: ${{ github.event.client_payload.appId }}
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ bin/
.env
.DS_Store
*.iml
=======
tmp
.vscode

3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "stackhawk-configs"]
path = stackhawk-configs
url = [email protected]:zconger/stackhawk-configs.git
1 change: 1 addition & 0 deletions integrations/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
53 changes: 53 additions & 0 deletions integrations/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Testing Integrations

These are demonstrations of industry recognized developer tools used to automate E2E browser testing. The E2E tests are all meant to be run against [**javaspringvulny**](https://github.com/kaakaww/javaspringvulny), an intentionally vulnerable web application, running on `https://localhost:9000`

See how these E2E testing tools can be combined with HawkScan with [Custom Scan Discovery](https://docs.stackhawk.com/hawkscan/scan-discovery/custom.html).

* [**Cypress**](https://github.com/stackhawk/stackhawk-custom-image/tree/main/integrations/cypress)
* [**Playwright**](https://github.com/stackhawk/stackhawk-custom-image/tree/main/integrations/playwright)
* [**Selenium**](https://github.com/stackhawk/stackhawk-custom-image/tree/main/integrations/selenium)

## Building Custom Docker Images

You can run the following commands from this directory to build custom docker images with hawkscan and these tests

## Authentication

To perform E2E testing on an application, these testing tools will require scripted authentication into the application. HawkScan provides [common patterns for Authentication](https://docs.stackhawk.com/hawkscan/authenticated-scanning/), and **javaspringvulny** demonstrates multiple forms of authentication.

#### form authentication

Demonstrated on the `/login` page in JavaSpringVulny.

A common way to authenticate to a web application is by `POST`ing a username and password which can be verified by your server. Upon verification the server returns a cookie or token to the requesting client.

See [Form with Username + Password](https://docs.stackhawk.com/hawkscan/authenticated-scanning/form-based-authentication.html) for more information.

#### jwt token authentication

Demonstrated on the `/jwt-auth` page in JavaSpringVulny.

[Oauth 2.0 connections](https://oauth.net/2/) will require APIKeys and bearer tokens passed into their request headers. This type of authentication scheme is common for modern web APIs.

See [Cookie and Token](https://docs.stackhawk.com/hawkscan/authenticated-scanning/inject-cookies-and-tokens.html) for more information.

#### token authentication

Demonstrated on the `/token-auth` page in JavaSpringVulny.

Some web applications require supplying an authorization token which can be used in conjunction with either a token or a cookie to maintain the session.

See [External Token Authentication](https://docs.stackhawk.com/hawkscan/authenticated-scanning/inject-cookies-and-tokens.html#external-token-authentication--custom-token-authorization) for more information.

#### basic authentication

Demonstrated on the `/basic-auth` page in JavaSpringVulny.

> :warning: The "Basic" authentication scheme sends credentials encoded but not encrypted. This authentication scheme is insecure unless the exchange is over a secure connection (HTTPS/TLS). It is not recommended for production web APIs.
#### multi-auth form authentication

Demonstrated on the `/login-form-multi` page in JavaSpringVulny.

This is the same as the form authentication with some extra steps, including a toggle to remember the user's session.
35 changes: 35 additions & 0 deletions integrations/cypress-stackhawk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
app:
applicationId: ${APP_ID}
env: ${APP_ENV:cypress}
host: ${APP_HOST:https://localhost:9000}
excludePaths:
- "/logout"
antiCsrfParam: "_csrf"
authentication:
loggedInIndicator: "\\QSign Out\\E"
loggedOutIndicator: ".*Location:.*/login.*"
usernamePassword:
type: FORM
loginPath: /login
loginPagePath: /login
usernameField: username
passwordField: password
scanUsername: "user"
scanPassword: "password"
cookieAuthorization:
cookieNames:
- "JSESSIONID"
testPath:
path: /search
success: "HTTP.*200.*"
hawk:
spider:
maxDurationMinutes: 5
base: false
custom:
command: npx cypress run --config-file cypress/cypress.config.js
logOutputToForeground: true
environment:
NO_PROXY: "<-loopback>" # This is required for Cypress scan discovery!
NO_COLOR: 1

14 changes: 14 additions & 0 deletions integrations/cypress/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM stackhawk/hawkscan

ARG NODE_VERSION="16.x"
ARG CYPRESS_VERSION="10.10.0"

USER root

RUN apt-get update && \
apt-get -y install curl libnss3 libatk-bridge2.0-0 libdrm-dev libxkbcommon-dev libgbm-dev libasound-dev libatspi2.0-0 libxshmfence-dev && \
curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION} | bash && \
apt-get -y install nodejs && \
npm install --global cypress@${CYPRESS_VERSION}

WORKDIR /hawk
47 changes: 47 additions & 0 deletions integrations/cypress/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
## [Cypress](https://www.cypress.io/)

![Cypress](../images/cypress-banner.png)

Cypress is a frontend testing tool that automates the testing of web applications through a browser already installed on the host system. Cypress test specs are executed from a designated browser as asynchronous jquery commands, that control the selection and testing of elements on the page.

At StackHawk, we like Cypress, and we encourage its use for teams looking to establish E2E testing as a function of their engineering quality, or who may be newer to frontend QA or integration testing.

Follow the [Cypress guide for getting started](https://docs.cypress.io/guides/getting-started/installing-cypress).

### Testing with [javaspringvulny](https://github.com/kaakaww/javaspringvulny)

> Ensure javaspringvulny web application is running on `https://localhost:9000`
UI: `npx cypress open --config-file cypress/cypress.config.js`

Headed: `npx cypress run --config-file cypress/cypress.config.js --headed`

Headless: `npx cypress run --config-file cypress/cypress.config.js`

Specific test: `npx cypress run --config-file cypress/cypress.config.js -s path/to/spec.*.ts`

#### Parallel Browser Testing

Cypress supports [parallel browser testing](https://docs.cypress.io/guides/guides/parallelization#Turning-on-parallelization) as a paid feature used alongside the Cypress Dashboard.

### Adding Custom Authentication

Cypress allows for the creation of [custom commands](https://github.com/stackhawk/stackhawk-custom-image/blob/main/integrations/cypress/support/commands.ts). When using Cypress with typescript, custom commands require [type signatures](https://github.com/stackhawk/stackhawk-custom-image/blob/main/integrations/cypress/support/index.d.ts) to be updated.

### Scanning with HawkScan

To use Cypress custom scan discovery, you will need to specify the `NO_PROXY: "<-loopback>"` environment variable to scan localhost traffic. Otherwise Cypress will pick up and use the HTTP_PROXY variable auto-configured by HawkScan.

See the docs for using [Cypress tests with Custom Scan Discovery](https://docs.stackhawk.com/hawkscan/scan-discovery/custom.html).

You can use the sample [cypress-stackhawk.yml](./cypress/cypress-stackhawk.yml) file for an example of scanning a web application with it.

### Cypress Best Practices

* Cypress provides native support for typescript, which makes e2e testing and developing custom cypress commands much easier.

* Run your Cypress tests in the pipeline! Create a custom docker image with Cypress and HawkScan and everything your web application needs to run.

* [Official Docker Images](https://github.com/cypress-io/cypress-docker-images)

* https://docs.cypress.io/guides/references/best-practices
21 changes: 21 additions & 0 deletions integrations/cypress/cypress.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const { defineConfig } = require("cypress");
const dotenv = require('dotenv')
const parsedConfig = dotenv.config().parsed

if (!parsedConfig || !parsedConfig["APP_TEST_HOST"]) {
console.warn("Cannot read .env config or identify scanned host. Cypress wont work.")
}

module.exports = defineConfig({
env: {
"LOGIN_PASSWORD": parsedConfig["LOGIN_PASSWORD"],
"LOGIN_USERNAME": parsedConfig["LOGIN_USERNAME"],
"TOKEN_NAME": parsedConfig["TOKEN_NAME"],
"TOKEN_VALUE": parsedConfig["TOKEN_VALUE"]
},
e2e: {
port: 8999,
experimentalStudio: true,
baseUrl: parsedConfig["APP_TEST_HOST"],
},
});
34 changes: 34 additions & 0 deletions integrations/cypress/e2e/javaspringvulny/login.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
describe('login', () => {

it('can login with formAuth', () => {
cy.formAuth();
cy.get('button:contains("Sign Out")').should('be.visible');
});

it('can login with jwtAuth', () => {
cy.jwtAuth();
cy.attemptSearch("test")
});

it('can login with tokenAuth', () => {
cy.tokenAuth();
cy.attemptSearch("test")
cy.get('#results').should('have.class', 'alert-success');
});

it('can login with basicAuth', () => {
cy.basicAuth();
cy.attemptSearch("test")
cy.get('#results').should('have.class', 'alert-success');
});

it('can login with formMultiAuth', () => {
cy.formMultiAuth();
cy.visit('/search')
cy.get('#search').should('be.visible')
});

afterEach(() => {
cy.signOut();
})
})
6 changes: 6 additions & 0 deletions integrations/cypress/e2e/javaspringvulny/spec.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
describe('empty spec', () => {
it('can visit hidden page', () => {
cy.visit('/hidden/cypress');
cy.title().should('include', 'cypress tests')
})
})
5 changes: 5 additions & 0 deletions integrations/cypress/fixtures/example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "[email protected]",
"body": "Fixtures are a great way to mock data for responses to routes"
}
Loading

0 comments on commit b55767a

Please sign in to comment.