diff --git a/ReviewParser.js b/ReviewParser.js index c3cd531..4c34929 100644 --- a/ReviewParser.js +++ b/ReviewParser.js @@ -4,6 +4,15 @@ import decode from './decode.js' const decodeHTML = function () { return decode(arguments[1]) } + +const truncateString = function (str, max) { + if (typeof str !== 'string') { + return str + } + return str.length > max ? str.slice(0, max) : str +} + +const maxCommentLength = 32767 /** * Parses data from a CKL format into a format suitable for further processing. * @@ -29,8 +38,6 @@ export function reviewsFromCkl( const errorMessages = [] - const maxCommentLength = 32767 - const normalizeKeys = function (input) { // lowercase and remove hyphens if (typeof input !== 'object') return input; @@ -82,6 +89,9 @@ export function reviewsFromCkl( if (!returnObj.target.name) { throw (new Error("No host_name in ASSET")) } + if (returnObj.target.name.length > 255) { + throw (new Error("Asset hostname cannot be more than 255 characters", returnObj.target.name)) + } returnObj.checklists = processIStig(parsed.CHECKLIST[0].STIGS[0].iSTIG) if (returnObj.checklists.length === 0) { throw (new Error("STIG_INFO element has no SI_DATA for SID_NAME == stigId")) @@ -94,9 +104,9 @@ export function reviewsFromCkl( let obj = { name: assetElement.HOST_NAME, description: null, - ip: assetElement.HOST_IP || null, - fqdn: assetElement.HOST_FQDN || null, - mac: assetElement.HOST_MAC || null, + ip: assetElement?.HOST_IP ? truncateString(assetElement.HOST_IP, 255) : null, + fqdn: assetElement.HOST_FQDN ? truncateString(assetElement.HOST_FQDN, 255) : null, + mac: assetElement.HOST_MAC ? truncateString(assetElement.HOST_MAC, 255) : null, noncomputing: assetElement.ASSET_TYPE === 'Non-Computing' } const metadata = {} @@ -127,6 +137,7 @@ export function reviewsFromCkl( // get benchmarkId let stigIdElement = iStig.STIG_INFO[0].SI_DATA.filter(d => d.SID_NAME === 'stigid')?.[0] checklist.benchmarkId = stigIdElement.SID_DATA.replace('xccdf_mil.disa.stig_benchmark_', '') + checklist.benchmarkId = truncateString(checklist.benchmarkId, 255) // get revision data. Extract digits from version and release fields to create revisionStr, if possible. const stigVersionData = iStig.STIG_INFO[0].SI_DATA.filter(d => d.SID_NAME === 'version')?.[0].SID_DATA let stigVersion = stigVersionData.match(/(\d+)/)?.[1] @@ -134,7 +145,7 @@ export function reviewsFromCkl( const stigRelease = stigReleaseInfo.match(/Release:\s*(.+?)\s/)?.[1] const stigRevisionStr = stigVersion && stigRelease ? `V${stigVersion}R${stigRelease}` : null checklist.revisionStr = stigRevisionStr - + if (checklist.benchmarkId) { let x = processVuln(iStig.VULN, iStig.__comment) checklist.reviews = x.reviews @@ -185,7 +196,8 @@ export function reviewsFromCkl( function generateReview(vuln, iStigComment) { let result = resultMap[vuln.STATUS] if (!result) return - const ruleId = getRuleIdFromVuln(vuln) + let ruleId = getRuleIdFromVuln(vuln) + ruleId = truncateString(ruleId, 45) if (!ruleId) return const hasComments = !!vuln.FINDING_DETAILS || !!vuln.COMMENTS @@ -204,7 +216,7 @@ export function reviewsFromCkl( } } - let detail = vuln.FINDING_DETAILS.length > maxCommentLength ? vuln.FINDING_DETAILS.slice(0, maxCommentLength) : vuln.FINDING_DETAILS + let detail = vuln.FINDING_DETAILS.length > maxCommentLength ? truncateString(vuln.FINDING_DETAILS, maxCommentLength) : vuln.FINDING_DETAILS if (!vuln.FINDING_DETAILS) { switch (importOptions.emptyDetail) { case 'ignore': @@ -219,7 +231,7 @@ export function reviewsFromCkl( } } - let comment = vuln.COMMENTS.length > maxCommentLength ? vuln.COMMENTS.slice(0, maxCommentLength) : vuln.COMMENTS + let comment = vuln.COMMENTS.length > maxCommentLength ? truncateString(vuln.COMMENTS, maxCommentLength) : vuln.COMMENTS if (!vuln.COMMENTS) { switch (importOptions.emptyComment) { case 'ignore': @@ -261,7 +273,7 @@ export function reviewsFromCkl( override = normalizeKeys(override) if (override.afmod?.toLowerCase() === 'true') { overrides.push({ - authority: override.answerfile, + authority: truncateString(override?.answerfile, 255), oldResult: resultMap[override.oldstatus] ?? 'unknown', newResult: result, remark: 'Evaluate-STIG Answer File' @@ -400,10 +412,11 @@ export function reviewsFromCkl( errorMessages.push(`Failed to parse Evaluate-STIG root XML comment for ${comment}`) } esRootComment = normalizeKeys(esRootComment) + const version = esRootComment?.global?.[0]?.version || esRootComment?.version resultEngineRoot = { type: 'script', product: 'Evaluate-STIG', - version: esRootComment?.global?.[0]?.version || esRootComment?.version, + version: truncateString(version, 255), time: esRootComment?.global?.[0]?.time, checkContent: { location: (esRootComment?.module?.[0]?.name ?? '') + @@ -504,11 +517,27 @@ export function reviewsFromXccdf( if (scapBenchmarkMap?.has(benchmarkId)) { benchmarkId = scapBenchmarkMap.get(benchmarkId) } + benchmarkId = truncateString(benchmarkId, 255) const target = processTarget(testResult) if (!target.name) { throw (new Error('No value for ')) } - + if(target.name.length > 255){ + throw (new Error('Asset hostname cannot be more than 255 characters', target.name)) + } + if(target.fqdn){ + target.fqdn = truncateString(target.fqdn, 255) + } + if(target.mac){ + target.mac = truncateString(target.mac, 255) + } + if(target.ip){ + target.ip = truncateString(target.ip, 255) + } + if(target.description){ + target.description = truncateString(target.description, 255) + } + // resultEngine info const testSystem = testResult['test-system'] // SCC injects a CPE WFN bound to a URN @@ -525,6 +554,10 @@ export function reviewsFromXccdf( product, version } + + resultEngineTpl.version = truncateString(resultEngineTpl.version, 255) + resultEngineTpl.product = truncateString(resultEngineTpl.product, 255) + const r = processRuleResults(testResult['rule-result'], resultEngineTpl) // Return object @@ -566,7 +599,8 @@ export function reviewsFromXccdf( function generateReview(ruleResult, resultEngineCommon) { let result = ruleResult.result if (!result) return - const ruleId = ruleResult.idref.replace('xccdf_mil.disa.stig_rule_', '') + let ruleId = ruleResult.idref.replace('xccdf_mil.disa.stig_rule_', '') + ruleId = truncateString(ruleId, 45) if (!ruleId) return const hasComments = false // or look for @@ -603,7 +637,7 @@ export function reviewsFromXccdf( if (checkContentHref || checkContentName) { resultEngine.checkContent = { location: checkContentHref, - component: checkContentName + component: truncateString(checkContentName, 255) } } @@ -611,10 +645,10 @@ export function reviewsFromXccdf( const overrides = [] for (const override of ruleResult.override) { overrides.push({ - authority: override.authority, + authority: truncateString(override?.authority,255), oldResult: override['old-result'], newResult: override['new-result'], - remark: override['remark'] + remark: truncateString(override['remark'],255) }) } if (overrides.length) { @@ -640,6 +674,7 @@ export function reviewsFromXccdf( break } } + detail = truncateString(detail, maxCommentLength) let comment = ruleResult.check?.['check-content']?.comment if (!comment) { @@ -655,6 +690,7 @@ export function reviewsFromXccdf( break } } + comment = truncateString(comment, maxCommentLength) const review = { ruleId, @@ -780,7 +816,6 @@ export function reviewsFromCklb( sourceRef }) { - const maxCommentLength = 32767 const resultMap = { not_a_finding: 'pass', open: 'fail', @@ -825,6 +860,9 @@ export function reviewsFromCklb( if (!returnObj.target.name) { throw (new Error("No host_name in target_data")) } + if(returnObj.target.name.length > 255){ + throw (new Error("Asset hostname cannot be more than 255 characters", returnObj.target.name)) + } returnObj.checklists = processStigs(cklb.stigs) if (returnObj.checklists.length === 0) { throw (new Error("stigs array is empty")) @@ -834,10 +872,10 @@ export function reviewsFromCklb( function processTargetData(td) { const obj = { name: td.host_name, - description: td.comments, - ip: td.ip_address || null, - fqdn: td.fqdn || null, - mac: td.mac_address || null, + description: td.comments ? truncateString(td.comments, 255): null, + ip: td.ip_address ? truncateString(td.ip_address, 255) : null, + fqdn: td.fqdn ? truncateString(td.fqdn, 255) : null, + mac: td.mac_address ? truncateString(td.mac_address, 255) : null, noncomputing: td.target_type === 'Non-Computing', metadata: {} } @@ -870,6 +908,7 @@ export function reviewsFromCklb( // } const checklist = { sourceRef } checklist.benchmarkId = typeof stig?.stig_id === 'string' ? stig.stig_id.replace('xccdf_mil.disa.stig_benchmark_', '') : '' + checklist.benchmarkId = truncateString(checklist.benchmarkId, 255) const stigVersion = '0' const stigRelease = typeof stig?.release_info === 'string' ? stig.release_info.match(/Release:\s*(.+?)\s/)?.[1] : '' checklist.revisionStr = checklist.benchmarkId && stigRelease ? `V${stigVersion}R${stigRelease}` : null @@ -912,6 +951,7 @@ export function reviewsFromCklb( let ruleId = rule.rule_id_src ?? rule.rule_id if (!ruleId) return ruleId = ruleId.endsWith('_rule') ? ruleId : ruleId + '_rule' + ruleId = truncateString(ruleId, 45) const hasComments = !!rule.finding_details || !!rule.comments @@ -929,7 +969,7 @@ export function reviewsFromCklb( } } - let detail = rule.finding_details?.length > maxCommentLength ? rule.finding_details.slice(0, maxCommentLength) : rule.finding_details + let detail = rule.finding_details?.length > maxCommentLength ? truncateString(rule.finding_details, maxCommentLength) : rule.finding_details if (!rule.finding_details) { switch (importOptions.emptyDetail) { case 'ignore': @@ -944,7 +984,7 @@ export function reviewsFromCklb( } } - let comment = rule.comments?.length > maxCommentLength ? rule.comments.slice(0, maxCommentLength) : rule.comments + let comment = rule.comments?.length > maxCommentLength ? truncateString(rule.comments, maxCommentLength) : rule.comments if (!rule.comments) { switch (importOptions.emptyComment) { case 'ignore': @@ -1062,7 +1102,7 @@ export function reviewsFromCklb( resultEngineCommon = { type: 'script', product: 'Evaluate-STIG', - version: module.version, + version: truncateString(module.version, 255), } return resultEngineCommon } diff --git a/WATCHER-test-files/WATCHER/ckl/Target-Object-Long-Properties b/WATCHER-test-files/WATCHER/ckl/Target-Object-Long-Properties new file mode 100644 index 0000000..4cf1fe6 --- /dev/null +++ b/WATCHER-test-files/WATCHER/ckl/Target-Object-Long-Properties @@ -0,0 +1,168 @@ + + + + + MyRole + Non-Computing + MyMarking + LlllloooooooooooooooooooonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnggggggggggggggggggggggggggggggNaaaaaaaaaaaaaaaaaaaaaammmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmeeeeeeeeeeeeeeeeeeee + 10.10.10.10..10.10.10.10.10.10..10.10.10.10.10.10.10.10.10..10.10.10..10.10.10..10.10.10..10.10.10..10.10.10..10.10.10.10.10.10.10.10.10.10.10.10.10.10.10.10.10.10.10.10.10.10.10.1010.10.10.10.10.10.1010.10.10.10.10.10.1010.10.10.10.10.10.1010.10.10.10.10.10.1010.10.10.10.10.10.1010.10.10.10.10.10.10.10.10.10.10.10.10.10.10.10.10.10 + 00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E00:1A:2B:3C:4D:5E + + MyAsset.hello.worldMyAsset.hello.worldMyAsset.hello.worldMyAsset.hello.worldMyAsset.hello.worldMyAsset.hello.worldMyAsset.hello.worldvMyAsset.hello.worldMyAsset.hello.worldMyAsset.hello.worldMyAsset.hello.worldMyAsset.hello.worldMyAsset.hello.worldMyAsset.hello.worldMyAsset.hello.worldMyAsset.hello.worldMyAsset.hello.world + + 2777 + false + + + + + + + + version + 1 + + + classification + + + customname + + + stigid + RHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATEDRHEL_9_TRUNCATED + + + description + This Security Technical Implementation Guide is published as a tool to improve the security of Department of Defense (DOD) information systems. The requirements are derived from the National Institute of Standards and Technology (NIST) 800-53 and related documents. Comments or proposed revisions to this document should be sent via email to the following address: disa.stig_spt@mail.mil. + + + filename + stig-manager-oss + + + releaseinfo + Release: 1 Benchmark Date: 22 Sep 2023 + + + title + Red Hat Enterprise Linux 9 TRUNCATED + + + uuid + 391aad33-3cc3-4d9a-b5f7-0d7538b7b5a2 + + + notice + terms-of-use + + + source + + + + + Vuln_Num + V-207191 + + + Severity + medium + + + Weight + 10.0 + + + Group_Title + SRG-NET-000063 + + + Rule_ID + SV-207191r803418_rV-207191r803418_rulV-207191r803418_rulV-207191r803418_rulV-207191r803418_rulule + + + Rule_Ver + SRG-NET-000063-VPN-000210 + + + Rule_Title + The remote access VPN Gateway must use a digital signature generated using FIPS-validated algorithms and an approved hash function to protect the integrity of TLS remote access sessions. + + + Vuln_Discuss + Without integrity protection, unauthorized changes may be made to the log files and reliable forensic analysis and discovery of the source of malicious system activity may be degraded. + +Remote access (e.g., RDP) is access to DoD nonpublic information systems by an authorized user (or an information system) communicating through an external, non-organization-controlled network. Remote access methods include broadband and wireless. + +Integrity checks include cryptographic checksums, digital signatures, or hash functions. Federal Information Processing Standard (FIPS) 186-4, Digital Signature Standard (DSS), specifies three NIST-approved algorithms: DSA, RSA, and ECDSA. All three are used to generate and verify digital signatures in conjunction with an approved hash function. + + + IA_Controls + + + + Check_Content + Verify the remote access VPN Gateway uses a digital signature generated using FIPS-validated algorithms and an approved hash function to protect the integrity of remote access sessions. + +If the remote access VPN Gateway does not use a digital signature generated using FIPS-validated algorithms and an approved hash function to protect the integrity of remote access sessions, this is a finding. + + + Fix_Text + Configure the remote access VPN Gateway to use a digital signature generated using FIPS-validated algorithms and an approved hash function to protect the integrity of remote access sessions. + + + False_Positives + + + + False_Negatives + + + + Documentable + false + + + Mitigations + + + + Potential_Impact + + + + Third_Party_Tools + + + + Mitigation_Control + + + + Responsibility + + + + Security_Override_Guidance + + + + STIGRef + Virtual Private Network (VPN) TRUNCATED :: Version 2, Release: 5 Benchmark Date: 07 Jun 2023 + + + CCI_REF + CCI-001453 + + NotAFinding + + + + + + + + + diff --git a/WATCHER-test-files/WATCHER/cklb/Truncate-Tests.cklb b/WATCHER-test-files/WATCHER/cklb/Truncate-Tests.cklb new file mode 100644 index 0000000..2e2934f --- /dev/null +++ b/WATCHER-test-files/WATCHER/cklb/Truncate-Tests.cklb @@ -0,0 +1,94 @@ +{ + "evaluate-stig": { + "version": "1.2310.11.2310.11.2310.11.2310.11.11.2310.11.2310.11.2310.11.11.2310.11.2310.11.2310.11.11.2310.11.2310.11.2310.11.11.2310.11.2310.11.2310.11.11.2310.11.2310.11.2310.11.11.2310.11.2310.11.2310.11.11.2310.11.2310.11.2310.11.11.2310.11.2310.11.2310.11.11.2310.11.2310.11.2310.11.11.2310.11.2310.11.2310.11.11.2310.11.2310.11.2310.11.11.2310.11.2310.11.2310.11.11.2310.11.2310.11.2310.11.11.2310.11.2310.11.2310.11.11.2310.11.2310.11.2310.11.11.2310.11.2310.11.2310.11.11.2310.11.2310.11.2310.11.2310.1" + }, + "title": "Asset-VPN_TRUNCATED-V2R5", + "id": "2f6fe9e0-8242-11ee-8b44-13c1c13d16bb", + "active": false, + "mode": 1, + "has_path": true, + "target_data": { + "target_type": "Non-Computing", + "host_name": "Assessessessesssessessessessessessessessevt", + "ip_address": "1.1.1.11.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.11.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.11.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.11.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.11.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.11.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.11.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.11.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.11.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.11.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.11.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.1.11.1.1.11.1.1.1", + "mac_address": "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:000:00:00:00:00:00:00:00", + "fqdn": "asset.comasset.comasset.comasset.comasset.comasset.comasset.comascomasset.comasset.comasset.comasset.comasset.comasset.comascomasset.comasset.comasset.comasset.comasset.comasset.comascomasset.comasset.comasset.comasset.comasset.comasset.comascomasset.comasset.comasset.comasset.comasset.comasset.comascomasset.comasset.comasset.comasset.comasset.comasset.comascomasset.comasset.comasset.comasset.comasset.comasset.comascomasset.comasset.comasset.comasset.comasset.comasset.comascomasset.comasset.comasset.comasset.comasset.comasset.comascomasset.comasset.comasset.comasset.comasset.comasset.comascomasset.comasset.comasset.comasset.comasset.comasset.comascomasset.comasset.comasset.comasset.comasset.comasset.comascomasset.comasset.comasset.comasset.comasset.comasset.comascomasset.comasset.comasset.comasset.comasset.comasset.comascomasset.comasset.comasset.comasset.comasset.comasset.comasset.comasset.com", + "comments": "xyzyzyzyzyyzyzyzyyzyzyzyyzyzyzyyzyzyzyzyyzyzyzyyzyzyzyyzyzyzyzyyzyzyzyyzyzyzyyzyzyzyzyyzyzyzyyzyzyzyyzyzyzyzyyzyzyzyyzyzyzyyzyyzyzyyzyzyzyyzyzyzyyzyzyzyzyyzyzyzyyzyzyzyyzyyzyzyyzyzyzyyzyzyzyyzyzyzyzyyzyzyzyyzyzyzyyzyyzyzyyzyzyzyyzyzyzyyzyzyzyzyyzyzyzyyzyzyzyyzyyzyzyyzyzyzyyzyzyzyyzyzyzyzyyzyzyzyyzyzyzyyzyyzyzyyzyzyzyyzyzyzyyzyzyzyzyyzyzyzyyzyzyzyyzyyzyzyyzyzyzyyzyzyzyyzyzyzyzyyzyzyzyyzyzyzyyzyyzyzyyzyzyzyyzyzyzyyzyzyzyzyyzyzyzyyzyzyzyyzyyzyzyyzyzyzyyzyzyzyyzyzyzyzyyzyzyzyyzyzyzyyzyzyzyzyyzyzyzyyzyzyzyyzyzyzyzyyzyzyzyyzyzyzyyzyzyzyzyyzyzyzyyzyzyzyyzyzyzyzyyzyzyzyyzyzyzyyzyzyzyzyz", + "role": null, + "is_web_database": false, + "technology_area": null, + "web_db_site": null, + "web_db_instance": null + }, + "stigs": [ + { + "evaluate-stig": { + "time": "2023-12-11T12:56:14.3576272-05:00", + "module": { + "name": "Scan-GoogleChrome_Checks", + "version": "1.2023.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.20233.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.20233.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.20233.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.20233.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.20233.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.20233.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.20233.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.20233.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.20233.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.241.2023.7.24" + } + }, + "stig_name": "Virtual Private Network (VPN) TRUNCATED", + "display_name": "Virtual Private Network (VPN) TRUNCATED", + "stig_id": "VPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATEDVPN_TRUNCATED", + "version": 2, + "release_info": "Release: 5 Benchmark Date: 07 Jun 2023", + "uuid": "2f714970-8242-11ee-8b44-13c1c13d16bb", + "reference_identifier": "0000", + "size": 10, + "rules": [ + { + "uuid": "2f7281f0-8242-11ee-8b44-13c1c13d16bb", + "stig_uuid": "2f714970-8242-11ee-8b44-13c1c13d16bb", + "target_key": null, + "stig_ref": null, + "group_id": "V-207184", + "rule_id": "SV-207184r6953-207184r6953-207184r6953-207184r6953-207184r6953-207184r695317", + "rule_id_src": "SV-257777r92531V-257777r92531V-257777r92531V-257777r92531V-257777r925317_rule", + "weight": "10.0", + "classification": "NONE", + "severity": "medium", + "rule_version": "SRG-NET-000019-VPN-000040", + "group_title": "SRG-NET-000019", + "rule_title": "The VPN Gateway must ensure inbound and outbound traffic is configured with a security policy in compliance with information flow control policies.", + "fix_text": "Configure the VPN Gateway to ensure inbound and outbound traffic is configured with a security policy in compliance with information flow control policies (e.g., IPsec policy configuration). Also, configure the VPN gateway to forward encapsulated or encrypted traffic received from other enclaves with different security policies to the perimeter firewall and IDPS before traffic is passed to the private network.", + "false_positives": null, + "false_negatives": null, + "discussion": "Unrestricted traffic may contain malicious traffic which poses a threat to an enclave or to other connected networks. Additionally, unrestricted traffic may transit a network, which uses bandwidth and other resources.\n\nVPN traffic received from another enclave with different security policy or level of trust must not bypass be inspected by the firewall before being forwarded to the private network.", + "check_content": "Verify the VPN Gateway has an inbound and outbound traffic security policy which is in compliance with information flow control policies (e.g., IPsec policy configuration).\n\nReview network device configurations and topology diagrams. Verify encapsulated or encrypted traffic received from other enclaves with different security policies terminate at the perimeter for filtering and content inspection by a firewall and IDPS before gaining access to the private network.\n\nIf the IPsec VPN Gateway does not use Encapsulating Security Payload (ESP) in tunnel mode for establishing secured paths to transport traffic between the organizations sites or between a gateway and remote end-stations, this is a finding,", + "documentable": "false", + "mitigations": null, + "potential_impacts": null, + "third_party_tools": null, + "mitigation_control": null, + "responsibility": null, + "security_override_guidance": null, + "ia_controls": null, + "check_content_ref": { + "href": "", + "name": "M" + }, + "legacy_ids": [], + "group_tree": [ + { + "id": "V-207184", + "title": "SRG-NET-000019", + "description": "" + } + ], + "createdAt": "2023-11-13T16:30:36.000Z", + "updatedAt": "2023-11-13T16:30:36.000Z", + "STIGUuid": "2f714970-8242-11ee-8b44-13c1c13d16bb", + "status": "not_a_finding", + "overrides": {}, + "comments": "", + "finding_details": "xyz", + "ccis": [ + "CCI-001414" + ] + } + ] + } + ] +} diff --git a/WATCHER-test-files/WATCHER/xccdf/Target-Object-Long-Properties-xccdf.xml b/WATCHER-test-files/WATCHER/xccdf/Target-Object-Long-Properties-xccdf.xml new file mode 100644 index 0000000..d498271 --- /dev/null +++ b/WATCHER-test-files/WATCHER/xccdf/Target-Object-Long-Properties-xccdf.xml @@ -0,0 +1,63 @@ + + + + + + accepted + MyStigTitle + Test Description + V1R1 + + DISA + STIG Manager OSS + + + MyStigGroup + + MyRuleTitle + + MyCheckContent + + + + + MyTitleForTestResult + MyAsset + + + + + MyMyAsssetMyAsset + DescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescripptionDescripptionDescripptionDescripptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescription + + MyAsset.domain.comMyAsset.domain.comMyAsset.domain.comMyAsset.domain.comMyAsset.domain.comMyAsset.domain.comMyAsset.domain.comMyAsset.domain.comMyAsset.domain.comMyAsset.domain.comMyAsset.domain.comMyAsset.domain.comMyAsset.domain.comMyAsset.domain.comMyAsset.domain.comMyAsset.domain.comMyAsset.domain.comMyAsset.domain.comMyAsset.domain.com + + 1.1.1.11.1.1.11.1.1.11.1.1.11.1.1.1.1.11.1.1.11.1.1.11.1.1.1.1.11.1.1.11.1.1.11.1.1.1.1.11.1.1.11.1.1.11.1.1.1.1.11.1.1.11.1.1.11.1.1.1.1.11.1.1.11.1.1.11.1.1.1.1.11.1.1.11.1.1.11.1.1.1.1.11.1.1.11.1.1.11.1.1.1.1.11.1.1.11.1.1.11.1.1.1.1.11.1.1.11.1.1.11.1.1.1.1.11.1.1.11.1.1.11.1.1.1.1.11.1.1.11.1.1.11.1.1.1.1.11.1.1.11.1.1.11.1.1.1.1.11.1.1.11.1.1.11.1.1.1.1.11.1.1.11.1.1.11.1.1.11.1.1.1 + + fe80::8c33fe80::8c33:57ff:fe94:2b3fe80::8c33:57ff:fe94:2b3fe80::8c33:57ff:fe94:2b3fe80::8c33:57ff:fe94:2b3fe80::8c33:57ff:fe94:2b3fe80::8c33:57ff:fe94:2b3fe80::8c33:57ff:fe94:2b3fe80::8c33:57ff:fe94:2b3fe80::8c33:57ff:fe94:2b3fe80::8c33:57ff:fe94:2b3fe80::8c33:57ff:fe94:2b3:57ff:fe94:2b33 + false + + + pass + + + + xyz + + + + AuAuthority1Authority1Authority1Authority1Authority1thuthority1Authority1Authority1Authority1Authority1thuthority1Authority1Authority1Authority1Authority1thuthority1Authority1Authority1Authority1Authority1thuthority1Authority1Authority1Authority1Authority1thuthority1Authority1Authority1Authority1Authority1thuthority1Authority1Authority1Authority1Authority1thuthority1Authority1Authority1Authority1Authority1thuthority1Authority1Authority1Authority1Authority1thuthority1Authority1Authority1Authority1Authority1thuthority1Authority1Authority1Authority1Authority1thuthority1Authority1Authority1Authority1Authority1thuthority1Authority1Authority1Authority1Authority1thuthority1Authority1Authority1Authority1Authority1thuthority1Authority1Authority1Authority1Authority1thuthority1Authority1Authority1Authority1Authority1thuthority1Authority1Authority1Authority1Authority1thuthority1Authority1Authority1Authority1Authority1thuthority1Authority1Authority1Authority1Authority1thuthority1Authority1Authority1Authority1Authority1thuthority1Authority1Authority1Authority1Authority1thority1 + pass + fail + Some remarome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkome remarkk + + + + 1.0 + + \ No newline at end of file diff --git a/test/ckl-tests/CKLResultEngine.test.js b/test/ckl-tests/CKLResultEngine.test.js index 5cedc20..767b118 100644 --- a/test/ckl-tests/CKLResultEngine.test.js +++ b/test/ckl-tests/CKLResultEngine.test.js @@ -412,4 +412,42 @@ describe('CKL result engine tests', () => { expectedResultEngine ) }) + it('Validating that parser truncates result engine values to their max oas spec', async () => { + // values tested: overrides: authority, resultEngine: version. + const importOptions = { + autoStatus: 'saved', + unreviewed: 'commented', + unreviewedCommented: 'informational', + emptyDetail: 'replace', + emptyComment: 'ignore', + allowCustom: true + } + + const fieldSettings = { + detail: { + enabled: 'always', + required: 'always' + }, + comment: { + enabled: 'findings', + required: 'findings' + } + } + + const allowAccept = true + + const filePath = + './WATCHER-test-files/WATCHER/ckl/Target-Object-Long-Properties' + + const review = await generateReviewObject( + filePath, + importOptions, + fieldSettings, + allowAccept + ) + + expect(review.checklists[0].reviews[0].resultEngine.version).to.have.lengthOf(255) + expect(review.checklists[0].reviews[0].resultEngine.overrides[0].authority).to.have.lengthOf(255) + + }) }) diff --git a/test/ckl-tests/CKLReviewParserChecklistArray.test.js b/test/ckl-tests/CKLReviewParserChecklistArray.test.js index 205c356..c0695ce 100644 --- a/test/ckl-tests/CKLReviewParserChecklistArray.test.js +++ b/test/ckl-tests/CKLReviewParserChecklistArray.test.js @@ -123,4 +123,42 @@ describe('CKL Checklist array testing for correct benchmarkId and revisionStr', ) } }) + it('Validating that parser truncates checklist values to their max oas spec', async () => { + // values tested: checklist[i].benchmarkId + const importOptions = { + autoStatus: 'saved', + unreviewed: 'commented', + unreviewedCommented: 'informational', + emptyDetail: 'replace', + emptyComment: 'ignore', + allowCustom: true + } + + const fieldSettings = { + detail: { + enabled: 'always', + required: 'always' + }, + comment: { + enabled: 'findings', + required: 'findings' + } + } + + const allowAccept = true + + const filePath = + './WATCHER-test-files/WATCHER/ckl/Target-Object-Long-Properties' + + const review = await generateReviewObject( + filePath, + importOptions, + fieldSettings, + allowAccept + ) + + expect(review.checklists[0].benchmarkId).to.have.lengthOf(255) + + + }) }) diff --git a/test/ckl-tests/CKLReviewParserReviewObject.test.js b/test/ckl-tests/CKLReviewParserReviewObject.test.js index 9b0d4f4..ee202f1 100755 --- a/test/ckl-tests/CKLReviewParserReviewObject.test.js +++ b/test/ckl-tests/CKLReviewParserReviewObject.test.js @@ -1997,5 +1997,44 @@ describe('MISC CKL. ', () => { ) expect(review.checklists[0].reviews).to.be.empty + }) + it('Validating that parser truncates review values to their max oas spec', async () => { + // values tested: ruleId + const importOptions = { + autoStatus: 'saved', + unreviewed: 'commented', + unreviewedCommented: 'informational', + emptyDetail: 'replace', + emptyComment: 'ignore', + allowCustom: true + } + + const fieldSettings = { + detail: { + enabled: 'always', + required: 'always' + }, + comment: { + enabled: 'findings', + required: 'findings' + } + } + + const allowAccept = true + + const filePath = + './WATCHER-test-files/WATCHER/ckl/Target-Object-Long-Properties' + + const review = await generateReviewObject( + filePath, + importOptions, + fieldSettings, + allowAccept + ) + + expect(review.checklists[0].reviews[0].ruleId).to.have.lengthOf(45) + + + }) }) diff --git a/test/ckl-tests/CKLReviewParserTargetObject.test.js b/test/ckl-tests/CKLReviewParserTargetObject.test.js index 5f76c25..dbebc90 100644 --- a/test/ckl-tests/CKLReviewParserTargetObject.test.js +++ b/test/ckl-tests/CKLReviewParserTargetObject.test.js @@ -164,4 +164,43 @@ describe('Testing that the Target object returned by the ckl review parser is ac } expect(review.target).to.deep.equal(expectedTarget) }) + + it('Validating that parser truncates asset target values to their max oas spec', async () => { + // values tested: target.description, target.ip, target.fqdn, target.mac + const importOptions = { + autoStatus: 'saved', + unreviewed: 'commented', + unreviewedCommented: 'informational', + emptyDetail: 'replace', + emptyComment: 'ignore', + allowCustom: true + } + + const fieldSettings = { + detail: { + enabled: 'always', + required: 'always' + }, + comment: { + enabled: 'findings', + required: 'findings' + } + } + + const allowAccept = true + + const filePath = + './WATCHER-test-files/WATCHER/ckl/Target-Object-Long-Properties' + + const review = await generateReviewObject( + filePath, + importOptions, + fieldSettings, + allowAccept + ) + + expect(review.target.ip).to.have.lengthOf(255) + expect(review.target.fqdn).to.have.lengthOf(255) + expect(review.target.mac).to.have.lengthOf(255) + }) }) diff --git a/test/cklb-tests/CKLBResultEngine.test.js b/test/cklb-tests/CKLBResultEngine.test.js index 72b0e1a..72dcd0b 100644 --- a/test/cklb-tests/CKLBResultEngine.test.js +++ b/test/cklb-tests/CKLBResultEngine.test.js @@ -221,5 +221,42 @@ describe('Testing that the CKLb Review Parser will handle parsing on result engi expectedResultEngine ) + }) + it('Validating that parser truncates resultEngine values to their max oas spec', async () => { + + const importOptions = { + autoStatus: 'saved', + unreviewed: 'commented', + unreviewedCommented: 'informational', + emptyDetail: 'replace', + emptyComment: 'ignore', + allowCustom: true + } + + const fieldSettings = { + detail: { + enabled: 'always', + required: 'always' + }, + comment: { + enabled: 'findings', + required: 'findings' + } + } + + const allowAccept = true + + const filePath = + './WATCHER-test-files/WATCHER/cklb/Truncate-Tests.cklb' + + const review = await generateReviewObject( + filePath, + importOptions, + fieldSettings, + allowAccept + ) + + expect(review.checklists[0].reviews[0].resultEngine.version).to.have.lengthOf(255) + }) }) diff --git a/test/cklb-tests/CKLBReviewParserChecklistArray.test.js b/test/cklb-tests/CKLBReviewParserChecklistArray.test.js index c381ab9..52fe3b3 100644 --- a/test/cklb-tests/CKLBReviewParserChecklistArray.test.js +++ b/test/cklb-tests/CKLBReviewParserChecklistArray.test.js @@ -121,4 +121,43 @@ describe('CKLB Checklist tests', () => { ) } }) + + it('Validating that parser truncates checklist values to their max oas spec', async () => { + // values tested: checklist[i].benchmarkId + const importOptions = { + autoStatus: 'saved', + unreviewed: 'commented', + unreviewedCommented: 'informational', + emptyDetail: 'replace', + emptyComment: 'ignore', + allowCustom: true + } + + const fieldSettings = { + detail: { + enabled: 'always', + required: 'always' + }, + comment: { + enabled: 'findings', + required: 'findings' + } + } + + const allowAccept = true + + const filePath = + './WATCHER-test-files/WATCHER/cklb/Truncate-Tests.cklb' + + const review = await generateReviewObject( + filePath, + importOptions, + fieldSettings, + allowAccept + ) + + expect(review.checklists[0].benchmarkId).to.have.lengthOf(255) + + + }) }) diff --git a/test/cklb-tests/CKLBReviewParserReviewObject.test.js b/test/cklb-tests/CKLBReviewParserReviewObject.test.js index f121764..f1f3b17 100644 --- a/test/cklb-tests/CKLBReviewParserReviewObject.test.js +++ b/test/cklb-tests/CKLBReviewParserReviewObject.test.js @@ -1939,5 +1939,43 @@ describe('MISC CKLb. ', () => { expect(review.checklists[0].reviews[0].detail).to.have.lengthOf(maxLength) expect(review.checklists[0].reviews[0].comment).to.have.lengthOf(maxLength) }) + it('Validating that parser truncates review values to their max oas spec', async () => { + // values tested: ruleId + const importOptions = { + autoStatus: 'saved', + unreviewed: 'commented', + unreviewedCommented: 'informational', + emptyDetail: 'replace', + emptyComment: 'ignore', + allowCustom: true + } + + const fieldSettings = { + detail: { + enabled: 'always', + required: 'always' + }, + comment: { + enabled: 'findings', + required: 'findings' + } + } + + const allowAccept = true + + const filePath = + './WATCHER-test-files/WATCHER/cklb/Truncate-Tests.cklb' + + const review = await generateReviewObject( + filePath, + importOptions, + fieldSettings, + allowAccept + ) + + expect(review.checklists[0].reviews[0].ruleId).to.have.lengthOf(45) + + + }) }) diff --git a/test/cklb-tests/CKLBReviewParserTargetObject.test.js b/test/cklb-tests/CKLBReviewParserTargetObject.test.js index fb7179e..73012e7 100644 --- a/test/cklb-tests/CKLBReviewParserTargetObject.test.js +++ b/test/cklb-tests/CKLBReviewParserTargetObject.test.js @@ -161,4 +161,44 @@ describe('Testing that the Target object returned by the cklb review parser is a } expect(review.target).to.deep.equal(expectedTarget) }) + + it('Validating that parser truncates asset target values to their max oas spec', async () => { + // values tested: target.description, target.ip, target.fqdn, target.mac + const importOptions = { + autoStatus: 'saved', + unreviewed: 'commented', + unreviewedCommented: 'informational', + emptyDetail: 'replace', + emptyComment: 'ignore', + allowCustom: true + } + + const fieldSettings = { + detail: { + enabled: 'always', + required: 'always' + }, + comment: { + enabled: 'findings', + required: 'findings' + } + } + + const allowAccept = true + + const filePath = + './WATCHER-test-files/WATCHER/cklb/Truncate-Tests.cklb' + + const review = await generateReviewObject( + filePath, + importOptions, + fieldSettings, + allowAccept + ) + + expect(review.target.ip).to.have.lengthOf(255) + expect(review.target.fqdn).to.have.lengthOf(255) + expect(review.target.mac).to.have.lengthOf(255) + expect(review.target.description).to.have.lengthOf(255) + }) }) diff --git a/test/xccdf-tests/XCCDFReviewParserReviewObject.test.js b/test/xccdf-tests/XCCDFReviewParserReviewObject.test.js index c1906a2..4eeff9f 100644 --- a/test/xccdf-tests/XCCDFReviewParserReviewObject.test.js +++ b/test/xccdf-tests/XCCDFReviewParserReviewObject.test.js @@ -1856,4 +1856,45 @@ describe('MISC. xccdf ', () => { expectedOveride ) }) + it('Validating that parser truncates review values to their max oas spec', async () => { + // values tested: ruleId + const importOptions = { + autoStatus: 'saved', + unreviewed: 'commented', + unreviewedCommented: 'informational', + emptyDetail: 'replace', + emptyComment: 'ignore', + allowCustom: true + } + + const fieldSettings = { + detail: { + enabled: 'always', + required: 'always' + }, + comment: { + enabled: 'findings', + required: 'findings' + } + } + + const allowAccept = true + + const filePath = + './WATCHER-test-files/WATCHER/xccdf/Target-Object-Long-Properties-xccdf.xml' + + const review = await generateReviewObject( + filePath, + importOptions, + fieldSettings, + allowAccept + ) + + expect(review.checklists[0].reviews[0].ruleId).to.have.lengthOf(45) + expect(review.checklists[0].benchmarkId).to.have.lengthOf(255) + expect(review.checklists[0].reviews[0].resultEngine.overrides[0].authority).to.have.lengthOf(255) + expect(review.checklists[0].reviews[0].resultEngine.overrides[0].remark).to.have.lengthOf(255) + expect(review.checklists[0].reviews[0].resultEngine.checkContent.component).to.have.lengthOf(255) + + }) }) diff --git a/test/xccdf-tests/XCCDFReviewParserTargetObject.test.js b/test/xccdf-tests/XCCDFReviewParserTargetObject.test.js index af834a2..7ec904b 100644 --- a/test/xccdf-tests/XCCDFReviewParserTargetObject.test.js +++ b/test/xccdf-tests/XCCDFReviewParserTargetObject.test.js @@ -176,4 +176,45 @@ describe('Target Object Tests xccdf', () => { } expect(review.target).to.deep.equal(expectedTarget) }) + it('Validating that parser truncates asset target values to their max oas spec', async () => { + // values tested: target.description, target.ip, target.fqdn, target.mac + const importOptions = { + autoStatus: 'saved', + unreviewed: 'commented', + unreviewedCommented: 'informational', + emptyDetail: 'replace', + emptyComment: 'ignore', + allowCustom: true + } + + const fieldSettings = { + detail: { + enabled: 'always', + required: 'always' + }, + comment: { + enabled: 'findings', + required: 'findings' + } + } + + const allowAccept = true + + const filePath = + './WATCHER-test-files/WATCHER/xccdf/Target-Object-Long-Properties-xccdf.xml' + + const review = await generateReviewObject( + filePath, + importOptions, + fieldSettings, + allowAccept + ) + + expect(review.target.ip).to.have.lengthOf(255) + expect(review.target.fqdn).to.have.lengthOf(255) + expect(review.target.mac).to.have.lengthOf(255) + expect(review.target.description).to.have.lengthOf(255) + + + }) })