Skip to content

Commit

Permalink
完善文档
Browse files Browse the repository at this point in the history
  • Loading branch information
shxgreen committed Oct 11, 2023
0 parents commit 8fa64d0
Show file tree
Hide file tree
Showing 69 changed files with 20,321 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
35 changes: 35 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# local env files
.env*.local
# vercel
/.vercel/

# typescript
*.tsbuildinfo
next-env.d.ts

/.vscode/

/wrangler.toml
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 onxss

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
68 changes: 68 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
![logo-no-background](./assets/logo-no-background.png)

# One XSS

- One XSS 是一款基于Cloudflare Pages/D1/KV实现的在线XSS平台,可自定义模块和项目,用于帮助渗透测试工程师进行XSS漏洞验证.

> 免责声明:此工具仅限于安全研究,用户承担因使用此工具而导致的所有法律和相关责任!作者不承担任何法律责任!
## 一、主要功能

1. 支持按URL区分XSS不同的项目
2. 支持用户自定义XSS模块
3. 支持项目Telegram提醒
4. 支持XSS Javascript代码混淆
5. 支持XSS日志根据项目所用模块,展示不同数据
6. 实现基本的用户管理
7. 实现用户邀请码注册功能

## 二、技术栈

- node.js
- Ant Design / Ant Design Pro
- next.js
- Cloudflare Pages
- Cloudflare Workers
- Cloudflare D1 无服务器 SQL 数据库
- Cloudflare KV 键值对

## 三、安装部署

- [查看部署说明Wiki](https://github.com/onxss/OneXSS/wiki/%E9%83%A8%E7%BD%B2%E8%AF%B4%E6%98%8E)

## 四、使用指南

- [查看使用指南Wiki](https://github.com/onxss/OneXSS/wiki/%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97)

## 五、运行截图

- Dashboard

![image-20231011122513539](./assets/image-20231011122513539.png)

- 项目管理![image-20231011122521265](./assets/image-20231011122521265.png)

- 模块仓库

![image-20231011122538923](./assets/image-20231011122538923.png)

- 用户管理

![image-20231011122612684](./assets/image-20231011122612684.png)

- 项目日志

![image-20231011122636392](./assets/image-20231011122636392.png)

## 六、免责声明

本工具仅面向**合法授权**的企业安全建设行为,如您需要测试本工具的可用性,请自行搭建靶机环境。

为避免被恶意使用,本项目所有收录的poc均为漏洞的理论判断,不存在漏洞利用过程,不会对目标发起真实攻击和漏洞利用。

在使用本工具进行检测时,您应确保该行为符合当地的法律法规,并且已经取得了足够的授权。**请勿对非授权目标进行扫描。**

如您在使用本工具的过程中存在任何非法行为,您需自行承担相应后果,我们将不承担任何法律及连带责任。

在安装并使用本工具前,请您**务必审慎阅读、充分理解各条款内容**,限制、免责条款或者其他涉及您重大权益的条款可能会以加粗、加下划线等形式提示您重点注意。 除非您已充分阅读、完全理解并接受本协议所有条款,否则,请您不要安装并使用本工具。您的使用行为或者您以其他任何明示或者默示方式表示接受本协议的,即视为您已阅读并同意本协议的约束。

Binary file added assets/image-20231011122513539.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-20231011122521265.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-20231011122538923.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-20231011122612684.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-20231011122636392.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-20231011125526562.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-20231011125918227.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-20231011134144341.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-20231011134221684.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-20231011135130362.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-20231011135627990.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-20231011140011305.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-20231011140745073.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-20231011141051146.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-20231011141258182.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-20231011141915566.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-20231011142515966.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-20231011142737484.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-20231011142807507.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-20231011143357130.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-20231011143842053.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/logo-no-background.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
151 changes: 151 additions & 0 deletions common/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@

export function isPasswordValid(password:string) {
// 检查密码长度是否至少为8个字符
if (password.length < 8) {
return false;
}

// 检查是否至少包含一个数字、一个字母和一个特殊字符
const hasNumber = /[0-9]/.test(password);
const hasLetter = /[a-zA-Z]/.test(password);
const hasSpecialChar = /[^a-zA-Z0-9]/.test(password);

return hasNumber && hasLetter && hasSpecialChar;
}


function byteStringToUint8Array(byteString: string) {
const ui = new Uint8Array(byteString.length);
for (let i = 0; i < byteString.length; ++i) {
ui[i] = byteString.charCodeAt(i);
}
return ui;
}

async function signText(plainData: string) {
const encoder = new TextEncoder();
const secretKeyData = encoder.encode(process.env.TOKEN_SALT);
const key = await crypto.subtle.importKey(
"raw",
secretKeyData,
{ name: "HMAC", hash: "SHA-256" },
false,
["sign"]
);
const mac = await crypto.subtle.sign(
"HMAC",
key,
encoder.encode(plainData)
);
let base64Mac = "";
const dataView = new DataView(mac);
for (let i = 0; i < mac.byteLength; i++) {
base64Mac += String.fromCharCode(dataView.getUint8(i));
}
base64Mac = btoa(base64Mac);
// base64Mac = base64Mac.replaceAll("+", "-");
return base64Mac;
}

async function verifyText(plainData: string, signature: string) {
const encoder = new TextEncoder();
const secretKeyData = encoder.encode(process.env.TOKEN_SALT);
const key = await crypto.subtle.importKey(
"raw",
secretKeyData,
{ name: "HMAC", hash: "SHA-256" },
false,
["verify"]
);
const receivedMac = byteStringToUint8Array(atob(signature));
const verified = await crypto.subtle.verify(
"HMAC",
key,
receivedMac,
encoder.encode(plainData)
);
return verified;
}

export async function signToken(userid: number, username: string, useremail: string, usertype: string, expiretime: number) {
return `${userid}::${await signText(`${userid}:${username}:${useremail}:${usertype}:${expiretime}`)}`;
}

export async function verifyToken(cookietoken:string|undefined) {
try {
if (cookietoken==null && cookietoken==undefined) {
let response_header = new Headers();
{
response_header.append("Content-Type", "application/json");
response_header.append("Set-Cookie", `token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; HttpOnly; SameSite=Strict; path=/;`);
}
return {
"code": 401,
"data": new Response(JSON.stringify({ code: 401, message: "Token错误,请重新登陆" }), { status: 401, headers: response_header })
}
}
const token_userid = cookietoken.split('::')[0];
const token = cookietoken.split('::')[1];

// 当前userid无token记录
const _tokenData = await process.env.JSKV.get(`token:${token_userid}`);
if (_tokenData==null || _tokenData==undefined) {
let response_header = new Headers();
{
response_header.append("Content-Type", "application/json");
response_header.append("Set-Cookie", `token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; HttpOnly; SameSite=Strict; path=/;`);
}
return {
"code": 401,
"data": new Response(JSON.stringify({ code: 401, message: "Token错误,请重新登陆" }), { status: 401, headers: response_header })
}
}
const tokenData = JSON.parse(_tokenData);
const plainData = `${tokenData.userid}:${tokenData.username}:${tokenData.useremail}:${tokenData.usertype}:${tokenData.expiretime}`;
const verified = await verifyText(plainData, token);
if (!verified || cookietoken != tokenData.token) {
let response_header = new Headers();
{
response_header.append("Content-Type", "application/json");
response_header.append("Set-Cookie", `token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; HttpOnly; SameSite=Strict; path=/;`);
}
return {
"code": 401,
"data": new Response(JSON.stringify({ code: 401, message: "Token验证失败,请重新登陆" }), { status: 401, headers: response_header })
}
}

if (Date.now() > tokenData.expiretime) {
await process.env.JSKV.delete(`token:${tokenData.userid}`);
let response_header = new Headers();
{
response_header.append("Content-Type", "application/json");
response_header.append("Set-Cookie", `token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; HttpOnly; SameSite=Strict; path=/;`);
}
return {
"code": 401,
"data": new Response(JSON.stringify({ code: 401, message: "Token过期,请重新登陆" }), { status: 401, headers: response_header })
}
}
return { "code": 200, "data": tokenData }
}catch(err:any){
let response_header = new Headers();
{
response_header.append("Content-Type", "application/json");
response_header.append("Set-Cookie", `token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; HttpOnly; SameSite=Strict; path=/;`);
}
return {
"code": 401,
"data": new Response(JSON.stringify({ code: 401, message: "Token验证失败,请重新登陆" }), { status: 401, headers: response_header })
}
}

}

export async function passwordHash(plainData: string) {
const encoder = new TextEncoder();
const hashArrayBuffer = (await crypto.subtle.digest("SHA-256", encoder.encode(plainData + process.env.PASSWORD_SALT)));
const hashArray = Array.from(new Uint8Array(hashArrayBuffer));
const hashHex = hashArray.map(byte => byte.toString(16).padStart(2, '0')).join('');
return hashHex;
}
Loading

0 comments on commit 8fa64d0

Please sign in to comment.