├── .eslintignore
├── examples
├── angular
│ ├── src
│ │ ├── assets
│ │ │ └── .gitkeep
│ │ ├── app
│ │ │ ├── app.component.css
│ │ │ ├── app.component.ts
│ │ │ ├── app-routing.module.ts
│ │ │ ├── app.module.ts
│ │ │ ├── app.component.spec.ts
│ │ │ └── app.component.html
│ │ ├── environments
│ │ │ ├── environment.prod.ts
│ │ │ └── environment.ts
│ │ ├── styles.css
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── main.ts
│ │ ├── test.ts
│ │ └── polyfills.ts
│ ├── .editorconfig
│ ├── tsconfig.app.json
│ ├── tsconfig.spec.json
│ ├── .browserslistrc
│ ├── .gitignore
│ ├── tsconfig.json
│ ├── README.md
│ ├── package.json
│ ├── karma.conf.js
│ └── angular.json
├── react
│ ├── public
│ │ ├── robots.txt
│ │ ├── favicon.ico
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── index.html
│ ├── src
│ │ ├── setupTests.js
│ │ ├── index.css
│ │ ├── reportWebVitals.js
│ │ ├── index.js
│ │ ├── App.css
│ │ ├── App.js
│ │ └── logo.svg
│ ├── .gitignore
│ ├── package.json
│ └── README.md
├── vue
│ ├── public
│ │ ├── favicon.ico
│ │ └── index.html
│ ├── babel.config.js
│ ├── src
│ │ ├── assets
│ │ │ └── logo.png
│ │ ├── main.js
│ │ ├── App.vue
│ │ └── components
│ │ │ └── HelloWorld.vue
│ ├── .gitignore
│ ├── README.md
│ └── package.json
└── README.md
├── jest.config.js
├── test
├── core.test.js
└── weakness.test.js
├── src
├── weakness
│ ├── xss.js
│ ├── sqlinjection.js
│ ├── fileupload.js
│ └── sensitive.js
├── utils
│ ├── loggers
│ │ ├── dom.js
│ │ └── request.js
│ └── interceptors
│ │ ├── dom.js
│ │ └── request.js
├── networks
│ └── api.js
└── index.js
├── .eslintrc.json
├── .github
├── PULL_REQUEST_TEMPLATE.md
├── workflows
│ └── main.yml
└── ISSUE_TEMPLATE
│ └── bug_report.md
├── CHANGELOG.md
├── package.json
├── LICENSE
├── .gitignore
├── README.md
└── CONTRIBUTING.md
/.eslintignore:
--------------------------------------------------------------------------------
1 | /examples
2 | *.test.js
--------------------------------------------------------------------------------
/examples/angular/src/assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/angular/src/app/app.component.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | testPathIgnorePatterns: ["examples"],
3 | };
4 |
--------------------------------------------------------------------------------
/examples/react/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/examples/angular/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/examples/angular/src/styles.css:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 |
--------------------------------------------------------------------------------
/examples/vue/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tophat-cloud/cumulus/HEAD/examples/vue/public/favicon.ico
--------------------------------------------------------------------------------
/examples/angular/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tophat-cloud/cumulus/HEAD/examples/angular/src/favicon.ico
--------------------------------------------------------------------------------
/examples/react/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tophat-cloud/cumulus/HEAD/examples/react/public/favicon.ico
--------------------------------------------------------------------------------
/examples/react/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tophat-cloud/cumulus/HEAD/examples/react/public/logo192.png
--------------------------------------------------------------------------------
/examples/react/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tophat-cloud/cumulus/HEAD/examples/react/public/logo512.png
--------------------------------------------------------------------------------
/examples/vue/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/examples/vue/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tophat-cloud/cumulus/HEAD/examples/vue/src/assets/logo.png
--------------------------------------------------------------------------------
/test/core.test.js:
--------------------------------------------------------------------------------
1 | // TODO nothing to do
2 | describe('pass', () => {
3 | it('1+2', (done) => {
4 | expect(1 + 2).toEqual(3);
5 | done();
6 | });
7 | });
8 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | # Cumulus use examples
2 |
3 | ## Current supported
4 |
5 | - [x] React (via npm)
6 | - [x] Vue (via npm)
7 | - [x] Angular (via npm)
8 | - [ ] VanillaJS (via CDN)
9 |
--------------------------------------------------------------------------------
/src/weakness/xss.js:
--------------------------------------------------------------------------------
1 | class Xss {
2 | checkString(data) {
3 | const regExp = /<|>|<|>|&|"|'/;
4 | return regExp.test(data);
5 | }
6 | }
7 |
8 | module.exports = new Xss();
9 |
--------------------------------------------------------------------------------
/src/weakness/sqlinjection.js:
--------------------------------------------------------------------------------
1 | class SqlInjection {
2 | checkString(data) {
3 | const regExp = /(union|select|from|where)/i;
4 | return regExp.test(data);
5 | }
6 | }
7 |
8 | module.exports = new SqlInjection();
9 |
--------------------------------------------------------------------------------
/examples/vue/src/main.js:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue'
2 | import App from './App.vue'
3 | import { protect } from 'cumulus'
4 |
5 | protect({
6 | key: 'Bs0hLQqej0b0IwPVg06Po',
7 | })
8 |
9 | createApp(App).mount('#app')
10 |
--------------------------------------------------------------------------------
/src/weakness/fileupload.js:
--------------------------------------------------------------------------------
1 | class FileUpload {
2 | checkBinary(data) {
3 | const name = data.name;
4 | const regExp = /[php|asp|aspx|jsp]$/gi;
5 |
6 | return regExp.test(name);
7 | }
8 | }
9 |
10 | module.exports = new FileUpload();
11 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "commonjs": true,
5 | "es2021": true
6 | },
7 | "extends": "eslint:recommended",
8 | "parserOptions": {
9 | "ecmaVersion": 13
10 | },
11 | "rules": {
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/examples/react/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/examples/angular/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-root',
5 | templateUrl: './app.component.html',
6 | styleUrls: ['./app.component.css']
7 | })
8 | export class AppComponent {
9 | title = 'angular';
10 | }
11 |
--------------------------------------------------------------------------------
/src/utils/loggers/dom.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | enableLogger: (callback) => {
3 | Object.keys(window).forEach(key => {
4 | if(/./.test(key)){
5 | window.addEventListener(key.slice(2), event => {
6 | callback(key, event);
7 | })
8 | }
9 | });
10 | },
11 | }
12 |
--------------------------------------------------------------------------------
/examples/angular/src/app/app-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { RouterModule, Routes } from '@angular/router';
3 |
4 | const routes: Routes = [];
5 |
6 | @NgModule({
7 | imports: [RouterModule.forRoot(routes)],
8 | exports: [RouterModule]
9 | })
10 | export class AppRoutingModule { }
11 |
--------------------------------------------------------------------------------
/src/weakness/sensitive.js:
--------------------------------------------------------------------------------
1 | class Sensitive {
2 | checkJSON(data) {
3 | const hasPassword = Object.keys(data).includes('password');
4 | const isSSL = window.location.protocol === 'https:';
5 |
6 | if (!hasPassword) {
7 | return false;
8 | }
9 |
10 | return !isSSL;
11 | }
12 | }
13 |
14 | module.exports = new Sensitive();
15 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | Before submitting a pull request, please take a look at our
2 | [Contributing](https://github.com/tophat-cloud/cumulus/blob/master/CONTRIBUTING.md) guidelines and verify:
3 |
4 | - [ ] If you've added code that should be tested, please add tests.
5 | - [ ] Ensure your code lints and the test suite passes (`yarn lint`) & (`yarn test`).
--------------------------------------------------------------------------------
/examples/vue/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/examples/angular/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see https://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.ts]
12 | quote_type = single
13 |
14 | [*.md]
15 | max_line_length = off
16 | trim_trailing_whitespace = false
17 |
--------------------------------------------------------------------------------
/examples/angular/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Angular
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/angular/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "./out-tsc/app",
6 | "types": []
7 | },
8 | "files": [
9 | "src/main.ts",
10 | "src/polyfills.ts"
11 | ],
12 | "include": [
13 | "src/**/*.d.ts"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/examples/react/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.toptal.com/developers/gitignore/api/react
3 | # Edit at https://www.toptal.com/developers/gitignore?templates=react
4 |
5 | ### react ###
6 | .DS_*
7 | *.log
8 | logs
9 | **/*.backup.*
10 | **/*.back.*
11 |
12 | node_modules
13 | bower_components
14 |
15 | *.sublime*
16 |
17 | psd
18 | thumb
19 | sketch
20 |
21 | # End of https://www.toptal.com/developers/gitignore/api/react
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: Build & Test
2 | on:
3 | push:
4 | branches:
5 | - main
6 | jobs:
7 | build:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v2
11 | - name: Install modules
12 | run: yarn
13 | - name: Run ESLint
14 | run: yarn lint
15 | - name: Run Jest
16 | run: yarn test
17 | - name: Run Codecov
18 | run: yarn test-codecov
19 |
--------------------------------------------------------------------------------
/examples/angular/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "./out-tsc/spec",
6 | "types": [
7 | "jasmine"
8 | ]
9 | },
10 | "files": [
11 | "src/test.ts",
12 | "src/polyfills.ts"
13 | ],
14 | "include": [
15 | "src/**/*.spec.ts",
16 | "src/**/*.d.ts"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/examples/react/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/examples/react/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 0.0.2
2 | - [weakness] ✨ Add SQLInjection detection
3 | - [weakness] ✨ Add File Upload Attack detection
4 | - [core] 🥅 Catch many of unexpected errors
5 | - [core] 🔧 Apply linting, test codes
6 | - [core] ♻️ Refactor to whole codes as modularization
7 |
8 | ## 0.0.1
9 | - [core] 🎉 Release first version
10 |
11 | ## 0.0.0
12 | This is first relase for cumulus SDK. alos It's open beta service. we basically guiding project's goal and code base structure.
13 |
--------------------------------------------------------------------------------
/examples/angular/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 |
4 | import { AppRoutingModule } from './app-routing.module';
5 | import { AppComponent } from './app.component';
6 |
7 | @NgModule({
8 | declarations: [
9 | AppComponent
10 | ],
11 | imports: [
12 | BrowserModule,
13 | AppRoutingModule
14 | ],
15 | providers: [],
16 | bootstrap: [AppComponent]
17 | })
18 | export class AppModule { }
19 |
--------------------------------------------------------------------------------
/examples/vue/README.md:
--------------------------------------------------------------------------------
1 | # Cumulus use example for Vue
2 |
3 | ```shell
4 | npm install
5 | npm run serve
6 | ```
7 |
8 | ## Guide
9 | Check the [`./src/main.js`](https://github.com/tophat-cloud/cumulus/blob/main/examples/vue/src/main.js)
10 |
11 | Configuration should happen as early as possible in your application's lifecycle.
12 |
13 | ```jsx
14 | import { createApp } from 'vue'
15 | import App from './App.vue'
16 | import { protect } from 'cumulus'
17 |
18 | protect({
19 | key: 'KMsB9W4hZCejJ6D1fiESP',
20 | })
21 |
22 | createApp(App).mount('#app')
23 | ```
24 |
--------------------------------------------------------------------------------
/examples/angular/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { environment } from './environments/environment';
6 |
7 | // @ts-ignore
8 | import { protect } from 'cumulus';
9 |
10 | protect({
11 | key: 'G0HTxSUKH5ZQhVg2DLNQW',
12 | });
13 |
14 | if (environment.production) {
15 | enableProdMode();
16 | }
17 |
18 | platformBrowserDynamic().bootstrapModule(AppModule)
19 | .catch(err => console.error(err));
20 |
--------------------------------------------------------------------------------
/examples/react/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | ReactDOM.render(
8 |
9 |
10 | ,
11 | document.getElementById('root')
12 | );
13 |
14 | // If you want to start measuring performance in your app, pass a function
15 | // to log results (for example: reportWebVitals(console.log))
16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17 | reportWebVitals();
18 |
--------------------------------------------------------------------------------
/examples/vue/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
16 |
17 |
27 |
--------------------------------------------------------------------------------
/examples/react/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/examples/vue/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
12 | We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/examples/react/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/examples/angular/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // This file can be replaced during build by using the `fileReplacements` array.
2 | // `ng build` replaces `environment.ts` with `environment.prod.ts`.
3 | // The list of file replacements can be found in `angular.json`.
4 |
5 | export const environment = {
6 | production: false
7 | };
8 |
9 | /*
10 | * For easier debugging in development mode, you can import the following file
11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
12 | *
13 | * This import should be commented out in production mode because it will have a negative impact
14 | * on performance if an error is thrown.
15 | */
16 | // import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
17 |
--------------------------------------------------------------------------------
/examples/angular/.browserslistrc:
--------------------------------------------------------------------------------
1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
2 | # For additional information regarding the format and rule options, please see:
3 | # https://github.com/browserslist/browserslist#queries
4 |
5 | # For the full list of supported browsers by the Angular framework, please see:
6 | # https://angular.io/guide/browser-support
7 |
8 | # You can see what browsers were selected by your queries by running:
9 | # npx browserslist
10 |
11 | last 1 Chrome version
12 | last 1 Firefox version
13 | last 2 Edge major versions
14 | last 2 Safari major versions
15 | last 2 iOS major versions
16 | Firefox ESR
17 | not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.
18 |
--------------------------------------------------------------------------------
/examples/angular/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 | /out-tsc
7 | # Only exists if Bazel was run
8 | /bazel-out
9 |
10 | # dependencies
11 | /node_modules
12 |
13 | # profiling files
14 | chrome-profiler-events*.json
15 |
16 | # IDEs and editors
17 | /.idea
18 | .project
19 | .classpath
20 | .c9/
21 | *.launch
22 | .settings/
23 | *.sublime-workspace
24 |
25 | # IDE - VSCode
26 | .vscode/*
27 | !.vscode/settings.json
28 | !.vscode/tasks.json
29 | !.vscode/launch.json
30 | !.vscode/extensions.json
31 | .history/*
32 |
33 | # misc
34 | /.sass-cache
35 | /connect.lock
36 | /coverage
37 | /libpeerconnection.log
38 | npm-debug.log
39 | yarn-error.log
40 | testem.log
41 | /typings
42 |
43 | # System Files
44 | .DS_Store
45 | Thumbs.db
46 |
--------------------------------------------------------------------------------
/examples/react/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cumulus-react-example",
3 | "version": "0.0.2",
4 | "dependencies": {
5 | "cumulus": "https://github.com/tophat-cloud/cumulus",
6 | "react": "^17.0.2",
7 | "react-dom": "^17.0.2",
8 | "react-scripts": "4.0.3",
9 | "web-vitals": "^1.0.1"
10 | },
11 | "scripts": {
12 | "start": "react-scripts start",
13 | "build": "react-scripts build",
14 | "eject": "react-scripts eject"
15 | },
16 | "eslintConfig": {
17 | "extends": [
18 | "react-app"
19 | ]
20 | },
21 | "browserslist": {
22 | "production": [
23 | ">0.2%",
24 | "not dead",
25 | "not op_mini all"
26 | ],
27 | "development": [
28 | "last 1 chrome version",
29 | "last 1 firefox version",
30 | "last 1 safari version"
31 | ]
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "🐛 Bug Report"
3 | about: Report a reproducible bug or regression in Cumulus SDK.
4 | title: ''
5 | labels: 'Status: Needs Triage'
6 | assignees: ''
7 |
8 | ---
9 |
10 |
11 |
12 | - [ ] Review the documentation: https://github.com/tophat-cloud/cumulus/wiki
13 | - [ ] Search for existing issues: https://github.com/tophat-cloud/cumulus/issues
14 | - [ ] Use the latest release: https://github.com/tophat-cloud/cumulus/releases
15 | - [ ] Provide a link to the affected event from your Cumulus account
16 |
17 | ## Type + Version
18 |
19 | - [ ] `xss`
20 | - [ ] `sqlinjection`
21 | - [ ] `core`
22 | - [ ] other:
23 |
24 | ### Version:
25 |
26 | ```
27 | 0.0.0
28 | ```
29 |
30 | ## Description
31 |
32 | Describe your issue in detail, ideally, you have a reproducible demo that you can show.
--------------------------------------------------------------------------------
/examples/angular/src/test.ts:
--------------------------------------------------------------------------------
1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2 |
3 | import 'zone.js/testing';
4 | import { getTestBed } from '@angular/core/testing';
5 | import {
6 | BrowserDynamicTestingModule,
7 | platformBrowserDynamicTesting
8 | } from '@angular/platform-browser-dynamic/testing';
9 |
10 | declare const require: {
11 | context(path: string, deep?: boolean, filter?: RegExp): {
12 | keys(): string[];
13 | (id: string): T;
14 | };
15 | };
16 |
17 | // First, initialize the Angular testing environment.
18 | getTestBed().initTestEnvironment(
19 | BrowserDynamicTestingModule,
20 | platformBrowserDynamicTesting(),
21 | { teardown: { destroyAfterEach: true }},
22 | );
23 |
24 | // Then we find all the tests.
25 | const context = require.context('./', true, /\.spec\.ts$/);
26 | // And load the modules.
27 | context.keys().map(context);
28 |
--------------------------------------------------------------------------------
/examples/angular/tsconfig.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "compileOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": "./",
6 | "outDir": "./dist/out-tsc",
7 | "forceConsistentCasingInFileNames": true,
8 | "strict": true,
9 | "noImplicitReturns": true,
10 | "noFallthroughCasesInSwitch": true,
11 | "sourceMap": true,
12 | "declaration": false,
13 | "downlevelIteration": true,
14 | "experimentalDecorators": true,
15 | "moduleResolution": "node",
16 | "importHelpers": true,
17 | "target": "es2017",
18 | "module": "es2020",
19 | "lib": [
20 | "es2018",
21 | "dom"
22 | ]
23 | },
24 | "angularCompilerOptions": {
25 | "enableI18nLegacyMessageIdFormat": false,
26 | "strictInjectionParameters": true,
27 | "strictInputAccessModifiers": true,
28 | "strictTemplates": true
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/examples/angular/README.md:
--------------------------------------------------------------------------------
1 | # Cumulus use example for Angular
2 |
3 | ```shell
4 | npm install
5 | npm start
6 | ```
7 |
8 | ## Guide
9 | Check the [`./src/main.ts`](https://github.com/tophat-cloud/cumulus/blob/main/examples/angular/src/main.ts)
10 |
11 | Configuration should happen as early as possible in your application's lifecycle.
12 |
13 | ```javascript
14 | import { enableProdMode } from '@angular/core';
15 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
16 |
17 | import { AppModule } from './app/app.module';
18 | import { environment } from './environments/environment';
19 |
20 | // @ts-ignore
21 | import { protect } from 'cumulus';
22 |
23 | protect({
24 | key: 'KMsB9W4hZCejJ6D1fiESP',
25 | });
26 |
27 | if (environment.production) {
28 | enableProdMode();
29 | }
30 |
31 | platformBrowserDynamic().bootstrapModule(AppModule)
32 | .catch(err => console.error(err));
33 | ```
34 |
35 | Note: Cumulus v0.0.1 not supported to typescript, but you can use with `@ts-ignore` comment. we know this issue and going to resolve ASAP.
36 |
--------------------------------------------------------------------------------
/examples/vue/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "core-js": "^3.6.5",
12 | "cumulus": "https://github.com/tophat-cloud/cumulus",
13 | "vue": "^3.0.0"
14 | },
15 | "devDependencies": {
16 | "@vue/cli-plugin-babel": "~4.5.0",
17 | "@vue/cli-plugin-eslint": "~4.5.0",
18 | "@vue/cli-service": "~4.5.0",
19 | "@vue/compiler-sfc": "^3.0.0",
20 | "babel-eslint": "^10.1.0",
21 | "eslint": "^6.7.2",
22 | "eslint-plugin-vue": "^7.0.0"
23 | },
24 | "eslintConfig": {
25 | "root": true,
26 | "env": {
27 | "node": true
28 | },
29 | "extends": [
30 | "plugin:vue/vue3-essential",
31 | "eslint:recommended"
32 | ],
33 | "parserOptions": {
34 | "parser": "babel-eslint"
35 | },
36 | "rules": {}
37 | },
38 | "browserslist": [
39 | "> 1%",
40 | "last 2 versions",
41 | "not dead"
42 | ]
43 | }
44 |
--------------------------------------------------------------------------------
/src/networks/api.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 | const FormData = require('form-data');
3 |
4 | class Api {
5 | constructor(projectKey) {
6 | this.projectKey = projectKey;
7 | axios.defaults.baseURL = 'https://api.cumulus.tophat.cloud';
8 | }
9 |
10 | async registerKey(domain) {
11 | const data = new FormData();
12 | data.append('project_id', this.projectKey);
13 | data.append('domain', domain);
14 |
15 | await axios.patch('/project/enroll', data, {
16 | headers: {
17 | 'content-type': 'application/x-www-form-urlencoded',
18 | },
19 | });
20 | }
21 |
22 | async createThunder(name, url, priority, details) {
23 | const data = new FormData();
24 | data.append('project', this.projectKey);
25 | data.append('thunder_name', name);
26 | data.append('url', url);
27 | data.append('priority', priority);
28 | data.append('details', details);
29 |
30 | await axios.post('/thunder/create', data, {
31 | headers: {
32 | 'content-type': 'application/x-www-form-urlencoded',
33 | },
34 | });
35 | }
36 | }
37 |
38 | module.exports = Api;
39 |
--------------------------------------------------------------------------------
/examples/angular/src/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { RouterTestingModule } from '@angular/router/testing';
3 | import { AppComponent } from './app.component';
4 |
5 | describe('AppComponent', () => {
6 | beforeEach(async () => {
7 | await TestBed.configureTestingModule({
8 | imports: [
9 | RouterTestingModule
10 | ],
11 | declarations: [
12 | AppComponent
13 | ],
14 | }).compileComponents();
15 | });
16 |
17 | it('should create the app', () => {
18 | const fixture = TestBed.createComponent(AppComponent);
19 | const app = fixture.componentInstance;
20 | expect(app).toBeTruthy();
21 | });
22 |
23 | it(`should have as title 'angular'`, () => {
24 | const fixture = TestBed.createComponent(AppComponent);
25 | const app = fixture.componentInstance;
26 | expect(app.title).toEqual('angular');
27 | });
28 |
29 | it('should render title', () => {
30 | const fixture = TestBed.createComponent(AppComponent);
31 | fixture.detectChanges();
32 | const compiled = fixture.nativeElement as HTMLElement;
33 | expect(compiled.querySelector('.content span')?.textContent).toContain('angular app is running!');
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/examples/angular/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "ng": "ng",
6 | "start": "ng serve",
7 | "build": "ng build",
8 | "watch": "ng build --watch --configuration development",
9 | "test": "ng test"
10 | },
11 | "private": true,
12 | "dependencies": {
13 | "@angular/animations": "~12.2.0",
14 | "@angular/common": "~12.2.0",
15 | "@angular/compiler": "~12.2.0",
16 | "@angular/core": "~12.2.0",
17 | "@angular/forms": "~12.2.0",
18 | "@angular/platform-browser": "~12.2.0",
19 | "@angular/platform-browser-dynamic": "~12.2.0",
20 | "@angular/router": "~12.2.0",
21 | "cumulus": "https://github.com/tophat-cloud/cumulus",
22 | "rxjs": "~6.6.0",
23 | "tslib": "^2.3.0",
24 | "zone.js": "~0.11.4"
25 | },
26 | "devDependencies": {
27 | "@angular-devkit/build-angular": "~12.2.10",
28 | "@angular/cli": "~12.2.10",
29 | "@angular/compiler-cli": "~12.2.0",
30 | "@types/jasmine": "~3.8.0",
31 | "@types/node": "^12.11.1",
32 | "jasmine-core": "~3.8.0",
33 | "karma": "~6.3.0",
34 | "karma-chrome-launcher": "~3.1.0",
35 | "karma-coverage": "~2.0.3",
36 | "karma-jasmine": "~4.0.0",
37 | "karma-jasmine-html-reporter": "~1.7.0",
38 | "typescript": "~4.3.5"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/utils/interceptors/dom.js:
--------------------------------------------------------------------------------
1 | let debounce = null;
2 |
3 | module.exports = {
4 | interceptInputEvent: (callback) => {
5 | document.querySelectorAll('input').forEach(input => {
6 | input.addEventListener('input', function (e) {
7 | if (debounce) {
8 | clearTimeout(debounce);
9 | }
10 |
11 | debounce = setTimeout(() => {
12 | try {
13 | callback(e);
14 | } catch (err) {
15 | // TODO raise error to maintainer
16 | }
17 | }, 500);
18 | });
19 | });
20 |
21 | document.querySelectorAll('textarea').forEach(input => {
22 | input.addEventListener('input', function (e) {
23 | if (debounce) {
24 | clearTimeout(debounce);
25 | }
26 |
27 | debounce = setTimeout(() => {
28 | try {
29 | callback(e);
30 | } catch (err) {
31 | // TODO raise error to maintainer
32 | }
33 | }, 500);
34 | });
35 | });
36 | },
37 | interceptFileEvent: (callback) => {
38 | document.querySelectorAll('input[type="file"]').forEach(input => {
39 | input.addEventListener('change', function (e) {
40 | try {
41 | callback(e);
42 | } catch (err) {
43 | // TODO raise error to maintainer
44 | }
45 | });
46 | });
47 | },
48 | };
49 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cumulus",
3 | "version": "0.0.2",
4 | "author": "TopHat",
5 | "license": "BSD-3-Clause",
6 | "description": "The official Cumulus SDK for JavaScript, providing as npm",
7 | "repository": "git://github.com/tophat-cloud/cumulus.git",
8 | "bugs": "https://github.com/tophat-cloud/cumulus/issues",
9 | "homepage": "https://cumulus.tophat.cloud",
10 | "main": "src/index.js",
11 | "scripts": {
12 | "test": "jest ./test/*.js",
13 | "test-codecov": "jest --ci --coverage && codecov",
14 | "lint": "eslint ."
15 | },
16 | "browserslist": {
17 | "production": [
18 | "last 10 Chrome versions",
19 | "last 10 Firefox versions",
20 | "last 2 Edge major versions",
21 | "last 2 Safari major versions",
22 | "last 3 iOS major versions",
23 | "last 1 OperaMobile version",
24 | "Firefox ESR"
25 | ],
26 | "development": [
27 | "last 10 Chrome versions",
28 | "last 10 Firefox versions",
29 | "last 2 Edge major versions",
30 | "last 2 Safari major versions",
31 | "last 3 iOS major versions",
32 | "last 1 OperaMobile version",
33 | "Firefox ESR"
34 | ],
35 | "test": [
36 | "current node"
37 | ]
38 | },
39 | "dependencies": {
40 | "axios": "^0.21.4"
41 | },
42 | "devDependencies": {
43 | "codecov": "^3.8.3",
44 | "eslint": "^8.0.0",
45 | "jest": "^27.2.5"
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2021, TopHat
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | * Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/examples/angular/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/1.0/config/configuration-file.html
3 |
4 | module.exports = function (config) {
5 | config.set({
6 | basePath: '',
7 | frameworks: ['jasmine', '@angular-devkit/build-angular'],
8 | plugins: [
9 | require('karma-jasmine'),
10 | require('karma-chrome-launcher'),
11 | require('karma-jasmine-html-reporter'),
12 | require('karma-coverage'),
13 | require('@angular-devkit/build-angular/plugins/karma')
14 | ],
15 | client: {
16 | jasmine: {
17 | // you can add configuration options for Jasmine here
18 | // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
19 | // for example, you can disable the random execution with `random: false`
20 | // or set a specific seed with `seed: 4321`
21 | },
22 | clearContext: false // leave Jasmine Spec Runner output visible in browser
23 | },
24 | jasmineHtmlReporter: {
25 | suppressAll: true // removes the duplicated traces
26 | },
27 | coverageReporter: {
28 | dir: require('path').join(__dirname, './coverage/angular'),
29 | subdir: '.',
30 | reporters: [
31 | { type: 'html' },
32 | { type: 'text-summary' }
33 | ]
34 | },
35 | reporters: ['progress', 'kjhtml'],
36 | port: 9876,
37 | colors: true,
38 | logLevel: config.LOG_INFO,
39 | autoWatch: true,
40 | browsers: ['Chrome'],
41 | singleRun: false,
42 | restartOnFileChange: true
43 | });
44 | };
45 |
--------------------------------------------------------------------------------
/examples/react/src/App.js:
--------------------------------------------------------------------------------
1 | import './App.css';
2 | import logo from './logo.svg';
3 | import { useState } from 'react';
4 | import { protect } from 'cumulus';
5 |
6 | protect({
7 | key: 'rwS5MzP0Ig_hpfWqyAre8',
8 | });
9 |
10 | function App() {
11 | const [keyword, setKeyword] = useState('');
12 |
13 | return (
14 |
57 | );
58 | }
59 |
60 | export default App;
61 |
--------------------------------------------------------------------------------
/examples/react/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 | You need to enable JavaScript to run this app.
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/test/weakness.test.js:
--------------------------------------------------------------------------------
1 | const Xss = require('../src/weakness/xss');
2 | const SqlInjection = require('../src/weakness/sqlinjection');
3 | const Sensitive = require('../src/weakness/sensitive');
4 | const Fileupload = require('../src/weakness/fileupload');
5 |
6 | describe('xss test', () => {
7 | it('detect case', (done) => {
8 | const isDetected = Xss.checkString(' ');
9 | expect(isDetected).toBeTruthy();
10 | done();
11 | });
12 |
13 | it('undetect case', (done) => {
14 | const isDetected = Xss.checkString('Hi, It is xss');
15 | expect(isDetected).not.toBeTruthy();
16 | done();
17 | });
18 | });
19 |
20 |
21 | describe('sqlinjection test', () => {
22 | it('detect case', (done) => {
23 | const isDetected = SqlInjection.checkString('select * from 1');
24 | expect(isDetected).toBeTruthy();
25 | done();
26 | });
27 |
28 | it('undetect case', (done) => {
29 | const isDetected = SqlInjection.checkString('Hi, It is sqlinjection');
30 | expect(isDetected).not.toBeTruthy();
31 | done();
32 | });
33 | });
34 |
35 |
36 | describe('sensitive test', () => {
37 | it('detect case', (done) => {
38 | window = {
39 | location: {
40 | protocol: 'http:'
41 | }
42 | };
43 |
44 | const isDetected = Sensitive.checkJSON({ password: '12345678' });
45 | expect(isDetected).toBeTruthy();
46 | done();
47 | });
48 |
49 | it('undetect case 1', (done) => {
50 | window = {
51 | location: {
52 | protocol: 'https:'
53 | }
54 | };
55 |
56 | const isDetected = Sensitive.checkJSON({ password: '00000000' });
57 | expect(isDetected).not.toBeTruthy();
58 | done();
59 | });
60 |
61 | it('undetect case 2', (done) => {
62 | window = {
63 | location: {
64 | protocol: 'http:'
65 | }
66 | };
67 |
68 | const isDetected = Sensitive.checkJSON({ name: 'jinny you' });
69 | expect(isDetected).not.toBeTruthy();
70 | done();
71 | });
72 | });
73 |
74 |
75 | describe('fileupload test', () => {
76 | // todo write test-code
77 | });
78 |
--------------------------------------------------------------------------------
/examples/react/README.md:
--------------------------------------------------------------------------------
1 | # Cumulus use example for React
2 |
3 |
4 | ```shell
5 | npm install
6 | npm start
7 | ```
8 |
9 | ## Guide
10 | Check the [`./src/App.js`](https://github.com/tophat-cloud/cumulus/blob/main/examples/react/src/App.js)
11 |
12 | Configuration should happen as early as possible in your application's lifecycle.
13 |
14 | ```jsx
15 | import './App.css';
16 | import logo from './logo.svg';
17 | import { useState } from 'react';
18 | import { protect } from 'cumulus';
19 |
20 | protect({
21 | key: 'KMsB9W4hZCejJ6D1fiESP',
22 | });
23 |
24 | function App() {
25 | const [keyword, setKeyword] = useState('');
26 |
27 | return (
28 |
71 | );
72 | }
73 |
74 | export default App;
75 | ```
76 |
--------------------------------------------------------------------------------
/examples/vue/src/components/HelloWorld.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ msg }}
4 |
7 |
8 |
9 | For a guide and recipes on how to configure / customize this project,
10 | check out the
11 | vue-cli documentation .
12 |
13 |
Installed CLI Plugins
14 |
18 |
Essential Links
19 |
26 |
Ecosystem
27 |
34 |
35 |
36 |
37 |
45 |
46 |
47 |
70 |
--------------------------------------------------------------------------------
/examples/react/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/utils/loggers/request.js:
--------------------------------------------------------------------------------
1 | function interceptNetworkRequests(ee) {
2 | const open = XMLHttpRequest.prototype.open;
3 | const send = XMLHttpRequest.prototype.send;
4 |
5 | const isRegularXHR = open.toString().indexOf('native code') !== -1;
6 |
7 | if (isRegularXHR) {
8 | XMLHttpRequest.prototype.open = function() {
9 | ee.onOpen && ee.onOpen(this, arguments);
10 | if (ee.onLoad) {
11 | this.addEventListener('load', ee.onLoad.bind(ee));
12 | }
13 | if (ee.onError) {
14 | this.addEventListener('error', ee.onError.bind(ee));
15 | }
16 | return open.apply(this, arguments);
17 | };
18 | XMLHttpRequest.prototype.send = function() {
19 | ee.onSend && ee.onSend(this, arguments);
20 | return send.apply(this, arguments);
21 | };
22 | }
23 |
24 | const fetch = window.fetch || "";
25 | const isFetchNative = fetch.toString().indexOf('native code') !== -1;
26 | if(isFetchNative) {
27 | window.fetch = function () {
28 | ee.onFetch && ee.onFetch(arguments);
29 | const p = fetch.apply(this, arguments);
30 | p.then(ee.onFetchResponse, ee.onFetchError);
31 | return p;
32 | };
33 | // at the moment, we don't listen to streams which are likely video
34 | const json = Response.prototype.json;
35 | const text = Response.prototype.text;
36 | const blob = Response.prototype.blob;
37 | Response.prototype.json = function () {
38 | const p = json.apply(this.arguments);
39 | p.then(ee.onFetchLoad && ee.onFetchLoad.bind(ee, "json"));
40 | return p;
41 | };
42 | Response.prototype.text = function () {
43 | const p = text.apply(this.arguments);
44 | p.then(ee.onFetchLoad && ee.onFetchLoad.bind(ee, "text"));
45 | return p;
46 | };
47 | Response.prototype.blob = function () {
48 | const p = blob.apply(this.arguments);
49 | p.then(ee.onFetchLoad && ee.onFetchLoad.bind(ee, "blob"));
50 | return p;
51 | };
52 | }
53 | return ee;
54 | }
55 |
56 | module.exports = {
57 | enableLogger: ({
58 | onFetch,
59 | onFetchResponse,
60 | onFetchLoad,
61 | onOpen,
62 | onSend,
63 | onError,
64 | onLoad,
65 | }) => {
66 | interceptNetworkRequests({
67 | onFetch: onFetch,
68 | onFetchResponse: onFetchResponse,
69 | onFetchLoad: onFetchLoad,
70 | onOpen: onOpen,
71 | onSend: onSend,
72 | onError: onError,
73 | onLoad: onLoad,
74 | });
75 | },
76 | }
77 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.toptal.com/developers/gitignore/api/node
3 | # Edit at https://www.toptal.com/developers/gitignore?templates=node
4 |
5 | ### Node ###
6 | # Logs
7 | logs
8 | *.log
9 | npm-debug.log*
10 | yarn-debug.log*
11 | yarn-error.log*
12 | lerna-debug.log*
13 | .pnpm-debug.log*
14 |
15 | # Diagnostic reports (https://nodejs.org/api/report.html)
16 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
17 |
18 | # Runtime data
19 | pids
20 | *.pid
21 | *.seed
22 | *.pid.lock
23 |
24 | # Directory for instrumented libs generated by jscoverage/JSCover
25 | lib-cov
26 |
27 | # Coverage directory used by tools like istanbul
28 | coverage
29 | *.lcov
30 |
31 | # nyc test coverage
32 | .nyc_output
33 |
34 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
35 | .grunt
36 |
37 | # Bower dependency directory (https://bower.io/)
38 | bower_components
39 |
40 | # node-waf configuration
41 | .lock-wscript
42 |
43 | # Compiled binary addons (https://nodejs.org/api/addons.html)
44 | build/Release
45 |
46 | # Dependency directories
47 | node_modules/
48 | jspm_packages/
49 |
50 | # Snowpack dependency directory (https://snowpack.dev/)
51 | web_modules/
52 |
53 | # TypeScript cache
54 | *.tsbuildinfo
55 |
56 | # Optional npm cache directory
57 | .npm
58 |
59 | # Optional eslint cache
60 | .eslintcache
61 |
62 | # Microbundle cache
63 | .rpt2_cache/
64 | .rts2_cache_cjs/
65 | .rts2_cache_es/
66 | .rts2_cache_umd/
67 |
68 | # Optional REPL history
69 | .node_repl_history
70 |
71 | # Output of 'npm pack'
72 | *.tgz
73 |
74 | # Yarn Integrity file
75 | .yarn-integrity
76 |
77 | # dotenv environment variables file
78 | .env
79 | .env.test
80 | .env.production
81 |
82 | # parcel-bundler cache (https://parceljs.org/)
83 | .cache
84 | .parcel-cache
85 |
86 | # Next.js build output
87 | .next
88 | out
89 |
90 | # Nuxt.js build / generate output
91 | .nuxt
92 | dist
93 |
94 | # Gatsby files
95 | .cache/
96 | # Comment in the public line in if your project uses Gatsby and not Next.js
97 | # https://nextjs.org/blog/next-9-1#public-directory-support
98 | # public
99 |
100 | # vuepress build output
101 | .vuepress/dist
102 |
103 | # Serverless directories
104 | .serverless/
105 |
106 | # FuseBox cache
107 | .fusebox/
108 |
109 | # DynamoDB Local files
110 | .dynamodb/
111 |
112 | # TernJS port file
113 | .tern-port
114 |
115 | # Stores VSCode versions used for testing VSCode extensions
116 | .vscode-test
117 |
118 | # yarn v2
119 | .yarn/cache
120 | .yarn/unplugged
121 | .yarn/build-state.yml
122 | .yarn/install-state.gz
123 | .pnp.*
124 |
125 | .DS_Store
126 | # End of https://www.toptal.com/developers/gitignore/api/node
--------------------------------------------------------------------------------
/examples/angular/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file includes polyfills needed by Angular and is loaded before the app.
3 | * You can add your own extra polyfills to this file.
4 | *
5 | * This file is divided into 2 sections:
6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
8 | * file.
9 | *
10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
13 | *
14 | * Learn more in https://angular.io/guide/browser-support
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /**
22 | * IE11 requires the following for NgClass support on SVG elements
23 | */
24 | // import 'classlist.js'; // Run `npm install --save classlist.js`.
25 |
26 | /**
27 | * Web Animations `@angular/platform-browser/animations`
28 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
29 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
30 | */
31 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
32 |
33 | /**
34 | * By default, zone.js will patch all possible macroTask and DomEvents
35 | * user can disable parts of macroTask/DomEvents patch by setting following flags
36 | * because those flags need to be set before `zone.js` being loaded, and webpack
37 | * will put import in the top of bundle, so user need to create a separate file
38 | * in this directory (for example: zone-flags.ts), and put the following flags
39 | * into that file, and then add the following code before importing zone.js.
40 | * import './zone-flags';
41 | *
42 | * The flags allowed in zone-flags.ts are listed here.
43 | *
44 | * The following flags will work for all browsers.
45 | *
46 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
47 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
48 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
49 | *
50 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
51 | * with the following flag, it will bypass `zone.js` patch for IE/Edge
52 | *
53 | * (window as any).__Zone_enable_cross_context_check = true;
54 | *
55 | */
56 |
57 | /***************************************************************************************************
58 | * Zone JS is required by default for Angular itself.
59 | */
60 | import 'zone.js'; // Included with Angular CLI.
61 |
62 |
63 | /***************************************************************************************************
64 | * APPLICATION IMPORTS
65 | */
66 |
--------------------------------------------------------------------------------
/examples/angular/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "version": 1,
4 | "newProjectRoot": "projects",
5 | "projects": {
6 | "angular": {
7 | "projectType": "application",
8 | "schematics": {
9 | "@schematics/angular:application": {
10 | "strict": true
11 | }
12 | },
13 | "root": "",
14 | "sourceRoot": "src",
15 | "prefix": "app",
16 | "architect": {
17 | "build": {
18 | "builder": "@angular-devkit/build-angular:browser",
19 | "options": {
20 | "outputPath": "dist/angular",
21 | "index": "src/index.html",
22 | "main": "src/main.ts",
23 | "polyfills": "src/polyfills.ts",
24 | "tsConfig": "tsconfig.app.json",
25 | "assets": [
26 | "src/favicon.ico",
27 | "src/assets"
28 | ],
29 | "styles": [
30 | "src/styles.css"
31 | ],
32 | "scripts": []
33 | },
34 | "configurations": {
35 | "production": {
36 | "budgets": [
37 | {
38 | "type": "initial",
39 | "maximumWarning": "500kb",
40 | "maximumError": "1mb"
41 | },
42 | {
43 | "type": "anyComponentStyle",
44 | "maximumWarning": "2kb",
45 | "maximumError": "4kb"
46 | }
47 | ],
48 | "fileReplacements": [
49 | {
50 | "replace": "src/environments/environment.ts",
51 | "with": "src/environments/environment.prod.ts"
52 | }
53 | ],
54 | "outputHashing": "all"
55 | },
56 | "development": {
57 | "buildOptimizer": false,
58 | "optimization": false,
59 | "vendorChunk": true,
60 | "extractLicenses": false,
61 | "sourceMap": true,
62 | "namedChunks": true
63 | }
64 | },
65 | "defaultConfiguration": "production"
66 | },
67 | "serve": {
68 | "builder": "@angular-devkit/build-angular:dev-server",
69 | "configurations": {
70 | "production": {
71 | "browserTarget": "angular:build:production"
72 | },
73 | "development": {
74 | "browserTarget": "angular:build:development"
75 | }
76 | },
77 | "defaultConfiguration": "development"
78 | },
79 | "extract-i18n": {
80 | "builder": "@angular-devkit/build-angular:extract-i18n",
81 | "options": {
82 | "browserTarget": "angular:build"
83 | }
84 | },
85 | "test": {
86 | "builder": "@angular-devkit/build-angular:karma",
87 | "options": {
88 | "main": "src/test.ts",
89 | "polyfills": "src/polyfills.ts",
90 | "tsConfig": "tsconfig.spec.json",
91 | "karmaConfig": "karma.conf.js",
92 | "assets": [
93 | "src/favicon.ico",
94 | "src/assets"
95 | ],
96 | "styles": [
97 | "src/styles.css"
98 | ],
99 | "scripts": []
100 | }
101 | }
102 | }
103 | }
104 | },
105 | "defaultProject": "angular"
106 | }
107 |
--------------------------------------------------------------------------------
/src/utils/interceptors/request.js:
--------------------------------------------------------------------------------
1 | function interceptNetworkRequests(ee) {
2 | const open = XMLHttpRequest.prototype.open;
3 | const send = XMLHttpRequest.prototype.send;
4 |
5 | const isRegularXHR = open.toString().indexOf('native code') !== -1;
6 |
7 | if (isRegularXHR) {
8 | XMLHttpRequest.prototype.open = function() {
9 | ee.onOpen && ee.onOpen(this, arguments);
10 | if (ee.onLoad) {
11 | this.addEventListener('load', ee.onLoad.bind(ee));
12 | }
13 | if (ee.onError) {
14 | this.addEventListener('error', ee.onError.bind(ee));
15 | }
16 | return open.apply(this, arguments);
17 | };
18 | XMLHttpRequest.prototype.send = function() {
19 | ee.onSend && ee.onSend(this, arguments);
20 | return send.apply(this, arguments);
21 | };
22 | }
23 |
24 | const fetch = window.fetch || "";
25 | const isFetchNative = fetch.toString().indexOf('native code') !== -1;
26 | if(isFetchNative) {
27 | window.fetch = function () {
28 | ee.onFetch && ee.onFetch(arguments);
29 | const p = fetch.apply(this, arguments);
30 | p.then(ee.onFetchResponse, ee.onFetchError);
31 | return p;
32 | };
33 | // at the moment, we don't listen to streams which are likely video
34 | const json = Response.prototype.json;
35 | const text = Response.prototype.text;
36 | const blob = Response.prototype.blob;
37 | Response.prototype.json = function () {
38 | const p = json.apply(this.arguments);
39 | p.then(ee.onFetchLoad && ee.onFetchLoad.bind(ee, "json"));
40 | return p;
41 | };
42 | Response.prototype.text = function () {
43 | const p = text.apply(this.arguments);
44 | p.then(ee.onFetchLoad && ee.onFetchLoad.bind(ee, "text"));
45 | return p;
46 | };
47 | Response.prototype.blob = function () {
48 | const p = blob.apply(this.arguments);
49 | p.then(ee.onFetchLoad && ee.onFetchLoad.bind(ee, "blob"));
50 | return p;
51 | };
52 | }
53 | return ee;
54 | }
55 |
56 | module.exports = {
57 | interceptRequest: (callback) => {
58 | interceptNetworkRequests({
59 | onFetch: (data) => {
60 | // for req of fetch API
61 | try {
62 | const payload = JSON.parse(data[1].body);
63 | callback(payload);
64 | } catch (e) {
65 | // TODO raise error to maintainer
66 | }
67 | },
68 | onFetchResponse: async (data) => {
69 | // for req of fetch API
70 | try {
71 | const clone = data.clone();
72 | const { value } = await clone.body.getReader().read();
73 | const payload = String.fromCharCode.apply(null, value);
74 |
75 | callback(payload);
76 | } catch (e) {
77 | // TODO raise error to maintainer
78 | }
79 | },
80 | onSend: (_, data) => {
81 | // for req of axios API
82 | try {
83 | const payload = JSON.parse(data[0]);
84 | callback(payload);
85 | } catch (e) {
86 | // TODO raise error to maintainer
87 | }
88 | },
89 | onOpen: async (self) => {
90 | // for res of axios API
91 | try {
92 | const promise = new Promise((resolve, reject) => {
93 | const timer = setTimeout(() => {
94 | reject();
95 | }, 3000);
96 |
97 | self.addEventListener('load', function() {
98 | clearTimeout(timer);
99 |
100 | const response = JSON.parse(this.responseText);
101 | resolve(response);
102 | });
103 | });
104 |
105 | const payload = await promise();
106 | callback(payload);
107 | } catch (e) {
108 | // TODO raise error to maintainer
109 | }
110 | },
111 | });
112 | },
113 | };
114 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Application Weakness Monitoring Software
9 |
10 |
11 |
12 | 
13 | [](https://codecov.io/gh/tophat-cloud/cumulus)
14 | [](https://github.com/tophat-cloud/cumulus/releases/tag/v0.0.2)
15 | [](https://discord.gg/BH7h6F2C7N)
16 |
17 |
18 |
19 | # What's Cumulus
20 |
21 | Cumulus is a service that helps you monitor and fix security weakness
22 | in realtime. The issues will be reported on web dashboard. It's very simple and powerful.
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | # Key features
31 | Just install SDK to web front, can be found security weakness on service
32 |
33 | - SDK detect weakness from Inner Layer, dynamically (ex_ DOM Event, XHR Request)
34 | - Scanner detect weakness from Out Layer, statically (ex_ Web crawling based analysis)
35 |
36 |
37 | | Name | Origin | Description |
38 | | ---- | ---- | ---- |
39 | | XSS | SDK | When user input a xss pattern string, trigger detection of XSS
40 | | SQLInjection | SDK | When user input a sqlinjection pattern, trigger detection of SQLInjection
41 | | Sensitive Payload | SDK | When requesting with sensitive payload. for example, unencoded raw password
42 | | File Upload | SDK | When user embed any file worried for system. for example, web shell
43 | | Unnecessary Comment | Scanner | Code comments are on the served HTML or JS
44 | | Directory Traversal | Scanner | Detect directory listing vulnerability
45 | | Guessing | Scanner | Detect sensitive page like admin
46 | | Unobfuscated Code | Scanner | Detect unobfuscated vulnerable codes
47 |
48 | If you think about able to detect additional weakness, please contribute on SDK or Scanner
49 |
50 | # Cumulus SDK for JavaScript
51 |
52 | The official Cumulus SDK for JavaScript, providing as npm
53 |
54 | > Note: current version is unsupported version on typescript project but we considering now and gonna make it, quickly! ([#2](https://github.com/tophat-cloud/cumulus/issues/2))
55 |
56 | ## Installation
57 |
58 | To install a SDK, simply add package like belows:
59 |
60 | ```
61 | npm install --save https://github.com/tophat-cloud/cumulus
62 | yarn add https://github.com/tophat-cloud/cumulus
63 | ```
64 |
65 | Setup and usage of SDK always follow the same principle.
66 |
67 | ```javascript
68 | import { protect, captureMessage } from 'cumulus';
69 |
70 | protect({
71 | key: '__key__',
72 | });
73 |
74 | captureMessage('Hello, world!');
75 | ```
76 |
77 | > If you haven't `__key__`, please [sign-up](https://cumulus.tophat.cloud/signup) and create project to get to key
78 |
79 | ## Contents
80 | - [Official Site](https://cumulus.tophat.cloud)
81 | - [Contributing](https://github.com/tophat-cloud/cumulus/blob/main/CONTRIBUTING.md)
82 | - [Change log](https://github.com/tophat-cloud/cumulus/blob/main/CHANGELOG.md)
83 | - [OpenSource License](https://cumulus.tophat.cloud/license.html)
84 | - [Documents](https://github.com/tophat-cloud/cumulus/wiki)
85 | - [Roadmap](https://github.com/tophat-cloud/cumulus/projects/1)
86 |
87 | ## Resources
88 | - [cumulus-scanner](https://github.com/tophat-cloud/cumulus-scanner)
89 | - [cumulus-front](https://github.com/tophat-cloud/cumulus-front)
90 | - [cumulus-back](https://github.com/tophat-cloud/cumulus-back)
91 |
92 | ## Author
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 | @Jinny You   from TopHat
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | # Contributing
10 |
11 | Welcome and Thanks your suggestion! we ready for accept grateful idea.
12 | Just throw your idea in the form of pull requests on [GitHub](https://github.com/tophat-cloud/tophat-cumulus-sdk).
13 | Let's contribute and be a cumulus family!
14 |
15 |
16 | ## Environment
17 |
18 | - node v14.16^
19 | - yarn v1.22^
20 |
21 |
22 | ## Setup
23 | ```
24 | npm install
25 | yarn install
26 | ```
27 |
28 |
29 | ## Running SDK (via fork)
30 |
31 | If you want to testing your version. you can just fork this repository and install your test project like belows:
32 |
33 | ```
34 | npm install https://github.com/path/to/repo
35 | yarn add https://github.com/path/to/repo
36 | ```
37 |
38 | ## Adding New Weakness
39 | If you found new weakness logic then add file to `./src/weakness/{name}.js`
40 |
41 | - each files on weakness directory are for finding each weakness.
42 | - also the file name will be report type name on cumulus service.
43 |
44 | For a case study, when you want to writing a logic about CSRF, create `csrf.js`:
45 | ```javascript
46 | class CSRF { // set class name as upper camel case
47 | checkString(data) {
48 | let isDetected = false;
49 |
50 | // TODO something to write for detection logic
51 |
52 | return isDetected; // must to be return boolean type
53 | }
54 | }
55 |
56 | module.exports = new CSRF();
57 | ```
58 |
59 | ## Improve Exsited Weakness
60 | If you want to contribute to exsited weakness logic, you can touch on middle of weakness class code:
61 | ```javascript
62 | class Xss {
63 | checkString(data) {
64 | let isDetected = false;
65 |
66 | const regExp = /<|>|<|>|&|"|'/;
67 | isDetected = regExp.test(data);
68 |
69 | // TODO something to write for improve logic
70 |
71 | return isDetected;
72 | }
73 |
74 | // NOTE or you can add new function like `checkType(data)`
75 | }
76 |
77 | module.exports = new Xss();
78 | ```
79 |
80 |
81 | ## Adding Tests
82 |
83 | Any nontrivial fixes/features should include tests. we have a test folder.
84 |
85 | You can write test code, about weakness logic is in `weakness.test.js`, the others are in `core.test.js`, also can suggest new kind of test code. please reference [./test](https://github.com/tophat-cloud/cumulus/tree/main/test).
86 |
87 | Don't forget to add test code when you add new logic for weakness!
88 |
89 | ## Running Tests
90 |
91 | Running tests works:
92 |
93 | ```
94 | yarn test
95 | ```
96 |
97 | Note: can triggering to test for only `*.test.js`.
98 |
99 | ## Linting
100 |
101 | Linting whole codes:
102 |
103 | ```
104 | yarn lint
105 | ```
106 |
107 | Note: we adopt [eslint](https://eslint.org/) for javascript linting.
108 |
109 |
110 | ## Versioning & Branch
111 | - We adopt [semver](https://semver.org) as versioning.
112 | - We adopt Git Flow branch strategy.
113 |
114 |
115 | ## Considerations Before Sending PR
116 | When contributing to the codebase, please note:
117 |
118 | - Non-trivial PRs will not be accepted without tests (see above).
119 | - Please do not bump version numbers yourself.
120 | - Please use [template](https://github.com/tophat-cloud/cumulus/blob/main/.github/ISSUE_TEMPLATE/bug_report.md) as much as possible
121 |
122 |
123 | ## Found an Issue?
124 | If you have found a bug then raise an issue on the cumulus repo: https://github.com/tophat-cloud/cumulus/issues
125 |
126 | Its worth checking to see if its already been reported, and including as much information as you can to help us diagnose your problem.
127 |
128 |
129 | ## Got a Question or Problem?
130 | If you have a question or problem relating to using Cumulus then you can contact to [Email](mailto:team@tophat.cloud).
131 |
132 | Or please visit user group on [Discord](https://discord.gg/BH7h6F2C7N)
133 |
134 |
135 | ## Publishing a Release
136 | These steps are only relevant to Cumulus employees when preparing and publishing a new SDK release.
137 |
138 | 1. Determine what version will be released (we use [semver](https://semver.org/)).
139 | 2. Update [CHANGELOG.md](https://github.com/tophat-cloud/cumulus/blob/main/CHANGELOG.md) to add an entry for the next release number and a list of 3. changes since the last release.
140 | 4. Run the Prepare Release workflow.
141 | 5. A new issue should appear in https://github.com/tophat-cloud/cumulus/issues.
142 | 6. Ask a member of the [@tophat-cloud](https://github.com/tophat-cloud) team to approve the release.
143 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | const Api = require('./networks/api');
2 | const Xss = require('./weakness/xss');
3 | const SqlInjection = require('./weakness/sqlinjection');
4 | const FileUpload = require('./weakness/fileupload');
5 | const Sensitive = require('./weakness/sensitive');
6 |
7 | // const domLogger = require('./utils/loggers/dom');
8 | // const requestLogger = require('./utils/loggers/request');
9 | const domInterceptor = require('./utils/interceptors/dom');
10 | const requestInterceptor = require('./utils/interceptors/request');
11 |
12 | let projectKey = '';
13 | let isLoading = true;
14 | let isAPIError = false;
15 |
16 | window.onload = async () => {
17 | const domain = window.location.host;
18 |
19 | if (!projectKey) {
20 | return;
21 | }
22 |
23 |
24 | let api;
25 | isLoading = true;
26 |
27 | try {
28 | api = new Api(projectKey);
29 | await api.registerKey(domain);
30 | } catch (e) {
31 | isAPIError = true;
32 | isLoading = false;
33 | return;
34 | }
35 |
36 | isAPIError = false;
37 | isLoading = false;
38 |
39 | // domLogger.enableLogger((key, event) => {
40 | // console.log(key, event);
41 | // });
42 |
43 | // requestLogger.enableLogger({
44 | // onFetch: console.log,
45 | // onFetchResponse: console.log,
46 | // onFetchLoad: console.log,
47 | // onOpen: console.log,
48 | // onSend: console.log,
49 | // onError: console.log,
50 | // onLoad: console.log,
51 | // });
52 |
53 | domInterceptor.interceptInputEvent(
54 | function (e) {
55 | const value = e.target.value;
56 |
57 | if (Xss.checkString(value)) {
58 | // console.log('xss deteted');
59 |
60 | api.createThunder(
61 | 'XSS',
62 | window.location.href,
63 | '1',
64 | JSON.stringify({
65 | description: 'Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted websites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user. Flaws that allow these attacks to succeed are quite widespread and occur anywhere a web application uses input from a user within the output it generates without validating or encoding it.',
66 | suggestion: 'Filter input on arrival - At the point where user input is received, filter as strictly as possible based on what is expected or valid input.',
67 | reference: 'https://portswigger.net/web-security/cross-site-scripting',
68 | }),
69 | );
70 | }
71 |
72 | if (SqlInjection.checkString(value)) {
73 | // console.log('sqlinjection deteted');
74 |
75 | api.createThunder(
76 | 'SQLInjection',
77 | window.location.href,
78 | '1',
79 | JSON.stringify({
80 | description: `In this section, we'll explain what SQL injection is, describe some common examples, explain how to find and exploit various kinds of SQL injection vulnerabilities, and summarize how to prevent SQL injection.`,
81 | suggestion: `Most instances of SQL injection can be prevented by using parameterized queries (also known as prepared statements) instead of string concatenation within the query.`,
82 | reference: 'https://portswigger.net/web-security/sql-injection',
83 | }),
84 | );
85 | }
86 | }
87 | );
88 |
89 | domInterceptor.interceptFileEvent(
90 | function (e) {
91 | const value = e.target.files;
92 |
93 | for (const file of value) {
94 | if (FileUpload.checkBinary(file)) {
95 | // console.log('fileupload deteted');
96 |
97 | api.createThunder(
98 | 'File Upload',
99 | window.location.href,
100 | '2',
101 | JSON.stringify({
102 | description: `File upload is becoming a more and more essential part of any application, where the user is able to upload their photo, their CV, or a video showcasing a project they are working on. The application should be able to fend off bogus and malicious files in a way to keep the application and the users safe.`,
103 | suggestion: `Finding missed extensions that can be executed on the server side or can be dangerous on the client side (e.g. “.php5”, “.pht”, “.phtml”, “.shtml”, “.asa”, “.cer”, “.asax”, “.swf”, or “.xap”).`,
104 | reference: 'https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload',
105 | }),
106 | );
107 | }
108 | }
109 | }
110 | );
111 |
112 | requestInterceptor.interceptRequest(
113 | function (body) {
114 | if (!body) {
115 | // NOTE: req body unavailable case
116 | return;
117 | }
118 |
119 | if (Sensitive.checkJSON(body)) {
120 | // console.log('sensitive detected');
121 |
122 | api.createThunder(
123 | 'Sensitive Payload',
124 | window.location.href,
125 | '2',
126 | JSON.stringify({
127 | description: `When you send sensitive data as request payload, It's triggering. for example, send password via non-SSL`,
128 | suggestion: `Sensitive information must be encrypted during transmission over networks that are easily accessed by malicious individuals. Misconfigured wireless networks and vulnerabilities in legacy encryption and authentication protocols continue to be targets of malicious individuals who exploit these vulnerabilities to gain privileged access to cardholder data environments`,
129 | reference: 'https://developer.mastercard.com/platform/documentation/security-and-authentication/securing-sensitive-data-using-payload-encryption/',
130 | }),
131 | );
132 | }
133 | }
134 | );
135 | };
136 |
137 |
138 | const protect = ({ key }) => {
139 | if (!key) {
140 | console.warn(`[cumulus] can't find project key!`);
141 | return;
142 | }
143 |
144 | projectKey = key;
145 | };
146 |
147 | const captureMessage = (msg) => {
148 | if (!projectKey) {
149 | console.error(`[cumulus] couldn't start - please register projectKey with call protect function.`);
150 | return;
151 | }
152 |
153 | if (isLoading) {
154 | console.warn(`[cumulus] too fast call - checking project key, please call captureMessage at little later moment.`);
155 | return;
156 | }
157 |
158 | if (isAPIError) {
159 | console.error(`[cumulus] couldn't start - please check your projectKey is valid.`);
160 | return;
161 | }
162 |
163 | console.log(`[cumulus] ${msg}`);
164 | };
165 |
166 | module.exports = {
167 | protect,
168 | captureMessage,
169 | };
170 |
--------------------------------------------------------------------------------
/examples/angular/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
304 |
305 |
306 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 | Rocket Ship
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
{{ title }} app is running!
345 |
346 |
347 | Rocket Ship Smoke
348 |
349 |
350 |
351 |
352 |
353 |
354 |
Resources
355 |
Here are some links to help you get started:
356 |
357 |
358 |
359 |
360 |
385 |
386 |
387 |
Next Steps
388 |
What do you want to do next with your app?
389 |
390 |
391 |
392 |
393 |
394 |
395 | New Component
396 |
397 |
398 |
399 |
400 | Angular Material
401 |
402 |
403 |
404 |
405 | Add PWA Support
406 |
407 |
408 |
409 |
410 | Add Dependency
411 |
412 |
413 |
414 |
415 | Run and Watch Tests
416 |
417 |
418 |
419 |
420 | Build for Production
421 |
422 |
423 |
424 |
425 |
426 |
ng generate component xyz
427 |
ng add @angular/material
428 |
ng add @angular/pwa
429 |
ng add _____
430 |
ng test
431 |
ng build
432 |
433 |
434 |
435 |
474 |
475 |
476 |
488 |
489 |
490 | Gray Clouds Background
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
--------------------------------------------------------------------------------