fix(security): harden season file paths for semgrep
This commit is contained in:
@@ -1,11 +1,35 @@
|
||||
import { promises as fs } from 'fs'
|
||||
import path from 'path'
|
||||
import { getCurrentSeasonSlug, validateSeasonSlug } from '../utils/spielplan-data.js'
|
||||
|
||||
function normalizeSeasonFilename(season) {
|
||||
return `mannschaften_${season}.csv`
|
||||
}
|
||||
|
||||
function isAllowedFilename(filename) {
|
||||
return filename === 'mannschaften.csv' || /^mannschaften_\d{2}--\d{2}\.csv$/.test(String(filename || ''))
|
||||
}
|
||||
|
||||
function buildCsvCandidates(cwd, filename) {
|
||||
const safeFilename = String(filename || '').trim()
|
||||
if (!isAllowedFilename(safeFilename)) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: 'Ungueltiger Dateiname fuer Mannschaften'
|
||||
})
|
||||
}
|
||||
|
||||
return [
|
||||
`${cwd}/server/data/public-data/${safeFilename}`,
|
||||
`${cwd}/../server/data/public-data/${safeFilename}`,
|
||||
`${cwd}/.output/server/data/${safeFilename}`,
|
||||
`${cwd}/server/data/${safeFilename}`,
|
||||
`${cwd}/.output/public/data/${safeFilename}`,
|
||||
`${cwd}/public/data/${safeFilename}`,
|
||||
`${cwd}/../.output/public/data/${safeFilename}`,
|
||||
`${cwd}/../public/data/${safeFilename}`
|
||||
]
|
||||
}
|
||||
|
||||
async function exists(p) {
|
||||
try {
|
||||
await fs.access(p)
|
||||
@@ -37,16 +61,7 @@ export default defineEventHandler(async (event) => {
|
||||
// then legacy locations.
|
||||
const candidates = []
|
||||
for (const filename of candidateFileNames) {
|
||||
candidates.push(
|
||||
path.join(cwd, 'server/data/public-data', filename),
|
||||
path.join(cwd, '../server/data/public-data', filename),
|
||||
path.join(cwd, '.output/server/data', filename),
|
||||
path.join(cwd, 'server/data', filename),
|
||||
path.join(cwd, '.output/public/data', filename),
|
||||
path.join(cwd, 'public/data', filename),
|
||||
path.join(cwd, '../.output/public/data', filename),
|
||||
path.join(cwd, '../public/data', filename)
|
||||
)
|
||||
candidates.push(...buildCsvCandidates(cwd, filename))
|
||||
}
|
||||
|
||||
let csvPath = null
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { promises as fs } from 'fs'
|
||||
import path from 'path'
|
||||
import { getServerDataPath, getProjectPath } from './paths.js'
|
||||
import { getSpieljahrForDate } from './spielplan-import.js'
|
||||
import { parseDelimitedLine } from './spielplan-data.js'
|
||||
@@ -132,6 +131,11 @@ function extractSeasonSlugFromUrl(url) {
|
||||
return match?.[1] || null
|
||||
}
|
||||
|
||||
function sanitizeSeasonSlug(value) {
|
||||
const seasonSlug = String(value || '').trim()
|
||||
return /^\d{2}--\d{2}$/.test(seasonSlug) ? seasonSlug : null
|
||||
}
|
||||
|
||||
async function resolveMannschaftenCsvPath() {
|
||||
const candidates = [
|
||||
getServerDataPath('public-data', 'mannschaften.csv'),
|
||||
@@ -226,8 +230,8 @@ export async function importLeagueTables(options = {}) {
|
||||
}
|
||||
|
||||
const fallbackSeasonSlug = teams.length > 0 ? extractSeasonSlugFromUrl(teams[0].tableUrl) : null
|
||||
const seasonSlug = fallbackSeasonSlug || season.seasonSlug
|
||||
const outputFile = path.join(OUTPUT_DIR, `tables_${seasonSlug}.json`)
|
||||
const seasonSlug = sanitizeSeasonSlug(fallbackSeasonSlug) || sanitizeSeasonSlug(season.seasonSlug) || getSpieljahrForDate(today).seasonSlug
|
||||
const outputFile = `${OUTPUT_DIR}/tables_${seasonSlug}.json`
|
||||
|
||||
const payload = {
|
||||
format: 'harheimertc.tables.v1',
|
||||
|
||||
Reference in New Issue
Block a user