Skip to content
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

Add analyzers for leap year readiness CA2260&CA2261 #3152

Closed
wants to merge 7 commits into from

Conversation

kwilkins
Copy link

@kwilkins kwilkins commented Jan 6, 2020

Changes associated with Proposed Analyzer: Leap Year Readiness #2937

Leap year date analyzers added

  • DoNotIncrementYearValueInDateConstructor : CA2260
  • DoNotUserYearValueFromDifferentDateInDateConstructor : CA2261

@dnfclas
Copy link

dnfclas commented Jan 6, 2020

CLA assistant check
All CLA requirements met.

@codecov
Copy link

codecov bot commented Jan 7, 2020

Codecov Report

Merging #3152 into master will increase coverage by <.01%.
The diff coverage is 99.89%.

@@            Coverage Diff             @@
##           master    #3152      +/-   ##
==========================================
+ Coverage   94.13%   94.14%   +<.01%     
==========================================
  Files         967      971       +4     
  Lines      209646   212660    +3014     
  Branches    10451    12108    +1657     
==========================================
+ Hits       197353   200210    +2857     
+ Misses      11407    11174     -233     
- Partials      886     1276     +390

@kwilkins kwilkins marked this pull request as ready for review January 7, 2020 19:28
@kwilkins kwilkins requested a review from a team as a code owner January 7, 2020 19:28
@mavasani mavasani self-assigned this Jan 8, 2020
@mavasani
Copy link
Contributor

mavasani commented Jan 8, 2020

FYI: You will need to move the added analyzer files to a different folder and project, Microsoft.CodeAnalysis.NetAnalyzers, once #3165 is merged. See #3139 (comment) for details.

I will try to review this PR tomorrow. Thanks!

@mattjohnsonpint
Copy link

Thanks for the great work on this @kwilkins !

@mavasani - Would it be possible to somehow mark the rest of CA2262 - CA2269 range (or larger) as "reserved for future use"? I can see that we might want to submit additional analyzers in this space in the future. It would be good to keep them grouped sequentially if possible. Thanks.

@mavasani
Copy link
Contributor

mavasani commented Jan 8, 2020

Would it be possible to somehow mark the rest of CA2262 - CA2269 range (or larger) as "reserved for future use"?

@mj1856 I would recommend updating the ranges in

# FxCop rules
Design: CA1000-CA1099, CA2210
Globalization: CA1300-CA1399, CA2101
Mobility: CA1600-CA1699
Performance: CA1800-CA1899, HA
Security: CA2100-CA2199, CA2300-CA2399, CA3000-CA3147, CA5300-CA5499
Usage: CA1801, CA1806, CA1816, CA2200-CA2209, CA2211-CA2299
Naming: CA1700-CA1799
Maintainability: CA1500-CA1599
Reliability: CA2000-CA2099, CA9999
Documentation: CA1200-CA1299
to explicitly introduce a gap for the IDs you want to reserve, say Usage: CA1801, CA1806, CA1816, CA2200-CA2209, CA2211-CA2262, CA2269-CA2299. Please also add a comment about the rules that need that reserved range. Note that this text file follows a specific format and we have an analyzer that enforces the rule category to rule ID range mapping specified in this file. Let me know if you need help in updating this file appropriately to get your desired reservation.

{
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze);
context.EnableConcurrentExecution();
context.RegisterSemanticModelAction(semanticModelAnalysisContext =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't register this action - there are performance issues associated with it. I think you need to move to using IOperation API and RegisterOperationAction for all semantic analysis of executable code.

}

[Fact]
public async Task YearIncrementVariableCases()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tagging @dotpaul

Looking at this test case, it seems like you essentially want to do a version of TaintedDataFlowAnalysis, where an expression is considered tainted if it is a binary operation with one of the operands as a year/month/day of a DateTime variable and other operand is a literal. We already have large number of Taint analysis based rules in the repo, and I think you should build on top of that framework instead of attempting to write your pseudo-dataflow analysis (done in DateKindSemanticModel.cs and DateKindContext.cs at start of this PR).

@dotpaul Your thoughts? If you agree, might be good for you guys to sync in person.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that if you don't want to handle the DFA cases in this test, and just want the cases in prior tests to work, which might be a reasonable place to start, then you can write an extremely simple IOperation based analyzer (possible 20-30 lines) that can handle those cases. I'd let you guys decide if you want the simpler analyzer that just analyzes arguments or a dataflow analysis based analyzer.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an example, consider the below SQL injection test based on TaintedDataFlowAnalysis:

[Fact]
public void CrossBinary_TaintedObject_Property_ConstructedInput()
{
VerifyCSharpWithDependencies(@"
namespace VulnerableWebApp
{
using System;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.UI;
using OtherDll;
public partial class WebForm : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string taintedInput = this.Request[""input""];
OtherDllClass<string> otherDllObj = new OtherDllClass<string>(taintedInput);
string sqlCommandText = ""SELECT * FROM users WHERE username = '"" + otherDllObj.ConstructedInput + ""'"";
ExecuteSql(sqlCommandText);
}
protected void ExecuteSql(string sqlCommandText)
{
SqlCommand sqlCommand = new SqlCommand()
{
CommandText = sqlCommandText,
CommandType = CommandType.Text,
};
}
}
}",
GetCSharpResultAt(29, 17, 16, 35, "string SqlCommand.CommandText", "void WebForm.ExecuteSql(string sqlCommandText)", "string HttpRequest.this[string key]", "void WebForm.Page_Load(object sender, EventArgs e)"));
}

It has a variable holding tainted data below as the string has a concatenation from an unknown source:

string sqlCommandText = ""SELECT * FROM users WHERE username = '"" + otherDllObj.ConstructedInput + ""'"";

This tainted value gets passed to a method call as argument:

Then it gets passed to the SqlCommand constructor in the invoked method:

SqlCommand sqlCommand = new SqlCommand()
{
CommandText = sqlCommandText,
CommandType = CommandType.Text,
};

The constructor gets flagged by this unit test.

IMO, this test shows how the analysis required for this analyzer closely matches the one done for SQL injection analyzer and can re-use almost all of the taint analysis dataflow framework.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TaintedDataAnalysis would need a bit of modification to treat integer values that get modified as a source.

I think the larger question is, are there other cases would we want to handle that dataflow analysis would help with it? E.g. dunno if something like this would be a case worth trying to find:

int y = originalDateTime.Year + 1;
int year = y;
DateTime newDateTime = new DateTime(year, originalDateTime.Month, originalDateTime.Day);

(There's also tracking the month and day values for determining if it's February 29, so that's another place where dataflow analysis might be helpful [but even more work].)

But all that being said, dataflow analysis isn't easy, so unless there are harder cases you really want to catch and you have time to work on it, I'd avoid it for now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dotpaul - are you suggesting that the analyzer be currently written as a simple IOperation analyzer that just flags violations where arithmetic is done in the callsite argument and avoid any DFA based cases? I think that is indeed a reasonable starting point and I am fine with that approach. I am lot more concerned with us attempting to write another pseudo-dataflow analysis solution, which should be avoided.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm saying I'll defer to @kwilkins as what to do for DFA. :) I dunno if tainted data analysis will meet all the needs. Agree it'd be better to avoid pseudo-DFA. I'd probably consider starting an entirely new analysis myself, given I had the time, but I haven't looked at all the cases.

Copy link
Contributor

@mavasani mavasani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this analyzer should be rewritten using the tainted dataflow analysis written by @dotpaul

@mattjohnsonpint
Copy link

@mavasani - Thanks for the feedback. While we agree, unfortunately we do not have resources to rewrite this to use tainted dataflow analysis in time for it to be released and usable before leap day.

We will still consider working on this to prevent leap year bugs over the long term, as we will have another leap year in 2024, 2028, etc.

@mavasani
Copy link
Contributor

mavasani commented Feb 7, 2020

@mj1856 That sounds reasonable. Would you be willing to simplify the analyzer as per https://github.com/dotnet/roslyn-analyzers/pull/3152/files#r365386559, so you don't perform any dataflow analysis at all, i.e. the first version of analyzer only supports analyzing values at arguments to call sites, but not flowing data values across statements? If so, you can delete large portion of the code being added in this PR, and then when you are ready to enhance the analyzer with dataflow analysis, you can work with @dotpaul to come with an appropriate DFA implementation.

@mavasani
Copy link
Contributor

mavasani commented Feb 7, 2020

Note about the merge conflicts: You will need to move your code to under https://github.com/dotnet/roslyn-analyzers/tree/master/src/NetAnalyzers/Core. The repo has been refactored since this PR was created.

@mavasani
Copy link
Contributor

FYI: You will need to fix a new RS diagnostic once #3444 goes in.

Base automatically changed from master to main March 5, 2021 02:20
@mavasani
Copy link
Contributor

Is this PR still actively being worked upon? If not, can we close it and reopen once ready?

@mattjohnsonpint
Copy link

It is not being worked on presently. The need still exists though.

You can close this. I hope to (at some point) make another one that does dataflow analysis.

@mavasani mavasani closed this May 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants