mirror of
https://github.com/whyour/qinglong.git
synced 2026-03-29 19:11:02 +08:00
修复严重鉴权绕过漏洞
This commit is contained in:
parent
d53437d169
commit
4a494739ae
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -28,3 +28,5 @@ __pycache__
|
||||||
/shell/preload/notify.*
|
/shell/preload/notify.*
|
||||||
/shell/preload/*-notify.json
|
/shell/preload/*-notify.json
|
||||||
/shell/preload/__ql_notify__.*
|
/shell/preload/__ql_notify__.*
|
||||||
|
docs/
|
||||||
|
docs/*
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,8 @@ export default ({ app }: { app: Application }) => {
|
||||||
secret: config.jwt.secret,
|
secret: config.jwt.secret,
|
||||||
algorithms: ['HS384'],
|
algorithms: ['HS384'],
|
||||||
}).unless({
|
}).unless({
|
||||||
path: [...config.apiWhiteList, /^\/(?!api\/).*/],
|
// Use case-insensitive regex to prevent bypassing JWT via uppercase paths like /Api/
|
||||||
|
path: [...config.apiWhiteList, /^\/(?!api\/)/i],
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -51,22 +52,25 @@ export default ({ app }: { app: Application }) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use(async (req: Request, res, next) => {
|
app.use(async (req: Request, res, next) => {
|
||||||
if (!['/open/', '/api/'].some((x) => req.path.startsWith(x))) {
|
// Normalize path to lowercase to prevent case-sensitivity bypass (e.g. /Open/, /API/)
|
||||||
|
const normalizedPath = req.path.toLowerCase();
|
||||||
|
if (!['/open/', '/api/'].some((x) => normalizedPath.startsWith(x))) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
const headerToken = getToken(req);
|
const headerToken = getToken(req);
|
||||||
if (req.path.startsWith('/open/')) {
|
if (normalizedPath.startsWith('/open/')) {
|
||||||
const apps = await shareStore.getApps();
|
const apps = await shareStore.getApps();
|
||||||
const doc = apps?.filter((x) =>
|
const doc = apps?.filter((x) =>
|
||||||
x.tokens?.find((y) => y.value === headerToken),
|
x.tokens?.find((y) => y.value === headerToken),
|
||||||
)?.[0];
|
)?.[0];
|
||||||
if (doc && doc.tokens && doc.tokens.length > 0) {
|
if (doc && doc.tokens && doc.tokens.length > 0) {
|
||||||
const currentToken = doc.tokens.find((x) => x.value === headerToken);
|
const currentToken = doc.tokens.find((x) => x.value === headerToken);
|
||||||
const keyMatch = req.path.match(/\/open\/([a-z]+)\/*/);
|
// Use case-insensitive match and normalize key to prevent scope bypass via uppercase paths
|
||||||
const key = keyMatch && keyMatch[1];
|
const keyMatch = req.path.match(/\/open\/([a-zA-Z]+)\/*/);
|
||||||
|
const key = keyMatch && keyMatch[1]?.toLowerCase();
|
||||||
if (
|
if (
|
||||||
doc.scopes.includes(key as any) &&
|
key && doc.scopes.includes(key as any) &&
|
||||||
currentToken &&
|
currentToken &&
|
||||||
currentToken.expiration >= Math.round(Date.now() / 1000)
|
currentToken.expiration >= Math.round(Date.now() / 1000)
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user