Skip to content

Commit

Permalink
fix: validate object and bucket names
Browse files Browse the repository at this point in the history
  • Loading branch information
inian committed Mar 18, 2021
1 parent 4fc4b03 commit 186bd74
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 10 deletions.
10 changes: 9 additions & 1 deletion src/routes/bucket/createBucket.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FastifyInstance } from 'fastify'
import { getPostgrestClient, getOwner, transformPostgrestError } from '../../utils'
import { getPostgrestClient, getOwner, transformPostgrestError, isValidKey } from '../../utils'
import { AuthenticatedRequest, Bucket } from '../../types/types'
import { FromSchema } from 'json-schema-to-ts'
import { bucketSchema } from '../../schemas/bucket'
Expand Down Expand Up @@ -44,6 +44,14 @@ export default async function routes(fastify: FastifyInstance) {
id = bucketName
}

if (!isValidKey(id) || !isValidKey(bucketName)) {
return response.status(400).send({
statusCode: '400',
error: 'Invalid key',
message: 'The key contains invalid characters',
})
}

const { data: results, error, status } = await postgrest
.from<Bucket>('buckets')
.insert([
Expand Down
10 changes: 9 additions & 1 deletion src/routes/object/copyObject.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FastifyInstance } from 'fastify'
import { getPostgrestClient, transformPostgrestError } from '../../utils'
import { getPostgrestClient, isValidKey, transformPostgrestError } from '../../utils'
import { copyObject, initClient } from '../../utils/s3'
import { getConfig } from '../../utils/config'
import { Obj, AuthenticatedRequest } from '../../types/types'
Expand Down Expand Up @@ -48,6 +48,14 @@ export default async function routes(fastify: FastifyInstance) {
const { sourceKey, destinationKey, bucketName } = request.body
console.log(sourceKey, bucketName)

if (!isValidKey(destinationKey)) {
return response.status(400).send({
statusCode: '400',
error: 'Invalid key',
message: 'The destination key contains invalid characters',
})
}

const postgrest = getPostgrestClient(jwt)
const objectResponse = await postgrest
.from<Obj>('objects')
Expand Down
10 changes: 9 additions & 1 deletion src/routes/object/createObject.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FastifyInstance } from 'fastify'
import { getPostgrestClient, getOwner, transformPostgrestError } from '../../utils'
import { getPostgrestClient, getOwner, transformPostgrestError, isValidKey } from '../../utils'
import { uploadObject, initClient, deleteObject } from '../../utils/s3'
import { getConfig } from '../../utils/config'
import { Obj, AuthenticatedRequest } from '../../types/types'
Expand Down Expand Up @@ -55,6 +55,14 @@ export default async function routes(fastify: FastifyInstance) {
const { bucketName } = request.params
const objectName = request.params['*']

if (!isValidKey(objectName) || !isValidKey(bucketName)) {
return response.status(400).send({
statusCode: '400',
error: 'Invalid key',
message: 'The key contains invalid characters',
})
}

const postgrest = getPostgrestClient(jwt)
let owner
try {
Expand Down
10 changes: 9 additions & 1 deletion src/routes/object/deleteObject.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FastifyInstance } from 'fastify'
import { getPostgrestClient, transformPostgrestError } from '../../utils'
import { getPostgrestClient, isValidKey, transformPostgrestError } from '../../utils'
import { deleteObject, initClient } from '../../utils/s3'
import { getConfig } from '../../utils/config'
import { Obj, AuthenticatedRequest } from '../../types/types'
Expand Down Expand Up @@ -49,6 +49,14 @@ export default async function routes(fastify: FastifyInstance) {

const postgrest = getPostgrestClient(jwt)

if (!isValidKey(objectName) || !isValidKey(bucketName)) {
return response.status(400).send({
statusCode: '400',
error: 'Invalid key',
message: 'The key contains invalid characters',
})
}

// todo what if objectName is * or something
const objectResponse = await postgrest
.from<Obj>('objects')
Expand Down
10 changes: 9 additions & 1 deletion src/routes/object/getObject.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FastifyInstance } from 'fastify'
import { FromSchema } from 'json-schema-to-ts'
import { getPostgrestClient, transformPostgrestError } from '../../utils'
import { getPostgrestClient, isValidKey, transformPostgrestError } from '../../utils'
import { getObject, initClient } from '../../utils/s3'
import { getConfig } from '../../utils/config'
import { AuthenticatedRequest, Obj } from '../../types/types'
Expand Down Expand Up @@ -42,6 +42,14 @@ export default async function routes(fastify: FastifyInstance) {
const { bucketName } = request.params
const objectName = request.params['*']

if (!isValidKey(objectName) || !isValidKey(bucketName)) {
return response.status(400).send({
statusCode: '400',
error: 'Invalid key',
message: 'The key contains invalid characters',
})
}

const objectResponse = await postgrest
.from<Obj>('objects')
.select('*')
Expand Down
2 changes: 1 addition & 1 deletion src/routes/object/getSignedURL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export default async function routes(fastify: FastifyInstance) {

const objectResponse = await postgrest
.from<Obj>('objects')
.select('*, buckets(*)')
.select('*')
.match({
name: objectName,
bucket_id: bucketName,
Expand Down
10 changes: 9 additions & 1 deletion src/routes/object/renameObject.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FastifyInstance } from 'fastify'
import { getPostgrestClient, transformPostgrestError } from '../../utils'
import { getPostgrestClient, isValidKey, transformPostgrestError } from '../../utils'
import { initClient, copyObject, deleteObject } from '../../utils/s3'
import { getConfig } from '../../utils/config'
import { Obj, AuthenticatedRequest } from '../../types/types'
Expand Down Expand Up @@ -48,6 +48,14 @@ export default async function routes(fastify: FastifyInstance) {

const { destinationKey, sourceKey, bucketName } = request.body

if (!isValidKey(destinationKey)) {
return response.status(400).send({
statusCode: '400',
error: 'Invalid key',
message: 'The destination key contains invalid characters',
})
}

const postgrest = getPostgrestClient(jwt)

const objectResponse = await postgrest
Expand Down
10 changes: 9 additions & 1 deletion src/routes/object/updateObject.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FastifyInstance } from 'fastify'
import { getPostgrestClient, getOwner, transformPostgrestError } from '../../utils'
import { getPostgrestClient, getOwner, transformPostgrestError, isValidKey } from '../../utils'
import { uploadObject, initClient } from '../../utils/s3'
import { getConfig } from '../../utils/config'
import { Obj, AuthenticatedRequest } from '../../types/types'
Expand Down Expand Up @@ -53,6 +53,14 @@ export default async function routes(fastify: FastifyInstance) {
const { bucketName } = request.params
const objectName = request.params['*']

if (!isValidKey(objectName) || !isValidKey(bucketName)) {
return response.status(400).send({
statusCode: '400',
error: 'Invalid key',
message: 'The key contains invalid characters',
})
}

const postgrest = getPostgrestClient(jwt)
const owner = await getOwner(jwt)

Expand Down
4 changes: 2 additions & 2 deletions src/test/object.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ describe('testing deleting multiple objects', () => {
expect(mockDeleteObjects).not.toHaveBeenCalled()
})

test('return 400 when delete from a non existent bucket', async () => {
test('deleting from a non existent bucket', async () => {
const response = await app().inject({
method: 'DELETE',
url: '/object/notfound',
Expand All @@ -538,7 +538,7 @@ describe('testing deleting multiple objects', () => {
prefixes: ['authenticated/delete-multiple3.png', 'authenticated/delete-multiple4.png'],
},
})
expect(response.statusCode).toBe(400)
expect(response.statusCode).toBe(200)
expect(mockDeleteObjects).not.toHaveBeenCalled()
})

Expand Down
6 changes: 6 additions & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,9 @@ export function transformPostgrestError(
message,
}
}

export function isValidKey(key: string): boolean {
// only allow s3 safe characters and characters which require special handling for now
// https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html
return /^(\w|\/|!|-|\.|\*|'|\(|\)| |&|\$|@|=|;|:|\+|,|\?)*$/.test(key)
}

0 comments on commit 186bd74

Please sign in to comment.