Skip to content

Commit

Permalink
optimize: performance of front-end and back-end
Browse files Browse the repository at this point in the history
optimize: security vulnerability
  • Loading branch information
XZB-1248 committed May 26, 2022
1 parent dae496d commit b9a5511
Show file tree
Hide file tree
Showing 45 changed files with 855 additions and 493 deletions.
24 changes: 12 additions & 12 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,16 @@ jobs:
run: |
cd ./releases
sudo apt install zip tar -y
tar -zcvf server_darwin_arm64.tar.gz server_darwin_arm64
tar -zcvf server_darwin_amd64.tar.gz server_darwin_amd64
tar -zcvf server_linux_arm.tar.gz server_linux_arm
tar -zcvf server_linux_arm64.tar.gz server_linux_arm64
tar -zcvf server_linux_i386.tar.gz server_linux_i386
tar -zcvf server_linux_amd64.tar.gz server_linux_amd64
zip -r server_windows_arm.zip server_windows_arm.exe
zip -r server_windows_arm64.zip server_windows_arm64.exe
zip -r server_windows_i386.zip server_windows_i386.exe
zip -r server_windows_amd64.zip server_windows_amd64.exe
tar -zcf server_darwin_arm64.tar.gz server_darwin_arm64 ../built
tar -zcf server_darwin_amd64.tar.gz server_darwin_amd64 ../built
tar -zcf server_linux_arm.tar.gz server_linux_arm ../built
tar -zcf server_linux_i386.tar.gz server_linux_i386 ../built
tar -zcf server_linux_arm64.tar.gz server_linux_arm64 ../built
tar -zcf server_linux_amd64.tar.gz server_linux_amd64 ../built
zip -r -9 -q server_windows_arm.zip server_windows_arm.exe ../built
zip -r -9 -q server_windows_i386.zip server_windows_i386.exe ../built
zip -r -9 -q server_windows_arm64.zip server_windows_arm64.exe ../built
zip -r -9 -q server_windows_amd64.zip server_windows_amd64.exe ../built
- name: Release
uses: softprops/action-gh-release@v1
Expand All @@ -142,12 +142,12 @@ jobs:
releases/server_darwin_arm64.tar.gz
releases/server_darwin_amd64.tar.gz
releases/server_linux_arm.tar.gz
releases/server_linux_arm64.tar.gz
releases/server_linux_i386.tar.gz
releases/server_linux_arm64.tar.gz
releases/server_linux_amd64.tar.gz
releases/server_windows_arm.zip
releases/server_windows_arm64.zip
releases/server_windows_i386.zip
releases/server_windows_arm64.zip
releases/server_windows_amd64.zip
- name: Clean up
Expand Down
8 changes: 7 additions & 1 deletion API.ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
## 通用

所有请求均为`POST`
<br />

### 鉴权

每次请求都必须在Header中带上`Authorization`
<br />
`Authorization`请求头格式:`Basic <token>`(basic auth)。
Expand All @@ -18,6 +20,10 @@ Authorization: Basic <base64('username:password')>
Authorization: Basic WFpCOjEyNDg=
```

在最初的Basic Authentication之后,服务端会分配一个`Authorization`的Cookie。
<br />
该Cookie可用于请求的后续鉴权,可以不再附带Authorization头。

---

## 响应
Expand Down
8 changes: 7 additions & 1 deletion API.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
## Common

Only `POST` requests are allowed.
<br />

### Authenticate

For every request, you should have `Authorization` on its header.
<br />
Authorization header is a string like `Basic <token>`(basic auth).
Expand All @@ -18,6 +20,10 @@ Example:
Authorization: Basic WFpCOjEyNDg=
```

After basic authentication, server will assign you a `Authorization` cookie.
<br />
You can use this token cookie to authenticate rest of your requests.

---

## Response
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## v0.0.9

* Optimize: performance of front-end and back-end.
* Optimize: security vulnerability.

* 优化:前后端性能。
* 优化:安全问题。



## v0.0.8

* Add: file upload.
Expand Down
16 changes: 14 additions & 2 deletions README.ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@

---

<div align="center">

|![GitHub repo size](https://img.shields.io/github/repo-size/DGP-Studio/Snap.Genshin?style=flat-square)|![GitHub issues](https://img.shields.io/github/issues/XZB-1248/Spark?style=flat-square)|![GitHub closed issues](https://img.shields.io/github/issues-closed/XZB-1248/Spark?style=flat-square)|
|-|-|-|

|[![GitHub downloads](https://img.shields.io/github/downloads/XZB-1248/Spark/total?style=flat-square)](https://github.com/XZB-1248/Spark/releases)|[![GitHub release (latest by date)](https://img.shields.io/github/downloads/XZB-1248/Spark/latest/total?style=flat-square)](https://github.com/XZB-1248/Spark/releases/latest)|
|-|-|

</div>

---

### **免责声明**

**本项目及其源代码和发行版,旨在用于学习和交流。使用本项目所带来的风险由使用者本人承担。作者和开发者不会对你的错误使用而造成的损害承担任何责任。**
Expand Down Expand Up @@ -123,12 +135,12 @@ $ statik -m -src="./web/dist" -f -dest="./server/embed" -p web -ns web
# 在使用类Unix系统时,运行以下命令。
$ go mod tidy
$ go mod download
$ ./build.client.sh
$ ./scripts/build.client.sh
$ statik -m -src="./built" -f -dest="./server/embed" -include=* -p built -ns built


# 最终开始编译服务端。
$ ./build.server.sh
$ ./scripts/build.server.sh
```

然后打开`releases`目录,放入上文提到的配置文件,选择对应平台的服务端运行即可。
Expand Down
23 changes: 19 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,30 @@
**Spark** is a free, safe, open-source, web-based, cross-platform and full-featured RAT (Remote Administration Tool)
that allow you to control all your devices via browser anywhere.

We **won't** collect any data, thus the server will never self-upgrade. Your clients will only communicate with your server forever.
We **won't** collect any data, thus the server will never self-upgrade. Your clients will only communicate with your
server forever.

### [English] [[中文]](./README.ZH.md) [[API Document]](./API.md) [[API文档]](./API.ZH.md)

---

<div align="center">

|![GitHub repo size](https://img.shields.io/github/repo-size/DGP-Studio/Snap.Genshin?style=flat-square)|![GitHub issues](https://img.shields.io/github/issues/XZB-1248/Spark?style=flat-square)|![GitHub closed issues](https://img.shields.io/github/issues-closed/XZB-1248/Spark?style=flat-square)|
|-|-|-|

|[![GitHub downloads](https://img.shields.io/github/downloads/XZB-1248/Spark/total?style=flat-square)](https://github.com/XZB-1248/Spark/releases)|[![GitHub release (latest by date)](https://img.shields.io/github/downloads/XZB-1248/Spark/latest/total?style=flat-square)](https://github.com/XZB-1248/Spark/releases/latest)|
|-|-|

</div>

---

## **Disclaimer**

**THIS PROJECT, ITS SOURCE CODE, AND ITS RELEASES SHOULD ONLY BE USED FOR EDUCATIONAL PURPOSES.YOU SHALL USE THIS PROJECT AT YOUR OWN RISK.THE AUTHORS AND DEVELOPERS ARE NOT RESPONSIBLE FOR ANY DAMAGE CAUSED BY YOUR MISUSE OF THIS PROJECT.**
**THIS PROJECT, ITS SOURCE CODE, AND ITS RELEASES SHOULD ONLY BE USED FOR EDUCATIONAL PURPOSES.YOU SHALL USE THIS
PROJECT AT YOUR OWN RISK.THE AUTHORS AND DEVELOPERS ARE NOT RESPONSIBLE FOR ANY DAMAGE CAUSED BY YOUR MISUSE OF THIS
PROJECT.**

**YOUR DATA IS PRICELESS. THINK TWICE BEFORE YOU CLICK ANY BUTTON OR ENTER ANY COMMAND.**

Expand Down Expand Up @@ -123,12 +138,12 @@ $ statik -m -src="./web/dist" -f -dest="./server/embed" -p web -ns web
# When you're using unix-like OS, you can use this.
$ go mod tidy
$ go mod download
$ ./build.client.sh
$ ./scripts/build.client.sh
$ statik -m -src="./built" -f -dest="./server/embed" -include=* -p built -ns built


# Finally we're compiling the server side.
$ ./build.server.sh
$ ./scripts/build.server.sh
```

Then you can find executable files in `releases` directory.
Expand Down
2 changes: 1 addition & 1 deletion client/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type Cfg struct {

// Localhost for my development only.
// Shall be commented out when development is done.
//var CfgBuffer = "\x00\xcd\x90\x50\x43\xfc\x3d\x36\x56\x6d\xf6\x01\xd1\xcd\x81\xc3\x1b\x80\xc9\x61\xd8\xdf\x5b\x76\x48\x88\xc5\xb1\x74\x22\x23\xab\x3b\xfc\x8b\xbe\x98\x27\xed\x05\xec\xbb\x40\x4f\xe9\xe7\xe5\xe0\x84\xaa\xb7\xfd\x4a\x30\x71\x08\x6c\x02\x50\xe9\xc5\x22\xcf\xcb\x89\x16\x0a\x89\x08\xd4\x26\xdc\x5c\xc1\xc9\xbf\xc4\xac\x0d\x92\x2f\x34\x7f\x45\xeb\x55\xa0\x6d\xf6\x64\xbc\xd5\x15\x40\x96\x43\x64\xe0\x24\x51\xfb\xe8\xc9\x7f\x48\x60\xcd\x30\x5e\x5e\x78\xba\xb6\x6f\x07\x64\xe8\x59\x81\x0b\x91\x13\x92\x1a\xdd\x49\x8f\x28\xe7\x74\xea\xff\x5b\x45\x0e\x4a\x2d\x60\x4e\xc9\xde\x9c\xbe\x50\xc6\x12\xc7\x45\xa2\x15\xa0\x58\x62\x45\x86\x74\x9f\xa5\x14\x5c\x17\x8a\xcc\x56\x73\xa7\x75\xb7\xf6\x6d\x52\x0f\xb8\xc1\xff\x9c\x39\x39\x00\x74\xe1\x4d\x65\x73\x9c\x02\x57\x8b\xcf\xdf\x0a\x20\x4c\xed\xe2\x25\xea\x01\x36\x12\x37\x12\x2e\x1a\x03\x41\x19\x2e\xc9\xdd\x71\xac\x73\x90\xfa\x5e\x60\x08\x43\x35\xef\x61\x45\xf9\xe3\xba\xcb\xb1\xc5\x7c\xf0\x11\xcd\x47\x57\x53\xdc\x35\x6b\x9f\xac\xad\x43\x4a\xc7\x54\x20\xb8\xd0\xf8\xb5\x0c\x45\x76\x57\xb9\xee\x4a\x3f\xd2\xda\xf7\x94\x54\x74\xf3\x91\xf3\x4d\x49\x98\xc6\xf8\x60\x80\xad\x84\x04\xef\x35\xca\x3a\xcf\xd3\x7e\x74\xc2\x4b\xb8\xb3\x9f\xb2\x83\xb8\xbd\x29\x13\x9f\x2b\xaa\x60\x47\x24\x7e\x20\xb2\x85\xdc\x47\xfe\x8f\x68\xb6\xc3\x43\xad\x61\x3d\x9b\x35\x60\x2e\x6c\x44\xf0\xaf\xb2\xf3\xdb\xe2\x1b\x8a\xec\x0a\x48\x5e\x43\xa9\xb3\x3a\x5e\xb6\x90\xa9\x3d\xee\x4f\xa1\x57\x7c\x94\xf4\xb1\x36\xda\x04\xa8\x5e\x48\x2a\xc3\xa1\xf0\x97\xf0\xe0\x10\x46\x32\x10\xe5\xd8\x36\x5a\x56\xa5\xbb\x37\x3c\x9f\xbd\xef\xf5\x2f"
//var CfgBuffer = "\x00\xcd\xc6\x68\x5d\xf5\x83\x53\x1c\x49\xa2\x35\x7b\x5b\xaf\xf2\x9e\x6d\x74\x00\x95\x23\x73\x00\x77\xa0\xe1\x46\x64\xd2\x33\x2b\x04\xb2\xca\x70\xda\x4b\xed\xec\x43\x6b\xeb\x6e\x10\x53\x6e\x62\x13\x3c\xb1\x0a\xdd\xc0\x48\x2d\x77\xfa\x4a\x9b\x26\xb5\x1b\x50\x62\x05\xcc\xc9\x3b\x22\xf5\x19\x5b\xac\x41\x74\xc9\x9e\x02\x9f\xe8\x75\xce\x3a\xe0\x50\x67\x0f\x81\x01\xca\x47\x0d\xb2\x09\x8b\x74\x6c\xfd\xc5\x73\xf9\x2a\xf0\x13\x52\xb7\x79\xff\xeb\xab\xcd\x9f\xe8\xb7\xae\xff\xa9\x50\xb2\x90\x11\x35\x4d\x94\x6e\x67\x55\x37\x66\x58\x21\xc0\x0d\xab\x3b\x6f\xc4\x00\x56\xd6\x06\xa0\x7e\x73\xdf\x46\x76\xe0\xb3\x89\x0d\xa2\x33\x07\x39\x81\x2b\x59\x30\x24\xc7\x4f\xe9\xb9\xf6\x3c\xb6\x24\xc5\x44\xde\xe6\x66\x66\x92\x49\xe1\x38\x50\xff\xb5\xf3\x20\xb9\x15\x60\x4a\xdf\xba\xd5\xae\x85\x7e\x3f\x8a\xf0\xb8\xf5\x23\x39\xf0\x46\x11\x64\x42\x04\x8c\xf0\x8a\x5e\xc7\x43\xd2\x0c\x89\xd1\xc4\x14\x26\xb1\x67\x64\x28\x77\xf4\xc8\xf3\x51\x69\xba\xf2\xca\xfa\x2f\x11\xe0\x8d\x6c\x4e\x8c\xb7\x28\xf5\x2a\x67\xe3\x8f\xf0\x7f\x79\xc5\xa5\x1a\xb5\xa1\x22\xe9\x55\x61\xdd\xce\x39\x13\x4b\xdd\x19\xf1\x5c\x86\x9b\x16\x89\x45\xba\x16\x68\xfc\x88\x4b\xd5\x13\xa4\x7e\x26\xce\x35\x2d\x42\x4d\x21\xf1\xc3\x6d\xf5\x64\x16\xc9\x05\xed\x9b\x6c\xbf\x26\xe3\xad\x40\x1d\xc6\x64\x03\xb9\xcb\xca\x3c\x62\x5d\x07\x6b\x07\x8b\xa9\x86\x60\x27\x28\xe7\xa3\xc2\x8d\x6f\xc0\x3d\x8e\x14\xa6\xcc\xe0\x50\x51\x22\x20\x6b\x16\x10\xe9\xe0\x4a\xd2\x4e\x77\xc8\xd1\xf7\x60\x4c\xed\xca\x3f\x1e\x13\x0a\x2e\x84\x15\xd3\xf6\x3e\x13\x4e\x68\xaf\xfd\x7a\xd7\x5b\xaa\x5b\x28\x7c\x3f\xb3\xd0\xd0"

// None
var CfgBuffer = "\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19"
Expand Down
25 changes: 1 addition & 24 deletions client/core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var (
errNoSecretHeader = errors.New(`can not find secret header`)
)
var handlers = map[string]func(pack modules.Packet, wsConn *common.Conn){
`ping`: ping,
`offline`: offline,
`lock`: lock,
`logoff`: logoff,
Expand Down Expand Up @@ -69,8 +70,6 @@ func Start() {

checkUpdate(common.WSConn)

go heartbeat(common.WSConn)

err = handleWS(common.WSConn)
if err != nil && !stop {
golog.Error(`Execution error: `, err)
Expand Down Expand Up @@ -212,25 +211,3 @@ func handleAct(pack modules.Packet, wsConn *common.Conn) {
act(pack, wsConn)
}
}

func heartbeat(wsConn *common.Conn) error {
t := 0
for range time.NewTicker(2 * time.Second).C {
t++
// GetPartialInfo always costs more than 1 second.
// So it is actually get disk info every 20*3 seconds (1 minute).
device, err := GetPartialInfo(t >= 20)
if err != nil {
golog.Error(err)
continue
}
if t >= 20 {
t = 0
}
err = common.SendPack(modules.CommonPack{Act: `setDevice`, Data: *device}, wsConn)
if err != nil {
return err
}
}
return nil
}
2 changes: 1 addition & 1 deletion client/core/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ func GetDevice() (*modules.Device, error) {
}, nil
}

func GetPartialInfo(getDisk bool) (*modules.Device, error) {
func GetPartialInfo() (*modules.Device, error) {
cpuInfo, err := GetCPUInfo()
if err != nil {
cpuInfo = modules.CPU{
Expand Down
11 changes: 11 additions & 0 deletions client/core/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,22 @@ import (
Screenshot "Spark/client/service/screenshot"
"Spark/client/service/terminal"
"Spark/modules"
"github.com/kataras/golog"
"os"
"reflect"
"strconv"
)

func ping(pack modules.Packet, wsConn *common.Conn) {
common.SendCb(modules.Packet{Code: 0}, pack, wsConn)
device, err := GetPartialInfo()
if err != nil {
golog.Error(err)
return
}
common.SendPack(modules.CommonPack{Act: `setDevice`, Data: *device}, wsConn)
}

func offline(pack modules.Packet, wsConn *common.Conn) {
common.SendCb(modules.Packet{Code: 0}, pack, wsConn)
stop = true
Expand Down
71 changes: 69 additions & 2 deletions client/service/file/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ package file
import (
"Spark/client/config"
"errors"
"github.com/imroc/req/v3"
"io"
"io/ioutil"
"os"
"path"
"strconv"

"github.com/imroc/req/v3"
"unicode/utf8"
)

type File struct {
Expand Down Expand Up @@ -41,6 +41,53 @@ func listFiles(path string) ([]File, error) {
return result, nil
}

func ReadText(path, bridge string) error {
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
uploadReq := req.R()
stat, err := file.Stat()
if err != nil {
return err
}
size := stat.Size()
// Check if size larger than 2MB.
if size > 2<<20 {
return errors.New(`${i18n|fileTooLarge}`)
}
headers := map[string]string{
`FileName`: stat.Name(),
`FileSize`: strconv.FormatInt(size, 10),
}
uploadReq.RawRequest.ContentLength = size

// Check file if is a text file.
// UTF-8 and GBK are only supported yet.
buf := make([]byte, size)
_, err = file.Read(buf)
if err != nil {
return err
}
if utf8.Valid(buf) {
headers[`FileEncoding`] = `utf-8`
} else if gbkValidate(buf) {
headers[`FileEncoding`] = `gbk`
} else {
return errors.New(`${i18n|fileEncodingUnsupported}`)
}

file.Seek(0, 0)
url := config.GetBaseURL(false) + `/api/bridge/push`
_, err = uploadReq.
SetBody(file).
SetHeaders(headers).
SetQueryParam(`bridge`, bridge).
Send(`PUT`, url)
return err
}

// FetchFile saves file from bridge to local.
// Save body as temp file and when done, rename it to file.
func FetchFile(dir, file, bridge string) error {
Expand Down Expand Up @@ -162,6 +209,26 @@ func UploadFile(path, bridge string, start, end int64) error {
return err
}

func gbkValidate(b []byte) bool {
length := len(b)
var i int = 0
for i < length {
if b[i] <= 0x7f {
i++
continue
} else {
if i+1 < length {
if b[i] >= 0x81 && b[i] <= 0xfe && b[i+1] >= 0x40 && b[i+1] <= 0xfe && b[i+1] != 0xf7 {
i += 2
continue
}
}
return false
}
}
return true
}

func getTempFileName(dir, file string) string {
exists := true
tempFile := ``
Expand Down
4 changes: 3 additions & 1 deletion client/service/screenshot/unsupported.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

package screenshot

import "errors"

func GetScreenshot(bridge string) error {
return utils.ErrUnsupported
return errors.New(`${i18n|operationNotSupported}`)
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.17
require (
github.com/creack/pty v1.1.18
github.com/denisbrodbeck/machineid v1.0.1
github.com/gin-contrib/pprof v1.3.0
github.com/gin-gonic/gin v1.7.7
github.com/gorilla/websocket v1.5.0
github.com/imroc/req/v3 v3.8.2
Expand Down
Loading

0 comments on commit b9a5511

Please sign in to comment.