@@ -617,7 +617,7 @@ func (e *BugBountyEngine) Execute(ctx context.Context, target string) (*BugBount
617617 }
618618
619619 tracker .StartPhase ("testing" )
620- findings , phaseResults := e .executeTestingPhase (ctx , target , prioritized , tracker )
620+ findings , phaseResults := e .executeTestingPhase (ctx , target , prioritized , tracker , dbLogger )
621621
622622 testingDuration := time .Since (testingStart )
623623 dbLogger .Infow (" Testing phase completed" ,
@@ -1069,8 +1069,11 @@ func (e *BugBountyEngine) analyzeAssetFeatures(asset *discovery.Asset) AssetFeat
10691069}
10701070
10711071// executeTestingPhase runs all vulnerability tests in parallel
1072- func (e * BugBountyEngine ) executeTestingPhase (ctx context.Context , target string , assets []* AssetPriority , tracker * progress.Tracker ) ([]types.Finding , map [string ]PhaseResult ) {
1073- e .logger .Infow ("Phase 3: Vulnerability Testing" , "assets" , len (assets ))
1072+ func (e * BugBountyEngine ) executeTestingPhase (ctx context.Context , target string , assets []* AssetPriority , tracker * progress.Tracker , dbLogger * logger.DBEventLogger ) ([]types.Finding , map [string ]PhaseResult ) {
1073+ dbLogger .Infow (" Phase 3: Starting vulnerability testing" ,
1074+ "assets" , len (assets ),
1075+ "component" , "orchestrator" ,
1076+ )
10741077
10751078 phaseResults := make (map [string ]PhaseResult )
10761079 allFindings := []types.Finding {}
@@ -1117,7 +1120,7 @@ func (e *BugBountyEngine) executeTestingPhase(ctx context.Context, target string
11171120 wg .Add (1 )
11181121 go func () {
11191122 defer wg .Done ()
1120- findings , result := e .runAuthenticationTests (ctx , target , assets )
1123+ findings , result := e .runAuthenticationTests (ctx , target , assets , dbLogger )
11211124 mu .Lock ()
11221125 allFindings = append (allFindings , findings ... )
11231126 phaseResults ["auth" ] = result
@@ -1131,7 +1134,7 @@ func (e *BugBountyEngine) executeTestingPhase(ctx context.Context, target string
11311134 wg .Add (1 )
11321135 go func () {
11331136 defer wg .Done ()
1134- findings , result := e .runSCIMTests (ctx , assets )
1137+ findings , result := e .runSCIMTests (ctx , assets , dbLogger )
11351138 mu .Lock ()
11361139 allFindings = append (allFindings , findings ... )
11371140 phaseResults ["scim" ] = result
@@ -1145,7 +1148,7 @@ func (e *BugBountyEngine) executeTestingPhase(ctx context.Context, target string
11451148 wg .Add (1 )
11461149 go func () {
11471150 defer wg .Done ()
1148- findings , result := e .runAPITests (ctx , assets )
1151+ findings , result := e .runAPITests (ctx , assets , dbLogger )
11491152 mu .Lock ()
11501153 allFindings = append (allFindings , findings ... )
11511154 phaseResults ["api" ] = result
@@ -1159,7 +1162,7 @@ func (e *BugBountyEngine) executeTestingPhase(ctx context.Context, target string
11591162 wg .Add (1 )
11601163 go func () {
11611164 defer wg .Done ()
1162- findings , result := e .runNmapScans (ctx , assets )
1165+ findings , result := e .runNmapScans (ctx , assets , dbLogger )
11631166 mu .Lock ()
11641167 allFindings = append (allFindings , findings ... )
11651168 phaseResults ["nmap" ] = result
@@ -1173,7 +1176,7 @@ func (e *BugBountyEngine) executeTestingPhase(ctx context.Context, target string
11731176 wg .Add (1 )
11741177 go func () {
11751178 defer wg .Done ()
1176- findings , result := e .runNucleiScans (ctx , assets )
1179+ findings , result := e .runNucleiScans (ctx , assets , dbLogger )
11771180 mu .Lock ()
11781181 allFindings = append (allFindings , findings ... )
11791182 phaseResults ["nuclei" ] = result
@@ -1187,7 +1190,7 @@ func (e *BugBountyEngine) executeTestingPhase(ctx context.Context, target string
11871190 wg .Add (1 )
11881191 go func () {
11891192 defer wg .Done ()
1190- findings , result := e .runGraphQLTests (ctx , assets )
1193+ findings , result := e .runGraphQLTests (ctx , assets , dbLogger )
11911194 mu .Lock ()
11921195 allFindings = append (allFindings , findings ... )
11931196 phaseResults ["graphql" ] = result
@@ -1201,7 +1204,7 @@ func (e *BugBountyEngine) executeTestingPhase(ctx context.Context, target string
12011204 wg .Add (1 )
12021205 go func () {
12031206 defer wg .Done ()
1204- findings , result := e .runIDORTests (ctx , assets )
1207+ findings , result := e .runIDORTests (ctx , assets , dbLogger )
12051208 mu .Lock ()
12061209 allFindings = append (allFindings , findings ... )
12071210 phaseResults ["idor" ] = result
@@ -1217,7 +1220,7 @@ func (e *BugBountyEngine) executeTestingPhase(ctx context.Context, target string
12171220}
12181221
12191222// runAuthenticationTests executes all authentication vulnerability tests
1220- func (e * BugBountyEngine ) runAuthenticationTests (ctx context.Context , target string , assets []* AssetPriority ) ([]types.Finding , PhaseResult ) {
1223+ func (e * BugBountyEngine ) runAuthenticationTests (ctx context.Context , target string , assets []* AssetPriority , dbLogger * logger. DBEventLogger ) ([]types.Finding , PhaseResult ) {
12211224 phaseStart := time .Now ()
12221225 phase := PhaseResult {
12231226 Phase : "authentication" ,
@@ -1447,7 +1450,7 @@ func (e *BugBountyEngine) runAuthenticationTests(ctx context.Context, target str
14471450}
14481451
14491452// runSCIMTests executes SCIM vulnerability tests in parallel
1450- func (e * BugBountyEngine ) runSCIMTests (ctx context.Context , assets []* AssetPriority ) ([]types.Finding , PhaseResult ) {
1453+ func (e * BugBountyEngine ) runSCIMTests (ctx context.Context , assets []* AssetPriority , dbLogger * logger. DBEventLogger ) ([]types.Finding , PhaseResult ) {
14511454 phaseStart := time .Now ()
14521455 phase := PhaseResult {
14531456 Phase : "scim" ,
@@ -1543,7 +1546,7 @@ func (e *BugBountyEngine) runSCIMTests(ctx context.Context, assets []*AssetPrior
15431546}
15441547
15451548// runAPITests executes API vulnerability tests
1546- func (e * BugBountyEngine ) runAPITests (ctx context.Context , assets []* AssetPriority ) ([]types.Finding , PhaseResult ) {
1549+ func (e * BugBountyEngine ) runAPITests (ctx context.Context , assets []* AssetPriority , dbLogger * logger. DBEventLogger ) ([]types.Finding , PhaseResult ) {
15471550 phase := PhaseResult {
15481551 Phase : "api" ,
15491552 Status : "running" ,
@@ -1595,7 +1598,7 @@ func (e *BugBountyEngine) runAPITests(ctx context.Context, assets []*AssetPriori
15951598}
15961599
15971600// runNmapScans performs service fingerprinting and port scanning
1598- func (e * BugBountyEngine ) runNmapScans (ctx context.Context , assets []* AssetPriority ) ([]types.Finding , PhaseResult ) {
1601+ func (e * BugBountyEngine ) runNmapScans (ctx context.Context , assets []* AssetPriority , dbLogger * logger. DBEventLogger ) ([]types.Finding , PhaseResult ) {
15991602 phaseStart := time .Now ()
16001603 phase := PhaseResult {
16011604 Phase : "nmap" ,
@@ -1744,7 +1747,7 @@ func (e *BugBountyEngine) runNmapScans(ctx context.Context, assets []*AssetPrior
17441747}
17451748
17461749// runNucleiScans performs vulnerability scanning with Nuclei templates
1747- func (e * BugBountyEngine ) runNucleiScans (ctx context.Context , assets []* AssetPriority ) ([]types.Finding , PhaseResult ) {
1750+ func (e * BugBountyEngine ) runNucleiScans (ctx context.Context , assets []* AssetPriority , dbLogger * logger. DBEventLogger ) ([]types.Finding , PhaseResult ) {
17481751 phaseStart := time .Now ()
17491752 phase := PhaseResult {
17501753 Phase : "nuclei" ,
@@ -1874,39 +1877,56 @@ func (e *BugBountyEngine) runNucleiScans(ctx context.Context, assets []*AssetPri
18741877}
18751878
18761879// runGraphQLTests performs GraphQL security testing
1877- func (e * BugBountyEngine ) runGraphQLTests (ctx context.Context , assets []* AssetPriority ) ([]types.Finding , PhaseResult ) {
1880+ func (e * BugBountyEngine ) runGraphQLTests (ctx context.Context , assets []* AssetPriority , dbLogger * logger. DBEventLogger ) ([]types.Finding , PhaseResult ) {
18781881 phase := PhaseResult {
18791882 Phase : "graphql" ,
18801883 Status : "running" ,
18811884 StartTime : time .Now (),
18821885 }
18831886
1884- e .logger .Infow ("Running GraphQL security tests" )
1887+ dbLogger .Infow (" Running GraphQL security tests" ,
1888+ "component" , "graphql_scanner" ,
1889+ )
18851890
18861891 var findings []types.Finding
18871892
1888- // Find GraphQL endpoints
1889- graphqlCount := 0
1893+ // Extract unique base URLs from assets for GraphQL testing
1894+ // The GraphQL scanner will test common paths like /graphql, /gql, /api/graphql, etc.
1895+ baseURLs := make (map [string ]bool )
18901896 for _ , asset := range assets {
1891- url := asset .Asset .Value
1892- // Check if URL likely contains GraphQL endpoint
1893- if ! strings .Contains (strings .ToLower (url ), "graphql" ) &&
1894- ! strings .Contains (strings .ToLower (url ), "/api" ) {
1895- continue
1897+ // Parse URL to extract base (scheme + host)
1898+ if strings .HasPrefix (asset .Asset .Value , "http://" ) || strings .HasPrefix (asset .Asset .Value , "https://" ) {
1899+ // Find the base URL (up to the first path separator after the host)
1900+ parts := strings .SplitN (asset .Asset .Value , "/" , 4 ) // ["https:", "", "example.com", "path..."]
1901+ if len (parts ) >= 3 {
1902+ baseURL := parts [0 ] + "//" + parts [2 ] // "https://example.com"
1903+ baseURLs [baseURL ] = true
1904+ }
18961905 }
1906+ }
1907+
1908+ dbLogger .Infow (" Extracted base URLs for GraphQL testing" ,
1909+ "total_assets" , len (assets ),
1910+ "unique_base_urls" , len (baseURLs ),
1911+ "component" , "graphql_scanner" ,
1912+ )
18971913
1914+ // Test each base URL - GraphQL scanner will discover endpoints automatically
1915+ graphqlCount := 0
1916+ for baseURL := range baseURLs {
18981917 graphqlCount ++
1899- e .logger .Debugw ("Testing GraphQL endpoint" ,
1900- "url" , url ,
1918+ dbLogger .Infow (" Testing base URL for GraphQL endpoints" ,
1919+ "url" , baseURL ,
1920+ "testing_count" , fmt .Sprintf ("%d/%d" , graphqlCount , len (baseURLs )),
19011921 "component" , "graphql_scanner" ,
19021922 )
19031923
1904- // Run Go GraphQL scanner
1905- results , err := e .graphqlScanner .Scan (ctx , url , nil )
1924+ // Run Go GraphQL scanner - it will test multiple common GraphQL paths
1925+ results , err := e .graphqlScanner .Scan (ctx , baseURL , nil )
19061926 if err != nil {
1907- e . logger . Errorw ("GraphQL scan failed" ,
1927+ dbLogger . Errorw (" GraphQL scan failed" ,
19081928 "error" , err ,
1909- "url" , url ,
1929+ "url" , baseURL ,
19101930 "component" , "graphql_scanner" ,
19111931 )
19121932 continue
@@ -1915,33 +1935,33 @@ func (e *BugBountyEngine) runGraphQLTests(ctx context.Context, assets []*AssetPr
19151935 // Convert results to findings
19161936 findings = append (findings , results ... )
19171937
1918- e . logger . Infow ("Go GraphQL scan completed" ,
1919- "url" , url ,
1938+ dbLogger . Infow (" Go GraphQL scan completed" ,
1939+ "url" , baseURL ,
19201940 "findings" , len (results ),
19211941 "component" , "graphql_scanner" ,
19221942 )
19231943
19241944 // Also run Python GraphCrawler if available
19251945 if e .pythonWorkers != nil {
1926- e . logger . Infow ("Running Python GraphCrawler" ,
1927- "url" , url ,
1946+ dbLogger . Infow (" Running Python GraphCrawler" ,
1947+ "url" , baseURL ,
19281948 "component" , "graphcrawler" ,
19291949 )
19301950
1931- jobStatus , err := e .pythonWorkers .ScanGraphQLSync (ctx , url , nil )
1951+ jobStatus , err := e .pythonWorkers .ScanGraphQLSync (ctx , baseURL , nil )
19321952 if err != nil {
1933- e . logger . Errorw ("GraphCrawler scan failed" ,
1953+ dbLogger . Errorw (" GraphCrawler scan failed" ,
19341954 "error" , err ,
1935- "url" , url ,
1955+ "url" , baseURL ,
19361956 "component" , "graphcrawler" ,
19371957 )
19381958 } else if jobStatus .Status == "completed" && jobStatus .Result != nil {
19391959 // Convert Python worker results to findings
1940- pythonFindings := convertPythonGraphQLToFindings (jobStatus .Result , url )
1960+ pythonFindings := convertPythonGraphQLToFindings (jobStatus .Result , baseURL )
19411961 findings = append (findings , pythonFindings ... )
19421962
1943- e . logger . Infow ("GraphCrawler scan completed" ,
1944- "url" , url ,
1963+ dbLogger . Infow (" GraphCrawler scan completed" ,
1964+ "url" , baseURL ,
19451965 "findings" , len (pythonFindings ),
19461966 "component" , "graphcrawler" ,
19471967 )
@@ -1954,17 +1974,18 @@ func (e *BugBountyEngine) runGraphQLTests(ctx context.Context, assets []*AssetPr
19541974 phase .Status = "completed"
19551975 phase .Findings = len (findings )
19561976
1957- e . logger . Infow ("GraphQL testing completed" ,
1977+ dbLogger . Infow (" GraphQL testing completed" ,
19581978 "findings" , len (findings ),
1959- "duration" , phase .Duration ,
1979+ "duration" , phase .Duration . String () ,
19601980 "endpoints_tested" , graphqlCount ,
1981+ "component" , "graphql_scanner" ,
19611982 )
19621983
19631984 return findings , phase
19641985}
19651986
19661987// runIDORTests performs IDOR vulnerability testing using Python workers
1967- func (e * BugBountyEngine ) runIDORTests (ctx context.Context , assets []* AssetPriority ) ([]types.Finding , PhaseResult ) {
1988+ func (e * BugBountyEngine ) runIDORTests (ctx context.Context , assets []* AssetPriority , dbLogger * logger. DBEventLogger ) ([]types.Finding , PhaseResult ) {
19681989 phase := PhaseResult {
19691990 Phase : "idor" ,
19701991 Status : "running" ,
0 commit comments