Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
derevnjuk committed Nov 4, 2022
2 parents 43a4662 + 4725cfb commit 78a4731
Show file tree
Hide file tree
Showing 22 changed files with 729 additions and 969 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,5 @@ Full configuration & usage examples can be found in our [demo project](https://g
* **XML External Entity (XXE)** - The endpoint, POST /api/metadata, receives URL-encoded XML data in the _xml_ query parameter, processes it with enabled external entities (using libxmnl library) and returns the serialized DOM. Additionally, for a request that tries to load file:///etc/passwd as an entity, the endpoint returns a mocked up content of the file.

* **JavaScript Vulnerabilities Scanning** - Index.html includes an older version of the jQuery library with known vulnerabilities.

* **AO1 Vertical access controls** - The page /dashboard can be reached despite the rights of user.
1,206 changes: 360 additions & 846 deletions package-lock.json

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@
"@nestjs/core": "^7.6.7",
"@nestjs/platform-fastify": "^7.6.7",
"@nestjs/swagger": "^4.7.12",
"@sectester/bus": "^0.16.2",
"@sectester/core": "^0.16.2",
"@sectester/repeater": "^0.16.2",
"@sectester/reporter": "^0.16.2",
"@sectester/runner": "^0.16.2",
"@sectester/scan": "^0.16.2",
"@sectester/bus": "^0.16.5",
"@sectester/core": "^0.16.5",
"@sectester/repeater": "^0.16.5",
"@sectester/reporter": "^0.16.5",
"@sectester/runner": "^0.16.5",
"@sectester/scan": "^0.16.5",
"axios": "^0.21.2",
"bcrypt": "^5.0.0",
"class-transformer": "^0.5.1",
Expand All @@ -45,11 +45,11 @@
"fastify-multipart": "^5.3.1",
"fastify-session": "^5.2.1",
"fastify-swagger": "^4.0.1",
"jose": "^4.5.0",
"jose": "^4.10.4",
"jsonwebtoken": "^8.5.1",
"jwk-to-pem": "^2.0.5",
"jwt-simple": "^0.5.6",
"libxmljs": "^0.19.7",
"libxmljs": "^0.19.10",
"node-jwk": "^0.1.0",
"pg": "^8.7.1",
"raw-body": "^2.4.1",
Expand Down Expand Up @@ -80,7 +80,7 @@
"eslint-config-prettier": "^6.15.0",
"eslint-plugin-prettier": "^3.1.4",
"jest": "^26.6.3",
"nodemon": "^2.0.6",
"nodemon": "^2.0.20",
"prettier": "^2.1.2",
"supertest": "^6.0.0",
"ts-jest": "^26.4.3",
Expand Down
6 changes: 3 additions & 3 deletions pg.sql
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
set names 'utf8';
set session_replication_role = 'replica';

create table "user" ("id" serial primary key, "created_at" timestamptz(0) not null, "updated_at" timestamptz(0) not null, "email" varchar(255) not null, "password" varchar(255) not null, "first_name" varchar(255) not null, "last_name" varchar(255) not null, "is_admin" bool not null, "photo" bytea null);
create table "user" ("id" serial primary key, "created_at" timestamptz(0) not null, "updated_at" timestamptz(0) not null, "email" varchar(255) not null, "password" varchar(255) not null, "first_name" varchar(255) not null, "last_name" varchar(255) not null, "is_admin" bool not null, "photo" bytea null, "company" varchar(255) not null, "card_number" varchar(255) not null, "phone_number" varchar(255) not null);

create table "testimonial" ("id" serial primary key, "created_at" timestamptz(0) not null, "updated_at" timestamptz(0) not null, "name" varchar(255) not null, "title" varchar(255) not null, "message" varchar(255) not null);

create table "product" ("id" serial primary key, "created_at" timestamptz(0) not null default now(), "category" varchar(255) not null, "photo_url" varchar(255) not null, "name" varchar(255) not null, "description" varchar(255) null);

set session_replication_role = 'origin';
--password is admin
INSERT INTO "user" (created_at, updated_at, email, password, first_name, last_name, is_admin, photo) VALUES (now(), now(), 'admin', '$2b$10$BBJjmVNNdyEgv7pV/zQR9u/ssIuwZsdDJbowW/Dgp28uws3GmO0Ky', 'admin', 'admin', true, null);
INSERT INTO "user" (created_at, updated_at, email, password, first_name, last_name, is_admin, photo) VALUES (now(), now(), 'user', '$2b$10$edsq4aqzAHnrJu68t8GS2.v0Z7hJSstAo7wBBDmmbpjYGxMMTYpVi', 'user', 'user', false, null);
INSERT INTO "user" (created_at, updated_at, email, password, first_name, last_name, is_admin, photo, company, card_number, phone_number) VALUES (now(), now(), 'admin', '$2b$10$BBJjmVNNdyEgv7pV/zQR9u/ssIuwZsdDJbowW/Dgp28uws3GmO0Ky', 'admin', 'admin', true, null, 'Brightsec', '1234 5678 9012 3456', '+1 234 567 890');
INSERT INTO "user" (created_at, updated_at, email, password, first_name, last_name, is_admin, photo, company, card_number, phone_number) VALUES (now(), now(), 'user', '$2b$10$edsq4aqzAHnrJu68t8GS2.v0Z7hJSstAo7wBBDmmbpjYGxMMTYpVi', 'user', 'user', false, null, 'Brightsec', '1234 5678 9012 3456', '+1 234 567 890');

--insert default products into the table
INSERT INTO "product" ("category", "photo_url", "name", "description") VALUES ('Healing', '/api/file?path=config/products/crystals/amethyst.jpg&type=image/jpg', 'Amethyst', 'a violet variety of quartz');
Expand Down
19 changes: 19 additions & 0 deletions public/public/css/theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,25 @@ section {
color: #b0b0b0;
}

.admin-wrap {
max-width: 700px;
padding-top: 8vh;
margin: 0 auto;
}

.admin-content {
background: #fff;
padding: 30px 30px 20px;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
}

.admin-logo {
text-align: center;
margin-bottom: 30px;
}

@media (max-width: 991px) {
.login-checkbox {
-webkit-box-orient: vertical;
Expand Down
11 changes: 11 additions & 0 deletions public/src/api/httpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,17 @@ export function getUser(
});
}

export function searchUsers(searchText: string): Promise<any> {
return makeApiRequest({
url: `${ApiUrl.Users}/search/${searchText}`,
method: 'get',
headers: {
authorization:
sessionStorage.getItem('token') || localStorage.getItem('token')
}
});
}

export function getUserData(
email: string,
config: AxiosRequestConfig = {}
Expand Down
5 changes: 5 additions & 0 deletions public/src/interfaces/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ export interface RegistrationUser {
email: string;
lastName: string;
firstName: string;
company: string;
cardNumber: string;
phoneNumber: string;
password?: string;
op?: LoginFormMode;
}
Expand All @@ -34,4 +37,6 @@ export interface UserData {
lastName: string;
firstName: string;
isAdmin?: boolean;
id: string;
company: string;
}
29 changes: 29 additions & 0 deletions public/src/pages/auth/AdminLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React, { FC } from 'react';

export const AdminLayout: FC = ({ children }) => {
return (
<div className="page-content--bge5">
<div className="container">
<div className="admin-wrap">
<div className="admin-content">
<div className="admin-logo">
<a href="/" className="logo mr-auto">
<img
width={100}
height={100}
src="assets/img/logo_blue.png"
alt=""
className="img-fluid"
/>
BROKEN CRYSTALS
</a>
</div>
{children}
</div>
</div>
</div>
</div>
);
};

export default AdminLayout;
43 changes: 36 additions & 7 deletions public/src/pages/auth/AdminPage.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,52 @@
import React, { FC, useEffect, useState } from 'react';
import { getAdminStatus } from '../../api/httpClient';
import AuthLayout from './AuthLayout';
import { UserData } from '../../interfaces/User';
import { getAdminStatus, searchUsers } from '../../api/httpClient';
import AdminLayout from './AdminLayout';

export const AdminPage: FC = () => {
const user = sessionStorage.getItem('email') || localStorage.getItem('email');
const [isAdmin, setIsAdmin] = useState<boolean>(false);
const [inputValue, setInputValue] = useState('');
const [users, setUsers] = useState<UserData[]>([]);

const onInput = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(e.target.value);
};

useEffect(() => {
if (user) getAdminStatus(user).then((data) => setIsAdmin(!!data.isAdmin));
}, [user]);
if (user) {
getAdminStatus(user).then((data) => setIsAdmin(!!data.isAdmin));
searchUsers(inputValue).then((data) => {
setUsers(data);
});
}
}, [user, inputValue]);

return (
<AuthLayout>
<AdminLayout>
{isAdmin ? (
<div>This is AdminPage</div>
<>
<div>User catalog:</div>
<input
type="text"
className="au-input au-input--full"
placeholder="Start typing name"
onChange={onInput}
/>
<div>
{users.map((user) => (
<div key={user.id}>
<b>First name:</b> {user.firstName}, <b>Last name:</b>{' '}
{user.lastName},<b>e-mail:</b> {user.email}, <b>company:</b>{' '}
{user.company}
</div>
))}
</div>
</>
) : (
<div>This page is forbidden for you</div>
)}
</AuthLayout>
</AdminLayout>
);
};

Expand Down
19 changes: 19 additions & 0 deletions public/src/pages/auth/Dashboard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React, { FC } from 'react';
import AuthLayout from './AuthLayout';

export const Dashboard: FC = () => {
return (
<AuthLayout>
<div>
<div>This is Admin Dashboard.</div>
<>This page represents </>
<a href="https://owasp.org/Top10/A01_2021-Broken_Access_Control/">
AO1 Vertical access controls
</a>
<> issue</>
</div>
</AuthLayout>
);
};

export default Dashboard;
49 changes: 48 additions & 1 deletion public/src/pages/auth/Register/Register.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,24 @@ const defaultUser: RegistrationUser = {
email: '',
firstName: '',
lastName: '',
company: '',
cardNumber: '',
phoneNumber: '',
password: '',
op: LoginFormMode.BASIC
};

export const Register: FC = () => {
const [form, setForm] = useState<RegistrationUser>(defaultUser);
const { email, firstName, lastName, password } = form;
const {
email,
firstName,
lastName,
password,
company,
cardNumber,
phoneNumber
} = form;

const [regResponse, setRegResponse] = useState<RegistrationUser | null>();
const [errorText, setErrorText] = useState<string | null>();
Expand Down Expand Up @@ -98,6 +109,42 @@ export const Register: FC = () => {
/>
</div>

<div className="form-group">
<label>Company</label>
<input
className="au-input au-input--full"
type="text"
name="company"
placeholder="Company"
value={company}
onInput={onInput}
/>
</div>

<div className="form-group">
<label>Card number</label>
<input
className="au-input au-input--full"
type="text"
name="cardNumber"
placeholder="Card number"
value={cardNumber}
onInput={onInput}
/>
</div>

<div className="form-group">
<label>Phone number</label>
<input
className="au-input au-input--full"
type="text"
name="phoneNumber"
placeholder="Phone number"
value={phoneNumber}
onInput={onInput}
/>
</div>

<div className="form-group">
<label>Email Address</label>
<input
Expand Down
Loading

0 comments on commit 78a4731

Please sign in to comment.