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 rate limit per source option #891

Merged
merged 23 commits into from
Aug 7, 2023

Conversation

dogancanbakir
Copy link
Member

@dogancanbakir dogancanbakir commented Jul 4, 2023

With this PR, users now have the capability to configure the rate limit for each individual source. Closes #718.

$ go run . -d hackerone.com -rls "crtsh=10/s,shodan=1/s"

               __    _____           __         
   _______  __/ /_  / __(_)___  ____/ /__  _____
  / ___/ / / / __ \/ /_/ / __ \/ __  / _ \/ ___/
 (__  ) /_/ / /_/ / __/ / / / / /_/ /  __/ /    
/____/\__,_/_.___/_/ /_/_/ /_/\__,_/\___/_/

                projectdiscovery.io

[INF] Current subfinder version v2.6.0 (latest)
[INF] Loading provider config from /home/vscode/.config/subfinder/provider-config.yaml
[INF] Enumerating subdomains for hackerone.com
www.hackerone.com
hackerone.com
links.hackerone.com
go.hackerone.com
mta-sts.managed.hackerone.com
mta-sts.hackerone.com
resources.hackerone.com
support.hackerone.com
info.hackerone.com
events.hackerone.com
gslink.hackerone.com
3d.hackerone.com
a.ns.hackerone.com
api.hackerone.com
docs.hackerone.com
mta-sts.forwarding.hackerone.com
design.hackerone.com
b.ns.hackerone.com
[INF] Found 18 subdomains for hackerone.com in 10 seconds 182 milliseconds

@dogancanbakir dogancanbakir linked an issue Jul 4, 2023 that may be closed by this pull request
v2/pkg/passive/passive.go Fixed Show fixed Hide fixed
@tarunKoyalwar tarunKoyalwar added the Status: Blocked There is some issue that needs to be resolved first. label Jul 5, 2023
@tarunKoyalwar tarunKoyalwar removed the Status: Blocked There is some issue that needs to be resolved first. label Jul 5, 2023
@Mzack9999 Mzack9999 added the Type: Enhancement Most issues will probably ask for additions or changes. label Jul 6, 2023
Copy link
Member

@Mzack9999 Mzack9999 left a comment

Choose a reason for hiding this comment

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

The lint error can be fixed by using a custom type as key for the context value. It's enough to create an alias of string, for example as follows:

type ctxarg string

const (
	ctxSourceArg ctxarg = "source"
)

Then use it as:

xxx := context.WithValue(ctx, ctxSourceArg, "xxx")

Copy link
Member

@Mzack9999 Mzack9999 left a comment

Choose a reason for hiding this comment

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

The implementation is lgtm - Anyway I recommend the following change as the global/custom rate-limiter have a naming and positional redundancy:

// Wrap both arguments into a custom type
type RateLimitJar struct {
   Global int
   Custom mapsutil.SyncMap[string, int]
}
// Expose Set and GetOrDefault operations
RateLimitJar.GetOrDefault(sourceName)
RateLimitJar.Set(sourceName, limit)

Then this struct can be passed around instead of the two arguments.
Also, I think that the parsing from interface{} to int or the options.RateLimits.AsMap() can be moved in options.ParseOptions()

Copy link
Member

@Mzack9999 Mzack9999 left a comment

Choose a reason for hiding this comment

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

lgtm!

Before:

$ go run . -d hackerone.com -rls crtsh=-1
...
[INF] Found 18 subdomains for hackerone.com in 2 seconds 19 milliseconds

After:

$ go run . -d hackerone.com -rls crtsh=1 
...
[INF] Found 18 subdomains for hackerone.com in 8 seconds 327 milliseconds

@tarunKoyalwar
Copy link
Member

@ehsandeep @Mzack9999 , i think its a breaking change for library users, if i remember correctly EnumerateCtx method was added by community member for passing context etc . so i think we should either address that it is breaking change for lib users or try to make it non breaking change

@Mzack9999
Copy link
Member

@tarunKoyalwar I tried to make the change compatible with older function signature. On a side I've to say that I like more the new syntax (WithXXX(...)) so I would recommend in the future to switch to it also for other parameters even if it's a breaking change.

@tarunKoyalwar
Copy link
Member

yeah i also think variadic parameter options is great idea. even outside subfinder we should use that whenever possible

Copy link
Member

@tarunKoyalwar tarunKoyalwar left a comment

Choose a reason for hiding this comment

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

suggesting some changes

  • add 2 flag , rls , rlsm similar to all tools . which means
    rls => ratelimit source (unit is seconds)
    rlsm => ratelimit source minute (unit is minute)

even better we can consider adding new flag type in goflags for ratelimit which accepts ratelimit along with unit @ehsandeep @Mzack9999

type RateLimit struct{
   MaxTokens unit
   Duration.    time.Duration
}

rls := []RateLimit{}
flag.RateLimitVar(&rls, "-rls",nil,"rate limit along with unit ex:  10/ms , 30/m, 8/s ")

things to review/reconsider

  • i think we should opt for whitelist instead of blacklist. subfinder sources have completely different ratelimit . and some sources documentation (api docs) don't mention ratelimit at all but throtle randomly . currently we are applying ratelimit to all sources . instead i think we should apply ratelimit to sources whose ratelimit is either known or user specifies (all=60) or a new flag to exclude ratelimit for xyz sources

  • implementation looks ok but maybe we could have abstracted all ratelimit logic inside session . this is a reference from my other WIP (but backlog) branch https://github.com/projectdiscovery/subfinder/blob/c3d8a02a7b636fa11bb5c76065c952a73fad561e/v2/pkg/subscraping/agent.go

v2/pkg/passive/passive.go Show resolved Hide resolved
@tarunKoyalwar
Copy link
Member

these are some of ratelimits i have collected from sources https://github.com/projectdiscovery/subfinder/blob/c3d8a02a7b636fa11bb5c76065c952a73fad561e/v2/pkg/subscraping/ratelimits.go

@dogancanbakir
Copy link
Member Author

@tarunKoyalwar , I like the idea of having default rate limits and defining a flag to make it easy to get the limit with different units of time. I'll update the PR.

@dogancanbakir
Copy link
Member Author

Now, it's using the RateLimit flag.

@tarunKoyalwar tarunKoyalwar requested review from Mzack9999 and removed request for tarunKoyalwar July 28, 2023 14:36
Copy link
Member

@Mzack9999 Mzack9999 left a comment

Choose a reason for hiding this comment

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

lgtm!

Optional:

  • Update readme file with better examples of custom rate limit
  • The rls flag accepts arbitrary keys, maybe we should validate them against the list of sources to help the user avoid typos:
$ go run . -rls "a=1/s,censyz=1/s"

Copy link
Member

@tarunKoyalwar tarunKoyalwar left a comment

Choose a reason for hiding this comment

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

lgtm !

Notes:

this new feature gives some stability to subfinder when input is more than 1 domain
earlier , when we pass multiple domains as input to subfinder it would return different results everytime it ran due to not respecting ratelimits of each source which affected overall results to change

its difficult to benchmark difference but idea is that subfinder will not get 429 if we set/use proper rate limits

@ehsandeep ehsandeep merged commit 2aff549 into projectdiscovery:dev Aug 7, 2023
9 checks passed
@dogancanbakir dogancanbakir deleted the ratelimit_per_source branch August 7, 2023 14:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Enhancement Most issues will probably ask for additions or changes.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Default internal rate limit per source
4 participants