Skip to content

Commit

Permalink
Validate env vars on the backend
Browse files Browse the repository at this point in the history
fixes #2502
  • Loading branch information
hardillb committed Sep 21, 2023
1 parent 849af71 commit 2698095
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 6 deletions.
12 changes: 12 additions & 0 deletions forge/db/controllers/ProjectTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,21 @@ module.exports = {
}
settings.env.forEach((envVar) => {
if (templateEnvPolicyMap[envVar.name] !== false && !/ /.test(envVar.name)) {
if (!envVar.name.match(/^[a-zA-Z_]+[a-zA-Z0-9_]*$/)) {
throw new Error(`Invalid Env Var name ${envVar.name}`)
}
if (envVar.name.match(/^FF_/)) {
throw new Error(`Illegal Env Var name ${envVar.name}`)
}
result.env.push(envVar)
}
})
// find duplicates
const seen = new Set()
const dups = result.env.some( item => { return seen.size === seen.add(item.name).size })
if (dups) {
throw new Error('Duplicate Env Var names provided')
}
}
// Validate palette modules:
// * No duplicates
Expand Down
18 changes: 12 additions & 6 deletions forge/routes/api/project.js
Original file line number Diff line number Diff line change
Expand Up @@ -394,13 +394,19 @@ module.exports = async function (app) {
env: request.body.settings.env
}
}
const newSettings = app.db.controllers.ProjectTemplate.validateSettings(bodySettings, request.project.ProjectTemplate)
if (newSettings.httpNodeAuth?.type === 'flowforge-user') {
const teamType = await request.project.Team.getTeamType()
if (teamType.properties.features?.teamHttpSecurity === false) {
reply.code(400).send({ code: 'invalid_request', error: 'FlowForge User Authentication not available for this team type' })
return
try {
const newSettings = app.db.controllers.ProjectTemplate.validateSettings(bodySettings, request.project.ProjectTemplate)
if (newSettings.httpNodeAuth?.type === 'flowforge-user') {
const teamType = await request.project.Team.getTeamType()
if (teamType.properties.features?.teamHttpSecurity === false) {
reply.code(400).send({ code: 'invalid_request', error: 'FlowForge User Authentication not available for this team type' })
return
}
}
} catch (err) {
console.log(err)
reply.code(400).send({ code: 'env_var_validation', error: `${err.message}` })
return
}

// Merge the settings into the existing values
Expand Down
52 changes: 52 additions & 0 deletions test/unit/forge/routes/api/project_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2330,4 +2330,56 @@ describe('Project API', function () {
response.statusCode.should.eqls(403)
})
})
describe.only('Validate Project Env Vars', function () {
it('Reject Duplicate Env Var Names', async function () {
const response = await app.inject({
method: 'PUT',
url: `/api/v1/projects/${app.project.id}`,
body: {
settings: {
env: [
{ name: 'FOO', value: 'bar' },
{ name: 'FOO', value: 'BAR' }
]
}
},
cookies: { sid: TestObjects.tokens.alice }
})
response.should.have.property('statusCode')
response.statusCode.should.eqls(400)
})
it('Reject Invalid names', async function () {
const response = await app.inject({
method: 'PUT',
url: `/api/v1/projects/${app.project.id}`,
body: {
settings: {
env: [
{ name: '99FOO', value: 'bar' }
]
}
},
cookies: { sid: TestObjects.tokens.alice }
})
response.should.have.property('statusCode')
response.statusCode.should.eqls(400)
})
it('Reject Illegal names', async function () {
const response = await app.inject({
method: 'PUT',
url: `/api/v1/projects/${app.project.id}`,
body: {
settings: {
env: [
{ name: 'FF_FOO', value: 'bar' }
]
}
},
cookies: { sid: TestObjects.tokens.alice }
})
response.should.have.property('statusCode')
response.statusCode.should.eqls(400)
})

})
})

0 comments on commit 2698095

Please sign in to comment.