@@ -6,21 +6,14 @@ import org.evomaster.core.languagemodel.LanguageModelConnector
66import org.evomaster.core.problem.api.param.Param
77import org.evomaster.core.problem.rest.data.RestCallAction
88import org.evomaster.core.problem.rest.data.RestIndividual
9- import org.evomaster.core.problem.rest.service.SecurityRest
109import org.evomaster.core.problem.security.data.ParamMapping
1110import org.evomaster.core.problem.security.verifiers.SSRFVulnerabilityVerifier
1211import org.evomaster.core.search.EvaluatedIndividual
1312import org.evomaster.core.search.Solution
1413import org.evomaster.core.search.service.Archive
15- import org.slf4j.Logger
16- import org.slf4j.LoggerFactory
1714
1815class VulnerabilityAnalyser {
1916
20- companion object {
21- private val log: Logger = LoggerFactory .getLogger(SecurityRest ::class .java)
22- }
23-
2417 @Inject
2518 private lateinit var config: EMConfig
2619
@@ -34,9 +27,12 @@ class VulnerabilityAnalyser {
3427 private lateinit var languageModelConnector: LanguageModelConnector
3528
3629
30+ /* *
31+ * TODO: This can be generalized later to accommodate more vulnerability types
32+ */
3733 private lateinit var ssrfVerifier: SSRFVulnerabilityVerifier
3834
39- private var paramMapping : MutableMap <String , ParamMapping > = mutableMapOf ()
35+ private var actionVulnerabilityMapping : MutableMap <String , MutableMap < String , ParamMapping > > = mutableMapOf ()
4036
4137 /* *
4238 * Individuals in the solution.
@@ -114,27 +110,29 @@ class VulnerabilityAnalyser {
114110 individualsInSolution.forEach { evaluatedIndividual ->
115111 val ea = evaluatedIndividual.evaluatedMainActions()[0 ].action
116112 if (ea is RestCallAction ) {
117- val descriptions = extractBodyParameterDescriptions(ea.getName(), ea.parameters)
118- paramMapping = descriptions
113+ val descriptions : MutableMap <String , ParamMapping > = extractBodyParameterDescriptions(ea.getName(), ea.parameters)
119114
120- descriptions.forEach { name , description ->
121- if (! description.description.isNullOrBlank()) {
122- val id = languageModelConnector.queryAsync (
123- getPromptWithNameAndDescription(
115+ descriptions.forEach { paramName , description ->
116+ val answer = if (! description.description.isNullOrBlank()) {
117+ languageModelConnector.query (
118+ ssrfVerifier. getPromptWithNameAndDescription(
124119 description.name,
125120 description.description
126121 )
127122 )
128- paramMapping[name]?.promptId = id
129123 } else {
130- val id = languageModelConnector.queryAsync (
131- getPromptWithNameOnly(
124+ languageModelConnector.query (
125+ ssrfVerifier. getPromptWithNameOnly(
132126 description.name
133127 )
134128 )
135- paramMapping[name]?.promptId = id
136129 }
130+
131+ if (answer == SSRFVulnerabilityVerifier .SSRF_PROMPT_ANSWER_FOR_POSSIBILITY )
132+ description.addVulnerabilityClass(VulnerabilityClass .SSRF )
137133 }
134+
135+ actionVulnerabilityMapping[ea.getName()] = descriptions
138136 }
139137 }
140138 }
@@ -175,7 +173,10 @@ class VulnerabilityAnalyser {
175173 // TODO: Run the tests again with generated value
176174 individualsInSolution.forEach { evaluatedIndividual ->
177175 val ea = evaluatedIndividual.evaluatedMainActions()[0 ].action as RestCallAction
178- val link = ssrfVerifier.generateLink(ea.getName())
176+ // Execute only the action which marked as a possible candidate
177+ if (actionVulnerabilityMapping.containsKey(ea.getName())) {
178+ val link = ssrfVerifier.generateLink(ea.getName())
179+ }
179180 }
180181 }
181182 }
@@ -190,35 +191,12 @@ class VulnerabilityAnalyser {
190191 val ea = eI.evaluatedMainActions()[0 ].action as RestCallAction
191192 val result = ssrfVerifier.verify(ea.getName())
192193
193- if (result == true ) {
194+ if (result) {
194195 // TODO: Mark as vulnerable
195196 }
196197 }
197198 }
198199 }
199200
200- /* *
201- * This prompt is for SSRF.
202- * TODO: In the future, this can be extended to for other classes by using a
203- * custom large language model.
204- */
205- private fun getPromptWithNameAndDescription (name : String , description : String ): String {
206- return """
207- Consider the word \"${name} \" and the description as \"${description} \", used as a name identifier
208- for a parameter inside a OpenAPI/Swagger schema. Would it likely represent a URL value ? give me
209- answer as boolean with TRUE or FALSE"""
210- }
211-
212- /* *
213- * This prompt is for SSRF.
214- * TODO: In the future, this can be extended to for other classes by using a
215- * custom large language model.
216- */
217- private fun getPromptWithNameOnly (name : String ): String {
218- return """
219- Consider the word \"${name} \", used as a name identifier
220- for a parameter inside a OpenAPI/Swagger schema. Would it likely represent a URL value ? give me
221- answer as boolean with TRUE or FALSE"""
222- }
223201
224202}
0 commit comments