avoid downloading known malware (#2702)

If graph flags an item as malware,
avoid attempting to download it.
Only applies to drive items.

---

#### Does this PR need a docs update or release note?

- [x]  Yes, it's included

#### Type of change

- [x] 🌻 Feature

#### Issue(s)

* #2701

#### Test Plan

- [x] 💪 Manual
- [x]  Unit test
This commit is contained in:
Keepers 2023-03-06 13:28:10 -07:00 committed by GitHub
parent 61edeec04e
commit d1404626f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 112 additions and 2 deletions

View File

@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- Show owner information when doing backup list in json format - Show owner information when doing backup list in json format
- Onedrive files that are flagged as malware get skipped during backup.
### Fixed ### Fixed
- Corso-generated .meta files and permissions no longer appear in the backup details. - Corso-generated .meta files and permissions no longer appear in the backup details.
@ -36,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Nested attachments are currently not restored due to an [issue](https://github.com/microsoft/kiota-serialization-json-go/issues/61) discovered in the Graph APIs - Nested attachments are currently not restored due to an [issue](https://github.com/microsoft/kiota-serialization-json-go/issues/61) discovered in the Graph APIs
- Breaking changes to Exchange Calendar backups. - Breaking changes to Exchange Calendar backups.
- The debugging env variable CORSO_URL_LOGGING causes exchange get requests to fail. - The debugging env variable CORSO_URL_LOGGING causes exchange get requests to fail.
- Onedrive files that are flagged as Malware consistently fail during backup.
## [v0.3.0] (alpha) - 2023-2-07 ## [v0.3.0] (alpha) - 2023-2-07

View File

@ -608,6 +608,14 @@ func (c *Collections) UpdateCollections(
break break
} }
if item.GetMalware() != nil {
// TODO: track the item as skipped; logging alone might
// slice out the data from tracking.
// https://learn.microsoft.com/en-us/graph/api/resources/malware?view=graph-rest-1.0
logger.Ctx(ctx).Infow("malware detected", "malware_description", ptr.Val(item.GetMalware().GetDescription()))
continue
}
var ( var (
itemID = ptr.Val(item.GetId()) itemID = ptr.Val(item.GetId())
ictx = clues.Add(ctx, "update_item_id", itemID) ictx = clues.Add(ctx, "update_item_id", itemID)

View File

@ -724,6 +724,34 @@ func (suite *OneDriveCollectionsSuite) TestUpdateCollections() {
}, },
expectedExcludes: map[string]struct{}{}, expectedExcludes: map[string]struct{}{},
}, },
{
testCase: "1 root file, 1 folder, 1 package, 1 good file, 1 malware",
items: []models.DriveItemable{
driveRootItem("root"),
driveItem("fileInRoot", "fileInRoot", testBaseDrivePath, "root", true, false, false),
driveItem("folder", "folder", testBaseDrivePath, "root", false, true, false),
driveItem("package", "package", testBaseDrivePath, "root", false, false, true),
driveItem("goodFile", "goodFile", testBaseDrivePath+folder, "folder", true, false, false),
malwareItem("malwareFile", "malwareFile", testBaseDrivePath+folder, "folder", true, false, false),
},
inputFolderMap: map[string]string{},
scope: anyFolder,
expect: assert.NoError,
expectedCollectionIDs: map[string]statePath{
"root": expectedStatePath(data.NotMovedState, ""),
"folder": expectedStatePath(data.NewState, folder),
"package": expectedStatePath(data.NewState, pkg),
},
expectedItemCount: 4,
expectedFileCount: 2,
expectedContainerCount: 3,
expectedMetadataPaths: map[string]string{
"root": expectedPath(""),
"folder": expectedPath("/folder"),
"package": expectedPath("/package"),
},
expectedExcludes: getDelList("fileInRoot", "goodFile"),
},
} }
for _, tt := range tests { for _, tt := range tests {
@ -1743,6 +1771,50 @@ func (suite *OneDriveCollectionsSuite) TestGet() {
expectedDelList: map[string]struct{}{}, expectedDelList: map[string]struct{}{},
doNotMergeItems: true, doNotMergeItems: true,
}, },
{
name: "OneDrive Two Item Pages with Malware",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
driveID1: {
{
items: []models.DriveItemable{
driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false),
malwareItem("malware", "malware", driveBasePath1+"/folder", "folder", true, false, false),
},
nextLink: &next,
},
{
items: []models.DriveItemable{
driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file2", "file2", driveBasePath1+"/folder", "folder", true, false, false),
malwareItem("malware2", "malware2", driveBasePath1+"/folder", "folder", true, false, false),
},
deltaLink: &delta,
},
},
},
errCheck: assert.NoError,
prevFolderPaths: map[string]map[string]string{
driveID1: {},
},
expectedCollections: map[string]map[data.CollectionState][]string{
rootFolderPath1: {data.NewState: {}},
folderPath1: {data.NewState: {"folder", "file", "file2"}},
},
expectedDeltaURLs: map[string]string{
driveID1: delta,
},
expectedFolderPaths: map[string]map[string]string{
driveID1: {
"root": rootFolderPath1,
"folder": folderPath1,
},
},
expectedDelList: getDelList("file", "file2"),
},
} }
for _, test := range table { for _, test := range table {
suite.Run(test.name, func() { suite.Run(test.name, func() {
@ -1886,13 +1958,13 @@ func (suite *OneDriveCollectionsSuite) TestGet() {
} }
} }
func driveItem( func coreItem(
id string, id string,
name string, name string,
parentPath string, parentPath string,
parentID string, parentID string,
isFile, isFolder, isPackage bool, isFile, isFolder, isPackage bool,
) models.DriveItemable { ) *models.DriveItem {
item := models.NewDriveItem() item := models.NewDriveItem()
item.SetName(&name) item.SetName(&name)
item.SetId(&id) item.SetId(&id)
@ -1914,6 +1986,34 @@ func driveItem(
return item return item
} }
func driveItem(
id string,
name string,
parentPath string,
parentID string,
isFile, isFolder, isPackage bool,
) models.DriveItemable {
return coreItem(id, name, parentPath, parentID, isFile, isFolder, isPackage)
}
func malwareItem(
id string,
name string,
parentPath string,
parentID string,
isFile, isFolder, isPackage bool,
) models.DriveItemable {
c := coreItem(id, name, parentPath, parentID, isFile, isFolder, isPackage)
mal := models.NewMalware()
malStr := "test malware"
mal.SetDescription(&malStr)
c.SetMalware(mal)
return c
}
func driveRootItem(id string) models.DriveItemable { func driveRootItem(id string) models.DriveItemable {
name := "root" name := "root"
item := models.NewDriveItem() item := models.NewDriveItem()