Skip to content

Commit

Permalink
use 128-bit random base64url identifiers for images & files, not uuid
Browse files Browse the repository at this point in the history
  • Loading branch information
dcousens committed Apr 2, 2024
1 parent 0f7760f commit 323893a
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 45 deletions.
16 changes: 7 additions & 9 deletions packages/core/src/lib/assets/createFilesContext.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
import crypto from 'crypto'
import { randomBytes } from 'node:crypto'

import type { KeystoneConfig, FilesContext } from '../../types'
import { localFileAssetsAPI } from './local'
import { s3FileAssetsAPI } from './s3'
import type { FileAdapter } from './types'

const defaultTransformName = (path: string) => {
// Appends a UUID to the filename so that people can't brute-force guess stored filenames
//
// This regex lazily matches for any characters that aren't a new line
// appends a 128-bit random identifier to the filename to prevent guessing
function defaultTransformName (path: string) {
// this regex lazily matches for any characters that aren't a new line
// it then optionally matches the last instance of a "." symbol
// followed by any alphanumerical character before the end of the string
const [, name, ext] = path.match(/^([^:\n].*?)(\.[A-Za-z0-9]{0,10})?$/) as RegExpMatchArray

const id = crypto.randomBytes(12).toString('base64url').slice(0, 12)

const id = randomBytes(16).toString('base64url')
const urlSafeName = name.replace(/[^A-Za-z0-9]/g, '-')
if (ext) return `${urlSafeName}-${id}${ext}`
return `${urlSafeName}-${id}`
Expand Down Expand Up @@ -46,11 +44,11 @@ export function createFilesContext (config: KeystoneConfig): FilesContext {
},
getDataFromStream: async (stream, originalFilename) => {
const storageConfig = config.storage![storageString]
const { transformName = defaultTransformName } = storageConfig as typeof storageConfig & {
const { transformName = defaultTransformName } = storageConfig as (typeof storageConfig) & {
type: 'file'
}
const filename = await transformName(originalFilename)

const filename = await transformName(originalFilename)
const { filesize } = await adapter.upload(stream, filename)
return { filename, filesize }
},
Expand Down
10 changes: 7 additions & 3 deletions packages/core/src/lib/assets/createImagesContext.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { v4 as uuid } from 'uuid'
import { randomBytes } from 'node:crypto'
import imageSize from 'image-size'

import type { KeystoneConfig, ImagesContext } from '../../types'
import type { ImageAdapter } from './types'
import { localImageAssetsAPI } from './local'
import { s3ImageAssetsAPI } from './s3'
import { streamToBuffer } from './utils'

function defaultTransformName (path: string) {
return randomBytes(16).toString('base64url')
}

async function getImageMetadataFromBuffer (buffer: Buffer) {
const fileType = await (await import('file-type')).fileTypeFromBuffer(buffer)
if (!fileType) {
Expand Down Expand Up @@ -50,13 +55,12 @@ export function createImagesContext (config: KeystoneConfig): ImagesContext {
},
getDataFromStream: async (stream, originalFilename) => {
const storageConfig = config.storage![storageString]
const { transformName = () => uuid() } = storageConfig
const { transformName = defaultTransformName } = storageConfig

const buffer = await streamToBuffer(stream)
const { extension, ...rest } = await getImageMetadataFromBuffer(buffer)

const id = await transformName(originalFilename, extension)

await adapter.upload(buffer, id, extension)
return { id, extension, ...rest }
},
Expand Down
35 changes: 3 additions & 32 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tests/api-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"@types/mime": "^2.0.3",
"@types/superagent": "^4.1.15",
"@types/supertest": "^2.0.11",
"@types/uuid": "^8.3.1",
"@types/uuid": "^9.0.0",
"express": "^4.17.1"
}
}

0 comments on commit 323893a

Please sign in to comment.