ChatGPT-Next-Web/app/store/sync.ts
B0zal 605dd72354
[+] CodeQL Report Fix log injection vulnerability in useSyncStore
Severity : High
Sanitize the 'res' object before logging it in the 'check' method of useSyncStore to prevent log injection attacks.
The 'res' object is now sanitized by extracting only the necessary properties ('status', 'statusText', and 'headers') and logging the sanitized object instead.
This ensures that only safe and expected data is logged, mitigating the risk of log injection vulnerabilities.
2023-09-11 08:49:08 +07:00

101 lines
2.2 KiB
TypeScript

import { Updater } from "../typing";
import { StoreKey } from "../constant";
import { createPersistStore } from "../utils/store";
import {
AppState,
getLocalAppState,
mergeAppState,
setLocalAppState,
} from "../utils/sync";
import { downloadAs, readFromFile } from "../utils";
import { showToast } from "../components/ui-lib";
import Locale from "../locales";
export interface WebDavConfig {
server: string;
username: string;
password: string;
}
export const useSyncStore = createPersistStore(
{
webDavConfig: {
server: "",
username: "",
password: "",
},
lastSyncTime: 0,
},
(set, get) => ({
export() {
const state = getLocalAppState();
const fileName = `Backup-${new Date().toLocaleString()}.json`;
downloadAs(JSON.stringify(state), fileName);
set({ lastSyncTime: Date.now() });
},
async import() {
const rawContent = await readFromFile();
try {
const remoteState = JSON.parse(rawContent) as AppState;
const localState = getLocalAppState();
mergeAppState(localState, remoteState);
setLocalAppState(localState);
location.reload();
} catch (e) {
console.error("[Import]", e);
showToast(Locale.Settings.Sync.ImportFailed);
}
},
async check() {
try {
const res = await fetch(this.path(""), {
method: "PROFIND",
headers: this.headers(),
});
const sanitizedRes = {
status: res.status,
statusText: res.statusText,
headers: res.headers,
};
console.log(sanitizedRes);
return res.status === 207;
} catch (e) {
console.error("[Sync] ", e);
return false;
}
},
path(path: string) {
let url = get().webDavConfig.server;
if (!url.endsWith("/")) {
url += "/";
}
if (path.startsWith("/")) {
path = path.slice(1);
}
return url + path;
},
headers() {
const auth = btoa(
[get().webDavConfig.username, get().webDavConfig.password].join(":"),
);
return {
Authorization: `Basic ${auth}`,
};
},
}),
{
name: StoreKey.Sync,
version: 1,
},
);