Exemple #1
0
        public void CheckNormalization(string str1, string str2)
        {
            // Arrange and Act
            str1 = TyposquattingStringNormalization.NormalizeString(str1);

            // Assert
            Assert.Equal(str1, str2);
        }
Exemple #2
0
        public void CheckNotTyposquattingDistance(string str1, string str2, int threshold)
        {
            // Arrange
            str1 = TyposquattingStringNormalization.NormalizeString(str1);
            str2 = TyposquattingStringNormalization.NormalizeString(str2);

            // Act
            var checkResult = TyposquattingDistanceCalculation.IsDistanceLessThanThreshold(str1, str2, threshold);

            // Assert
            Assert.False(checkResult);
        }
        public bool IsUploadedPackageIdTyposquatting(string uploadedPackageId, User uploadedPackageOwner, out List <string> typosquattingCheckCollisionIds)
        {
            typosquattingCheckCollisionIds = new List <string>();
            var wasUploadBlocked = false;

            if (!_contentObjectService.TyposquattingConfiguration.IsCheckEnabled || _reservedNamespaceService.GetReservedNamespacesForId(uploadedPackageId).Any())
            {
                return(wasUploadBlocked);
            }

            if (uploadedPackageId == null)
            {
                throw new ArgumentNullException(nameof(uploadedPackageId));
            }

            if (uploadedPackageOwner == null)
            {
                throw new ArgumentNullException(nameof(uploadedPackageOwner));
            }

            var checklistRetrievalStopwatch = Stopwatch.StartNew();
            var packageRegistrations        = _packageService.GetAllPackageRegistrations();
            var packagesCheckList           = packageRegistrations
                                              .OrderByDescending(pr => pr.IsVerified)
                                              .ThenByDescending(pr => pr.DownloadCount)
                                              .Select(pr => pr.Id)
                                              .Take(TyposquattingCheckListLength)
                                              .ToList();

            checklistRetrievalStopwatch.Stop();

            var algorithmProcessingStopwatch = Stopwatch.StartNew();
            var threshold = GetThreshold(uploadedPackageId);
            var normalizedUploadedPackageId = TyposquattingStringNormalization.NormalizeString(uploadedPackageId);

            var collisionIds = new ConcurrentBag <string>();

            Parallel.ForEach(packagesCheckList, (packageId, loopState) =>
            {
                string normalizedPackageId = TyposquattingStringNormalization.NormalizeString(packageId);
                if (TyposquattingDistanceCalculation.IsDistanceLessThanThreshold(normalizedUploadedPackageId, normalizedPackageId, threshold))
                {
                    collisionIds.Add(packageId);
                }
            });

            algorithmProcessingStopwatch.Stop();

            var totalTime = checklistRetrievalStopwatch.Elapsed.Add(algorithmProcessingStopwatch.Elapsed);

            _telemetryService.TrackMetricForTyposquattingChecklistRetrievalTime(uploadedPackageId, checklistRetrievalStopwatch.Elapsed);
            _telemetryService.TrackMetricForTyposquattingAlgorithmProcessingTime(uploadedPackageId, algorithmProcessingStopwatch.Elapsed);

            if (collisionIds.Count == 0)
            {
                _telemetryService.TrackMetricForTyposquattingCheckResultAndTotalTime(
                    uploadedPackageId,
                    totalTime,
                    wasUploadBlocked,
                    typosquattingCheckCollisionIds,
                    TyposquattingCheckListLength);

                return(false);
            }

            var ownersCheckStopwatch         = Stopwatch.StartNew();
            var collisionPackagesIdAndOwners = packageRegistrations
                                               .Where(pr => collisionIds.Contains(pr.Id))
                                               .Select(pr => new { Id = pr.Id, Owners = pr.Owners.Select(x => x.Key).ToList() })
                                               .ToList();

            typosquattingCheckCollisionIds = collisionPackagesIdAndOwners
                                             .Where(pio => !pio.Owners.Any(k => k == uploadedPackageOwner.Key))
                                             .Select(pio => pio.Id)
                                             .ToList();

            /// <summary>
            /// The following statement is used to double check whether the collision Id belongs to the same user who is uploading the package.
            /// The current policy is that if the user has the ownership of any of the collision packages, we will pass the package.
            /// The reason is that maybe this user is trying to update an existing package who is owned by themselves.
            /// Example:
            /// User "a" is uploading a package named "xyz", while "xyz" collides with existing packages "xyzz" (owned by "a", "b", "c"), "xyyz" (owned by "b"), "xxyz" (owned by "b", "c").
            /// We will pass this package because "a" has the ownership of package "xyzz" even though this package Id collides with "xyyz" and "xxyz".
            /// The "typosquattingCheckCollisionIds" will be saved as "xyyz" and "xxyz" because this package collides with these two packages which are not owned by "a", while "xyzz" will not be saved as "a" owns it.
            /// </summary>
            var isUserAllowedTyposquatting = collisionPackagesIdAndOwners
                                             .Any(pio => pio.Owners.Any(k => k == uploadedPackageOwner.Key));

            wasUploadBlocked = _contentObjectService.TyposquattingConfiguration.IsBlockUsersEnabled && !isUserAllowedTyposquatting;

            ownersCheckStopwatch.Stop();

            totalTime = totalTime.Add(ownersCheckStopwatch.Elapsed);
            _telemetryService.TrackMetricForTyposquattingOwnersCheckTime(uploadedPackageId, ownersCheckStopwatch.Elapsed);
            _telemetryService.TrackMetricForTyposquattingCheckResultAndTotalTime(
                uploadedPackageId,
                totalTime,
                wasUploadBlocked,
                typosquattingCheckCollisionIds,
                TyposquattingCheckListLength);

            return(wasUploadBlocked);
        }