1
0
mirror of https://github.com/stonith404/pingvin-share.git synced 2024-11-15 03:50:11 +01:00

fix: share password can be bypassed if a deleted share with the same id was visited before

This commit is contained in:
Elias Schneider 2024-10-23 15:48:47 +02:00
parent 546d2c1ce4
commit acbff6e129
No known key found for this signature in database
GPG Key ID: 07E623B294202B6C
2 changed files with 29 additions and 13 deletions

View File

@ -315,12 +315,22 @@ export class ShareService {
},
});
if (
share?.security?.password &&
!(await argon.verify(share.security.password, password))
) {
if (share?.security?.password) {
if (!password) {
throw new ForbiddenException(
"This share is password protected",
"share_password_required",
);
}
const isPasswordValid = await argon.verify(
share.security.password,
password,
);
if (!isPasswordValid) {
throw new ForbiddenException("Wrong password", "wrong_password");
}
}
if (share.security?.maxViews && share.security.maxViews <= share.views) {
throw new ForbiddenException(
@ -335,12 +345,13 @@ export class ShareService {
}
async generateShareToken(shareId: string) {
const { expiration } = await this.prisma.share.findUnique({
const { expiration, createdAt } = await this.prisma.share.findUnique({
where: { id: shareId },
});
const tokenPayload = {
shareId,
shareCreatedAt: moment(createdAt).unix(),
iat: moment().unix(),
};
@ -356,7 +367,7 @@ export class ShareService {
}
async verifyShareToken(shareId: string, token: string) {
const { expiration } = await this.prisma.share.findUnique({
const { expiration, createdAt } = await this.prisma.share.findUnique({
where: { id: shareId },
});
@ -367,7 +378,10 @@ export class ShareService {
ignoreExpiration: moment(expiration).isSame(0),
});
return claims.shareId == shareId;
return (
claims.shareId == shareId &&
claims.shareCreatedAt == moment(createdAt).unix()
);
} catch {
return false;
}

View File

@ -37,8 +37,10 @@ const Share = ({ shareId }: { shareId: string }) => {
modals,
t("share.error.visitor-limit-exceeded.title"),
t("share.error.visitor-limit-exceeded.description"),
"go-home",
"go-home"
);
} else if (error == "share_password_required") {
showEnterPasswordModal(modals, getShareToken);
} else {
toast.axiosError(e);
}
@ -59,21 +61,21 @@ const Share = ({ shareId }: { shareId: string }) => {
modals,
t("share.error.removed.title"),
e.response.data.message,
"go-home",
"go-home"
);
} else {
showErrorModal(
modals,
t("share.error.not-found.title"),
t("share.error.not-found.description"),
"go-home",
"go-home"
);
}
} else if (e.response.status == 403 && error == "private_share") {
showErrorModal(
modals,
t("share.error.access-denied.title"),
t("share.error.access-denied.description"),
t("share.error.access-denied.description")
);
} else if (error == "share_password_required") {
showEnterPasswordModal(modals, getShareToken);
@ -84,7 +86,7 @@ const Share = ({ shareId }: { shareId: string }) => {
modals,
t("common.error"),
t("common.error.unknown"),
"go-home",
"go-home"
);
}
});