Merge branch 'main' into cors-check

This commit is contained in:
counter 2023-01-28 16:49:32 -08:00
commit 46a861ed9c
35 changed files with 20301 additions and 13372 deletions

58
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View file

@ -0,0 +1,58 @@
---
name: Bug report
about: Create a report to help us improve
title: ""
labels: bug, needs triage
assignees: trufflesecurity/skunkworks
---
### Community Note
* Please vote on this issue by adding a 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to the original issue to help the community and maintainers prioritize this request
* Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
* If you are interested in working on this issue or have submitted a pull request, please leave a comment
### TruffleHog Version
<!--- Please run `trufflehog --version` to show the version. If you are not running the latest version, please upgrade because your issue may have already been fixed. --->
### Trace Output
<!---
Please provide a link to a GitHub Gist containing the complete debug output. Please do NOT paste the debug output in the issue; just paste a link to the Gist.
To obtain the trace output, run trufflehog with the --trace flag.
--->
### Expected Behavior
<!--- What should have happened? --->
### Actual Behavior
<!--- What actually happened? --->
### Steps to Reproduce
<!--- Please list the steps required to reproduce the issue. --->
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
## Environment
* OS: [e.g. iOS]
* Version [e.g. 22]
## Additional Context
<!--- Add any other context about the problem here. --->
### References
<!---
Information about referencing Github Issues: https://help.github.com/articles/basic-writing-and-formatting-syntax/#referencing-issues-and-pull-requests
Are there any other GitHub issues (open or closed) or pull requests that should be linked here? Vendor documentation? For example:
--->
* #0000

View file

@ -0,0 +1,38 @@
---
name: Feature request
about: Suggest an idea for this project
title: ""
labels: enhancement, needs triage
assignees: trufflesecurity/skunkworks
---
### Community Note
* Please vote on this issue by adding a 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to the original issue to help the community and maintainers prioritize this request
* Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
* If you are interested in working on this issue or have submitted a pull request, please leave a comment
### Description
<!--- Please leave a helpful description of the feature request here. --->
## Problem to be Addressed
<!--- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] --->
## Description of the Preferred Solution
<!--- A clear and concise description of what you want to happen. What
information may be required and what would be the preferred way to provide it?
What should the output include? --->
## Additional Context
<!--- Add any other context or screenshots about the feature request here. --->
### References
<!---
Information about referencing Github Issues: https://help.github.com/articles/basic-writing-and-formatting-syntax/#referencing-issues-and-pull-requests
Are there any other GitHub issues (open or closed) or pull requests that should be linked here? Vendor blog posts or documentation? For example:
--->
* #0000

4
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View file

@ -0,0 +1,4 @@
<!--
Please create an issue to collect feedback prior to feature additions. Please also reference that issue in any PRs.
If possible try to keep PRs scoped to one feature, and add tests for new features.
-->

16
.github/dependabot.yml vendored Normal file
View file

@ -0,0 +1,16 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "npm" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
# Check for updates to GitHub Actions every weekday
interval: "weekly"

70
.github/workflows/codeql-analysis.yml vendored Normal file
View file

@ -0,0 +1,70 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ main ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ main ]
schedule:
- cron: '35 11 * * 2'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://git.io/codeql-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.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# 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.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

29
.github/workflows/secrets.yml vendored Normal file
View file

@ -0,0 +1,29 @@
name: Scan for secrets
on:
push:
tags:
- v*
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Install Go
uses: actions/setup-go@v3
with:
go-version: '1.18'
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ github.head_ref }}
- name: TruffleHog
uses: ./
with:
path: ./
base: ${{ github.event.repository.default_branch }}
head: HEAD

3
.gitignore vendored
View file

@ -1,5 +1,5 @@
*.env
node_modules/*
node_modules
*.bak
postgres-db-data/*
dev.sh
@ -12,3 +12,4 @@ ssldata/*
config.env
payload-fire-images/*.gz
payload-fire-images/*.png
deploy.sh

View file

@ -1,10 +1,8 @@
FROM node:12
FROM node:16
# Set up directory for the server
RUN mkdir /app/
WORKDIR /app/
# Copy front-end over
COPY front-end/ /app/front-end/
WORKDIR /app/front-end/
RUN npm install
@ -27,9 +25,7 @@ COPY docker-entrypoint.sh /app/
RUN chmod +x /app/docker-entrypoint.sh
COPY templates /app/templates
# Expose both HTTP and HTTPS ports
EXPOSE 80
EXPOSE 443
USER 1111
# Start the server
ENTRYPOINT ["/app/docker-entrypoint.sh"]

8
api.js
View file

@ -5,7 +5,7 @@ const cors = require('cors');
const path = require('path');
const uuid = require('uuid');
const asyncfs = require('fs').promises;
const sessions = require('@nvanexan/node-client-sessions');
const sessions = require('@truffledustin/node-client-sessions');
const favicon = require('serve-favicon');
const database = require('./database.js');
const Users = database.Users;
@ -24,7 +24,7 @@ const {OAuth2Client} = require('google-auth-library');
const SCREENSHOTS_DIR = path.resolve(process.env.SCREENSHOTS_DIR);
const client = new OAuth2Client(process.env.CLIENT_ID, process.env.CLIENT_SECRET, `https://${process.env.HOSTNAME}/oauth-login`);
const client = new OAuth2Client(process.env.CLIENT_ID, process.env.CLIENT_SECRET, process.env.NODE_ENV == 'production' ? `https://${process.env.HOSTNAME}/oauth-login` : `http://${process.env.HOSTNAME}/oauth-login`);
const SCREENSHOT_FILENAME_REGEX = new RegExp(/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}\.png$/i);
@ -35,7 +35,7 @@ var sessions_settings_object = {
activeDuration: 1000 * 60 * 5, // Extend for five minutes if actively used
cookie: {
httpOnly: true,
secure: true
secureProxy: process.env.NODE_ENV == 'production'
}
}
@ -153,7 +153,7 @@ async function set_up_api_server(app) {
app.get('/login', (req, res) => {
const authUrl = client.generateAuthUrl({
redirect_uri: `https://${process.env.HOSTNAME}/oauth-login`,
redirect_uri: process.env.NODE_ENV == 'production' ? `https://${process.env.HOSTNAME}/oauth-login` : `http://${process.env.HOSTNAME}/oauth-login`,
access_type: 'offline',
scope: ['email', 'profile'],
prompt: 'select_account'

4
app.js
View file

@ -51,6 +51,8 @@ const SCREENSHOT_FILENAME_REGEX = new RegExp(/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]
async function get_app_server() {
const app = express();
app.set('trust proxy', true);
app.disable('x-powered-by');
// I have a question for Express:
// https://youtu.be/ZtjFsQBuJWw?t=4
@ -262,7 +264,7 @@ async function get_app_server() {
id: payload_fire_id,
user_id: userID,
url: req.body.uri,
ip_address: req.connection.remoteAddress.toString(),
ip_address: req.ip,
referer: req.body.referrer,
user_agent: req.body['user-agent'],
cookies: req.body.cookies,

View file

@ -13,7 +13,10 @@ const sequelize = new Sequelize(
host: process.env.DATABASE_HOST,
dialect: 'postgres',
benchmark: true,
logging: true
logging: false,
dialectOptions: {
socketPath: process.env.NODE_ENV == 'production' ? process.env.DATABASE_HOST : null,
},
},
);
@ -374,36 +377,6 @@ InjectionRequests.init({
]
});
function get_banner() {
return `
============================================================================
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
Hi. I love you.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
============================================================================
`;
}
async function print_banner() {
console.log(get_banner());
}
async function database_init() {
const force = false;
@ -415,11 +388,6 @@ async function database_init() {
CollectedPages.sync({ force: force }),
InjectionRequests.sync({ force: force }),
]);
await Promise.all([
// Set up admin panel user if not already set up.
print_banner(),
]);
}
module.exports = {

View file

@ -3,86 +3,28 @@ services:
# XSS Hunter Express service
xsshunterexpress:
build: .
environment:
# [REQUIRED] The hostname/domain pointed to
# the IP of the server running this service.
# SSL will automatically be set up and
# renewed with LetsEncrypt.
- HOSTNAME=your.host.name
# THis hostname is where your JS is served out of
- XSS_HOSTNAME=your.xss.domain
# [REQUIRED] Email for SSL
- SSL_CONTACT_EMAIL=YourEmail@gmail.com
# Maximum XSS callback payload size
# This includes the webpage screenshot, DOM HTML,
# page text, and other metadata. Note that if the
# payload is above this limit, you won't be notified
# of the XSS firing.
- MAX_PAYLOAD_UPLOAD_SIZE_MB=50
# Whether or not to enable the web control panel
# Set to "false" or remove to disable the web UI.
# Useful for minimizing attack surface.
- CONTROL_PANEL_ENABLED=true
# Whether or not to enable email notifications via
# SMTP for XSS payload fires.
- SMTP_EMAIL_NOTIFICATIONS_ENABLED=true
- SMTP_HOST=smtp.gmail.com
- SMTP_PORT=465
- SMTP_USE_TLS=true
- SMTP_USERNAME=YourEmail@gmail.com
- SMTP_PASSWORD=YourEmailPassword
- SMTP_FROM_EMAIL=YourEmail@gmail.com
- SMTP_RECEIVER_EMAIL=YourEmail@gmail.com
# CLIENT ID FOR OAUTH LOGIN
- CLIENT_ID=your_client_id
- CLIENT_SECRET=your_client_secret
# GENERATE A RANDOM LONG STRING FOR THIS
- SESSION_SECRET_KEY=
# THERE IS NO NEED TO MODIFY BELOW THIS LINE
# ------------------------------------------
# FEEL FREE, BUT KNOW WHAT YOU'RE DOING.
# Where XSS screenshots are stored
- SCREENSHOTS_DIR=/app/payload-fire-images
- DATABASE_NAME=xsshunterexpress
- DATABASE_USER=xsshunterexpress
- DATABASE_PASSWORD=xsshunterexpress
- DATABASE_HOST=postgresdb
- NODE_ENV=production
- USE_CLOUD_STORAGE=true
- BUCKET_NAME=YourBucket
env_file:
- dev.env
ports:
- "80:80"
- "443:443"
- "127.0.0.1:8080:8080"
volumes:
# Stores the SSL/TLS certificates and keys
# in the "ssldata" directory.
# Your certificates are automatically renewed
# via LetsEncrypt, no extra work needed!
- ./ssldata:/app/greenlock.d
# Directory where payload fire images are stored.
- ./payload-fire-images:/app/payload-fire-images
# Comment out if you're using an external SQL
# server and have commented out the DB section.
depends_on:
- postgresdb
# Postgres server to store injection data (not including
# screenshots which are stored separately).
# NOTE: If you're using an external SQL server, you can comment
# out this service.
# WARNING: This database gives the "postgres" user admin priveleges
# with a default password of "xsshunterexpress". Do not expose it
# externally. If you do, be sure to change the password.
postgresdb:
condition: service_healthy
postgresdb:
image: postgres
restart: always
user: postgres
environment:
# This is a volume mounted into the container
# (see the directory ./postgres-db-data)
# So the database will be persisted across
# container deletion.
PGDATA: /var/lib/postgresql/data/pgdata
POSTGRES_USER: xsshunterexpress
POSTGRES_DB: xsshunterexpress
POSTGRES_PASSWORD: xsshunterexpress
POSTGRES_PASSWORD: postgres
POSTGRES_HOST_AUTH_METHOD: trust
healthcheck:
test: ["CMD-SHELL", "pg_isready"]
interval: 3s
timeout: 5s
retries: 5
volumes:
- ./postgres-db-data:/var/lib/postgresql/data/pgdata

View file

@ -1,9 +1,4 @@
#!/usr/bin/env bash
echo "Initializing SSL/TLS..."
# Set up Greenlock
# Test if --maintainer-email is required, we can set it via environment variables...
npx greenlock init --config-dir /app/greenlock.d --maintainer-email $SSL_CONTACT_EMAIL
npx greenlock add --subject $HOSTNAME --altnames "$HOSTNAME,$XSS_HOSTNAME"
echo "Starting server..."
node server.js

30483
front-end/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -15,7 +15,7 @@
"dependencies": {
"@deveodk/vue-toastr": "^1.1.0",
"chart.js": "^2.9.3",
"eslint": "^7.23.0",
"eslint": "^7.32.0",
"i": "^0.3.6",
"moment": "^2.29.1",
"npm": "^7.15.0",
@ -34,13 +34,15 @@
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.5.7",
"@vue/cli-plugin-eslint": "^4.4.6",
"@vue/cli-plugin-eslint": "^5.0.8",
"@vue/cli-plugin-pwa": "^4.4.6",
"@vue/cli-service": "^4.4.6",
"node-sass": "^4.14.1",
"sass-loader": "^8.0.2",
"cache-loader": "^4.1.0",
"sass": "1.56.2",
"sass-loader": "10.1.1",
"vue-cli-plugin-i18n": "^1.0.1",
"vue-template-compiler": "^2.6.11"
"vue-template-compiler": "^2.6.11",
"webpack": "^4.46.0"
},
"browserslist": [
"> 1%",

View file

@ -5,7 +5,7 @@
<!-- Login modal if not authenticated -->
<modal class="show d-block" body-classes="p-0" modal-classes="modal-dialog-centered modal-sm ]" v-if="show_login_prompt">
<card type="secondary" header-classes="bg-white pb-5" body-classes="px-lg-5 py-lg-5" class="border-0 mb-0" style="text-align: center">
<h3>XSS Hunter<br />
<h3 style="margin-bottom: 0; color: #2e5543;">XSS Hunter<br />
<i>Please login to continue.</i></h3>
</card>
</modal>

View file

@ -103,8 +103,7 @@
// Apply the mixin to the buttons
// .btn-default { @include btn-styles($default-color, $default-states-color); }
.btn-primary { @include btn-styles($primary, $primary-states);
.btn-primary { @include btn-styles($default, $default-states);
}
.btn-success { @include btn-styles($success, $success-states);

View file

@ -4,11 +4,12 @@
position: relative;
width: 100%;
margin-bottom: 30px;
box-shadow: $box-shadow;
background: #e7e0d8;
background: transparent;
color: black;
label{
color: rgba($white, 0.6);
color: rgba(black, 0.6);
}
.card-title {
@ -18,6 +19,24 @@
.card-body{
padding: 15px;
.card {
border: 1px solid #ae8c57;
color: black;
background: #f4efe9;
.card-title {
color: black;
font-weight: 500;
font-size: 1.1rem;
}
.card-subtitle {
margin-top: 0.4rem;
color: #5a5a5a !important;
font-size: 0.8rem;
}
}
&.table-full-width{
padding-left: 0;
padding-right: 0;

View file

@ -1,5 +1,5 @@
.footer{
padding: 24px 0 24px 250px;
padding: 24px 0 24px 320px;
[class*="container-"] {
padding: 0;

View file

@ -2,15 +2,23 @@
@include form-control-placeholder(#6c757c, 1);
.form-control{
border-color: lighten($black,5%);
border-radius: $border-radius-lg;
font-size: $font-size-sm;
font-size: $font-size-base;
@include transition-input-focus-color();
font-family: monospace;
border-color: #dfd3b0;
color: #5a5a5a;
background-color: white;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
&:focus{
border-color: $primary;
background-color: $input-bg;
border-color: #ae8c57;
background-color: rgba(white, 0.8);
color: #5a5a5a;
@include box-shadow(none);
& + .input-group-append .input-group-text,

View file

@ -179,7 +179,10 @@ a[data-toggle="collapse"][aria-expanded="true"] .caret,
}
code {
color: $pink;
color: #5bb381;
font-weight: bold;
background: #ffffffcc;
padding: 2px 6px;
}
@media screen and (max-width: 991px){

View file

@ -100,6 +100,8 @@
}
.navbar-brand {
font-family: $font-family-primary;
display: none;
position: fixed;
padding-top: .3125rem;
padding-bottom: .3125rem;
@ -107,7 +109,18 @@
margin-left: 17px;
margin-top: 3px;
text-transform: uppercase;
font-size: $font-paragraph;
font-size: $font-size-xl;
font-weight: bold;
small {
font-size: $font-paragraph;
}
}
@media screen and (max-width: 991px){
.navbar-brand {
display: block;
}
}
.navbar-toggle button:focus, .navbar-toggler{

View file

@ -18,9 +18,8 @@
}
.sidebar,
.off-canvas-sidebar{
@include linear-gradient($primary-states, $primary);
height: calc(100vh - 90px);
width: 230px;
height: 100vh;
width: 280px;
position: fixed;
top: 0;
left: 0;
@ -28,10 +27,8 @@
background-size: cover;
background-position: center center;
display: block;
box-shadow: 0px 0px 45px 0px rgba(0,0,0,0.6);
margin-top: 80px;
margin-left: 20px;
border-radius: 5px;
box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.4);
background: #2e5543;
.sidebar-wrapper{
width: $full-width;
@ -182,22 +179,11 @@
}
&.active > a:not([data-toggle="collapse"]){
background: transparent;
background: rgba(0, 0, 0, 0.15);
i,p{
color: white;
}
&:before{
content: " ";
position: absolute;
height: 6px;
width: 6px;
top: 22px;
left: -4px;
background: $white;
border-radius: 50%;
}
}
&.active > a[data-toggle="collapse"]{
@ -250,6 +236,7 @@
display: block;
height: auto;
white-space: nowrap;
font-size: $font-size-base;
@extend .animation-transition-general;
}
@ -266,6 +253,7 @@
}
.logo{
font-size: $font-size-xl;
position: relative;
padding: $padding-base-vertical $padding-base-horizontal;
z-index: 4;
@ -302,6 +290,7 @@
}
a.logo-normal{
font-weight: bold;
display: block;
opacity: 1;
@include transform-translate-x(0px);
@ -460,7 +449,7 @@
width: $full-width;
min-height: 100vh;
border-top: 2px solid $primary;
background: linear-gradient($background-black, $background-states-black);
background: none;
@include transitions (0.50s, cubic-bezier(0.685, 0.0473, 0.346, 1));
@ -481,7 +470,7 @@
}
> .content {
padding: 78px 30px 30px 280px;
padding: 30px 30px 30px 320px;
min-height: calc(100vh - 70px);
}
@ -682,6 +671,7 @@
width: 100%;
.content {
padding-left: 30px;
padding-top: 60px;
}
}

View file

@ -99,28 +99,28 @@ $colors: map-merge((
$default-color-opacity: rgba(182, 182, 182, .6) !default;
$orange-color: #f96332 !default;
$default: #344675 !default;
$primary: #e14eca !default;
$default: #89553d !default;
$primary: #2e5543 !default;
$secondary: #f4f5f7 !default;
$success: #00f2c3 !default;
$success: #5bb381 !default;
$info: #1d8cf8 !default;
$warning: #ff8d72 !default;
$danger: #fd5d93 !default;
$danger: #c15750 !default;
$black: #222a42 !default;
$vue: #42b883 !default;
// gradient
$default-states: #263148 !default;
$primary-states: #ba54f5 !default;
$default-states: #5b3524 !default;
$primary-states: #111513 !default;
$success-states: #0098f0 !default;
$info-states: #3358f4 !default;
$warning-states: #ff6491 !default;
$danger-states: #ec250d !default;
$danger-states: #662019 !default;
$black-states: #1d253b !default;
$vue-states: #389466 !default;
$background-black: #1e1e2f !default;
$background-states-black: #1e1e24 !default;
$background-black: #323232 !default;
$background-states-black: #1c1a1a !default;
// opacity
$default-opacity: rgba(182, 182, 182, .6) !default;
@ -379,7 +379,7 @@ $general-transition-time: 300ms !default;
// Fonts
$font-family-primary: 'Poppins', sans-serif !default;
$font-family-base: 'Poppins', sans-serif !default;
$font-family-alt: 'Poppins', sans-serif !default;
@ -899,7 +899,7 @@ $card-border-color: rgba($black, .05);
$card-inner-border-radius: calc(#{$card-border-radius} - #{$card-border-width});
$card-cap-bg: $gray-100 !default;
$card-bg: $white !default;
$card-black-background: #27293d !default;
$card-black-background: #463727 !default;
$card-img-overlay-padding: 1.25rem !default;
//$card-group-margin: ($grid-gutter-width / 2);

View file

@ -1,5 +1,4 @@
@mixin btn-styles($btn-color, $btn-states-color) {
@include diagonal-gradient($btn-color, $btn-states-color);
background-color: $btn-color;
transition: all 0.15s ease;
box-shadow: none;
@ -18,10 +17,6 @@
&.active:hover
{
background-color: $btn-states-color !important;
background-image: linear-gradient(to bottom left, $btn-color, $btn-states-color, $btn-color) !important;
background-image: -webkit-linear-gradient(to bottom left, $btn-color, $btn-states-color, $btn-color) !important;
background-image: -o-linear-gradient(to bottom left, $btn-color, $btn-states-color, $btn-color) !important;
background-image: -moz-linear-gradient(to bottom left, $btn-color, $btn-states-color, $btn-color) !important;
color: $white;
box-shadow: none;
}
@ -165,10 +160,6 @@
&:not(:disabled):not(.disabled):active{
color: $white;
border-color: $btn-color;
background-image: linear-gradient(to bottom left, $btn-color, $btn-states-color, $btn-color) !important;
background-image: -webkit-linear-gradient(to bottom left, $btn-color, $btn-states-color, $btn-color) !important;
background-image: -o-linear-gradient(to bottom left, $btn-color, $btn-states-color, $btn-color) !important;
background-image: -moz-linear-gradient(to bottom left, $btn-color, $btn-states-color, $btn-color) !important;
background-color: $btn-states-color !important;
box-shadow: none;
}

View file

@ -17,6 +17,12 @@
<p>Github Repo</p>
</a>
</li>
<li class="nav-item mt-5">
<a target="_blank" href="https://trufflesecurity.com/" class="nav-link">
<i class="fas fab fa-power-off"></i>
<p>Powered by TruffleSec</p>
</a>
</li>
</template>
</side-bar>
<div class="main-panel">

View file

@ -13,18 +13,8 @@
<span class="navbar-toggler-bar bar3"></span>
</button>
</div>
<a class="navbar-brand" href="#pablo">{{routeName}}</a>
<a class="navbar-brand" href="#pablo">XSS HUNTER | <small>{{routeName}}</small></a>
</div>
<button class="navbar-toggler" type="button"
@click="toggleMenu"
data-toggle="collapse"
data-target="#navigation"
aria-controls="navigation-index"
aria-label="Toggle navigation">
<span class="navbar-toggler-bar navbar-kebab"></span>
<span class="navbar-toggler-bar navbar-kebab"></span>
<span class="navbar-toggler-bar navbar-kebab"></span>
</button>
<collapse-transition>
<div class="collapse navbar-collapse show" v-show="showMenu">

View file

@ -317,7 +317,6 @@ export default {
}
.xss-card-container {
max-width: 1000px;
width: 100%;
}

View file

@ -5,29 +5,32 @@
<card class="xss-card-container">
<div class="row pl-4 pr-4 p-2" style="display: block;">
<div>
<h1><i class="fas fa-cogs"></i>User Settings</h1>
<h1><i class="fas fa-cogs"></i>&nbsp;User Settings</h1>
</div>
<card>
<h4 class="card-title">Injection Correlation API Key</h4>
<h6 class="card-subtitle mb-2 text-muted">Use with an XSS Hunter compatible client to track which injection caused a payload fire.</h6>
<h6 class="card-subtitle mb-2 text-muted">Use with an XSS Hunter-compatible client to track which injection caused a payload fire.</h6>
<p class="card-text">
<base-input v-bind:value="correlation_api_key" type="text" placeholder="..." ></base-input>
</p>
<base-button class="mr-1" type="primary" v-clipboard:copy="correlation_api_key" >
<i class="far fa-copy"></i> Copy API Key
<span style="display: inline-block; margin-right: 6px;"><i class="far fa-copy"></i></span>
Copy API Key
</base-button>
<base-button type="danger" v-on:click="generate_new_correlation_api_key">
<i class="fas fa-sync-alt"></i> Rotate API Key
<span style="display: inline-block; margin-right: 6px;"><i class="fas fa-sync-alt"></i></span>
Rotate API Key
</base-button>
</card>
<card>
<h4 class="card-title">XSSHunter Path</h4>
<h6 class="card-subtitle mb-2 text-muted">This unique path ties injection payloads back to you. You can set it to something shorter (it defaults to 20 chars).</h6>
<h6 class="card-subtitle mb-2 text-muted">Unique path that ties injection payloads back to you. Can be set to something shorter. (defaults to 20 chars)</h6>
<p class="card-text">
<base-input v-model:value="user_path" type="text" placeholder="..."></base-input>
</p>
<base-button type="primary" v-on:click="update_path">
<i class="fas fa-lock"></i> Update Path
<span style="display: inline-block; margin-right: 6px;"><i class="fas fa-lock"></i></span>
Update Path
</base-button>
</card>
<card>
@ -37,25 +40,28 @@
<base-input v-model="chainload_uri" type="text" placeholder="https://example.com/remote.js"></base-input>
</p>
<base-button type="primary" v-on:click="update_chainload_uri">
<i class="far fa-save"></i> Save JavaScript URL
<span style="display: inline-block; margin-right: 6px;"><i class="far fa-save"></i></span>
Save JavaScript URL
</base-button>
</card>
<card>
<h4 class="card-title">Miscellaneous Options</h4>
<div v-if="send_alert_emails">
<base-button type="primary" v-on:click="set_email_reporting">
<i class="far fa-bell-slash"></i> Disable Email Reporting
<span style="display: inline-block; margin-right: 6px;"><i class="far fa-bell-slash"></i></span>
Disable Email Reporting
</base-button>
<h6 class="mt-2 text-muted">
Disable the sending of XSS payload fire reports to the specified email address.
Disable sending XSS payload fire reports to the specified email address.
</h6>
</div>
<div v-if="!send_alert_emails">
<base-button type="primary" v-on:click="set_email_reporting">
<i class="far fa-bell"></i> Enable Email Reporting
<span style="display: inline-block; margin-right: 6px;"><i class="far fa-bell"></i></span>
Enable Email Reporting
</base-button>
<h6 class="mt-2 text-muted">
Enable the sending of XSS payload fire reports to the specified email address.
Enable sending XSS payload fire reports to the specified email address.
</h6>
</div>

View file

@ -5,9 +5,10 @@
<card class="xss-card-container">
<div class="row pl-4 pr-4 p-2" style="display: block;">
<div>
<h1><i class="fas fa-fire"></i> XSS Payload Fire Reports ({{format_with_commas(report_count)}} Total)</h1>
<h1><i class="fas fa-fire"></i> XSS Payload Fire Reports ({{format_with_commas(report_count)}} total)</h1>
<hr />
<div v-for="report in payload_fire_reports">
<div v-if="report_count === 0" style="color: white;">No reports!</div>
<div v-else v-for="report in payload_fire_reports">
<card class="mb-0">
<div class="screenshot-image-container mb-2">
<a v-bind:href="base_api_path + '/screenshots/' + report.screenshot_id + '.png'" target="_blank">
@ -210,7 +211,7 @@
<hr />
</div>
<!-- Pagination -->
<div class="text-center pagination-div">
<div v-if="report_count !== 0" class="text-center pagination-div">
<base-pagination v-bind:page-count="total_pages" v-model="page"></base-pagination>
</div>
</div>
@ -507,7 +508,6 @@ export default {
}
.xss-card-container {
max-width: 1000px;
width: 100%;
}
@ -808,7 +808,7 @@ a.badge-dark:focus {
}
hr {
background-color: #344675;
background-color: #ae8c57;
}
.corner-loader {}

View file

@ -13,7 +13,9 @@
<p class="card-text">
<base-input type="text" v-bind:value="payload.func()" placeholder="..."></base-input>
</p>
<base-button type="primary" v-clipboard:copy="payload.func()"><i class="far fa-copy"></i> Copy Payload</base-button>
<base-button type="primary" v-clipboard:copy="payload.func()">
<span style="display: inline-block; margin-right: 6px;"><i class="far fa-copy"></i></span>
Copy Payload</base-button>
</card>
</div>
</card>

View file

@ -12,12 +12,12 @@ const routes = [
children: [
{
path: "",
name: "XSS Payload Fire Reports",
name: "Payload Fire Reports",
component: XSSPayloadFireReports
},
{
path: "/xsspayloads",
name: "XSS Payloads",
name: "Payloads",
component: XSSPayloads
},
{

2591
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -11,17 +11,19 @@
"license": "MIT",
"dependencies": {
"@deveodk/vue-toastr": "^1.1.0",
"@nvanexan/node-client-sessions": "^0.8.0",
"@truffledustin/node-client-sessions": "^0.8.0",
"bcrypt": "^5.0.1",
"body-parser": "^1.20.1",
"cors": "^2.8.5",
"@google-cloud/storage": "^6.9.0",
"express": "^4.17.1",
"express-jsonschema": "^1.1.6",
"greenlock-express": "^4.0.3",
"google-auth-library": "^8.7.0",
"googleapis": "^110.0.0",
"keygrip": "^1.1.0",
"memorystore": "^1.6.6",
"moment": "^2.29.1",
"multer": "^1.4.2",
"multer": "^1.4.5-lts.1",
"mustache": "^4.1.0",
"nodemailer": "^6.5.0",
"pg": "^8.5.1",
@ -29,9 +31,6 @@
"sequelize": "^6.5.0",
"serve-favicon": "^2.5.0",
"uuid": "^8.3.2",
"vue-moment": "^4.1.0",
"body-parser": "^1.20.1",
"google-auth-library": "^8.7.0",
"googleapis": "^110.0.0"
"vue-moment": "^4.1.0"
}
}

View file

@ -16,10 +16,9 @@ if(!process.env.SSL_CONTACT_EMAIL) {
const app = await get_app_server();
require('greenlock-express').init({
packageRoot: __dirname,
configDir: './greenlock.d',
cluster: false,
maintainerEmail: process.env.SSL_CONTACT_EMAIL,
}).serve(app);
const port = process.env.PORT;
app.listen(port, () => {
console.log(`XSS Hunter listening on port ${port}`)
});
})();