Skip to content

Commit

Permalink
Merge pull request #15784 from egregius313/egregius313/csharp/dataflo…
Browse files Browse the repository at this point in the history
…w/sources/file

C#: Add source models for `file` threat model/source kind for .NET standard library
  • Loading branch information
egregius313 authored Mar 22, 2024
2 parents f48e295 + c7a746e commit 1785086
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 34 deletions.
4 changes: 4 additions & 0 deletions csharp/ql/lib/change-notes/2024-03-13-system.io-models.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Additional models have been added for `System.IO`. These are primarily source models with the `file` threat model, and summaries related to reading from a file or stream.
24 changes: 24 additions & 0 deletions csharp/ql/lib/ext/System.IO.model.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,25 @@ extensions:
- ["System.IO", "File", False, "Create", "", "", "ReturnValue", "file-write", "manual"]
- ["System.IO", "File", False, "CreateText", "", "", "ReturnValue", "file-write", "manual"]
- ["System.IO", "File", False, "Open", "", "", "ReturnValue", "file-write", "manual"]
- ["System.IO", "File", False, "Open", "", "", "ReturnValue", "file", "manual"]
- ["System.IO", "File", False, "OpenRead", "", "", "ReturnValue", "file", "manual"]
- ["System.IO", "File", False, "OpenText", "", "", "ReturnValue", "file", "manual"]
- ["System.IO", "File", False, "OpenWrite", "", "", "ReturnValue", "file-write", "manual"]
- ["System.IO", "File", False, "ReadAllBytes", "", "", "ReturnValue", "file", "manual"]
- ["System.IO", "File", False, "ReadAllBytesAsync", "", "", "ReturnValue", "file", "manual"]
- ["System.IO", "File", False, "ReadAllLines", "", "", "ReturnValue", "file", "manual"]
- ["System.IO", "File", False, "ReadAllLinesAsync", "", "", "ReturnValue", "file", "manual"]
- ["System.IO", "File", False, "ReadAllText", "", "", "ReturnValue", "file", "manual"]
- ["System.IO", "File", False, "ReadAllTextAsync", "", "", "ReturnValue", "file", "manual"]
- ["System.IO", "File", False, "ReadLines", "", "", "ReturnValue", "file", "manual"]
- ["System.IO", "File", False, "ReadLinesAsync", "", "", "ReturnValue", "file", "manual"]
- ["System.IO", "FileInfo", False, "AppendText", "", "", "ReturnValue", "file-write", "manual"]
- ["System.IO", "FileInfo", False, "Create", "", "", "ReturnValue", "file-write", "manual"]
- ["System.IO", "FileInfo", False, "CreateText", "", "", "ReturnValue", "file-write", "manual"]
- ["System.IO", "FileInfo", False, "Open", "", "", "ReturnValue", "file-write", "manual"]
- ["System.IO", "FileInfo", False, "Open", "", "", "ReturnValue", "file", "manual"]
- ["System.IO", "FileInfo", False, "OpenRead", "", "", "ReturnValue", "file", "manual"]
- ["System.IO", "FileInfo", False, "OpenText", "", "", "ReturnValue", "file", "manual"]
- ["System.IO", "FileInfo", False, "OpenWrite", "", "", "ReturnValue", "file-write", "manual"]
- ["System.IO", "FileStream", False, "FileStream", "", "", "Argument[this]", "file", "manual"]
- ["System.IO", "FileStream", False, "FileStream", "", "", "Argument[this]", "file-write", "manual"]
Expand All @@ -25,6 +39,8 @@ extensions:
pack: codeql/csharp-all
extensible: summaryModel
data:
- ["System.IO", "BufferedStream", False, "BufferedStream", "(System.IO.Stream)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
- ["System.IO", "BufferedStream", False, "BufferedStream", "(System.IO.Stream,System.Int32)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
- ["System.IO", "FileStream", False, "FileStream", "(System.String,System.IO.FileMode)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
- ["System.IO", "FileStream", False, "FileStream", "(System.String,System.IO.FileMode,System.IO.FileAccess)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
- ["System.IO", "FileStream", False, "FileStream", "(System.String,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
Expand Down Expand Up @@ -69,8 +85,16 @@ extensions:
- ["System.IO", "Stream", True, "CopyToAsync", "(System.IO.Stream,System.Int32,System.Threading.CancellationToken)", "", "Argument[this]", "Argument[0]", "taint", "manual"]
- ["System.IO", "Stream", False, "CopyToAsync", "(System.IO.Stream,System.Threading.CancellationToken)", "", "Argument[this]", "Argument[0]", "taint", "manual"]
- ["System.IO", "Stream", True, "Read", "(System.Byte[],System.Int32,System.Int32)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
- ["System.IO", "Stream", True, "Read", "(System.Span<System.Byte>)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
- ["System.IO", "Stream", False, "ReadAsync", "(System.Byte[],System.Int32,System.Int32)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
- ["System.IO", "Stream", True, "ReadAsync", "(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
# Post-update nodes for `Memory<T>` are currently unsupported. This model is provided for completeness
- ["System.IO", "Stream", True, "ReadAsync", "(System.Memory<System.Byte>,System.Threading.CancellationToken)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
- ["System.IO", "Stream", True, "ReadAtLeast", "(System.Span<System.Byte>,System.Int32,System.Boolean)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
# Post-update nodes for `Memory<T>` are currently unsupported. This model is provided for completeness
- ["System.IO", "Stream", True, "ReadAtLeastAsync", "(System.Memory<System.Byte>,System.Int32,System.Boolean,System.Threading.CancellationToken)", "", "Argument[this]", "Argument[0]", "taint", "manual"]
- ["System.IO", "Stream", True, "ReadExactly", "(System.Span<System.Byte>)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
- ["System.IO", "Stream", True, "ReadExactly", "(System.Byte[],System.Int32,System.Int32)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
- ["System.IO", "Stream", True, "Write", "(System.Byte[],System.Int32,System.Int32)", "", "Argument[0].Element", "Argument[this]", "taint", "manual"]
- ["System.IO", "Stream", False, "WriteAsync", "(System.Byte[],System.Int32,System.Int32)", "", "Argument[0].Element", "Argument[this]", "taint", "manual"]
- ["System.IO", "Stream", True, "WriteAsync", "(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken)", "", "Argument[0].Element", "Argument[this]", "taint", "manual"]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using System.IO;

namespace Test
{
class Files
{
public static void ReadAllText(string path)
{
string text = File.ReadAllText(path);
Sink(text); // $ hasTaintFlow=line:9
}

public static void ReadAllLines(string path)
{
string[] lines = File.ReadAllLines(path);
Sink(lines); // $ hasTaintFlow=line:15
}

public static void ReadAllBytes(string path)
{
byte[] bytes = File.ReadAllBytes(path);
Sink(bytes); // $ hasTaintFlow=line:21
}

public static void ReadLines(string path)
{
foreach (string line in File.ReadLines(path))
{
Sink(line); // $ hasTaintFlow=line:27
}
}

public static void BufferedRead(string path)
{
using (FileStream fs = new FileStream(path, FileMode.Open))
{
using (BufferedStream bs = new BufferedStream(fs))
{
using (StreamReader sr = new StreamReader(bs))
{
string line;
while ((line = sr.ReadLine()) != null)
{
Sink(line); // $ hasTaintFlow=line:35
}
}
}
}
}

public static void ReadBlocks(string path)
{
using (FileStream fs = File.OpenRead(path))
{
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0)
{
Sink(buffer[0]); // $ hasTaintFlow=line:53
}
}
}

public static async void ReadAllTextAsync(string path)
{
string text = await File.ReadAllTextAsync(path);
Sink(text); // $ hasTaintFlow=line:66

using (FileStream fs = File.Open(path, FileMode.Open))
{
using (StreamReader sr = new StreamReader(fs))
{
string line;
while ((line = await sr.ReadLineAsync()) != null)
{
Sink(line); // $ hasTaintFlow=line:69
}
}
}
}

static void Sink(object o) { }
}
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
extensions:

- addsTo:
pack: codeql/threat-models
extensible: threatModelConfiguration
data:
- ["file", true, 0]
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import csharp
import semmle.code.csharp.security.dataflow.flowsources.FlowSources
import TestUtilities.InlineFlowTest
import TaintFlowTest<FilesConfig>

module FilesConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof ThreatModelFlowSource }

predicate isSink(DataFlow::Node sink) {
exists(MethodCall mc | mc.getTarget().hasName("Sink") | sink.asExpr() = mc.getArgument(0))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
semmle-extractor-options: /nostdlib /noconfig
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.App.csproj
semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs
Loading

0 comments on commit 1785086

Please sign in to comment.