From 026611323e3a9aa2c338a72234f40852e8eda9ab Mon Sep 17 00:00:00 2001 From: jose clavo tafur Date: Thu, 6 Nov 2025 09:48:17 -0300 Subject: [PATCH 1/4] add comments about logic --- .../br/unb/cic/soot/svfa/jimple/JSVFA.scala | 61 +++++++++++++------ 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/modules/core/src/main/scala/br/unb/cic/soot/svfa/jimple/JSVFA.scala b/modules/core/src/main/scala/br/unb/cic/soot/svfa/jimple/JSVFA.scala index a9692466..0bf01409 100644 --- a/modules/core/src/main/scala/br/unb/cic/soot/svfa/jimple/JSVFA.scala +++ b/modules/core/src/main/scala/br/unb/cic/soot/svfa/jimple/JSVFA.scala @@ -317,7 +317,7 @@ abstract class JSVFA case (p: Local, q: ArrayRef) => // p = q[i] loadArrayRule(assignStmt.stmt, q, method, defs) case (p: Local, q: InvokeExpr) => - invokeRule(assignStmt, q, method, defs) // call a method + invokeRule(assignStmt, q, method, defs) // p = myObject.method() : call a method and assign its return value to a local variable case (p: Local, q: Local) => copyRule(assignStmt.stmt, q, method, defs) case (p: Local, _) => copyRuleInvolvingExpressions(assignStmt.stmt, method, defs) @@ -367,10 +367,18 @@ abstract class JSVFA }) } - /** Handles invocation rules for a call statement by traversing the call - * graph. This method avoids infinite recursion and limits the traversal - * depth for performance. - */ + /** + * Handles invocation rules for a call statement by traversing the call + * graph. This method avoids infinite recursion and limits the traversal + * depth for performance. + * + * i.e: + * + * myObject.method() + * myObject.method(q) + * this.method() + * this.method(q) + */ private def invokeRule( callStmt: Statement, exp: InvokeExpr, @@ -1039,14 +1047,28 @@ abstract class JSVFA case v => v } - /** CASE 1: UPDATE EDGE(S) "FROM" each stmt where the variable, passed as an - * argument, is defined. "TO" stmt where the method is called (call-site - * stmt). - * - * CASE 2: ??? - * - * CASE 2: ??? - */ + /** CASE #1: UPDATE EDGE(S) "FROM" each stmt where the variable, passed as an + * argument, is defined. "TO" stmt where the method is called (call-site + * stmt). i.e: [s1 -> s2] + * + * ------------------- + * s1: p = ... + * s2: myObj.method(p) + * ------------------- + * + * CASE #2: + * TO-DO + * + * CASE #3: UPDATE EDGE(S) "FROM" from definition of base object "TO" where it + * calls any of its methods. The expression must be type (invoke). + * i.e: [s1 -> s2] + * + * ------------------- + * s1: myObj = new Object() + * s2: myObj.method() + * ------------------- + * + */ private def defsToCallOfSinkMethod( stmt: Statement, exp: InvokeExpr, @@ -1054,7 +1076,7 @@ abstract class JSVFA defs: SimpleLocalDefs ) = { - // CASE 1 + // CASE #1 exp.getArgs .stream() .filter(a => a.isInstanceOf[Local]) @@ -1069,22 +1091,21 @@ abstract class JSVFA updateGraph( source, target - ) // update 'edge(s)' FROM "declaration stmt(s) for args" TO "call-site stmt" (current stmt) + ) }) - // CASE 2 + // CASE #2 if (local.getType.isInstanceOf[ArrayType]) { val stores = arrayStores.getOrElseUpdate(local, List()) stores.foreach(sourceStmt => { val source = createNode(caller, sourceStmt) val target = createNode(caller, targetStmt) - updateGraph(source, target) // add comment + updateGraph(source, target) }) } }) - // CASE 3 - // edges from definition to base object of an invoke expression + // CASE #3 if (isFieldSensitiveAnalysis() && exp.isInstanceOf[InstanceInvokeExpr]) { if (exp.asInstanceOf[InstanceInvokeExpr].getBase.isInstanceOf[Local]) { val local = @@ -1095,7 +1116,7 @@ abstract class JSVFA .forEach(sourceStmt => { val source = createNode(caller, sourceStmt) val target = createNode(caller, targetStmt) - updateGraph(source, target) // add comment + updateGraph(source, target) }) } } From 6e32245e2f4f6b88434e636d8a11a71eaeeeed1b Mon Sep 17 00:00:00 2001 From: jose clavo tafur Date: Thu, 6 Nov 2025 10:11:16 -0300 Subject: [PATCH 2/4] improvements from session tests --- .../deprecated/SecuribenchTestSuite.scala | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/modules/securibench/src/test/scala/br/unb/cic/securibench/deprecated/SecuribenchTestSuite.scala b/modules/securibench/src/test/scala/br/unb/cic/securibench/deprecated/SecuribenchTestSuite.scala index fad55639..eac9a554 100644 --- a/modules/securibench/src/test/scala/br/unb/cic/securibench/deprecated/SecuribenchTestSuite.scala +++ b/modules/securibench/src/test/scala/br/unb/cic/securibench/deprecated/SecuribenchTestSuite.scala @@ -1212,7 +1212,7 @@ class SecuribenchTestSuite extends FunSuite { /** SESSION TESTs */ - ignore( + test( "in the class Session1 we should detect 1 conflict of a simple session test case" ) { val testName = "Session1" @@ -1221,9 +1221,38 @@ class SecuribenchTestSuite extends FunSuite { val svfa = new SecuribenchTest(s"securibench.micro.session.$testName", "doGet") svfa.buildSparseValueFlowGraph() +// println(svfa.svgToDotModel()) assert(svfa.reportConflictsSVG().size == expectedConflicts) } + /** + * WHY IS IT FAILING? + * + * Here is a section of the jimple from file: "Session1.java" + * + * --------------------------------------------------------------------------------------------------------------------------------- + * s1: name = interfaceinvoke req.("name"); + * s2: session = interfaceinvoke req.(); + * s3: interfaceinvoke session.("name", name); + * s4: $stack7 = interfaceinvoke session.("name"); + * s5: s2 = (java.lang.String) $stack7; + * s6: writer = interfaceinvoke resp.(); + * s7: virtualinvoke writer.(s2); + * --------------------------------------------------------------------------------------------------------------------------------- + * + * Currently, statements (s1, s2, s3, s4, s6) of type "interfaceinvoke" are not processed totally by the program + * (not edges are created at least they are "source/sink" nodes). I found 2 cases to improve + * + * #1: If the expression is local as (s3/s4), it must be created an edge FROM its declaration TO the current stmt. + * #2: If the argument(s) passed in the expression call are locals as (s3), it must be created an edge FROM the argument(s) declaration + * TO the current stmt. + * + * Moreover, I found that these expression falls under rules conditions in (JSVFA.scala@invokeRule:449). + * We need to validate if this logic is right. + * + * PD: "Session2.java" and "Session3.java" have similar issues. + */ + ignore( "in the class Session2 we should detect 1 conflict of a simple session test case" ) { From e9b0e403bbf50191cf2c82d1507e462147dde381 Mon Sep 17 00:00:00 2001 From: jose clavo tafur Date: Tue, 2 Dec 2025 19:09:55 -0500 Subject: [PATCH 3/4] remove comment --- .../deprecated/SecuribenchTestSuite.scala | 30 +------------------ 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/modules/securibench/src/test/scala/br/unb/cic/securibench/deprecated/SecuribenchTestSuite.scala b/modules/securibench/src/test/scala/br/unb/cic/securibench/deprecated/SecuribenchTestSuite.scala index 996ac457..ac4a9865 100644 --- a/modules/securibench/src/test/scala/br/unb/cic/securibench/deprecated/SecuribenchTestSuite.scala +++ b/modules/securibench/src/test/scala/br/unb/cic/securibench/deprecated/SecuribenchTestSuite.scala @@ -1191,38 +1191,10 @@ class SecuribenchTestSuite extends FunSuite { val svfa = new SecuribenchTest(s"securibench.micro.session.$testName", "doGet") svfa.buildSparseValueFlowGraph() -// println(svfa.svgToDotModel()) + // println(svfa.svgToDotModel()) assert(svfa.reportConflictsSVG().size == expectedConflicts) } - /** - * WHY IS IT FAILING? - * - * Here is a section of the jimple from file: "Session1.java" - * - * --------------------------------------------------------------------------------------------------------------------------------- - * s1: name = interfaceinvoke req.("name"); - * s2: session = interfaceinvoke req.(); - * s3: interfaceinvoke session.("name", name); - * s4: $stack7 = interfaceinvoke session.("name"); - * s5: s2 = (java.lang.String) $stack7; - * s6: writer = interfaceinvoke resp.(); - * s7: virtualinvoke writer.(s2); - * --------------------------------------------------------------------------------------------------------------------------------- - * - * Currently, statements (s1, s2, s3, s4, s6) of type "interfaceinvoke" are not processed totally by the program - * (not edges are created at least they are "source/sink" nodes). I found 2 cases to improve - * - * #1: If the expression is local as (s3/s4), it must be created an edge FROM its declaration TO the current stmt. - * #2: If the argument(s) passed in the expression call are locals as (s3), it must be created an edge FROM the argument(s) declaration - * TO the current stmt. - * - * Moreover, I found that these expression falls under rules conditions in (JSVFA.scala@invokeRule:449). - * We need to validate if this logic is right. - * - * PD: "Session2.java" and "Session3.java" have similar issues. - */ - ignore( "in the class Session2 we should detect 1 conflict of a simple session test case" ) { From e048933eec1f99d233b3e353841f1102e187fe99 Mon Sep 17 00:00:00 2001 From: jose clavo tafur Date: Wed, 3 Dec 2025 17:49:47 -0500 Subject: [PATCH 4/4] create skeleton for trait CopyFromSessionTag --- .../br/unb/cic/soot/svfa/jimple/JSVFA.scala | 18 ++++++++++++++++++ .../br/unb/cic/soot/svfa/jimple/dsl/DSL.scala | 3 ++- .../soot/svfa/jimple/dsl/LanguageParser.scala | 7 ++++++- .../cic/soot/svfa/jimple/dsl/RuleFactory.scala | 3 +++ 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/modules/core/src/main/scala/br/unb/cic/soot/svfa/jimple/JSVFA.scala b/modules/core/src/main/scala/br/unb/cic/soot/svfa/jimple/JSVFA.scala index f146028c..a8cbff7d 100644 --- a/modules/core/src/main/scala/br/unb/cic/soot/svfa/jimple/JSVFA.scala +++ b/modules/core/src/main/scala/br/unb/cic/soot/svfa/jimple/JSVFA.scala @@ -240,6 +240,24 @@ abstract class JSVFA } } + trait CopyFromSessionTag extends RuleAction { + + def apply( + sootMethod: SootMethod, + invokeStmt: jimple.Stmt, + localDefs: SimpleLocalDefs + ) = { + /** + * TO-DO + * Implement logic here + */ + } + } + + /** + * Core Code + */ + def createSceneTransform(): (String, Transform) = ("wjtp", new Transform("wjtp.svfa", new Transformer())) diff --git a/modules/core/src/main/scala/br/unb/cic/soot/svfa/jimple/dsl/DSL.scala b/modules/core/src/main/scala/br/unb/cic/soot/svfa/jimple/dsl/DSL.scala index 872da94d..a0cd1b3a 100644 --- a/modules/core/src/main/scala/br/unb/cic/soot/svfa/jimple/dsl/DSL.scala +++ b/modules/core/src/main/scala/br/unb/cic/soot/svfa/jimple/dsl/DSL.scala @@ -84,7 +84,8 @@ trait DSL { rule sessionMethods = if NamedMethodRule(className: "javax.servlet.http.HttpSession", methodName: "getAttribute") then [ - CopyFromMethodCallToLocal() + CopyFromMethodCallToLocal(), + CopyFromSessionTag() ] rule skipNativeMethods = if NativeRule() then DoNothing() diff --git a/modules/core/src/main/scala/br/unb/cic/soot/svfa/jimple/dsl/LanguageParser.scala b/modules/core/src/main/scala/br/unb/cic/soot/svfa/jimple/dsl/LanguageParser.scala index df6f1f31..e092e74c 100644 --- a/modules/core/src/main/scala/br/unb/cic/soot/svfa/jimple/dsl/LanguageParser.scala +++ b/modules/core/src/main/scala/br/unb/cic/soot/svfa/jimple/dsl/LanguageParser.scala @@ -156,10 +156,15 @@ class LanguageParser(val jsvfa: JSVFA) extends RegexParsers { _.toString } + def COPY_FROM_SESSION_TAG: Parser[String] = + """CopyFromSessionTag""".r ^^ { + _.toString + } + def ACTIONS: Parser[String] = DO_NOTHING | COPY_BETWEEN_ARGS | COPY_FROM_METHOD_ARGUMENT_TO_BASE_OBJECT | COPY_FROM_METHOD_CALL_TO_LOCAL | - COPY_FROM_METHOD_ARGUMENT_TO_LOCAL ^^ { + COPY_FROM_METHOD_ARGUMENT_TO_LOCAL | COPY_FROM_SESSION_TAG ^^ { _.toString } diff --git a/modules/core/src/main/scala/br/unb/cic/soot/svfa/jimple/dsl/RuleFactory.scala b/modules/core/src/main/scala/br/unb/cic/soot/svfa/jimple/dsl/RuleFactory.scala index ccf5e5fa..46966726 100644 --- a/modules/core/src/main/scala/br/unb/cic/soot/svfa/jimple/dsl/RuleFactory.scala +++ b/modules/core/src/main/scala/br/unb/cic/soot/svfa/jimple/dsl/RuleFactory.scala @@ -38,6 +38,9 @@ class RuleFactory(val jsvfa: JSVFA) { case "CopyFromMethodCallToLocal" => ruleActions = ruleActions ++ List(new jsvfa.CopyFromMethodCallToLocal {}) + case "CopyFromSessionTag" => + ruleActions = + ruleActions ++ List(new jsvfa.CopyFromSessionTag {}) case _ => ruleActions = ruleActions ++ List(new DoNothing {}) }