Skip to content

Just initialize this new branch for Cohesity internal collaboration/r… - #2

Open
yinghuang123 wants to merge 343 commits into
masterfrom
CohesitySecurity.internal
Open

Just initialize this new branch for Cohesity internal collaboration/r…#2
yinghuang123 wants to merge 343 commits into
masterfrom
CohesitySecurity.internal

Conversation

@yinghuang123

Copy link
Copy Markdown

…eview.

Required items, please complete

Change(s):

  • See guidance below

Reason for Change(s):

  • See guidance below

Version Updated:

  • Required only for Detections/Analytic Rule templates
  • See guidance below

Testing Completed:

  • See guidance below

Checked that the validations are passing and have addressed any issues that are present:

  • See guidance below

Guidance <- remove section before submitting


Before submitting this PR please ensure that you have read the following sections and filled out the changes, reason for change and testing complete sections:

Thank you for your contribution to the Microsoft Sentinel Github repo.

Details of the code changes in your submitted PR. Providing descriptions for pull requests ensures there is context to changes being made and greatly enhances the code review process. Providing associated Issues that this resolves also easily connects the reason.

Change(s):

  • Updated syntax for XYZ.yaml

Reason for Change(s):

Version updated:

  • Yes
  • Detections/Analytic Rule templates are required to have the version updated

The code should have been tested in a Microsoft Sentinel environment that does not have any custom parsers, functions or tables, so that you validate no incorrect syntax and execution functions properly. If your submission requires a custom parser or function, it must be submitted with the PR.

Testing Completed:

  • Yes/No/Need Help

Note: If updating a detection, you must update the version field.

Before the submission has been made, please look at running the KQL and Yaml Validation Checks locally.
https://github.com/Azure/Azure-Sentinel#run-kql-validation-locally

Checked that the validations are passing and have addressed any issues that are present:

  • Yes/No/Need Help

Note: Let us know if you have tried fixing the validation error and need help.

References:


@eerus eerus left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@yinghuang123 , I finished my review. Please submit changes before you submit another round of reviews to Microsoft.

@ishitagupta25 , please chime in, too. In a few comments I specifically tagged you if I think that you should do the change.

Comment thread Solutions/CohesitySecurity/Analytic Rules/RansomwareAlert.yaml Outdated
* need to rewrite GetAccessTokenAsync function
* as it uses obsolete technology to get the bearer token.
*/
internal async Task<string> GetAccessTokenAsync(string uri)

@eerus eerus Dec 5, 2022

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Rewrite GetAccessTokenAsync function as it uses obsolete technology to get the bearer token. Here's the migration guide to new authentication functions. Please remember that the new authentication mechanism may nit need TenantID, ClientID and and ClientKey, so you'll also have to apply changes in local.settings.json and the corresponding ARM templates.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

put this one to lower priority.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Comment thread Solutions/CohesitySecurity/readme.md Outdated
Comment thread Tools/Create-Azure-Sentinel-Solution/input/Solution_CohesitySecurity.json Outdated
Comment thread Tools/Create-Azure-Sentinel-Solution/input/Solution_CohesitySecurity.json Outdated
Comment thread Tools/Create-Azure-Sentinel-Solution/input/Solution_CohesitySecurity.json Outdated
Comment thread Tools/Create-Azure-Sentinel-Solution/input/Solution_CohesitySecurity.json Outdated

@eerus eerus left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Deleted comments about pre-built binaries

@yinghuang123
yinghuang123 force-pushed the CohesitySecurity.internal branch from 8463ba0 to 2bb8bdb Compare December 10, 2022 00:03

@eerus eerus left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@yinghuang123 , I walked through your changes. The code definitely looks better in terms of handling exceptions and parallelism. I left only a few comments.

log.LogError("URI --> " + URI);
log.LogError("body --> " + body);
log.LogError("ex --> " + ex.Message);
throw new Exception();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Move it outside of the catch block, i.e. outside of the exception handler. Place it after the line 71. This way, it'll be clearer that you're intentionally re-throwing the exception if the code didn't reach ln 63: return result. Also, it'd be great to explain in the comments why you're doing it and how to customize your queue wait and retry times.

}

[FunctionName("IncidentConsumer")]
[FixedDelayRetry(5, "00:05:00")]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I'd move these parameters to host.json file together with other settings (see my another comment in host.json).

Comment thread .script/tests/KqlvalidationsTests/CustomTables/HeliosAuditNativePoller_CL.json Outdated

@eerus eerus left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Please address the comment about exposing extra-parameters and then please switch to updating the Restore From Last Snapshot playbook.
Other comments can be addressed later.

"CohesityQueueName": "your CohesityQueueName",
"DefaultEndpointsProtocol": "your DefaultEndpointsProtocol",
"AccountKey": "your AccountKey",
"BlobEndpoint": "https://127.0.0.1:10000/devstoreaccount1",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I don't think that you use the following parameters anywhere.

Please remove them.

"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"apiKey": "11111111-2222-3333-4444-555555555555",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Come up with a single standard for naming variables and stick to it. For ex, apiKey is written in camel case starting from the lowercase letter, while CohesityQueueName starts from the uppercase letter.

}
else
{
throw new InvalidProgramException("Invalid format string");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Make the error message clearer and more specific, e.g. "Invalid storage connection string."

try
{
const string container = "extra-parameters";
string Blob = incidentID + "\\" + param; // ID unique to the incident

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nit: Come up with a single way for variable naming and stick to it. For ex, Blob starts from the uppercase letter and blobStorageKeys from the lowercase one.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

These 2 variables can be made class variables and can be initialized only once in RunAsync. There's no need to re-initialize them every time in every function call as they never change.

var blobStorageConnectionString = Environment.GetEnvironmentVariable("BlobStorageConnectionString");
var blobStorageKeys = Environment.GetEnvironmentVariable("BlobStorageAccountKeys");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Also, after your remove the variables above to a different place, will you still need TextWriter function for just 2 lines of code? Probably, it'd be better to remove the function and just directly call
WriteData(incidentID + "\\" + param, value);


foreach (var alert in alerts)
{
await ParseAlertToQueueAsync(outputQueueItem, alert, log);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why are you doing it sequentially now? There was a code here that did all iterations in parallel.

else
output.properties.severity = "Medium";
break;
case 0:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nit: Sort the case statements in ascending order for a better readability, like this
case 0:
case 4:
case 7:
case 10:
case 11:

{
switch (i)
{
case 12:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nit: For a better readability, put case 12 statement to the end of switch as it's easier to read when the values go in ascending order, especially if we plan to extend the amount of extra info.

{
try
{
const string container = "extra-parameters";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The container name can't be hardcoded as users are supposed to create it prior deployment.

  • Create an environment variable with the container name. Make the default value equal to "cohesity-extra-parameters".
  • Make sure that the corresponding playbooks are getting it as a parameter as well.
  • The corresponding readme-files should be updated with the instructions about creating containers and entering container names during deployment.

I also think that this constant can be initialized only once, e.g. in RunAsync or when the object is created. You can make it a class variable as there's no need to re-initialize it multiple times with every function call.

{
var db = Connection.GetDatabase();
string apiKey = Environment.GetEnvironmentVariable("apiKey");
string redisKey = Environment.GetEnvironmentVariable("workspace") + apiKey;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

With introducing the storage blob we don't really need storing timestamps in Redis anymore. We can re-use the same container and create there a separate blob with the name equal to Environment.GetEnvironmentVariable("workspace") + apiKey.

It'll reduce monthly bill for the customer.

@eerus eerus left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Everything looks good. I left a few more nit comments.

}
}

private static void WriteData(string storageConnectionString, string path, string data)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

storageConnectionString doesn't change. There's no need to pass it all the time. You can get the value only once at the object creation time or in RunAsync.
private static void WriteData(string path, string data)

{
if (CloudStorageAccount.TryParse(storageConnectionString, out var storageAccount))
{
var cloudBlobClient = storageAccount.CreateCloudBlobClient();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The values of these variables don't change much. You can easily set them up during object initialization or in RunAsync.

var cloudBlobClient = storageAccount.CreateCloudBlobClient();
var container = cloudBlobClient.GetContainerReference(containerName);

try
{
const string container = "extra-parameters";
string Blob = incidentID + "\\" + param; // ID unique to the incident

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Also, after your remove the variables above to a different place, will you still need TextWriter function for just 2 lines of code? Probably, it'd be better to remove the function and just directly call
WriteData(incidentID + "\\" + param, value);

eerus and others added 20 commits December 19, 2022 21:59
Added specific name for the vault
Added specific name for the playbook
- Fixed broken links
- Added info about the Cohesity Close Helios Incident playbook
- Did some formatting
- Replaced Helios with DataHawk + a few other formatting changes.
- Added info about creating an automation trigger for closing SNOW tickets
Add info about skipping steps if the API key is already stored in the vault.
Fixed broken links
Fixed broken links
Fixed broken links
Added connection authorization instructions
Added instructions about connection authorization
Test Azure func deploy
Initial version of the IncidentProducer Function App
    ./Solutions/CohesitySecurity/Playbooks/Cohesity_Close_Helios_Incident/azuredeploy.json
    ./Solutions/CohesitySecurity/Playbooks/Cohesity_CreateOrUpdate_ServiceNow_Incident/azuredeploy.json
+++ ./Solutions/CohesitySecurity/Package/createUiDefinition.json
+++ ./Solutions/CohesitySecurity/Package/mainTemplate.json
Returned the reference to the Restore playbook
add Anomaly Strength in description
re-organize the codes

@eerus eerus left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Added a few optimization suggestions after getting rid of Redis.

{
if (CloudStorageAccount.TryParse(blobStorageConnectionString, out var storageAccount))
{
var cloudBlobClient = storageAccount.CreateCloudBlobClient();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The values for both of these variables never change after initialization. It's worth putting them outside of the function

                var cloudBlobClient = storageAccount.CreateCloudBlobClient();
                var container = cloudBlobClient.GetContainerReference(containerName);


private static void TextWriter(string incidentID, string param, string value, ILogger log)
{
WriteData(incidentID + "\\" + param, value, log);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

It doesn't make sense to have a one-line function, TextWriter. Call WriteData directly.

"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"apiKey": "11111111-2222-3333-4444-555555555555",
"startDaysAgo": "-30",
"connectStr": "your azure redis cache connection string",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remove it as you don't have Redis dependency anymore.

"workspace": "your instance name",
"CohesityQueueName": "your CohesityQueueName",
"DefaultEndpointsProtocol": "your DefaultEndpointsProtocol",
"AccountKey": "your AccountKey",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Where do you use it? Remove it if you don't.

"DefaultEndpointsProtocol": "your DefaultEndpointsProtocol",
"AccountKey": "your AccountKey",
"BlobStorageConnectionString": "your BlobStorageConnectionString",
"BlobStorageAccountKeys": "your BlobStorageAccountKeys",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Where do you use it? Remove it if you don't.

@eerus eerus left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

New comments about redundant env variables

{
private static readonly object queueLock = new object();
private static Lazy<ConnectionMultiplexer> lazyConnection = CreateConnection();
private static string containerName = Environment.GetEnvironmentVariable("containerName");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

There's no need to take it from the environment as it's created by deployment wizard and never changed. Set it equal to "cohesity-extra-parameters"

@yinghuang123 yinghuang123 Dec 23, 2022

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

so, you means this change?

-        private static string containerName = GetSecret("containerName");
+        private static string containerName = "cohesity-extra-parameters";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Yes, but also can you move shared constants and functions to one place, so both producer and consumer can use them. For ex, you can create a shared library for it or reference from both projects.

@eerus eerus left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Thoughts on queue name to simplify deployment configs

}

[FunctionName("IncidentConsumer")]
public void Run([QueueTrigger("%CohesityQueueName%", Connection = "AzureWebJobsStorage")]string queueItem, ILogger log)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why did we decide to put the queue name to the environment variable? If the deployment wizard creates a storage account with a unique name, then we can just have a common constant between producer and consumer for the queue name

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Here you can create a shared constant "cohesity-incidents" that both projects have access to.

}

public static async Task ParseAlertToQueue(
[Queue("%CohesityQueueName%"), StorageAccount("AzureWebJobsStorage")] ICollector<string> outputQueueItem,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why did we decide to put the queue name to the environment variable? If the deployment wizard creates a storage account with a unique name, then we can just have a common constant between producer and consumer for the queue name

ARM template for deploying both Azure functions.
v-sudkharat and others added 17 commits October 8, 2024 14:16
…torUpdate

Updated azuredeploy template of Rubrik Data Connector to prevent public access and cross tenant replicaion in storage account
Bumps [System.Text.Json](https://github.com/dotnet/runtime) from 8.0.4 to 8.0.5.
- [Release notes](https://github.com/dotnet/runtime/releases)
- [Commits](dotnet/runtime@v8.0.4...v8.0.5)

---
updated-dependencies:
- dependency-name: System.Text.Json
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
…ure-function-v4

Cybersixgill Actionable Alerts Python Version Upgrade
…tors/O365-DataCSharp/Teams.CustomConnector.StorageHandler/System.Text.Json-8.0.5

Bump System.Text.Json from 8.0.4 to 8.0.5 in /DataConnectors/O365 DataCSharp/Teams.CustomConnector.StorageHandler
Updated code to fix the bug in CrowdStrike Replicator V2
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.