Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c6fdcf4

Browse files
authored
Merge pull request #1021 from calumgrant/cs/nhibernate
C#: Model NHibernate framework
2 parents 548a28f + 3fd10ec commit c6fdcf4

13 files changed

Lines changed: 243 additions & 2 deletions

File tree

change-notes/1.20/analysis-csharp.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,9 @@
3434
- Stored data flow sources
3535
- Sinks for SQL expressions
3636
- Data flow through fields that are mapped to the database.
37+
* Support has been added for NHibernate-Core, including
38+
- Stored data flow sources
39+
- Sinks for SQL expressions
40+
- Data flow through fields that are mapped to the database.
3741

3842
## Changes to the autobuilder

csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module DataFlow {
1010
private import semmle.code.csharp.dataflow.DelegateDataFlow
1111
private import semmle.code.csharp.dataflow.LibraryTypeDataFlow
1212
private import semmle.code.csharp.frameworks.EntityFramework
13+
private import semmle.code.csharp.frameworks.NHibernate
1314
private import Internal::Cached
1415
private import dotnet
1516
private import cil
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import csharp
2+
private import semmle.code.csharp.frameworks.System
3+
private import semmle.code.csharp.frameworks.system.Collections
4+
private import semmle.code.csharp.frameworks.Sql
5+
6+
module NHibernate {
7+
/** A class that is mapped to the database. */
8+
abstract class MappedClass extends Class { }
9+
10+
/** The interface `NHibernamte.ISession`. */
11+
class ISessionInterface extends Interface {
12+
ISessionInterface() { this.hasQualifiedName("NHibernate.ISession") }
13+
14+
/** Gets a parameter that uses a mapped object. */
15+
Parameter getAMappedObjectParameter() {
16+
exists(Callable c |
17+
result.getType() instanceof ObjectType and
18+
c = this.getAMethod() and
19+
result = c.getAParameter() and
20+
result.getName() = "obj"
21+
)
22+
}
23+
24+
/** Gets a type parameter that specifies a mapped class. */
25+
TypeParameter getAMappedObjectTp() {
26+
exists(string methodName |
27+
methodName = "Load"
28+
or
29+
methodName = "Merge"
30+
or
31+
methodName = "Get"
32+
or
33+
methodName = "Query"
34+
|
35+
result = this.getAMethod(methodName).(UnboundGenericMethod).getTypeParameter(0)
36+
)
37+
}
38+
}
39+
40+
/** A mapped class that is mapped because it is used as a type argument. */
41+
private class MappedByTypeArgument extends MappedClass {
42+
MappedByTypeArgument() {
43+
this = any(ISessionInterface si).getAMappedObjectTp().getASuppliedType()
44+
}
45+
}
46+
47+
/** A mapped class that is mapped because it is passed as a parameter. */
48+
private class MappedByParam extends MappedClass {
49+
MappedByParam() {
50+
exists(ISessionInterface si, Expr e, MethodCall c, Parameter p |
51+
p = si.getAMappedObjectParameter() and
52+
e = c.getArgumentForParameter(p) and
53+
this = e.getType()
54+
) and
55+
not this instanceof ObjectType and
56+
not this.getABaseInterface*() instanceof SystemCollectionsIEnumerableInterface and
57+
not this instanceof SystemTypeClass
58+
}
59+
}
60+
61+
/** A property that is persisted in the database. */
62+
class MappedProperty extends Property {
63+
MappedProperty() {
64+
this.getDeclaringType() instanceof MappedClass and
65+
this.isPublic()
66+
}
67+
}
68+
69+
/** A parameter that is interpreted as SQL. */
70+
class SqlParameter extends Parameter {
71+
SqlParameter() {
72+
this.getType() instanceof StringType and
73+
(this.getName() = "sql" or this.getName() = "sqlString" or this.getName() = "query") and
74+
this
75+
.getCallable()
76+
.getDeclaringType()
77+
.getDeclaringNamespace()
78+
.getParent*()
79+
.hasQualifiedName("", "NHibernate")
80+
}
81+
}
82+
83+
/** A call to a method in NHibernate that executes SQL. */
84+
class NHibernateSqlSink extends SqlExpr, Call {
85+
SqlParameter sqlParam;
86+
87+
NHibernateSqlSink() { this.getTarget().getAParameter() = sqlParam }
88+
89+
override Expr getSql() { result = this.getArgumentForParameter(sqlParam) }
90+
}
91+
92+
/** A taint source where the data has come from a mapped property stored in the database. */
93+
class StoredFlowSource extends DataFlow::Node {
94+
StoredFlowSource() {
95+
this.asExpr() = any(PropertyRead read | read.getTarget() instanceof MappedProperty)
96+
}
97+
}
98+
99+
/**
100+
* A dataflow node whereby data flows from a property write to a property read
101+
* via some database. The assumption is that all writes can flow to all reads.
102+
*/
103+
class MappedPropertyJumpNode extends DataFlow::NonLocalJumpNode {
104+
MappedProperty property;
105+
106+
MappedPropertyJumpNode() { this.asExpr() = property.getAnAssignedValue() }
107+
108+
override DataFlow::Node getAJumpSuccessor(boolean preservesValue) {
109+
result.asExpr().(PropertyRead).getTarget() = property and
110+
preservesValue = false
111+
}
112+
}
113+
}

csharp/ql/src/semmle/code/csharp/frameworks/Sql.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import csharp
44
private import semmle.code.csharp.frameworks.system.Data
55
private import semmle.code.csharp.frameworks.system.data.SqlClient
66
private import semmle.code.csharp.frameworks.EntityFramework
7+
private import semmle.code.csharp.frameworks.NHibernate
78

89
/** An expression containing a SQL command. */
910
abstract class SqlExpr extends Expr {

csharp/ql/src/semmle/code/csharp/security/dataflow/flowsources/Stored.qll

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import csharp
66
private import semmle.code.csharp.frameworks.system.data.Common
77
private import semmle.code.csharp.frameworks.system.data.Entity
88
private import semmle.code.csharp.frameworks.EntityFramework
9+
private import semmle.code.csharp.frameworks.NHibernate
910
private import semmle.code.csharp.frameworks.Sql
1011

1112
/** A data flow source of stored user input. */
@@ -48,6 +49,9 @@ class DbDataReaderPropertyStoredFlowSource extends StoredFlowSource {
4849
}
4950

5051
/** A read of a mapped property. */
51-
class EntityFrameworkMappedProperty extends StoredFlowSource {
52-
EntityFrameworkMappedProperty() { this instanceof EntityFramework::StoredFlowSource }
52+
class ORMMappedProperty extends StoredFlowSource {
53+
ORMMappedProperty() {
54+
this instanceof EntityFramework::StoredFlowSource or
55+
this instanceof NHibernate::StoredFlowSource
56+
}
5357
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| nhibernate.cs:50:14:50:19 | access to property Name | Data flow from $@. | nhibernate.cs:45:24:45:32 | "tainted" | "tainted" |
2+
| nhibernate.cs:55:14:55:23 | access to property Address | Data flow from $@. | nhibernate.cs:45:24:45:32 | "tainted" | "tainted" |
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import csharp
2+
import semmle.code.csharp.dataflow.TaintTracking
3+
4+
class MyConfiguration extends TaintTracking::Configuration {
5+
MyConfiguration() { this = "MyConfiguration" }
6+
7+
override predicate isSource(DataFlow::Node node) {
8+
node.asExpr().(StringLiteral).getValue() = "tainted"
9+
}
10+
11+
override predicate isSink(DataFlow::Node node) {
12+
exists(MethodCall mc | mc.getTarget().hasName("Sink") and node.asExpr() = mc.getArgument(0))
13+
}
14+
}
15+
16+
from MyConfiguration config, DataFlow::Node source, DataFlow::Node sink
17+
where config.hasFlow(source, sink)
18+
select sink, "Data flow from $@.", source, source.toString()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| nhibernate.cs:16:9:16:26 | object creation of type SqlString |
2+
| nhibernate.cs:17:9:17:27 | call to method Delete |
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import csharp
2+
import semmle.code.csharp.frameworks.Sql
3+
4+
from SqlExpr e
5+
select e
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
| nhibernate.cs:49:14:49:17 | access to property Id |
2+
| nhibernate.cs:50:14:50:19 | access to property Name |
3+
| nhibernate.cs:51:14:51:22 | access to property Address |
4+
| nhibernate.cs:53:14:53:18 | access to property Id |
5+
| nhibernate.cs:54:14:54:19 | access to property Age |
6+
| nhibernate.cs:55:14:55:23 | access to property Address |

0 commit comments

Comments
 (0)