-
Notifications
You must be signed in to change notification settings - Fork 1.8k
C#: Model NHibernate framework #1021
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
113 changes: 113 additions & 0 deletions
113
csharp/ql/src/semmle/code/csharp/frameworks/NHibernate.qll
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
import csharp | ||
private import semmle.code.csharp.frameworks.System | ||
private import semmle.code.csharp.frameworks.system.Collections | ||
private import semmle.code.csharp.frameworks.Sql | ||
|
||
module NHibernate { | ||
/** A class that is mapped to the database. */ | ||
abstract class MappedClass extends Class { } | ||
|
||
/** The interface `NHibernamte.ISession`. */ | ||
class ISessionInterface extends Interface { | ||
ISessionInterface() { this.hasQualifiedName("NHibernate.ISession") } | ||
|
||
/** Gets a parameter that uses a mapped object. */ | ||
Parameter getAMappedObjectParameter() { | ||
exists(Callable c | | ||
result.getType() instanceof ObjectType and | ||
c = this.getAMethod() and | ||
result = c.getAParameter() and | ||
result.getName() = "obj" | ||
) | ||
} | ||
|
||
/** Gets a type parameter that specifies a mapped class. */ | ||
TypeParameter getAMappedObjectTp() { | ||
exists(string methodName | | ||
methodName = "Load" | ||
or | ||
methodName = "Merge" | ||
or | ||
methodName = "Get" | ||
or | ||
methodName = "Query" | ||
| | ||
result = this.getAMethod(methodName).(UnboundGenericMethod).getTypeParameter(0) | ||
) | ||
} | ||
} | ||
|
||
/** A mapped class that is mapped because it is used as a type argument. */ | ||
private class MappedByTypeArgument extends MappedClass { | ||
MappedByTypeArgument() { | ||
this = any(ISessionInterface si).getAMappedObjectTp().getASuppliedType() | ||
} | ||
} | ||
|
||
/** A mapped class that is mapped because it is passed as a parameter. */ | ||
private class MappedByParam extends MappedClass { | ||
MappedByParam() { | ||
exists(ISessionInterface si, Expr e, MethodCall c, Parameter p | | ||
p = si.getAMappedObjectParameter() and | ||
e = c.getArgumentForParameter(p) and | ||
this = e.getType() | ||
) and | ||
not this instanceof ObjectType and | ||
not this.getABaseInterface*() instanceof SystemCollectionsIEnumerableInterface and | ||
not this instanceof SystemTypeClass | ||
} | ||
} | ||
|
||
/** A property that is persisted in the database. */ | ||
class MappedProperty extends Property { | ||
MappedProperty() { | ||
this.getDeclaringType() instanceof MappedClass and | ||
this.isPublic() | ||
} | ||
} | ||
|
||
/** A parameter that is interpreted as SQL. */ | ||
class SqlParameter extends Parameter { | ||
SqlParameter() { | ||
this.getType() instanceof StringType and | ||
(this.getName() = "sql" or this.getName() = "sqlString" or this.getName() = "query") and | ||
this | ||
.getCallable() | ||
.getDeclaringType() | ||
.getDeclaringNamespace() | ||
.getParent*() | ||
.hasQualifiedName("", "NHibernate") | ||
} | ||
} | ||
|
||
/** A call to a method in NHibernate that executes SQL. */ | ||
class NHibernateSqlSink extends SqlExpr, Call { | ||
SqlParameter sqlParam; | ||
|
||
NHibernateSqlSink() { this.getTarget().getAParameter() = sqlParam } | ||
|
||
override Expr getSql() { result = this.getArgumentForParameter(sqlParam) } | ||
} | ||
|
||
/** A taint source where the data has come from a mapped property stored in the database. */ | ||
class StoredFlowSource extends DataFlow::Node { | ||
StoredFlowSource() { | ||
this.asExpr() = any(PropertyRead read | read.getTarget() instanceof MappedProperty) | ||
} | ||
} | ||
|
||
/** | ||
* A dataflow node whereby data flows from a property write to a property read | ||
* via some database. The assumption is that all writes can flow to all reads. | ||
*/ | ||
class MappedPropertyJumpNode extends DataFlow::NonLocalJumpNode { | ||
MappedProperty property; | ||
|
||
MappedPropertyJumpNode() { this.asExpr() = property.getAnAssignedValue() } | ||
|
||
override DataFlow::Node getAJumpSuccessor(boolean preservesValue) { | ||
result.asExpr().(PropertyRead).getTarget() = property and | ||
preservesValue = false | ||
} | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 2 additions & 0 deletions
2
csharp/ql/test/library-tests/frameworks/NHibernate/DataFlow.expected
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
| nhibernate.cs:50:14:50:19 | access to property Name | Data flow from $@. | nhibernate.cs:45:24:45:32 | "tainted" | "tainted" | | ||
| nhibernate.cs:55:14:55:23 | access to property Address | Data flow from $@. | nhibernate.cs:45:24:45:32 | "tainted" | "tainted" | |
18 changes: 18 additions & 0 deletions
18
csharp/ql/test/library-tests/frameworks/NHibernate/DataFlow.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import csharp | ||
import semmle.code.csharp.dataflow.TaintTracking | ||
|
||
class MyConfiguration extends TaintTracking::Configuration { | ||
MyConfiguration() { this = "MyConfiguration" } | ||
|
||
override predicate isSource(DataFlow::Node node) { | ||
node.asExpr().(StringLiteral).getValue() = "tainted" | ||
} | ||
|
||
override predicate isSink(DataFlow::Node node) { | ||
exists(MethodCall mc | mc.getTarget().hasName("Sink") and node.asExpr() = mc.getArgument(0)) | ||
} | ||
} | ||
|
||
from MyConfiguration config, DataFlow::Node source, DataFlow::Node sink | ||
where config.hasFlow(source, sink) | ||
select sink, "Data flow from $@.", source, source.toString() |
2 changes: 2 additions & 0 deletions
2
csharp/ql/test/library-tests/frameworks/NHibernate/SqlExprs.expected
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
| nhibernate.cs:16:9:16:26 | object creation of type SqlString | | ||
| nhibernate.cs:17:9:17:27 | call to method Delete | |
5 changes: 5 additions & 0 deletions
5
csharp/ql/test/library-tests/frameworks/NHibernate/SqlExprs.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import csharp | ||
import semmle.code.csharp.frameworks.Sql | ||
|
||
from SqlExpr e | ||
select e |
6 changes: 6 additions & 0 deletions
6
csharp/ql/test/library-tests/frameworks/NHibernate/StoredFlowSources.expected
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
| nhibernate.cs:49:14:49:17 | access to property Id | | ||
| nhibernate.cs:50:14:50:19 | access to property Name | | ||
| nhibernate.cs:51:14:51:22 | access to property Address | | ||
| nhibernate.cs:53:14:53:18 | access to property Id | | ||
| nhibernate.cs:54:14:54:19 | access to property Age | | ||
| nhibernate.cs:55:14:55:23 | access to property Address | |
5 changes: 5 additions & 0 deletions
5
csharp/ql/test/library-tests/frameworks/NHibernate/StoredFlowSources.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import csharp | ||
import semmle.code.csharp.security.dataflow.flowsources.Stored | ||
|
||
from StoredFlowSource source | ||
select source |
62 changes: 62 additions & 0 deletions
62
csharp/ql/test/library-tests/frameworks/NHibernate/nhibernate.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// semmle-extractor-options: /r:System.Data.dll /r:System.ComponentModel.Primitives.dll ${testdir}/../../../resources/stubs/NHibernate.cs ${testdir}/../../../resources/stubs/System.Data.cs /r:System.ComponentModel.TypeConverter.dll /r:System.Data.Common.dll | ||
|
||
|
||
using NHibernate; | ||
using NHibernate.SqlCommand; | ||
|
||
namespace NHibernateTest | ||
{ | ||
class Test | ||
{ | ||
ISession session; | ||
|
||
void SqlExprs() | ||
{ | ||
var sql = "sql"; | ||
new SqlString(sql); // SQL expression | ||
session.Delete(sql); // SQL expression | ||
} | ||
|
||
class Person | ||
{ | ||
public int Id { get; set; } | ||
public string Name { get; set; } | ||
public string Address { get; set; } | ||
} | ||
|
||
class Person2 | ||
{ | ||
public int Id { get; set; } | ||
public int Age { get; set; } | ||
public string Address { get; set; } | ||
} | ||
|
||
void FlowSources() | ||
{ | ||
session.Query<Person>(); | ||
session.Save(new Person2()); | ||
} | ||
|
||
void DataFlow() | ||
{ | ||
var p = new Person(); | ||
var p2 = new Person2(); | ||
|
||
string taint = "tainted"; | ||
p.Name = taint; | ||
p2.Address = taint; | ||
|
||
Sink(p.Id); // Not tainted | ||
Sink(p.Name); // Tainted | ||
Sink(p.Address); // Not tainted | ||
|
||
Sink(p2.Id); // Not tainted | ||
Sink(p2.Age); // Not tainted | ||
Sink(p2.Address); // Tainted | ||
} | ||
|
||
void Sink(object sink) | ||
{ | ||
} | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
|
||
namespace NHibernate | ||
{ | ||
public interface ISession | ||
{ | ||
void Delete(string query); | ||
T Query<T>(); | ||
void Save(object obj); | ||
} | ||
|
||
namespace SqlCommand | ||
{ | ||
public class SqlString | ||
{ | ||
public SqlString(string sql) { } | ||
} | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sometimes, the argument could be a
List
or aDictionary
which isn't supposed to be mapped. This happened on the NHibernate-Core codebase anyway.