Skip to content

Commit ab509b2

Browse files
authored
Merge pull request #1471 from isomerpages/release_v0.95.0
Release v0.95.0
2 parents 0fe2a2a + 8fac8db commit ab509b2

File tree

10 files changed

+101
-14
lines changed

10 files changed

+101
-14
lines changed

.github/workflows/deploy_prod.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
uses: ./.github/workflows/aws_deploy.yml
1414
with:
1515
aws-region: "ap-southeast-1"
16-
cicd-role: "arn:aws:iam::095733531422:role/isomer-infra-github-oidc-role-16ea937"
16+
cicd-role: "arn:aws:iam::095733531422:role/isomer-infra-prod-deploy-role"
1717
ecr-repository: "isomer-infra-prod-ecr"
1818
ecs-cluster-name: "isomer-prod-ecs"
1919
ecs-web-service-name: "isomer-prod-ecs-service"
@@ -38,7 +38,7 @@ jobs:
3838
uses: ./.github/workflows/aws_deploy.yml
3939
with:
4040
aws-region: "ap-southeast-1"
41-
cicd-role: "arn:aws:iam::095733531422:role/isomer-infra-github-oidc-role-16ea937"
41+
cicd-role: "arn:aws:iam::095733531422:role/isomer-infra-prod-deploy-role"
4242
ecr-repository: "isomer-infra-prod-ecr"
4343
ecs-cluster-name: "isomer-prod-ecs"
4444
ecs-web-service-name: "prod-support-ecs-service"

.github/workflows/deploy_staging.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
uses: ./.github/workflows/aws_deploy.yml
1717
with:
1818
aws-region: "ap-southeast-1"
19-
cicd-role: "arn:aws:iam::095733531422:role/isomer-infra-github-oidc-role-16ea937"
19+
cicd-role: "arn:aws:iam::095733531422:role/isomer-infra-stg-deploy-role"
2020
ecr-repository: "isomer-infra-staging-ecr"
2121
ecs-cluster-name: "isomer-stg-ecs"
2222
ecs-web-service-name: "isomer-stg-ecs-service"
@@ -41,7 +41,7 @@ jobs:
4141
uses: ./.github/workflows/aws_deploy.yml
4242
with:
4343
aws-region: "ap-southeast-1"
44-
cicd-role: "arn:aws:iam::095733531422:role/isomer-infra-github-oidc-role-16ea937"
44+
cicd-role: "arn:aws:iam::095733531422:role/isomer-infra-stg-deploy-role"
4545
ecr-repository: "isomer-infra-staging-ecr"
4646
ecs-cluster-name: "isomer-stg-ecs"
4747
ecs-web-service-name: "stg-support-ecs-service"

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,20 @@ All notable changes to this project will be documented in this file. Dates are d
44

55
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
66

7+
#### [v0.95.0](https://github.com/isomerpages/isomercms-backend/compare/v0.94.0...v0.95.0)
8+
9+
- fix: validate path is safe for creates [`#1469`](https://github.com/isomerpages/isomercms-backend/pull/1469)
10+
- chore: update IAM deploy role [`#1468`](https://github.com/isomerpages/isomercms-backend/pull/1468)
11+
- fix(vapt): prevent users from requesting themselves to be reviewers [`#1467`](https://github.com/isomerpages/isomercms-backend/pull/1467)
12+
- chore: bump version to v0.94.0 [`#1465`](https://github.com/isomerpages/isomercms-backend/pull/1465)
13+
714
#### [v0.94.0](https://github.com/isomerpages/isomercms-backend/compare/v0.93.0...v0.94.0)
815

16+
> 16 October 2025
17+
918
- fix: validate path traversal [`#1463`](https://github.com/isomerpages/isomercms-backend/pull/1463)
1019
- chore: bump version to v0.93.0 [`#1462`](https://github.com/isomerpages/isomercms-backend/pull/1462)
20+
- chore: bump version to v0.94.0 [`b5f109c`](https://github.com/isomerpages/isomercms-backend/commit/b5f109c02c36bb0e3ce91a0c0a9095d624eb68be)
1121

1222
#### [v0.93.0](https://github.com/isomerpages/isomercms-backend/compare/v0.92.0...v0.93.0)
1323

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "isomercms",
3-
"version": "0.94.0",
3+
"version": "0.95.0",
44
"private": true,
55
"scripts": {
66
"build": "tsc -p tsconfig.build.json",

src/routes/v2/authenticated/__tests__/review.spec.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { mockUserId } from "@fixtures/identity"
1313
import { MOCK_USER_EMAIL_ONE, MOCK_USER_EMAIL_TWO } from "@fixtures/users"
1414
import { CollaboratorRoles, ReviewRequestStatus } from "@root/constants"
1515
import MissingSiteError from "@root/errors/MissingSiteError"
16+
import { MOCK_USER_SESSION_DATA_ONE } from "@root/fixtures/sessionData"
1617
import GitHubService from "@root/services/db/GitHubService"
1718
import CollaboratorsService from "@services/identity/CollaboratorsService"
1819
import NotificationsService from "@services/identity/NotificationsService"
@@ -335,6 +336,34 @@ describe("Review Requests Router", () => {
335336
).not.toHaveBeenCalled()
336337
expect(mockNotificationsService.create).not.toHaveBeenCalled()
337338
})
339+
340+
it("should return 400 if the user requests themselves to review", async () => {
341+
// Arrange
342+
mockCollaboratorsService.getRole.mockResolvedValueOnce("role")
343+
mockIdentityUsersService.findByEmail.mockResolvedValueOnce("user")
344+
345+
// Act
346+
const response = await request(app)
347+
.post("/mockSite/review/request")
348+
.send({
349+
// NOTE: this is injected via `generateRouterForDefaultUserWithSite`
350+
// and from there, `attachDefaultUserSessionDataWithSite`
351+
reviewers: [MOCK_USER_SESSION_DATA_ONE.email],
352+
title: "mockTitle",
353+
description: "mockDescription",
354+
})
355+
356+
// Assert
357+
expect(response.status).toEqual(400)
358+
expect(mockSitesService.getBySiteName).toHaveBeenCalledTimes(1)
359+
expect(mockCollaboratorsService.getRole).toHaveBeenCalledTimes(1)
360+
expect(mockIdentityUsersService.findByEmail).toHaveBeenCalledTimes(1)
361+
expect(mockCollaboratorsService.list).not.toHaveBeenCalled()
362+
expect(
363+
mockReviewRequestService.createReviewRequest
364+
).not.toHaveBeenCalled()
365+
expect(mockNotificationsService.create).not.toHaveBeenCalled()
366+
})
338367
})
339368

340369
describe("listReviews", () => {

src/routes/v2/authenticated/review.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,26 @@ export class ReviewsRouter {
210210
)
211211
const { reviewers, title, description } = req.body
212212

213+
// NOTE: reject requests that asks for the user to be the reviewer
214+
// rather than accept and filter later.
215+
// We should be stricter because this is prohibited on frontend
216+
// so this means that the user is trying to do something they know is forbidden
217+
if (reviewers.includes(userWithSiteSessionData.email)) {
218+
logger.error({
219+
message: `User ${userWithSiteSessionData.email} attempted to request a review from themselves for site ${siteName}`,
220+
method: "createReviewRequest",
221+
meta: {
222+
userId: userWithSiteSessionData.isomerUserId,
223+
email: userWithSiteSessionData.email,
224+
siteName,
225+
},
226+
})
227+
return res.status(400).send({
228+
message:
229+
"Please ensure that you are not requesting a review from yourself!",
230+
})
231+
}
232+
213233
// Step 3: Check if reviewers are admins of repo
214234
// Check if number of requested reviewers > 0
215235
if (reviewers.length === 0) {

src/services/directoryServices/ResourceDirectoryService.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ const {
77
} = require("@utils/markdown-utils")
88
const { slugifyCollectionName } = require("@utils/utils")
99

10+
const { isSafePath } = require("@root/validators/validators")
11+
1012
const INDEX_FILE_NAME = "index.html"
1113

1214
class ResourceDirectoryService {
@@ -79,7 +81,13 @@ class ResourceDirectoryService {
7981
sessionData,
8082
{ resourceRoomName, resourceCategoryName }
8183
) {
82-
if (/[^a-zA-Z0-9- ]/g.test(resourceCategoryName)) {
84+
if (
85+
/[^a-zA-Z0-9- ]/g.test(resourceCategoryName) ||
86+
!isSafePath(
87+
`/${resourceRoomName}/${resourceCategoryName}`,
88+
`/${resourceRoomName}`
89+
)
90+
) {
8391
// Contains non-allowed characters
8492
throw new BadRequestError(
8593
"Special characters not allowed in resource category name"
@@ -111,7 +119,13 @@ class ResourceDirectoryService {
111119
githubSessionData,
112120
{ resourceRoomName, resourceCategoryName, newDirectoryName }
113121
) {
114-
if (/[^a-zA-Z0-9- ]/g.test(newDirectoryName)) {
122+
if (
123+
/[^a-zA-Z0-9- ]/g.test(newDirectoryName) ||
124+
!isSafePath(
125+
`/${resourceRoomName}/${newDirectoryName}`,
126+
`/${resourceRoomName}`
127+
)
128+
) {
115129
// Contains non-allowed characters
116130
throw new BadRequestError(
117131
"Special characters not allowed in resource category name"

src/services/fileServices/MdPageServices/ResourcePageService.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ const {
55
convertDataToMarkdown,
66
} = require("@utils/markdown-utils")
77

8-
const { hasSpecialCharInTitle, isDateValid } = require("@validators/validators")
8+
const {
9+
hasSpecialCharInTitle,
10+
isDateValid,
11+
isSafePath,
12+
} = require("@validators/validators")
913

1014
class ResourcePageService {
1115
constructor({ gitHubService }) {
@@ -16,7 +20,7 @@ class ResourcePageService {
1620
const fileNameArray = fileName.split(".md")[0]
1721
const tokenArray = fileNameArray.split("-")
1822
const date = tokenArray.slice(0, 3).join("-")
19-
if (!isDateValid(date))
23+
if (!isDateValid(date) || !isSafePath(`/${fileName}`, "/"))
2024
throw new BadRequestError("Special characters not allowed in file name")
2125

2226
const type = ["file", "post", "link"].includes(tokenArray[3])

src/services/fileServices/MdPageServices/SubcollectionPageService.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const {
66
} = require("@utils/markdown-utils")
77
const { deslugifyCollectionName } = require("@utils/utils")
88

9-
const { hasSpecialCharInTitle } = require("@validators/validators")
9+
const { hasSpecialCharInTitle, isSafePath } = require("@validators/validators")
1010

1111
class SubcollectionPageService {
1212
constructor({ gitHubService, collectionYmlService }) {
@@ -27,7 +27,11 @@ class SubcollectionPageService {
2727
) {
2828
if (
2929
!shouldIgnoreCheck &&
30-
hasSpecialCharInTitle({ title: fileName, isFile: true })
30+
(hasSpecialCharInTitle({ title: fileName, isFile: true }) ||
31+
!isSafePath(
32+
`/${collectionName}/${subcollectionName}/${fileName}`,
33+
`/${collectionName}`
34+
))
3135
)
3236
throw new BadRequestError(
3337
`Special characters not allowed when creating files. Given name: ${fileName}`
@@ -117,7 +121,13 @@ class SubcollectionPageService {
117121
sha,
118122
}
119123
) {
120-
if (hasSpecialCharInTitle({ title: newFileName, isFile: true }))
124+
if (
125+
hasSpecialCharInTitle({ title: newFileName, isFile: true }) ||
126+
!isSafePath(
127+
`/${collectionName}/${subcollectionName}/${newFileName}`,
128+
`/${collectionName}`
129+
)
130+
)
121131
throw new BadRequestError(
122132
`Special characters not allowed when renaming files. Given name: ${newFileName}`
123133
)

0 commit comments

Comments
 (0)