Open vanderpol opened 3 weeks ago
@solind, This one is a bit more 'out there', but SCC uses it to process the DISA STIGS's for SQL, and we likely will be using this for some OS checks as well, where the DISA STIG says "make sure that the system setting
If you want to see it in action, just grab a copy of SCC and view the manual questions for the SQL Instance or SQL Database STIG, this proposal just formalizes our overloaded method of using the check-content field as a delimited list of data.
@vanderpol This is an interesting (by which I mean terrifying) idea!
What would you say to modifying the XCCDF set-value
element so that it could reference any check-content? It would need some kind of a check-import child identifying what it's supposed to retrieve, maybe via XPATH. I'm fuzzy on the details, but I recall implementing check-import, so @maxullman or @A-Biggs could weigh in with those.
@solind, given that we've been using the equivalent of the proposed schema change for the past year in production level content, I'd personally prefer not having to redesign our implementation, unless there is a 'better' alternate proposal. If you can mock up in more detail what you saying above, my opinion my change.
Hi @vanderpol , your proposal said:
The specific format in XCCDF is open for discussion/debate, but below is a potential solution.
... and then you explicitly asked me for my opinion. I'm purely a volunteer offering you feedback, I'm not looking to create more work for anyone, least of all myself.
Looking closely at your schema mods and example, I think you meant to write it as follows:
<xccdf:check system="http://oval.mitre.org/XMLSchema/oval-definitions-5" selector="">
<xccdf:check-content-ref name="oval:navy.navwar.niwcatlantic.scc.ms.sql.server.2016.inst:def:21" href="U_MS_SQL_Server_2016_Instance_V3R1_STIG_SCAP_1-3_Benchmark-enhancedV3-oval.xml"/>
<xccdf:check-content-ref name="ocil:navy.navwar.niwcatlantic.scc.ms.sql.server.2016.inst.hybrid:questionnaire:21" href="U_MS_SQL_Server_2016_Instance_V3R1_STIG_SCAP_1-3_Benchmark-enhancedV3-ocil.xml"/>
<xccdf:check-content-hybrid variable-name="oval:navy.navwar.niwcatlantic.scc.ms.sql.server.2016.inst:var:21" target="dbmsinstance" datatype="array" element-name="user_name" />
</xccdf:check>
The big change to your original example was to express your check-content-hybrid tag's content as entity attributes, not string content.
But, I must admit, I'm confused about what the above example means. I am guessing that it's supposed to somehow tie together a variable sourced from executed OCIL to a variable value used by the OVAL check. But I don't see how it does that. What's the name of the variable being exported to the OVAL? What's the name of the answer value being imported from the OCIL questionnaire? How does the interpreter know which check is which?
The behavior for multiple check-content-refs is already defined in XCCDF as specifying multiple locations for the same check, in order of preference, only one of which must be evaluated. But this defined behavior doesn't exactly seem to apply here.
My suggestion was merely that you might want to consider modifying an already-defined mechanism for passing values into checks.
@solind Sorry, I wasn't meaning to ask for your input and then reject it... I was primarily looking to see if our implementation made any sense from a SCAP perspective. When I designed this functionality in SCC a couple years ago, I'll admit that I wasn't thinking this would end up being officially part of SCAP (primarily because SCAP seemed like it was in a coma, and I wasn't sure if any feature release would occur), but after seeing your confusion with the data I provided, I realized there is some magic going on behind the scenes to make it all work. I'll write up exactly what SCC is doing, and we'll see if this can somehow be converted into something ready for XCCDF/SCAP. If we deem that it's really just best for a proprietary implementation, that's fine too. Given that all we have going on with updating OVAL 5.12 and OVAL 6.0, and the very limited timeframe to get XCCDF/SCAP updated, this may not be in scope. I am open to your set-value concepts, I'm just not sure I'm going to be the one designing it right now. If doing so provides what we need, without some of our behind the scenes magic, then I'm all for it.
Below is a behind the scenes explanation of how the proposed update to XCCDF is used in our implementation. If this update is accepted as part of XCCDF 1.3/SCAP 3.0, the XCCDF documentation may need to have something similar to below in order to adequately explain how it should be implemented.
If both OVAL and OCIL check-content refs exist for the same check, and the overall check system is "OVAL", this is a "hybrid" test, process the OCIL content first: Example:
<xccdf:check system="http://oval.mitre.org/XMLSchema/oval-definitions-5" selector="">
<xccdf:check-content-ref name="oval:navy.navwar.niwcatlantic.scc.ms.sql.server.2016.inst:def:21" href="U_MS_SQL_Server_2016_Instance_V3R1_STIG_SCAP_1-3_Benchmark-enhancedV3-oval.xml"/>
<xccdf:check-content-ref name="ocil:navy.navwar.niwcatlantic.scc.ms.sql.server.2016.inst.hybrid:questionnaire:21" href="U_MS_SQL_Server_2016_Instance_V3R1_STIG_SCAP_1-3_Benchmark-enhancedV3-ocil.xml"/>
<xccdf:check-content-hybrid variable-name="oval:navy.navwar.niwcatlantic.scc.ms.sql.server.2016.inst:var:21" target="dbmsinstance" datatype="array" element-name="user_name" />
</xccdf:check>
The results from this OCIL test will not directly be returned back to XCCDF, and to prevent any confusion, we setup the test to always return UNKNOWN, we didn't want anyone seeing pass/fail results in OCIL XML when compared to the OVAL and XCCDF results.
<string_question_test_action question_ref="ocil:navy.navwar.niwcatlantic.scc.ms.sql.server.2016.inst.hybrid:question:21"
id="ocil:navy.navwar.niwcatlantic.scc.ms.sql.server.2016.inst.hybrid:testaction:21">
<title>CAT I, V-213930, SV-213930r960768, SRG-APP-000023-DB-000001</title>
<when_pattern>
<result>UNKNOWN</result>
<pattern>^.*$</pattern>
</when_pattern>
</string_question_test_action>
The "target", "datatype" and "element-name" are used determine what type of interface to provide to the end user in order to best gather the data. For example, if you only want a single item returned, you don't want to give the user the ability to enter an array of data etc... See attached screen shot for an example.
![hybrid_interface](https://github.com/user-attachments/assets/e8cb7d6f-b2a9-4dd2-a8b5-7048975fda66)
3. The application should analyze the results of the OCIL string_question, and store the data as an array of strings (or a single string), and associate this data with the variable defined in check-content-hybrid variable-name
4. Before the OVAL scanning starts, the application should programmatically populate the OVAL external variable using the data from step 3.
5. The external variable is then used as a state element as the 'requirement'
<independent-def:sql512_state xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#independent" version="1" comment="If the accounts authorized to manage this SQL Server intance are documented and approved, this is not a finding. " id="oval:navy.navwar.niwcatlantic.scc.ms.sql.server.2016.inst:ste:22">
OK, I think we can eliminate all the "magic" by coming up with a way to implement this functionality largely using existing constructs. The existing mechanism for setting variable values is through the Profile set-value tag. There is also an existing mechanism to import values from check systems (although they currently only end up showing up in XCCDF TestResults).
Imagine that we come up with a new tag called xccdf:set-value-from-check
. It could have an xccdf:check
child element, which could support any SCAP check system (OCIL, or OVAL). The check element would be required to contain the following:
check-import
element, with an import-xpath
attribute defining how to fetch the value derived from the corresponding check system's result output or an import-name
specifying a something readily retrievable from results like the ID of a question or variable.check-content-ref
element, which identifies the OCIL href and questionnaire ID, or OVAL href and definition ID to run.Putting this together would signal the interpreter that it needs to run the specified piece of content to retrieve the value of the Value, when the corresponding Profile is selected.
I think it would be a lot simpler to document this method of implementing your requirement.
@solind thanks for your thoughts on this, sorry for my delayed response, I've been out of the office. Would you be willing to mock up some tiny XCCDF 1.3 content that demonstrates this? Would this hypothetical implementation be able to support setting a list/array of values vs a single value? I'm not an XCCDF expert, but it was my understanding that the current set Value only supported a single value.
Well, you can always use the SplitFunctionType to break apart a single string value into multiple variable values. There's also the possibility of using the "complex" values in XCCDF 1.3.
I'll try and put together an XML snippet later today to illustrate what I'm proposing.
@solind just a reminder to drop an XML snippet out here when you get a chance. Our next SCAP 3.0 meeting is tomorrow, and would like to give Dragos an update as to if we think this feature is going to be feasible for SCAP 3.0 or not.
OK, so here's a snippet illustrating how you could use a Profile to set an XCCDF Value from the value of a variable found in an OVAL check.
<xccdf:Profile id="xccdf_net.solin_profile_david_writes_a_snippet">
<xccdc:set-value-from-check idref="xccdf_net.solin_value_check_derived">
<xccdf:check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
<xccdf:check-import import-name="oval:net.solin:var:123">
<xccdf:check-content-ref href="ovaldefs.xml" name="oval:net.solin:def:123"/>
</xccdf:check>
</xccdc:set-value-from-check>
</xccdf:Profile>
@solind thanks, and it's likely me being a bit dense, but could you expand this to show how you'd set that XCCDF value based on the result of an OCIL check, and then use that as a variable in OVAL?
@vanderpol sure, in that case we just insert an OCIL check. In this example it would import the value of a variable.
<xccdf:Profile id="xccdf_net.solin_profile_david_writes_a_snippet">
<xccdc:set-value-from-check idref="xccdf_net.solin_value_check_derived">
<xccdf:check system="http://scap.nist.gov/schema/ocil/2">
<xccdf:check-import import-name="ocil:net.solin:variable:123">
<xccdf:check-content-ref href="questionnaire.xml" name="ocil:some.checklist:questionnaire:1"/>
</xccdf:check>
</xccdc:set-value-from-check>
</xccdf:Profile>
The import-name
attribute of check-import
in XCCDF is not well-specified. I made a best-guess of what I thought would make sense for OVAL and OCIL and SCE so that the import-name
could specify something meaningful in the results documents. BUT, I also implemented the optional import-xpath
attribute, which runs an XPATH query against the XML results document -- this makes it possible to unambiguously specify what you want to retrieve.
Thanks again @solind I'll have to dive into the OCIL spec to see about how I would update the content to have the results end up as variables. Seems doable, just need to put on my OCIL hat, which I have not warn in years.
@vanderpol it wouldn't necessarily have to be a variable value. It could be a question answer or artifact or something else, too. The interpreter just has to "know" how to retrieve the value given the check system and associated conventions for the "value-name".
@solind, I haven't had much free time to try to prototype this, but I have a couple questions/concerns that maybe you can help me understand this better.
I realize my questions 2 and 3 are not 'critical' 'to making this work, but they are pretty key to making it user friendly.
Hi @vanderpol, answers below:
<local_variable id="var:2">
<split delimiter=",">
<variable_component var_ref="var:1"/>
</split>
</local_variable>
Now, var:2 is your multi-valued variable (i.e., array).
Alternatively, you could add an attribute to xccd:check-import that would permit some custom import naming convention, but then you have to define exactly how it works.
@solind for 1 above, what I'm asking is how do you tell the OCIL interpreter which delimiter to create when exporting the variable back to XCCDF before we import it into OVAL. I could see where different tools may use different delimiters and being able to specify what to use would be key. Maybe I'm missing something here. The Value is based on what the end user enters, and maybe we you just explain it to the end user to put the data using comma separated delimiters etc... but in our implementation we allowed for CSV, new line etc... and then we cleaned up the data and then output our cleaned variable. In our limited examples commas were always fine, but the data may need some other delimiter.
For 2 above, this is really just me trying to make our application to be smarter in how to display what to ask for. We update the GUI based on if we are expecting 1 result or N results, and we update the GUI to say what we want. Not a showstopper, just a nice to have.
If SCC is really going to be the only tool using Hybrid variables and actually implementing all of this it may make more sense for us to just leave it proprietary.
@vanderpol Alas, I haven't touched OCIL in a very long time! But, my thinking was that we're dealing with the result format of the specified check system and nothing else, so in this case, OCIL results. If you intend to parse raw user input, the user would have to write an answer that's compatible with whatever parsing you've implemented on the importing side. The job of XCCDF here is just to transport a value obtained from a result to an imported variable value.
We could add an attribute to the RegexCaptureFunctionType that would make it possible to produce multiple values (currently it captures the first instance and nothing more). That would make it possible to implement more robust parsing of imported variable values.
Of course, you can always keep the custom implementation. I'm just trying to suggest a mechanism that is more straightforward (in my opinion, anyway) to standardize.
I'll reach out to DISA to see if they have any interest/plans to do any OCIL/OVAL hybrid tests. If they seem at all interested, we'll continue this R&D. I do appreciate your input, and in past conversations with DISA I think their thoughts on this were closer to inline with your thoughts, so we may end up going there. If it's just NIWC doing their own thing, I'm not sure we want to redesign what we are doing, and end up with a less user friendly experience.
Some policies are written which to not clearly define the exact requirement to be verified, but state things such as "verify that the database owner matches system documentation". Without the ability to pass the end user provided data from OCIL to OVAL, this can only be a manual test, but if we pass data to OVAL, then this can be automated, based on end user feedback.
This has been implemented in the SCAP Compliance Checker (SCC) application for the last few years, primarily in support of DISA's SQL STIG content. Examples can be found at https://www.niwcatlantic.navy.mil/Technology/SCAP/SCAP-Content-Repository/. The current SCC implementation overloads the existing check-content element with several pieces of delimited data, which is all schema valid, but only will work in SCC. Our goal here is to provide the capability to any SCAP content/SCAP application that supports both OVAL and OCIL. We have dubbed this check type as "hybrid" as it's a combination of manual and automated tests.
The specific format in XCCDF is open for discussion/debate, but below is a potential solution. Essentially taking our check-content overloaded method and clearly specifying the attributes.
Example:
Add a new element name called "check-content-hybrid" of datatype checkContentHybridType
Where checkContentHybridType is (refer to #1) for details on new targetType
Example usage: