Skip to content

Commit bcbec58

Browse files
committed
master
1 parent bea8ae4 commit bcbec58

5 files changed

Lines changed: 99 additions & 16 deletions

File tree

.github/workflows/scan.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: ApkSentinel Scan
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
scan:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v3
14+
15+
- name: Set up Go
16+
uses: actions/setup-go@v4
17+
with:
18+
go-version: '1.25'
19+
20+
- name: Install jadx
21+
run: |
22+
sudo apt-get update
23+
sudo apt-get install -y jadx
24+
25+
- name: Build ApkSentinel
26+
run: go build -v -o apk-sentinel cmd/apk-sentinel.go
27+
28+
- name: Run Scan
29+
run: |
30+
# Example scan on a sample APK if available, or just test build
31+
# ./apk-sentinel -i samples/test.apk -o results -f both
32+
./apk-sentinel --help

.gitlab-ci.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
image: golang:1.24
2+
3+
stages:
4+
- build
5+
- scan
6+
7+
build_job:
8+
stage: build
9+
script:
10+
- go build -v -o apk-sentinel cmd/apk-sentinel.go
11+
artifacts:
12+
paths:
13+
- apk-sentinel
14+
15+
scan_job:
16+
stage: scan
17+
before_script:
18+
- apt-get update && apt-get install -y jadx
19+
script:
20+
- ./apk-sentinel --help
21+
# Example scan:
22+
# - ./apk-sentinel -i your-app.apk -o results -f both
23+
artifacts:
24+
paths:
25+
- report/

apk-sentinel

258 KB
Binary file not shown.

cmd/apk-sentinel.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ detect hard-coded secrets, API keys, and sensitive URLs in Android applications.
4747
// 2. Scan
4848
patternFile := customPatterns
4949
if patternFile == "" {
50-
// fallback to default patterns
51-
patternFile = "internal/patterns/default_patterns.json"
50+
// fallback to default patterns directory
51+
patternFile = "internal/patterns"
5252
}
5353

5454
s, err := scanner.NewScanner(patternFile)

internal/scanner/scanner.go

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,30 +40,56 @@ type Scanner struct {
4040
context *regexp.Regexp
4141
}
4242

43-
// NewScanner initializes a Scanner with patterns from a JSON file.
44-
func NewScanner(patternFilePath string) (*Scanner, error) {
45-
data, err := os.ReadFile(patternFilePath)
43+
// NewScanner initializes a Scanner with patterns from one or more JSON files.
44+
func NewScanner(patternPath string) (*Scanner, error) {
45+
var patternFiles []string
46+
47+
info, err := os.Stat(patternPath)
4648
if err != nil {
47-
return nil, fmt.Errorf("failed to read pattern file: %w", err)
49+
return nil, fmt.Errorf("failed to access pattern path: %w", err)
4850
}
4951

50-
var config struct {
51-
Patterns []Pattern `json:"patterns"`
52-
}
53-
if err := json.Unmarshal(data, &config); err != nil {
54-
return nil, fmt.Errorf("failed to unmarshal patterns: %w", err)
52+
if info.IsDir() {
53+
files, err := os.ReadDir(patternPath)
54+
if err != nil {
55+
return nil, fmt.Errorf("failed to read pattern directory: %w", err)
56+
}
57+
for _, f := range files {
58+
if !f.IsDir() && filepath.Ext(f.Name()) == ".json" {
59+
patternFiles = append(patternFiles, filepath.Join(patternPath, f.Name()))
60+
}
61+
}
62+
} else {
63+
patternFiles = append(patternFiles, patternPath)
5564
}
5665

57-
for i := range config.Patterns {
58-
re, err := regexp.Compile(config.Patterns[i].Regex)
66+
var allPatterns []Pattern
67+
for _, pf := range patternFiles {
68+
data, err := os.ReadFile(pf)
5969
if err != nil {
60-
return nil, fmt.Errorf("invalid regex for pattern %s: %w", config.Patterns[i].Name, err)
70+
continue // Skip unreadable files
6171
}
62-
config.Patterns[i].Compiled = re
72+
73+
var config struct {
74+
Patterns []Pattern `json:"patterns"`
75+
}
76+
if err := json.Unmarshal(data, &config); err == nil {
77+
for i := range config.Patterns {
78+
re, err := regexp.Compile(config.Patterns[i].Regex)
79+
if err == nil {
80+
config.Patterns[i].Compiled = re
81+
allPatterns = append(allPatterns, config.Patterns[i])
82+
}
83+
}
84+
}
85+
}
86+
87+
if len(allPatterns) == 0 {
88+
return nil, fmt.Errorf("no valid patterns found in %s", patternPath)
6389
}
6490

6591
return &Scanner{
66-
Patterns: config.Patterns,
92+
Patterns: allPatterns,
6793
resolver: analyzer.NewObfuscationResolver(),
6894
context: regexp.MustCompile(`(?i)(api|key|secret|token|auth|pwd|pass|private|access)`),
6995
}, nil

0 commit comments

Comments
 (0)