v8.28.0

apify/crawleev8.28.0Jul 20, 2025by zricethezav

AI Summary

The primary highlight is the introduction of Gitleaks composite rules, which allow for more complex rule matching. Additionally, the release adds detections for Anthropic and Artifactory API keys and includes several optimizations.

Key Highlights

  • Introduced Gitleaks Composite Rules with proximity matching
  • Added Anthropic API key detection
  • Added Artifactory reference token and API key detection
  • Optimized fragment newline calculation to save time
  • Fixed Git port handling and security CVEs

New Features

  • Gitleaks Composite Rules
  • Anthropic API key detection
  • Artifactory reference token and API key detection

Full Release Notes

## Changelog
* 4fb4382 cant count
* b1c9c7e Composite rules (#1905)
* 72977e4 feat: add Anthropic API key detection (#1910)
* 7b02c98 fix(git): handle port (#1912)
* 2a7bcff dont prematurely calculate fragment newlines (#1909)
* bd79c3e feat(allowlist): promote optimizations (#1908)
* 7fb4eda Fix: CVEs on go and go crypto (#1868)
* a044b81 feat: add artifactory reference token and api key detection (#1906)
* bf380d4 silly
* f487f85 Update gitleaks.yml
* 958f55a add just like that, no leaks


#### Optimizations
#1909 waits to find newlines until a match. This ends up saving a boat load of time since before we were finding newlines for every fragment regardless if a rule matched or not.
#1908 promoted @rgmz excellent stopword optimization

#### Composite Rules (Multi-part or `required` Rules) #1905 
In v8.28.0 Gitleaks introduced composite rules, which are made up of a single "primary" rule and one or more auxiliary or `required` rules. To create a composite rule, add a `[[rules.required]]` table to the primary rule specifying an `id` and optionally `withinLines` and/or `withinColumns` proximity constraints. A fragment is a chunk of content that Gitleaks processes at once (typically a file, part of a file, or git diff), and proximity matching instructs the primary rule to only report a finding if the auxiliary `required` rules also find matches within the specified area of the fragment.

**Proximity matching:** Using the `withinLines` and `withinColumns` fields instructs the primary rule to only report a finding if the auxiliary `required` rules also find matches within the specified proximity. You can set:

- **`withinLines: N`** - required findings must be within N lines (vertically)
- **`withinColumns: N`** - required findings must be within N characters (horizontally)  
- **Both** - creates a rectangular search area (both constraints must be satisfied)
- **Neither** - fragment-level matching (required findings can be anywhere in the same fragment)

Here are diagrams illustrating each proximity behavior:

```
p = primary captured secret
a = auxiliary (required) captured secret
fragment = section of data gitleaks is looking at


    *Fragment-level proximity*               
    Any required finding in the fragment
          ┌────────┐                       
   ┌──────┤fragment├─────┐                 
   │      └──────┬─┤     │ ┌───────┐       
   │             │a│◀────┼─│✓ MATCH│       
   │          ┌─┐└─┘     │ └───────┘       
   │┌─┐       │p│        │                 
   ││a│    ┌─┐└─┘        │ ┌───────┐       
   │└─┘    │a│◀──────────┼─│✓ MATCH│       
   └─▲─────┴─┴───────────┘ └───────┘       
     │    ┌───────┐                        
     └────│✓ MATCH│                        
          └───────┘                        
                                           
                                           
   *Column bounded proximity*
   `withinColumns = 3`                    
          ┌────────┐                       
   ┌────┬─┤fragment├─┬───┐                 
   │      └──────┬─┤     │ ┌───────────┐   
   │    │        │a│◀┼───┼─│+1C ✓ MATCH│   
   │          ┌─┐└─┘     │ └───────────┘   
   │┌─┐ │     │p│    │   │                 
┌──▶│a│  ┌─┐  └─┘        │ ┌───────────┐   
│  │└─┘ ││a│◀────────┼───┼─│-2C ✓ MATCH│   
│  │       ┘             │ └───────────┘   
│  └── -3C ───0C─── +3C ─┘                 
│  ┌─────────┐                             
│  │ -4C ✗ NO│                             
└──│  MATCH  │                             
   └─────────┘                             
                                           
                                           
   *Line bounded proximity*
   `withinLines = 4`                      
         ┌────────┐                        
   ┌─────┤fragment├─────┐                  
  +4L─ ─ ┴────────┘─ ─ ─│                  
   │                    │                  
   │              ┌─┐   │ ┌────────────┐   
   │         ┌─┐  │a│◀──┼─│+1L ✓ MATCH │   
   0L  ┌─┐   │p│  └─┘   │ ├────────────┤   
   │   │a│◀──┴─┴────────┼─│-1L ✓ MATCH │   
   │   └─┘              │ └────────────┘   
   │                    │ ┌─────────┐      
  -4L─ ─ ─ ─ ─ ─ ─ ─┌─┐─│ │-5L ✗ NO │      
   │                │a│◀┼─│  MATCH  │      
   └────────────────┴─┴─┘ └─────────┘      
                                           
                                           
   *Line and column bounded proximity*
   `withinLines = 4`                      
   `withinColumns = 3`                    
         ┌────────┐                        
   ┌─────┤fragment├─────┐                  
  +4L   ┌└────────┴ ┐   │                  
   │            ┌─┐     │ ┌───────────────┐
   │    │       │a│◀┼───┼─│+2L/+1C ✓ MATCH│
   │         ┌─┐└─┘     │ └───────────────┘
   0L   │    │p│    │   │                  
   │         └─┘        │                  
   │    │           │   │ ┌────────────┐   
  -4L    ─ ─ ─ ─ ─ ─┌─┐ │ │-5L/+3C ✗ NO│   
   │                │a│◀┼─│   MATCH    │   
   └───-3C────0L───+3C┴─┘ └────────────┘   
```