mobilepkg

package module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 1, 2026 License: MIT Imports: 19 Imported by: 0

README

mobilepkg

MultiPlatformUnitTest Coverage Build reviewdog Go Reference

logo

mobilepkg inspects APK, AAB, APKS, XAPK, and IPA files and emits package metadata plus security findings as JSON, Markdown, or RDJSONL. It is intended for release triage and CI checks.

It reads the package as a zip archive, parses the manifest and DEX bytecode in-process, and finishes in seconds. No Android SDK, Xcode, or device required. Runs on Linux, Windows, and macOS (Go 1.25+).

Scope

  • Manifest metadata, signing info, permissions, exported components, deep links, and network endpoints from Android packages (APK, XAPK, APKS, AAB).
  • DEX bytecode scanning across base and split APKs for hardcoded secrets, cleartext HTTP URLs, dangerous API calls, and insecure WebView configuration.
  • XAPK and APKS bundles read directly — no prior extraction needed.
  • Markdown reports for $GITHUB_STEP_SUMMARY and pull request comments.
  • Baseline diff for tracking permission, component, and version changes between releases.
  • CI integration: --fail-on warn exits non-zero when findings exceed a severity threshold.
Known limitations and common false positives
  • On well-maintained production apps, mobilepkg typically reports allow_backup, a few exported components, and some dangerous API calls from third-party libraries. Library-originated API calls (e.g. crash reporters using Runtime.exec) are automatically downgraded to warn/medium.
  • Cleartext URL findings from DEX strings may include legitimate logging or configuration endpoints that happen to use HTTP.
  • iOS IPA inspection covers entitlements, ATS settings, code signing certificates, provisioning profile expiry, URL schemes, and associated domains. It does not scan compiled Swift/ObjC binaries for API calls or secrets. Android inspection is deeper.
  • WebView argument tracking is lightweight: it checks the immediately preceding const/4 or const/16 instruction. Non-trivial argument flow (e.g. values loaded from fields or computed) falls back to conservative reporting.
Format Platform Description
APK Android Standard Android package
XAPK Android APKPure extended package
APKS Android Bundletool APK set
AAB Android Android App Bundle
IPA iOS Standard iOS package

Install

go install github.com/nao1215/mobilepkg/cmd/mobilepkg@latest  # CLI
go get github.com/nao1215/mobilepkg                            # library

CLI

inspect — Inspect a mobile package
$ mobilepkg inspect app.apk                                # JSON output (default)
$ mobilepkg inspect --format markdown app.apk              # Markdown summary
$ mobilepkg inspect --format markdown app.xapk             # XAPK works the same way
$ mobilepkg inspect --fail-on warn app.apk                 # CI: exit 1 if severity >= warn
$ mobilepkg inspect --baseline prev.json app.apk           # diff against previous result
Markdown output

The --format markdown output leads with the most actionable information — top findings and severity counts — before expanding into component and endpoint details. It is designed for $GITHUB_STEP_SUMMARY, pull request comments, and manual review.

Example: vulnerable app (AndroGoat)

On an intentionally vulnerable app like AndroGoat, the report surfaces debug builds, hardcoded AWS keys, command injection via Runtime.exec, and unguarded exported components:

## Top Findings
> [!WARNING]
> 10 finding(s) at warning severity or above.

| ID | Severity | Confidence | Message |
|----|----------|------------|---------|
| dex.api.java.lang.Runtime.exec... | error | high | Runtime.exec() called — potential command injection risk |
| dex.secret.aws_key... | error | high | potential aws_key found in DEX string table |
| manifest.debuggable | error | high | application is debuggable |
| signing.debug_cert | error | high | signed with debug certificate |
| dex.cleartext... | warn | medium | cleartext HTTP URL found in DEX strings: demo.testfire.net |
| manifest.allow_backup | warn | high | application allows backup |
| exported.provider... | warn | high | exported provider: ...ContentProviderActivity |
Example: normal app (F-Droid)

On a well-maintained production app like F-Droid, findings are less severe. Library-originated API calls are flagged at reduced severity. The deep link and endpoint sections show the app's registered URI handlers:

## Top Findings
> [!WARNING]
> 6 finding(s) at warning severity or above.

| ID | Severity | Confidence | Message |
|----|----------|------------|---------|
| dex.api...Runtime.exec...compat.FileCompat | error | high | Runtime.exec() called (in app code) |
| dex.api...Runtime.exec...acra... | warn | medium | Runtime.exec() called (in library) |
| dex.cleartext.logback.qos.ch | warn | medium | cleartext HTTP URL found in DEX strings |
| manifest.allow_backup | warn | high | application allows backup |

## Network Endpoints
| Endpoint | Source | Confidence |
|----------|--------|------------|
| f-droid.org | intent_filter | high |
| play.google.com | intent_filter | high |
| market://details | intent_filter | high |
JSON output

The default JSON output is a ReportFile with schema_version, tool_version, and result:

Example JSON (AndroGoat)
{
  "schema_version": "1.0.0",
  "tool_version": "0.1.0",
  "result": {
    "platform": "android",
    "format": "apk",
    "identity": {
      "identifier": "owasp.sat.agoat",
      "display_name": "AndroGoat - Insecure App (Kotlin)"
    },
    "version": { "marketing": "1.0", "build": "1" },
    "debuggable": true,
    "allow_backup": true,
    "permissions": [
      { "canonical": "camera",  "raw_name": "android.permission.CAMERA",  "source": "manifest" },
      { "canonical": "network", "raw_name": "android.permission.INTERNET", "source": "manifest" }
    ],
    "exported_components": [
      { "kind": "provider", "name": "owasp.sat.agoat.ContentProviderActivity", "exported": true },
      { "kind": "receiver", "name": "owasp.sat.agoat.ShowDataReceiver",       "exported": true }
    ],
    "signing": {
      "scheme": "v1+v2",
      "certificates": [{ "subject": "Android Debug", "issuer": "Android Debug" }]
    },
    "findings": [
      { "severity": "error", "id": "manifest.debuggable",  "message": "application is debuggable" },
      { "severity": "error", "id": "signing.debug_cert",    "message": "signed with debug certificate" },
      { "severity": "warn",  "id": "manifest.allow_backup", "message": "application allows backup" }
    ],
    "secret_candidates": [],
    "diagnostics": []
  }
}
Baseline diff and CI

Save a report and use it as the baseline for the next run. The --baseline flag accepts a report.json file produced by a previous inspect run:

# Save today's result
mobilepkg inspect app.apk > baseline.json

# Compare against baseline in CI
mobilepkg inspect --baseline baseline.json --fail-on warn app.apk

When --fail-on is specified, the output includes a verdict field with passed, reasons, and triggering_findings, and the command exits with code 1 if the policy is violated.

compare — Compare two packages
$ mobilepkg compare old.apk new.apk

Shows identity, version, and entry point changes, plus added/removed permissions, exported components, and network endpoints.

Library

InspectFile — One call, full result
result, err := mobilepkg.InspectFile(ctx, "app.apk")
if err != nil {
    log.Fatal(err)
}

fmt.Println(result.Identity.Identifier)  // "com.example.app"
fmt.Println(result.Debuggable)           // true

for _, f := range result.Findings {
    fmt.Printf("[%s] %s\n", f.Severity, f.Message)
}
Detection coverage
Category Findings
Manifest debuggable, allowBackup, usesCleartextTraffic, testOnly, profileableByShell
Network security config Base-config cleartext, per-domain cleartext, nested domain-config inheritance, debug-overrides
Signing Debug certificates, expired certificates, v1-only signing, weak digest (MD5/SHA-1), weak key size (RSA<2048, ECDSA<256), self-signed test certificates
Provisioning (iOS) Expired provisioning profile
Components Exported activities/services/receivers/providers with intent-filters and deep links. No-permission components elevated to warn/error. Browsable activities flagged. Provider authorities, readPermission, writePermission, grantUriPermissions extracted.
Permissions Dangerous permissions (CAMERA, SMS, LOCATION, etc.)
iOS ATS NSAllowsArbitraryLoads, insecure exception domains (NSExceptionAllowsInsecureHTTPLoads)
iOS entitlements get-task-allow (debug build), URL schemes, associated domains
Secrets Regex-based scan of manifest/plist metadata and DEX string tables (AWS keys, GCP API keys, GitHub tokens, private keys, bearer tokens, Firebase URLs, generic api_key/secret/credential patterns). Both sources use the same pattern list.
DEX WebView setJavaScriptEnabled(true), addJavascriptInterface, setAllowFileAccess(true), setAllowUniversalAccessFromFileURLs(true), setWebContentsDebuggingEnabled(true), setMixedContentMode, SslErrorHandler.proceed bypass, WebView.loadUrl("http://..."). Boolean argument tracking via preceding const/4/const/16. Library-originated calls reported at reduced severity.
DEX APIs Runtime.exec, ProcessBuilder, DexClassLoader, PathClassLoader, Method.invoke, SmsManager.sendTextMessage, DevicePolicyManager.resetPassword, Cipher.getInstance. Library-originated calls reported at reduced severity.
DEX cleartext http:// URLs in string tables (localhost/schema/spec URLs excluded).
Fail conditions (CI)
verdict := mobilepkg.Check(result, mobilepkg.DefaultFailPolicy())
if !verdict.Passed {
    os.Exit(1)
}
Baseline diff
result, _ := mobilepkg.InspectWithBaseline(ctx, "new.apk", prevResult)
fmt.Println(result.Diff.VersionChanged)
fmt.Println(result.Diff.AddedComponents)
Output formats
rf := mobilepkg.NewReportFile(result, "1.0.0")
mobilepkg.WriteReportJSON(os.Stdout, rf)       // JSON
mobilepkg.WriteSummaryMarkdown(os.Stdout, rf)   // Markdown
mobilepkg.WriteRDJSONL(os.Stdout, result.Findings, "app.apk") // reviewdog

GitHub Actions

- run: mobilepkg inspect --fail-on warn app.apk > report.json
- run: mobilepkg inspect --format markdown app.apk >> "$GITHUB_STEP_SUMMARY"

Test Data

Examples use AndroGoat (v2.0.1), an intentionally vulnerable Android app. The APK is under testdata/no_commit/ for local testing only and is not committed.

mkdir -p testdata/no_commit
curl -L -o testdata/no_commit/AndroGoat.apk \
  https://github.com/satishpatnayak/AndroGoat/releases/download/v2.0.1/AndroGoat.apk

Contributing

See CONTRIBUTING.md.

Sponsorship

Sponsor this project

License

MIT License

Documentation

Overview

Package mobilepkg provides a unified API for inspecting and analyzing Android (APK/XAPK/APKS/AAB) and iOS (IPA) mobile application packages.

It abstracts platform-specific differences so that callers can perform common operational tasks with a single set of API calls:

  • CI quality gates: validate identity, version, and permissions
  • Security inspection: detect debuggable builds, exposed components, dangerous permissions
  • Release diff: compare two packages to detect changes
  • Catalog extraction: collect display name, icon, and platform info

The primary entry point is InspectFile, which performs a complete inspection in a single call — extracting package metadata, running analysis, and returning a unified InspectResult:

result, err := mobilepkg.InspectFile(ctx, "app.apk")
if err != nil {
    log.Fatal(err)
}
fmt.Println(result.Identity.Identifier) // "com.example.app"
for _, f := range result.Findings {
    fmt.Printf("[%s] %s\n", f.Severity, f.Message)
}

For CI fail conditions, use Check:

verdict := mobilepkg.Check(result, mobilepkg.DefaultFailPolicy())

For release comparison, use Compare:

diff := mobilepkg.Compare(oldResult, newResult)

For custom validation rules, use Validate:

violations := mobilepkg.Validate(result, rules)

For expert use, InspectFileWithOptions accepts archive safety limits.

Index

Examples

Constants

View Source
const SchemaVersion = "1.0.0"

SchemaVersion is the current schema version of the report.json output.

Variables

View Source
var (
	// ErrUnsupportedFormat is returned when the file is not a recognized
	// mobile application package (neither APK nor IPA).
	ErrUnsupportedFormat = errors.New("mobilepkg: unsupported package format")
	// ErrManifestMissing is returned when the primary manifest
	// (AndroidManifest.xml or Info.plist) is not found in the archive.
	ErrManifestMissing = errors.New("mobilepkg: primary manifest not found")
	// ErrManifestCorrupt is returned when the primary manifest exists
	// but cannot be parsed.
	ErrManifestCorrupt = errors.New("mobilepkg: primary manifest could not be parsed")
	// ErrArchiveCorrupt is returned when the archive structure is damaged
	// or unreadable beyond the initial ZIP open.
	ErrArchiveCorrupt = errors.New("mobilepkg: archive is corrupt or unreadable")

	// ErrPathTraversal is returned when a ZIP entry name contains path
	// traversal components such as ".." or begins with an absolute path.
	ErrPathTraversal = errors.New("mobilepkg: path traversal detected")
	// ErrTooManyFiles is returned when the archive contains more entries
	// than the configured [ArchiveLimits.MaxEntryCount].
	ErrTooManyFiles = errors.New("mobilepkg: too many files in archive")
	// ErrOversize is returned when the archive or an individual entry
	// exceeds the configured size limits.
	ErrOversize = errors.New("mobilepkg: archive exceeds size limit")
	// ErrTooDeep is returned when nested archives exceed the configured
	// [ArchiveLimits.MaxNestingDepth].
	ErrTooDeep = errors.New("mobilepkg: archive nesting too deep")
	// ErrCompressionRatioExceeded is returned when a ZIP entry's
	// compression ratio exceeds [ArchiveLimits.MaxCompressionRatio].
	ErrCompressionRatioExceeded = errors.New("mobilepkg: compression ratio exceeded")
	// ErrSymlink is returned when a ZIP entry is a symlink or hardlink
	// and [ArchiveLimits.AllowSymlinks] is false.
	ErrSymlink = errors.New("mobilepkg: symlink or hardlink in archive")
	// ErrInvalidName is returned when a ZIP entry name contains NUL bytes,
	// control characters, or exceeds the configured path length limit.
	ErrInvalidName = errors.New("mobilepkg: invalid entry name")
)

Sentinel errors returned by the public API. Use errors.Is to check for these in wrapped errors.

View Source
var ErrUnknownField = errors.New("mobilepkg: unknown field name")

ErrUnknownField is returned by RequireFields when an unrecognized field name is provided. This fail-closed behavior prevents silent misconfiguration.

Functions

func WriteRDJSONL

func WriteRDJSONL(w io.Writer, findings []Finding, archivePath string) error

WriteRDJSONL writes findings in reviewdog's rdjsonl format to w. Each finding is written as a single JSON line. This output is intended for use with reviewdog's github-check reporter.

The archivePath parameter is used as the file path in the rdjsonl output since findings reference archive-internal paths rather than repository file paths.

func WriteReportJSON

func WriteReportJSON(w io.Writer, rf ReportFile) error

WriteReportJSON writes the report as pretty-printed JSON to w.

func WriteSummaryMarkdown

func WriteSummaryMarkdown(w io.Writer, rf ReportFile) error

WriteSummaryMarkdown writes a human-readable Markdown summary of the inspection result to w. The layout leads with the most actionable information — top findings and new risks — before metrics tables.

If the result includes a baseline diff (ar.Diff != nil), the summary highlights changes compared to the previous report.

Types

type ArchiveLimits

type ArchiveLimits struct {
	// MaxInputBytes is the maximum allowed size of the input file in bytes.
	// Archives larger than this are rejected before parsing.
	MaxInputBytes int64
	// MaxEntryCount is the maximum number of entries allowed in the archive.
	MaxEntryCount int
	// MaxTotalUncompressedBytes is the maximum total uncompressed size
	// of all entries combined.
	MaxTotalUncompressedBytes int64
	// MaxSingleEntryUncompressedBytes is the maximum uncompressed size
	// of any single entry.
	MaxSingleEntryUncompressedBytes int64
	// MaxNestingDepth is the maximum allowed depth for nested archives
	// (e.g. an APK inside an XAPK). Zero means no limit on nesting depth.
	MaxNestingDepth int
	// MaxPathLength is the maximum allowed length (in bytes) for any
	// single entry path within the archive.
	MaxPathLength int
	// MaxCompressionRatio is the maximum allowed ratio of uncompressed
	// to compressed size for any single entry. This guards against
	// compression bombs. Zero means no ratio limit.
	MaxCompressionRatio float64
	// AllowSymlinks controls whether symlink entries in the archive are
	// accepted. When false (the default), symlinks cause a safety error.
	AllowSymlinks bool
}

ArchiveLimits controls safety limits applied when reading ZIP archives. These limits protect against malicious or malformed archives such as zip bombs, path-traversal attacks, and symlink exploits.

A zero value for any numeric field means "no limit" for that check. Use DefaultArchiveLimits to obtain a set of sensible defaults.

func DefaultArchiveLimits

func DefaultArchiveLimits() ArchiveLimits

DefaultArchiveLimits returns an ArchiveLimits with sensible defaults suitable for most use cases.

  • MaxInputBytes: 2 GiB
  • MaxEntryCount: 100,000
  • MaxTotalUncompressedBytes: 4 GiB
  • MaxSingleEntryUncompressedBytes: 512 MiB
  • MaxNestingDepth: 4
  • MaxPathLength: 512
  • MaxCompressionRatio: 100
  • AllowSymlinks: false

type CertSummary

type CertSummary struct {
	// Subject is the certificate subject (typically CN or O).
	Subject string `json:"subject"`
	// Issuer is the certificate issuer.
	Issuer string `json:"issuer"`
	// NotBefore is the certificate validity start in RFC 3339 format.
	NotBefore string `json:"not_before"`
	// NotAfter is the certificate validity end in RFC 3339 format.
	NotAfter string `json:"not_after"`
	// SHA256Fingerprint is the hex-encoded SHA-256 fingerprint of the DER certificate.
	SHA256Fingerprint string `json:"sha256_fingerprint"`
	// SerialNumber is the certificate serial number in decimal.
	SerialNumber string `json:"serial_number"`
	// SignatureAlgorithm is the algorithm used to sign the certificate (e.g. "SHA256-RSA").
	SignatureAlgorithm string `json:"signature_algorithm,omitempty"`
	// PublicKeyAlgorithm is the public key algorithm (e.g. "RSA", "ECDSA").
	PublicKeyAlgorithm string `json:"public_key_algorithm,omitempty"`
	// KeySize is the public key size in bits (e.g. 2048, 4096).
	KeySize int `json:"key_size,omitempty"`
	// SelfSigned is true if the certificate subject matches the issuer.
	SelfSigned bool `json:"self_signed,omitempty"`
}

CertSummary holds a summary of an X.509 certificate used for code signing.

type Confidence

type Confidence string

Confidence represents how certain the analysis is about a Finding.

const (
	// ConfidenceHigh indicates strong certainty in the finding.
	ConfidenceHigh Confidence = "high"
	// ConfidenceMedium indicates moderate certainty in the finding.
	ConfidenceMedium Confidence = "medium"
	// ConfidenceLow indicates weak certainty; the finding may be a false positive.
	ConfidenceLow Confidence = "low"
)

type DataSpec

type DataSpec struct {
	// Scheme is the URI scheme (e.g. "https", "myapp").
	Scheme string `json:"scheme,omitempty"`
	// Host is the hostname or authority.
	Host string `json:"host,omitempty"`
	// Path is the URI path.
	Path string `json:"path,omitempty"`
}

DataSpec holds scheme/host/path from an Android intent-filter <data> element.

type Diagnostic

type Diagnostic struct {
	// Code is a machine-readable identifier (e.g. "icon.not_found", "plist.parse_failed").
	Code string `json:"code"`
	// Severity classifies the importance of the diagnostic.
	Severity Severity `json:"severity"`
	// Message is a human-readable description.
	Message string `json:"message"`
	// Detail carries optional machine-readable metadata associated with
	// the diagnostic (e.g. {"path": "res/icon.png"} for an icon failure).
	// May be nil when no additional detail is available.
	Detail map[string]string `json:"detail,omitempty"`
}

Diagnostic describes a non-fatal issue encountered during inspection.

type Diff

type Diff struct {
	// OldPlatform is the platform of the old report.
	OldPlatform Platform `json:"old_platform"`
	// NewPlatform is the platform of the new report.
	NewPlatform Platform `json:"new_platform"`
	// IdentityChanged is true when the identity fields differ.
	IdentityChanged bool `json:"identity_changed"`
	// VersionChanged is true when the version fields differ.
	VersionChanged bool `json:"version_changed"`
	// EntryChanged is true when the entry point fields differ.
	EntryChanged bool `json:"entry_changed"`
	// AddedPermissions lists permissions present in the new report but not the old.
	AddedPermissions []Permission `json:"added_permissions,omitempty"`
	// RemovedPermissions lists permissions present in the old report but not the new.
	RemovedPermissions []Permission `json:"removed_permissions,omitempty"`
	// AddedComponents lists exported components present in the new report but not the old.
	AddedComponents []ExportedComponent `json:"added_components,omitempty"`
	// RemovedComponents lists exported components present in the old report but not the new.
	RemovedComponents []ExportedComponent `json:"removed_components,omitempty"`
	// AddedEndpoints lists network endpoints present in the new report but not the old.
	AddedEndpoints []NetworkEndpoint `json:"added_endpoints,omitempty"`
	// RemovedEndpoints lists network endpoints present in the old report but not the new.
	RemovedEndpoints []NetworkEndpoint `json:"removed_endpoints,omitempty"`
}

Diff represents the structured differences between two report values.

func Compare

func Compare(oldIR, newIR *InspectResult) Diff

Compare compares two InspectResult values and returns a Diff describing what changed between them.

This is useful for release-diff scenarios where a release manager wants to detect added/removed permissions, version bumps, exported component changes, or new network endpoints between two builds.

Example

ExampleCompare demonstrates comparing two inspect results.

package main

import (
	"fmt"

	"github.com/nao1215/mobilepkg"
)

func main() {
	oldResult := &mobilepkg.InspectResult{
		Platform: mobilepkg.PlatformAndroid,
		Identity: mobilepkg.Identity{
			Identifier:  "com.example.app",
			DisplayName: "My App",
		},
		Version: mobilepkg.Version{
			Marketing: "1.0.0",
			Build:     "1",
		},
	}
	newResult := &mobilepkg.InspectResult{
		Platform: mobilepkg.PlatformAndroid,
		Identity: mobilepkg.Identity{
			Identifier:  "com.example.app",
			DisplayName: "My App",
		},
		Version: mobilepkg.Version{
			Marketing: "2.0.0",
			Build:     "5",
		},
	}

	diff := mobilepkg.Compare(oldResult, newResult)
	fmt.Println("Identity changed:", diff.IdentityChanged)
	fmt.Println("Version changed:", diff.VersionChanged)
}
Output:
Identity changed: false
Version changed: true
Example (Permissions)

ExampleCompare_permissions demonstrates detecting permission changes.

package main

import (
	"fmt"

	"github.com/nao1215/mobilepkg"
)

func main() {
	oldResult := &mobilepkg.InspectResult{
		Permissions: []mobilepkg.Permission{
			{Canonical: "camera", RawName: "android.permission.CAMERA", Source: "manifest"},
			{Canonical: "network", RawName: "android.permission.INTERNET", Source: "manifest"},
		},
	}
	newResult := &mobilepkg.InspectResult{
		Permissions: []mobilepkg.Permission{
			{Canonical: "camera", RawName: "android.permission.CAMERA", Source: "manifest"},
			{Canonical: "location", RawName: "android.permission.ACCESS_FINE_LOCATION", Source: "manifest"},
		},
	}

	diff := mobilepkg.Compare(oldResult, newResult)
	for _, p := range diff.AddedPermissions {
		fmt.Printf("+ %s (%s)\n", p.Canonical, p.RawName)
	}
	for _, p := range diff.RemovedPermissions {
		fmt.Printf("- %s (%s)\n", p.Canonical, p.RawName)
	}
}
Output:
+ location (android.permission.ACCESS_FINE_LOCATION)
- network (android.permission.INTERNET)

type DomainConfig

type DomainConfig struct {
	// Domains lists the domains this config applies to.
	Domains []string `json:"domains"`
	// CleartextPermitted indicates whether cleartext traffic is allowed
	// for these domains.
	CleartextPermitted bool `json:"cleartext_permitted"`
	// HasPinSet is true if this domain config includes certificate pinning.
	HasPinSet bool `json:"has_pin_set"`
	// NestedConfigs holds nested domain-config entries within this domain-config.
	NestedConfigs []DomainConfig `json:"nested_configs,omitempty"`
}

DomainConfig represents a <domain-config> entry in network_security_config.xml.

type EntryPoint

type EntryPoint struct {
	// Kind classifies the entry point ("activity", "executable", or "unknown").
	Kind string `json:"kind"`
	// Name is the fully qualified name of the entry point.
	Name string `json:"name"`
}

EntryPoint describes the main entry point of the application.

type Evidence

type Evidence struct {
	// ArchivePath is the path of the file inside the archive where the
	// evidence was found (e.g. "AndroidManifest.xml").
	ArchivePath string `json:"archive_path"`
	// Field identifies a logical field or key within the file
	// (e.g. "android:permission", "NSCameraUsageDescription").
	Field string `json:"field,omitempty"`
	// MatchedTextMasked is the matched value with sensitive parts masked.
	MatchedTextMasked string `json:"matched_text_masked,omitempty"`
	// Line is the line number within the file where the evidence was found.
	// Zero means the line is unknown or not applicable.
	Line int `json:"line,omitempty"`
	// Offset is the byte offset within the file where the evidence was found.
	// Zero means the offset is unknown or not applicable.
	Offset int `json:"offset,omitempty"`
}

Evidence represents a piece of supporting evidence for a Finding. It locates the relevant data within the analyzed archive.

type ExportedComponent

type ExportedComponent struct {
	// Kind is the component type: "activity", "service", "receiver", or "provider".
	Kind string `json:"kind"`
	// Name is the fully qualified component name.
	Name string `json:"name"`
	// Exported indicates whether the component is exported.
	Exported bool `json:"exported"`
	// Permission is the permission required to access this component, if any.
	Permission string `json:"permission,omitempty"`
	// Authorities holds the content provider authorities (provider only).
	Authorities string `json:"authorities,omitempty"`
	// IntentFilters holds parsed intent-filter data for the component.
	IntentFilters []IntentFilter `json:"intent_filters,omitempty"`
	// ReadPermission is the permission required to read from this provider.
	ReadPermission string `json:"read_permission,omitempty"`
	// WritePermission is the permission required to write to this provider.
	WritePermission string `json:"write_permission,omitempty"`
	// GrantURIPermissions indicates if URI permissions can be granted.
	GrantURIPermissions bool `json:"grant_uri_permissions,omitempty"`
}

ExportedComponent represents an application component that is accessible to other applications on the device. On Android this includes activities, services, broadcast receivers, and content providers that are explicitly or implicitly exported.

type FailPolicy

type FailPolicy struct {
	// FailOnSeverity fails if any finding has severity >= this value.
	// Empty string means severity is not checked.
	FailOnSeverity Severity `json:"fail_on_severity,omitempty"`
	// FailOnConfidence fails if any finding has confidence >= this value.
	// Empty string means confidence is not checked.
	FailOnConfidence Confidence `json:"fail_on_confidence,omitempty"`
	// NewOnly restricts fail checks to new findings only. When true and
	// a baseline is provided to [EvaluateFailConditions], only findings
	// not present in the baseline trigger failure. Has no effect when
	// used with [Check] (which has no baseline).
	NewOnly bool `json:"new_only,omitempty"`
}

FailPolicy configures the conditions under which an inspection is considered failed. A finding triggers failure if it meets ANY of the specified thresholds (OR logic). Use Check or EvaluateFailConditions to produce a pass/fail verdict.

func DefaultFailPolicy

func DefaultFailPolicy() FailPolicy

DefaultFailPolicy returns a FailPolicy suitable for CI use:

  • fail_on_severity: warn (fails on warn or error)
  • fail_on_confidence: (empty — not checked)
  • new_only: false

type FailResult

type FailResult struct {
	// Passed is true if no fail conditions were triggered.
	Passed bool `json:"passed"`
	// Reasons lists the reasons for failure, if any.
	Reasons []string `json:"reasons,omitempty"`
	// TriggeringFindings lists the findings that triggered failure.
	TriggeringFindings []Finding `json:"triggering_findings,omitempty"`
}

FailResult holds the outcome of fail condition evaluation.

func Check

func Check(result *InspectResult, policy FailPolicy) FailResult

Check evaluates the inspection result against the given fail policy and returns whether the check passes or fails.

This is the simplified API for CI quality gates. For baseline comparison, use EvaluateFailConditions instead.

func EvaluateFailConditions

func EvaluateFailConditions(ir *InspectResult, policy FailPolicy, baseline *InspectResult) FailResult

EvaluateFailConditions evaluates the inspection result against the given fail policy and returns whether the check passes or fails.

A finding triggers failure if it matches ANY specified threshold:

  • If FailOnSeverity is set and the finding's severity >= threshold, it fails.
  • If FailOnConfidence is set and the finding's confidence >= threshold, it fails.

When policy.NewOnly is true and baseline is non-nil, only findings not present in the baseline are considered.

Example

ExampleEvaluateFailConditions demonstrates CI fail condition evaluation.

package main

import (
	"fmt"

	"github.com/nao1215/mobilepkg"
)

func main() {
	ar := &mobilepkg.InspectResult{
		Findings: []mobilepkg.Finding{
			{
				ID:         "manifest.debuggable",
				Severity:   mobilepkg.SeverityError,
				Confidence: mobilepkg.ConfidenceHigh,
				Message:    "application is debuggable",
			},
		},
	}

	result := mobilepkg.EvaluateFailConditions(ar, mobilepkg.DefaultFailPolicy(), nil)
	fmt.Println("Passed:", result.Passed)
	fmt.Println("Reasons:", len(result.Reasons))
}
Output:
Passed: false
Reasons: 1

type Finding

type Finding struct {
	// ID is a unique, machine-readable identifier for this specific finding
	// instance (e.g. "perm.dangerous.CAMERA", "secret.api_key.1").
	ID string `json:"id"`
	// Category groups related findings (e.g. "permission", "endpoint",
	// "secret", "exported_component", "signing").
	Category string `json:"category"`
	// Severity classifies the importance of the finding.
	Severity Severity `json:"severity"`
	// Confidence indicates how certain the analysis is about this finding.
	Confidence Confidence `json:"confidence"`
	// Message is a human-readable description of the finding.
	Message string `json:"message"`
	// Evidence lists the supporting evidence for this finding.
	Evidence []Evidence `json:"evidence"`
	// Fingerprint is a stable identifier derived from the finding content,
	// used for baseline comparison. Two findings with the same fingerprint
	// across different runs are considered the same finding.
	Fingerprint string `json:"fingerprint"`
}

Finding represents a security-relevant observation found during analysis. Each finding carries enough context for manual review (message, evidence) and for automated baseline comparison (id, fingerprint).

Findings are the primary output of security analysis. They are produced by the internal analysis step and included in [InspectResult.Findings].

func DiffFindings

func DiffFindings(baseline, current []Finding) (added, removed []Finding)

DiffFindings compares two slices of Finding and returns which were added and which were removed. The comparison key is ID + Fingerprint.

type Format

type Format string

Format identifies the specific packaging format of a mobile application. While Platform tells you Android vs iOS, Format distinguishes the concrete archive layout (e.g. APK vs XAPK vs AAB).

const (
	// FormatUnknown indicates an unrecognized format.
	FormatUnknown Format = "unknown"
	// FormatAPK indicates a standard Android APK.
	FormatAPK Format = "apk"
	// FormatIPA indicates an iOS IPA.
	FormatIPA Format = "ipa"
	// FormatXAPK indicates an XAPK (APKPure extended package with
	// manifest.json and one or more inner APKs).
	FormatXAPK Format = "xapk"
	// FormatAPKS indicates an APK Set archive produced by bundletool,
	// containing split APKs under a splits/ directory.
	FormatAPKS Format = "apks"
	// FormatAAB indicates an Android App Bundle whose manifest is
	// encoded in protobuf format.
	FormatAAB Format = "aab"
)

type IconAsset

type IconAsset struct {
	// Path is the archive-internal path of the icon file.
	Path string `json:"path"`
	// Bytes contains the raw icon data.
	// Excluded from JSON serialization to avoid bloating output.
	Bytes []byte `json:"-"`
	// Format describes the image format (e.g. "png", "jpeg").
	Format string `json:"format"`
	// Width is the icon width in pixels (0 if unknown).
	Width int `json:"width"`
	// Height is the icon height in pixels (0 if unknown).
	Height int `json:"height"`
}

IconAsset holds the extracted icon data.

type Identity

type Identity struct {
	// Identifier is the package name (Android) or bundle ID (iOS).
	Identifier string `json:"identifier"`
	// DisplayName is the user-visible application name.
	DisplayName string `json:"display_name"`
}

Identity holds the package identifier and display name.

type InspectError

type InspectError struct {
	// Code is a machine-readable error code such as "manifest.missing",
	// "manifest.corrupt", "archive.corrupt", or "format.unsupported".
	Code string
	// Message is a human-readable description of the error.
	Message string
	// Err is the underlying cause, if any.
	Err error
}

InspectError is a structured error returned by inspection functions. It carries a machine-readable [Code] for programmatic handling and supports errors.Is / errors.As through the wrapped [Err].

func (*InspectError) Error

func (e *InspectError) Error() string

Error implements the error interface.

func (*InspectError) Unwrap

func (e *InspectError) Unwrap() error

Unwrap returns the underlying error for use with errors.Is and errors.As.

type InspectOptions

type InspectOptions struct {
	// Archive controls safety limits for archive processing.
	// Nil means [DefaultArchiveLimits] are used.
	Archive *ArchiveLimits
}

InspectOptions controls what InspectFileWithOptions extracts from a package. All sections are always extracted; the options control archive safety limits. Icons are always extracted at the best available size.

type InspectResult

type InspectResult struct {
	// Platform is the detected platform (android or ios).
	Platform Platform `json:"platform"`
	// Format identifies the specific packaging format (e.g. "apk", "ipa").
	Format Format `json:"format"`
	// Identity holds the package identifier and display name.
	Identity Identity `json:"identity"`
	// Version holds the marketing and build version strings.
	Version Version `json:"version"`
	// Entry holds the main entry point of the application.
	Entry EntryPoint `json:"entry"`
	// SDK holds the SDK and OS version constraints.
	SDK SDKConstraints `json:"sdk"`
	// Signing holds code signing and certificate information.
	// Nil when signing information is not available.
	Signing *SigningInfo `json:"signing,omitempty"`
	// Icon holds the extracted icon asset, if available.
	// Nil when no icon was found in the package.
	Icon *IconAsset `json:"icon,omitempty"`

	// Debuggable indicates whether the application is marked as debuggable.
	Debuggable bool `json:"debuggable"`
	// TestOnly indicates whether the application is marked as testOnly.
	TestOnly bool `json:"test_only"`
	// ProfileableByShell indicates whether the application can be profiled
	// from the shell without root.
	ProfileableByShell bool `json:"profileable_by_shell"`
	// AllowBackup indicates whether the application allows data backup.
	AllowBackup bool `json:"allow_backup"`
	// UsesCleartextTraffic indicates whether the application allows
	// cleartext (unencrypted HTTP) network traffic.
	UsesCleartextTraffic bool `json:"uses_cleartext_traffic"`
	// NetworkSecurityConfig is the resource reference to the network
	// security configuration (Android only, e.g. "@xml/network_security_config").
	// Empty when not declared or for iOS packages.
	NetworkSecurityConfig string `json:"network_security_config,omitempty"`
	// NSCPolicy holds the parsed network security configuration.
	// Nil when no network_security_config.xml is found or for iOS packages.
	NSCPolicy *NetworkSecurityPolicy `json:"nsc_policy,omitempty"`
	// Permissions lists the declared permissions.
	Permissions []Permission `json:"permissions"`
	// ExportedComponents lists components that are exported and accessible
	// to other applications.
	ExportedComponents []ExportedComponent `json:"exported_components"`
	// NetworkEndpoints lists network endpoints found in the package metadata.
	NetworkEndpoints []NetworkEndpoint `json:"network_endpoints"`

	// Findings holds security-relevant observations from analysis.
	Findings []Finding `json:"findings"`
	// SecretCandidates lists potential secrets, tokens, or credentials.
	SecretCandidates []SecretCandidate `json:"secret_candidates"`

	// Diff holds the comparison against a baseline, if provided.
	Diff *Diff `json:"diff,omitempty"`

	// Diagnostics collects non-fatal issues encountered during inspection
	// and analysis.
	Diagnostics []Diagnostic `json:"diagnostics"`
}

InspectResult is the single output of an inspection performed by InspectFile or Inspect. It combines package metadata, security-relevant facts, analysis findings, and diagnostics into one flat structure.

This is the primary result type for the mobilepkg API. It contains everything needed for CI quality gates, security review, and release comparison in a single value.

func Inspect

func Inspect(ctx context.Context, r io.ReaderAt, size int64) (*InspectResult, error)

Inspect performs a complete inspection from an io.ReaderAt. This is useful when the package is already in memory or comes from a non-file source (e.g. an HTTP response body).

The reader must contain a valid APK, XAPK, APKS, AAB, or IPA. It extracts metadata, runs security analysis, and returns a unified InspectResult.

func InspectFile

func InspectFile(ctx context.Context, path string) (*InspectResult, error)

InspectFile performs a complete inspection of the mobile package at the given path. It extracts all available metadata, runs security analysis, and returns a unified InspectResult. No options are needed for the primary path — sensible defaults are applied automatically.

This is the primary entry point for the mobilepkg API. For expert use cases that need to control archive limits or icon size, use InspectFileWithOptions instead.

Example:

result, err := mobilepkg.InspectFile(ctx, "app.apk")
if err != nil {
    log.Fatal(err)
}
fmt.Println(result.Identity.Identifier)
for _, f := range result.Findings {
    fmt.Printf("[%s] %s\n", f.Severity, f.Message)
}
Example

ExampleInspectFile demonstrates the primary inspection path.

package main

import (
	"context"
	"fmt"

	"github.com/nao1215/mobilepkg"
)

func main() {
	// For demonstration, we show the API shape. In real usage, provide
	// a valid APK/IPA path:
	//
	//   result, err := mobilepkg.InspectFile(ctx, "app.apk")
	//   if err != nil {
	//       log.Fatal(err)
	//   }
	//   fmt.Println(result.Identity.Identifier)
	//   for _, f := range result.Findings {
	//       fmt.Printf("[%s] %s\n", f.Severity, f.Message)
	//   }
	_ = context.Background()

	// Construct a result manually for the example output.
	result := &mobilepkg.InspectResult{
		Platform: mobilepkg.PlatformAndroid,
		Format:   mobilepkg.FormatAPK,
		Identity: mobilepkg.Identity{
			Identifier:  "com.example.helloworld",
			DisplayName: "HelloWorld",
		},
		Version: mobilepkg.Version{Marketing: "1.0", Build: "1"},
		Entry:   mobilepkg.EntryPoint{Kind: "activity", Name: "com.example.helloworld.MainActivity"},
	}

	fmt.Println("Platform:", result.Platform)
	fmt.Println("ID:", result.Identity.Identifier)
	fmt.Println("Name:", result.Identity.DisplayName)
	fmt.Println("Version:", result.Version.Marketing)
	fmt.Println("Entry:", result.Entry.Kind, result.Entry.Name)
}
Output:
Platform: android
ID: com.example.helloworld
Name: HelloWorld
Version: 1.0
Entry: activity com.example.helloworld.MainActivity

func InspectFileWithOptions

func InspectFileWithOptions(ctx context.Context, path string, opts InspectOptions) (*InspectResult, error)

InspectFileWithOptions performs a complete inspection of the mobile package at the given path with the specified options. It extracts all available metadata, runs security analysis, and returns a unified InspectResult.

Use this when you need to control archive safety limits. For most callers, InspectFile is sufficient.

func InspectWithBaseline

func InspectWithBaseline(ctx context.Context, path string, baseline *InspectResult) (*InspectResult, error)

InspectWithBaseline performs a complete inspection and compares the result against a previous InspectResult. The baseline diff is included in the returned result.

This is useful for release-diff scenarios where you want to detect added/removed permissions, version bumps, or new security findings between two builds.

type IntentFilter

type IntentFilter struct {
	// Actions lists the intent actions (e.g. "android.intent.action.VIEW").
	Actions []string `json:"actions,omitempty"`
	// Categories lists the intent categories (e.g. "android.intent.category.DEFAULT").
	Categories []string `json:"categories,omitempty"`
	// Data lists the data specifications (scheme, host, path) for the filter.
	Data []DataSpec `json:"data,omitempty"`
}

IntentFilter holds parsed intent-filter data from an Android manifest. Each filter declares what intents the component can respond to.

type NetworkEndpoint

type NetworkEndpoint struct {
	// Scheme is the URL scheme (e.g. "https", "http", "wss").
	Scheme string `json:"scheme,omitempty"`
	// Host is the hostname or IP address.
	Host string `json:"host"`
	// Port is the port number, if specified.
	Port string `json:"port,omitempty"`
	// Path is the URL path, if available.
	Path string `json:"path,omitempty"`
	// Source describes where this endpoint was found
	// (e.g. "manifest", "info_plist", "entitlement").
	Source string `json:"source"`
	// Confidence indicates how certain the detection is.
	Confidence Confidence `json:"confidence"`
}

NetworkEndpoint represents a network endpoint found in the package metadata.

type NetworkSecurityPolicy

type NetworkSecurityPolicy struct {
	// CleartextPermitted indicates whether the base config allows
	// cleartext (HTTP) traffic.
	CleartextPermitted bool `json:"cleartext_permitted"`
	// DomainConfigs lists per-domain security configurations.
	DomainConfigs []DomainConfig `json:"domain_configs,omitempty"`
	// TrustAnchors lists the trust anchor sources (e.g. "system", "user",
	// or a raw certificate reference).
	TrustAnchors []string `json:"trust_anchors,omitempty"`
	// HasPinSet is true if any domain config includes certificate pinning.
	HasPinSet bool `json:"has_pin_set"`
	// HasDebugOverrides is true if debug-overrides section is present.
	HasDebugOverrides bool `json:"has_debug_overrides,omitempty"`
}

NetworkSecurityPolicy holds a partial summary of an Android network_security_config.xml file. It captures the base-config cleartext policy, top-level domain-configs (domains + cleartext + pin-set presence), and base-config trust-anchor sources.

Limitations: nested domain-configs, per-domain trust-anchors, and debug-overrides are not parsed. This provides a useful triage signal but is not a full representation of the config.

type Permission

type Permission struct {
	// Canonical is a cross-platform classification (e.g. "camera", "location").
	// Empty if no mapping is available.
	Canonical string `json:"canonical,omitempty"`
	// RawName is the platform-specific permission identifier
	// (e.g. "android.permission.CAMERA", "NSCameraUsageDescription").
	RawName string `json:"raw_name"`
	// Source indicates where the permission was declared
	// ("manifest", "info_plist", or "entitlement").
	Source string `json:"source"`
}

Permission represents a declared permission in a mobile application package.

type Platform

type Platform string

Platform represents the mobile platform of an application package.

const (
	// PlatformUnknown indicates an unrecognized package format.
	PlatformUnknown Platform = "unknown"
	// PlatformAndroid indicates an Android APK package.
	PlatformAndroid Platform = "android"
	// PlatformIOS indicates an iOS IPA package.
	PlatformIOS Platform = "ios"
)

type ReportFile

type ReportFile struct {
	// SchemaVersion identifies the format version of this report file.
	SchemaVersion string `json:"schema_version"`
	// ToolVersion identifies the version of the tool that produced this report.
	ToolVersion string `json:"tool_version"`
	// Result contains the inspection output (metadata + findings + secrets + diff).
	Result InspectResult `json:"result"`
	// Verdict holds the fail-condition evaluation result, if a policy was
	// applied. Nil when no policy was evaluated.
	Verdict *FailResult `json:"verdict,omitempty"`
}

ReportFile is the top-level structure for the report.json output file. It wraps an InspectResult with metadata required for tooling. Use WriteReportJSON to serialize it.

func LoadReportFile

func LoadReportFile(r io.Reader) (ReportFile, error)

LoadReportFile reads and parses a report.json file from the given reader. It validates that the schema_version matches SchemaVersion; mismatched versions produce a descriptive error so that stale baselines are caught early rather than causing subtle diff inaccuracies.

func NewReportFile

func NewReportFile(ir *InspectResult, toolVersion string) ReportFile

NewReportFile creates a ReportFile from an InspectResult. Nil slices are normalized to empty slices so that JSON output contains [] instead of null.

Example

ExampleNewReportFile demonstrates creating a report.json output.

package main

import (
	"bytes"
	"fmt"
	"log"

	"github.com/nao1215/mobilepkg"
)

func main() {
	ar := &mobilepkg.InspectResult{
		Platform: mobilepkg.PlatformAndroid,
		Format:   mobilepkg.FormatAPK,
		Identity: mobilepkg.Identity{Identifier: "com.example.app"},
	}
	rf := mobilepkg.NewReportFile(ar, "1.0.0")

	var buf bytes.Buffer
	if err := mobilepkg.WriteReportJSON(&buf, rf); err != nil {
		log.Fatal(err)
	}
	fmt.Println("Schema:", rf.SchemaVersion)
	fmt.Println("Tool:", rf.ToolVersion)
}
Output:
Schema: 1.0.0
Tool: 1.0.0

type Rule

type Rule interface {
	Validate(result *InspectResult) []Violation
}

Rule defines an inspection rule that checks an InspectResult for violations. Implementations should be stateless and safe for concurrent use.

func PermissionAllowList

func PermissionAllowList(allowed ...string) Rule

PermissionAllowList returns a Rule that reports a violation for every permission whose [Permission.RawName] is not in the allowed set.

func PermissionDenyList

func PermissionDenyList(denied ...string) Rule

PermissionDenyList returns a Rule that reports a violation for every permission whose [Permission.RawName] is in the denied set.

func RequireFields

func RequireFields(fields ...string) (Rule, error)

RequireFields returns a Rule that checks whether the named fields are populated (non-empty) in the report. Supported field names:

  • "identifier" — Identity.Identifier
  • "display_name" — Identity.DisplayName
  • "version_marketing" — Version.Marketing
  • "version_build" — Version.Build
  • "min_sdk" — SDK.MinSDK
  • "target_sdk" — SDK.TargetSDK
  • "entry_name" — Entry.Name

An error wrapping ErrUnknownField is returned if any field name is not recognized. This fail-closed behavior prevents silent misconfiguration.

func VersionFormat

func VersionFormat(pattern string) Rule

VersionFormat returns a Rule that checks whether the marketing version string matches the given regular expression pattern. An empty marketing version is not checked (use RequireFields for that).

type RuleFunc

type RuleFunc func(*InspectResult) []Violation

RuleFunc is an adapter that allows ordinary functions to be used as [Rule]s.

func (RuleFunc) Validate

func (f RuleFunc) Validate(result *InspectResult) []Violation

Validate implements the Rule interface.

type SDKConstraints

type SDKConstraints struct {
	// MinSDK is the minimum SDK/OS version required.
	// Android: minSdkVersion (e.g. "21"). iOS: MinimumOSVersion (e.g. "15.0").
	MinSDK string `json:"min_sdk,omitempty"`
	// TargetSDK is the target SDK version (Android only).
	// Empty for iOS packages.
	TargetSDK string `json:"target_sdk,omitempty"`
}

SDKConstraints holds the SDK and OS version requirements extracted from the application manifest.

type SecretCandidate

type SecretCandidate struct {
	// Kind classifies the secret type (e.g. "api_key", "token", "aws_key").
	Kind string `json:"kind"`
	// MaskedValue shows a short prefix of the secret with the rest redacted.
	MaskedValue string `json:"masked_value"`
	// Source describes where this candidate was found.
	Source string `json:"source"`
	// Confidence indicates how certain the detection is.
	Confidence Confidence `json:"confidence"`
}

SecretCandidate represents a potential secret, token, or credential found in the package. Raw values are never exposed; only a short masked prefix is provided for human identification.

type Severity

type Severity string

Severity classifies the importance of a Diagnostic.

const (
	// SeverityInfo indicates an informational note.
	SeverityInfo Severity = "info"
	// SeverityWarn indicates a potential problem that did not prevent extraction.
	SeverityWarn Severity = "warn"
	// SeverityError indicates a problem that prevented extraction of some data.
	SeverityError Severity = "error"
)

type SigningInfo

type SigningInfo struct {
	// Scheme describes the signing schemes detected.
	// Android examples: "v1", "v2", "v3", "v1+v2", "v1+v3".
	// iOS: "apple".
	Scheme string `json:"scheme"`
	// Certificates lists the signing certificates found.
	Certificates []CertSummary `json:"certificates,omitempty"`
	// ProvisioningExpiresAt is the provisioning profile expiration date
	// in RFC 3339 format (iOS only). Empty for Android or when unknown.
	ProvisioningExpiresAt string `json:"provisioning_expires_at,omitempty"`
}

SigningInfo holds code signing and certificate information extracted from a mobile application package.

type Version

type Version struct {
	// Marketing is the user-facing version string
	// (Android versionName / iOS CFBundleShortVersionString).
	Marketing string `json:"marketing"`
	// Build is the internal build identifier
	// (Android versionCode / iOS CFBundleVersion).
	Build string `json:"build"`
}

Version holds marketing and build version strings.

type Violation

type Violation struct {
	// RuleID is the machine-readable identifier of the rule that produced
	// this violation (e.g. "required_field", "permission_denied").
	RuleID string `json:"rule_id"`
	// Severity classifies the importance of the violation.
	Severity Severity `json:"severity"`
	// Message is a human-readable description of the violation.
	Message string `json:"message"`
	// Field identifies the report field related to the violation
	// (e.g. "Identity.Identifier", "Permissions[2].RawName").
	Field string `json:"field"`
}

Violation represents a single rule violation found during validation.

func Validate

func Validate(result *InspectResult, rules []Rule) []Violation

Validate applies every rule in rules to the result and collects all resulting violations into a single slice. Rules are evaluated in order.

Directories

Path Synopsis
cmd
mobilepkg command
mobilepkg is a CLI tool for inspecting mobile application packages.
mobilepkg is a CLI tool for inspecting mobile application packages.
internal
cmdinfo
Package cmdinfo provides build metadata for the mobilepkg CLI.
Package cmdinfo provides build metadata for the mobilepkg CLI.
dex
Package dex provides a minimal parser for Android DEX (Dalvik Executable) files.
Package dex provides a minimal parser for Android DEX (Dalvik Executable) files.
platform/android
Package android provides Android-specific APK inspection logic.
Package android provides Android-specific APK inspection logic.
platform/ios
Package ios provides iOS-specific IPA inspection logic.
Package ios provides iOS-specific IPA inspection logic.
scanner
Package scanner provides a security rule engine for analyzing Android application packages using parsed DEX bytecode and manifest data.
Package scanner provides a security rule engine for analyzing Android application packages using parsed DEX bytecode and manifest data.
secrets
Package secrets defines shared secret-detection patterns used by both the manifest/plist scanner (root package) and the DEX string scanner.
Package secrets defines shared secret-detection patterns used by both the manifest/plist scanner (root package) and the DEX string scanner.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL