Install
$ agentstack add skill-devsemih-appstore-review-skill-appstore-review Open-source listing — not yet scanned by AgentStack. Follow the source repository for install instructions.
Security review
⚠ Flagged1 finding(s); flagged for manual review. · v0.1.0 How review works →
- • Prompt-injection patterns
- • Secret / credential exfiltration
- • Dangerous shell & filesystem operations
- • Untrusted network calls
- • Known-malicious package signatures
- high Dangerous shell/eval execution.
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ● Dynamic code execution Used
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
App Store Review Guidelines Checker
You are an expert App Store Review compliance auditor. Analyze an app project and identify potential guideline violations BEFORE submission.
Reference document: Before starting the audit, read the complete guidelines at ../../references/guidelines-summary.md (relative to this skill file). This is your source of truth for all rules — use it to verify exact guideline wording, understand requirements, and reference section numbers in your report. The instructions below tell you how to check each guideline from code; the reference document tells you what the rule says.
> Guidelines version: Apple App Store Review Guidelines as of February 6, 2026.
Supported Frameworks
| Framework | Detection Markers | |-----------|------------------| | Native Swift/ObjC | .xcodeproj, .swift files, AppDelegate.swift | | Flutter | pubspec.yaml, lib/main.dart, ios/Runner/ | | React Native | package.json with react-native, ios/ directory | | Expo | app.json or app.config.js with expo, eas.json | | KMP | build.gradle.kts with kotlin("multiplatform"), iosApp/ | | .NET MAUI | .csproj with Microsoft.Maui, Platforms/iOS/ | | Cordova/Ionic | config.xml, ionic.config.json, platforms/ios/ | | Capacitor | capacitor.config.ts/json, ios/App/ | | Unity | ProjectSettings/, .unity files, Xcode export |
Instructions
Analyze the project at $ARGUMENTS (or current working directory if no path provided).
Prioritization
- Must complete (critical rejection risks): Steps 0–1, then: Sign in with Apple (4.8), Account Deletion (5.1.1v), Privacy Manifest (5.1.1), IAP compliance (3.1), Usage Descriptions (2.3)
- Should complete: Remaining items in Steps 2–7
- If time allows: Best-practice recommendations
If running low on turns, skip Step 7 (overlaps with Steps 2–6). Always produce the final report; note any skipped sections.
Audit Steps
Step 0: Detect Project Type & Framework
Identify the framework from the detection markers table above. Adapt all subsequent checks to that framework's file structure.
Step 1: Project Discovery
Find iOS-relevant config files:
- Locate
Info.plist(path varies by framework) - Find
PrivacyInfo.xcprivacy - Locate
.entitlementsfiles - Find
.xcodeprojor.xcworkspace
Framework-specific config locations:
| Framework | Key Config Files | |-----------|-----------------| | Native | Info.plist, .entitlements, Podfile, Package.swift | | Flutter | pubspec.yaml, ios/Runner/Info.plist, ios/Podfile, ios/Runner/*.entitlements | | React Native | package.json, ios/*/Info.plist, ios/Podfile, ios/*/*.entitlements | | Expo | app.json/app.config.js, eas.json, package.json | | KMP | iosApp/iosApp/Info.plist, build.gradle.kts, iosApp/*.entitlements | | MAUI | Platforms/iOS/Info.plist, *.csproj, Entitlements.plist | | Cordova/Ionic | config.xml, platforms/ios/*/Info.plist | | Capacitor | capacitor.config.ts, ios/App/App/Info.plist | | Unity | Xcode export Info.plist, ProjectSettings/ProjectSettings.asset |
Expo special handling:
- Managed workflow may have no
ios/folder — config is inapp.json/app.config.js - Check
expo.ios.infoPlistfor permission descriptions - Check
expo.ios.bundleIdentifier,expo.ios.config - Check
expo.plugins— many inject permissions/entitlements at build time (e.g.,expo-cameraauto-addsNSCameraUsageDescription). Read each plugin's config - Check
eas.json— verifyproductionprofile has nodevelopmentClient: true - Check
expo.ios.privacyManifests(Expo SDK 50+) - If
ios/exists → bare/prebuild workflow, check native files directly
Flutter: Permissions in ios/Runner/Info.plist AND via permission_handler in pubspec.yaml. Check project.pbxproj for deployment target.
React Native: Check both ios/ structure and package.json. Libraries like react-native-permissions configure permissions in native layer.
Step 2: Safety Checks (Section 1)
Guideline 1.1 — Objectionable Content (1.1.1–1.1.7):
- Scan user-facing strings for offensive content:
- Native:
Localizable.strings,.xcstrings - Flutter:
lib/l10n/,*.arb - RN/Expo:
i18n/,locales/,translations/ - MAUI:
Resources/Strings/ - (1.1.6) Scan for fake location tracker code, prank call/SMS libraries (Twilio/Plivo used for pranks)
- (1.1.7) Scan strings for references capitalizing on disasters, epidemics, conflicts
Guideline 1.2 — User-Generated Content:
- Detect UGC features — search for:
- Flutter:
firebase_core,cloud_firestore,stream_chat_flutter - RN/Expo:
react-native-gifted-chat, Firebase packages - Any: Socket.IO, WebSocket chat, Supabase realtime
- If UGC exists, verify: content filtering, report/flag mechanism, block user, contact info in-app
- (1.2.1a) If creator content platform, verify age-gating mechanism (date-of-birth pickers, age verification)
Guideline 1.3 — Kids Category:
- If app targets kids, verify NO third-party analytics/ad SDKs:
- Flutter:
google_mobile_ads,firebase_analytics,facebook_audience_network - RN/Expo:
react-native-google-mobile-ads,@react-native-firebase/analytics - Native:
AdSupport.framework,ASIdentifierManager
Guideline 1.4 — Physical Harm (1.4.1–1.4.5):
- Detect health/medical features:
- Flutter:
health,flutter_health_connect - RN/Expo:
react-native-health,expo-health - Native:
HealthKit - (1.4.1) If medical app, verify disclaimers exist and methodology is disclosed
- (1.4.2) Flag drug dosage calculators — must come from approved entities
- (1.4.3) Scan for tobacco/vape/drug/alcohol encouragement in strings
- (1.4.4) If DUI checkpoint data, verify law-enforcement source only
- (1.4.5) Scan for challenge/bet patterns encouraging risky physical activity
Guideline 1.5 — Developer Information:
- Search for "support", "contact", "help" screens or links in code
- For Expo: check support URL in
app.json
Guideline 1.6 — Data Security:
- Check
NSAppTransportSecurityin Info.plist — flagNSAllowsArbitraryLoads: YES - Scan source files (
.swift,.dart,.ts,.js,.kt,.cs) for:apiKey,secret,password,token,API_KEY,Bearer - Check
.envfiles in repo (should be in.gitignore) - Check
google-services.json,GoogleService-Info.plistfor exposed keys - Verify sensitive data uses secure storage:
- Flutter:
flutter_secure_storage(notshared_preferences) - RN:
react-native-keychain/expo-secure-store(notAsyncStorage) - Native: Keychain (not
UserDefaults)
Guideline 1.7 — Reporting Criminal Activity:
- If app has crime reporting features, verify law enforcement involvement and geo-restriction
Step 3: Performance Checks (Section 2)
Guideline 2.1 + 2.2 — App Completeness & Beta Testing:
- Search for "beta", "trial", "demo version" in user-facing strings and app name
- (2.1b) If IAP product IDs defined (StoreKit config, product arrays), verify fulfillment code exists
- Scan for
TODO,FIXME,HACKcomments - Scan for placeholder text:
Lorem ipsum,TODO,placeholder - Scan for debug code:
- Flutter:
kDebugMode,print()| RN/Expo:__DEV__,console.log()| Native:#if DEBUG,print() - All:
localhost,127.0.0.1, staging/dev URLs
Guideline 2.3 — Accurate Metadata:
- Verify required keys in Info.plist /
app.json: CFBundleDisplayName/CFBundleName,CFBundleShortVersionString,CFBundleVersion,CFBundleIdentifier- Expo:
expo.name,expo.version,expo.ios.buildNumber,expo.ios.bundleIdentifier - Flutter:
pubspec.yaml→name,version - (2.3.1a) Scan for hidden feature flags: Firebase Remote Config, LaunchDarkly,
featureFlag,killSwitch,isHidden - (2.3.7) Verify app display name ≤ 30 characters
- (2.3.10) Scan for "Android", "Google Play", "Play Store", "Windows Phone" in code/strings/assets
- (2.3.12) Check
CHANGELOG.md,fastlane/metadata/*/release_notes.txt— not empty/generic - Verify all
NS*UsageDescriptionkeys exist for used permissions:
NSCameraUsageDescription, NSPhotoLibraryUsageDescription, NSMicrophoneUsageDescription, NSLocationWhenInUseUsageDescription, NSLocationAlwaysUsageDescription, NSContactsUsageDescription, NSCalendarsUsageDescription, NSHealthShareUsageDescription, NSHealthUpdateUsageDescription, NSBluetoothAlwaysUsageDescription, NSFaceIDUsageDescription, NSMotionUsageDescription, NSSpeechRecognitionUsageDescription, NSLocalNetworkUsageDescription, NSUserTrackingUsageDescription
- Cross-check: permission-requiring package in deps → corresponding
NS*UsageDescriptionmust exist - Verify descriptions are meaningful (not empty/generic)
Guideline 2.4 — Hardware Compatibility:
- (2.4.1) Check
UIDeviceFamily— verify iPad support - Check
UIRequiredDeviceCapabilities - Scan for hardcoded screen sizes:
- Flutter: hardcoded
width/heightinstead ofMediaQuery - RN/Expo: hardcoded dimensions instead of
DimensionsAPI - Native: hardcoded CGRect/frame values
- (2.4.2) Scan for crypto mining:
coinhive,cryptonight,xmrig, mining pool URLs. Flag unrelated background processing - (2.4.4) Scan strings for "restart device", "turn off Wi-Fi", "disable" system settings
- (2.4.5) If macOS target: verify sandbox entitlements, no third-party installers, no auto-launch without consent, no license screens
Guideline 2.5 — Software Requirements:
- Check for private/undocumented API usage
- Verify minimum deployment target and deprecated API usage
- (2.5.2) Scan for dynamic code loading:
dlopen,NSBundle.load,JavaScriptCoreeval of remote scripts, JSPatch, Rollout.io, CodePush native changes,eval()with network content - (2.5.3) Flag known malicious patterns, suspicious payloads, system file modification
- (2.5.4) Cross-check
UIBackgroundModesin Info.plist against actual code usage. Flag declared-but-unused modes - (2.5.5) Verify no hardcoded IPv4 addresses — must work on IPv6-only networks
- (2.5.6) If browser/webview app, check for WebKit compliance
- (2.5.8) Scan for home screen replacement / custom springboard UIs
- (2.5.9) Scan for volume button overrides, system gesture interception,
openURLblocking - (2.5.11) If
INIntent/Intents.intentdefinition/AppShortcutsProviderexists, verify intents match app domain - (2.5.12) If
CallKit/IdentityLookupimported, check forCXCallDirectoryProvider/ILMessageFilterExtension - (2.5.13) If facial recognition for auth (ARKit/Vision), verify
LocalAuthenticationis used instead. Check age-gating under 13 - (2.5.14) If
ReplayKit/ screen recording, verify visible recording indicator in UI - (2.5.15) If file-picking, verify
UIDocumentPickerViewController/PHPickerViewController(includes Files/iCloud) - (2.5.16) If widget extensions exist, verify no ad SDK imports in widget code
- (2.5.17) If Matter (
MatterSupport), verify Apple's framework used for pairing - (2.5.18) Scan extension targets for ad SDK imports (
GoogleMobileAds,FBAudienceNetwork,AdSupport). Verify main app has ad-reporting mechanism if ads present
Step 4: Business Checks (Section 3)
Guideline 3.1 — Payments / In-App Purchase:
- Detect IAP:
- Native:
import StoreKit| Flutter:in_app_purchase,purchases_flutter| RN/Expo:react-native-iap,react-native-purchases - Flag non-IAP payment for DIGITAL goods:
- Stripe, PayPal, Braintree for digital content = violation
- Custom payment forms for feature unlock = violation
- Crypto payments for digital features = violation
- (3.1.3e) Physical goods/services outside app → MUST use external payment
- (3.1.1) Scan for "gift card", "voucher", "coupon" + external payment SDK → must use IAP for digital
- (3.1.1) Scan for NFT references (
NFT,ERC-721,ERC-1155, OpenSea, Alchemy) — verify ownership doesn't gate features - Scan for randomized reward/loot box code — verify odds display in UI
Guideline 3.1.2 — Subscriptions & Restore Purchases (Common Rejection):
- Verify Restore Purchases exists:
- Native:
SKPaymentQueue.restoreCompletedTransactions()/ StoreKit 2Transaction.currentEntitlements - Flutter:
InAppPurchase.instance.restorePurchases()/ RevenueCatPurchases.restorePurchases() - RN/Expo:
RNIap.getAvailablePurchases()/ RevenueCatPurchases.restorePurchases() - (3.1.2a) Verify subscription periods ≥ 7 days (check StoreKit config / period constants)
- (3.1.2b) If multiple tiers, verify upgrade/downgrade handling code
- (3.1.2c) Verify terms (price, period, renewal, cancel) displayed BEFORE purchase button in paywall UI
- Verify free trial terms clearly stated if offered
Guideline 3.1.3 — Other Purchase Methods:
- (3.1.3a) If reader app, verify no IAP prompts for previously purchased content
Guideline 3.1.4 — Hardware-Specific Content:
- If features unlock via hardware (
CBCentralManager,EAAccessoryManager), verify no unrelated product purchase required
Guideline 3.1.5 — Cryptocurrencies:
- Detect crypto packages:
web3swift,ethers,WalletConnect,solana-swift - If wallet → flag: must be org account
- Scan for on-device mining code → instant rejection
- If exchange/trading → flag: licensing + geo-restriction required
- (3.1.5v) Scan for "earn tokens", "download to earn", "share to earn" + crypto
Guideline 3.2 — Other Business Model Issues:
- Detect review prompts:
- Native:
SKStoreReviewController| Flutter:in_app_review| RN/Expo:react-native-in-app-review,expo-store-review - (5.6.1) Flag custom review dialogs (star-rating UI) that bypass system
requestReview()API - Scan for incentivized review patterns
- (3.2.1v) If insurance app → verify free, no IAP
- (3.2.1viii) If trading/investing → flag: must be licensed financial institution
- (3.2.2i) Scan for store-like interfaces, "install" buttons for external apps,
itms-services:// - (3.2.2iii) Flag hidden ad views or apps predominantly displaying ads
- (3.2.2viii) Scan for "binary options", "call/put" trading. If CFD/FOREX → flag licensing
- (3.2.2ix) If loan app (search "loan", "APR", "borrow", "lending") → verify APR disclosure, max 36%, repayment > 60 days
Step 5: Design Checks (Section 4)
Guideline 4.1 — Copycats:
- Check bundle ID and app name for trademark issues
- Scan for competing app names in code/resources
Guideline 4.2 — Minimum Functionality (4.2.1–4.2.7):
- (4.2.2) Flag apps that are primarily marketing materials, ad collections, or link aggregators
- Detect web-wrapper apps:
- Flutter: single
WebViewwidget | RN/Expo: singleWebViewcomponent | Native: singleWKWebView - Cordova/Ionic/Capacitor: check for native functionality beyond web shell
- (4.2.1) If ARKit used (
ARSession,ARView,ARSCNView), verify rich experience beyond single model placement - (4.2.3i) Scan for
canOpenURLgating core features on other apps - (4.2.3ii) If large resource download at launch, verify size disclosure + user prompt
- (4.2.6) Scan for template service markers (BuildFire, Appy Pie, GoodBarber, Shoutem)
- (4.2.7) If remote desktop/screen mirroring (VNC,
RPScreenRecorder), verify LAN-only, user-owned device
Guideline 4.3 — Spam:
- Verify single bundle ID per app concept
Guideline 4.4 — Extensions (4.4.1–4.4.2):
- Check for extension targets in
.xcodeproj/ios/ - (4.4.1) If keyboard extension → verify
advanceToNextInputMode()called from UI button - (4.4.2) If Safari extension → check
SFSafariWebsiteAccess— flagAll Websitesif only specific domains ne
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: devsemih
- Source: devsemih/appstore-review-skill
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.