Skip to content

Commit

Permalink
Merge pull request #1308 from CVEProject/dr_utc
Browse files Browse the repository at this point in the history
Standardize all timestamps values to UTC
  • Loading branch information
jdaigneau5 authored Dec 20, 2024
2 parents 9d92da9 + 6901b17 commit c646956
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 9 deletions.
4 changes: 3 additions & 1 deletion src/constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,9 @@ function getConstants () {
CVE_ID_PATTERN: cveSchemaV5.definitions.cveId.pattern,
// Ajv's pattern validation uses the "u" (unicode) flag:
// https://ajv.js.org/json-schema.html#pattern
CVE_ID_REGEX: new RegExp(cveSchemaV5.definitions.cveId.pattern, 'u')
CVE_ID_REGEX: new RegExp(cveSchemaV5.definitions.cveId.pattern, 'u'),
DATE_FIELDS: ['cveMetadata.datePublished', 'cveMetadata.dateUpdated', 'cveMetadata.dateReserved', 'providerMetadata.dateUpdated', 'datePublic', 'dateAssigned'
]
}

return defaults
Expand Down
16 changes: 9 additions & 7 deletions src/controller/cve.controller/cve.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const errors = require('./error')
const getConstants = require('../../constants').getConstants
const error = new errors.CveControllerError()
const booleanIsTrue = require('../../utils/utils').booleanIsTrue
const convertDatesToISO = require('../../utils/utils').convertDatesToISO
const isEnrichedContainer = require('../../utils/utils').isEnrichedContainer
const url = process.env.NODE_ENV === 'staging' ? 'https://test.cve.org/' : 'https://cve.org/'

Expand Down Expand Up @@ -332,7 +333,7 @@ async function submitCve (req, res, next) {
const CONSTANTS = getConstants()

try {
const newCve = new Cve({ cve: req.ctx.body })
const newCve = new Cve({ cve: convertDatesToISO(req.ctx.body, CONSTANTS.DATE_FIELDS) })
const id = req.ctx.params.id
const cveId = newCve.cve.cveMetadata.cveId
const state = newCve.cve.cveMetadata.state
Expand Down Expand Up @@ -392,7 +393,8 @@ async function updateCve (req, res, next) {
const CONSTANTS = getConstants()

try {
const newCve = new Cve({ cve: req.ctx.body })
// All CVE fields are stored in UTC format, we need to check and convert dates to ISO before storing in the database.
const newCve = new Cve({ cve: convertDatesToISO(req.ctx.body, CONSTANTS.DATE_FIELDS) })
const cveId = req.ctx.params.id
const cveRepo = req.ctx.repositories.getCveRepository()
const cveIdRepo = req.ctx.repositories.getCveIdRepository()
Expand Down Expand Up @@ -486,7 +488,7 @@ async function submitCna (req, res, next) {
return res.status(403).json(error.cveRecordExists())
}

const cnaContainer = req.ctx.body.cnaContainer
const cnaContainer = convertDatesToISO(req.ctx.body.cnaContainer, CONSTANTS.DATE_FIELDS)
if (erlCheck && !isEnrichedContainer(cnaContainer)) {
// Process the ERL check here
return res.status(403).json(error.erlCheckFailed())
Expand Down Expand Up @@ -582,7 +584,7 @@ async function updateCna (req, res, next) {
return res.status(403).json(error.cveRecordDne())
}

const cnaContainer = req.ctx.body.cnaContainer
const cnaContainer = convertDatesToISO(req.ctx.body.cnaContainer, CONSTANTS.DATE_FIELDS)
if (erlCheck && !isEnrichedContainer(cnaContainer)) {
// Process the ERL check here
return res.status(403).json(error.erlCheckFailed())
Expand Down Expand Up @@ -684,7 +686,7 @@ async function rejectCVE (req, res, next) {

const providerMetadata = createProviderMetadata(providerOrgObj.UUID, req.ctx.org, (new Date()).toISOString())
const rejectedCve = Cve.newRejectedCve(cveIdObj, req.ctx.body, owningCnaShortName, providerMetadata)
const newCveObj = new Cve({ cve: rejectedCve })
const newCveObj = new Cve({ cve: convertDatesToISO(rejectedCve, CONSTANTS.DATE_FIELDS) })

result = Cve.validateCveRecord(newCveObj.cve)
if (!result.isValid) {
Expand Down Expand Up @@ -757,7 +759,7 @@ async function rejectExistingCve (req, res, next) {

// update CVE record to rejected
const updatedRecord = Cve.updateCveToRejected(id, providerMetadata, result.cve, req.ctx.body)
const updatedCve = new Cve({ cve: updatedRecord })
const updatedCve = new Cve({ cve: convertDatesToISO(updatedRecord, CONSTANTS.DATE_FIELDS) })

result = Cve.validateCveRecord(updatedCve.cve)
if (!result.isValid) {
Expand Down Expand Up @@ -867,7 +869,7 @@ async function insertAdp (req, res, next) {
cveRecord.containers.adp.push(adpContainer)
}

const cveModel = new Cve({ cve: cveRecord })
const cveModel = new Cve({ cve: convertDatesToISO(cveRecord, CONSTANTS.DATE_FIELDS) })
result = Cve.validateCveRecord(cveModel.cve)
if (!result.isValid) {
logger.error(JSON.stringify({ uuid: req.ctx.uuid, message: 'CVE JSON schema validation FAILED.' }))
Expand Down
61 changes: 60 additions & 1 deletion src/utils/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const Org = require('../model/org')
const User = require('../model/user')
const getConstants = require('../constants').getConstants
const _ = require('lodash')
const { DateTime } = require('luxon')

async function getOrgUUID (shortName) {
Expand Down Expand Up @@ -154,6 +155,62 @@ function toDate (val) {
return result
}

// Covert Dates to ISO format
function convertDatesToISO (obj, dateKeys) {
// Helper function to check if a value is a valid date
function isValidDate (value) {
return value instanceof Date && !isNaN(value)
}

// Helper function to check if a string is a valid date
function isStringDate (value) {
const date = new Date(value)
return !isNaN(date.getTime())
}

function updateDateValue (objectToUpdate, key, value) {
if (isValidDate(value)) {
_.set(objectToUpdate, key, value.toISOString())
} else if (typeof value === 'string' && isStringDate(value)) {
_.set(objectToUpdate, key, new Date(value).toISOString())
}
}

// For the top layer object
for (const key of dateKeys) {
if (_.has(obj, key)) {
const value = _.get(obj, key)
updateDateValue(obj, key, value)
}
}

// For the ADP(s)
if (_.has(obj, 'containers.adp')) {
// Use lodash for each to loop over array and check for date keys
_.each(obj.containers.adp, (adp) => {
for (const key of dateKeys) {
if (_.has(adp, key)) {
const value = _.get(adp, key)
updateDateValue(adp, key, value)
}
}
})
}
// For the CNAs

if (_.has(obj, 'containers.cna')) {
// Use lodash to check the containers.cna object for date keys
for (const key of dateKeys) {
if (_.has(obj.containers.cna, key)) {
const value = _.get(obj.containers.cna, key)
updateDateValue(obj.containers.cna, key, value)
}
}
}

return obj
}

function isEnrichedContainer (container) {
const hasCvss = container?.metrics?.some(item => 'cvssV4_0' in item || 'cvssV3_1' in item || 'cvssV3_0' in item || 'cvssV2_0' in item)
const hasCwe = container?.problemTypes?.some(pItem => pItem?.descriptions?.some(dItem => 'cweId' in dItem))
Expand All @@ -174,5 +231,7 @@ module.exports = {
getUserUUID,
reqCtxMapping,
booleanIsTrue,
toDate
toDate,
convertDatesToISO

}

0 comments on commit c646956

Please sign in to comment.