{"id":13387663,"url":"https://github.com/securing/iossecuritysuite","last_synced_at":"2025-05-14T18:05:22.147Z","repository":{"id":38416995,"uuid":"184268041","full_name":"securing/IOSSecuritySuite","owner":"securing","description":"iOS platform security \u0026 anti-tampering Swift library","archived":false,"fork":false,"pushed_at":"2024-08-18T20:07:13.000Z","size":483,"stargazers_count":2476,"open_issues_count":9,"forks_count":298,"subscribers_count":71,"default_branch":"master","last_synced_at":"2025-05-14T18:05:16.142Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.securing.biz/","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/securing.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-30T13:34:01.000Z","updated_at":"2025-05-13T10:07:14.000Z","dependencies_parsed_at":"2023-02-19T08:45:30.765Z","dependency_job_id":"1d76b4c5-ccd6-4126-a187-a0f06a64726e","html_url":"https://github.com/securing/IOSSecuritySuite","commit_stats":{"total_commits":151,"total_committers":20,"mean_commits":7.55,"dds":0.4635761589403974,"last_synced_commit":"4426f54b0ae442fff530955de257d4fa5f80b295"},"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/securing%2FIOSSecuritySuite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/securing%2FIOSSecuritySuite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/securing%2FIOSSecuritySuite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/securing%2FIOSSecuritySuite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/securing","download_url":"https://codeload.github.com/securing/IOSSecuritySuite/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254198514,"owners_count":22030965,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T12:01:26.364Z","updated_at":"2025-05-14T18:05:17.132Z","avatar_url":"https://github.com/securing.png","language":"Swift","funding_links":[],"categories":["\u003ca id=\"58cd9084afafd3cd293564c1d615dd7f\"\u003e\u003c/a\u003e工具"],"sub_categories":["\u003ca id=\"d0108e91e6863289f89084ff09df39d0\"\u003e\u003c/a\u003e新添加的"],"readme":"## ⭐️ Do you want to become a certified iOS Application Security Engineer? ⭐️\n\nCheck out our practical \u0026 fully online course at: [https://courses.securing.pl/courses/iase](https://courses.securing.pl/courses/iase?utm_source=githubiosss\u0026utm_medium=githubiosss\u0026utm_campaign=githubiosss\u0026utm_id=githubiosss)\n\n![iASE logo](./iase_bg.png)\n\n\n## ISS Description\n\n![ISS logo](./logo.png)\n### by [@_r3ggi](https://twitter.com/_r3ggi)\n\n🌏 iOS Security Suite is an advanced and easy-to-use platform security \u0026 anti-tampering library written in pure Swift! If you are developing for iOS and you want to protect your app according to the OWASP [MASVS](https://github.com/OWASP/owasp-masvs) standard, chapter v8, then this library could save you a lot of time. 🚀\n\nWhat ISS detects:\n\n* Jailbreak (even the iOS 11+ with brand new indicators! 🔥)\n* Attached debugger 👨🏻‍🚀\n* If an app was run in an emulator 👽\n* Common reverse engineering tools running on the device 🔭\n\n## Setup\nThere are 4 ways you can start using IOSSecuritySuite\n\n### 1. Add source\nAdd `IOSSecuritySuite/*.swift` files to your project\n\n### 2. Setup with CocoaPods\n`pod 'IOSSecuritySuite'`\n\n### 3. Setup with Carthage\n`github \"securing/IOSSecuritySuite\"`\n\n### 4. Setup with Swift Package Manager\n```swift\n.package(url: \"https://github.com/securing/IOSSecuritySuite.git\", from: \"1.5.0\")\n```\n\n### Update Info.plist\nAfter adding ISS to your project, you will also need to update your main Info.plist. There is a check in jailbreak detection module that uses ```canOpenURL(_:)``` method and [requires](https://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl) specifying URLs that will be queried.\n\n```xml\n\u003ckey\u003eLSApplicationQueriesSchemes\u003c/key\u003e\n\u003carray\u003e\n    \u003cstring\u003eundecimus\u003c/string\u003e\n    \u003cstring\u003esileo\u003c/string\u003e\n    \u003cstring\u003ezbra\u003c/string\u003e\n    \u003cstring\u003efilza\u003c/string\u003e\n\u003c/array\u003e\n```\n\n### Pricing\n\nCheck our EULA license for the details.\n\nTLDR:\nIf your company employs:\n* 0-99 people - **free to use**\n* 100-1000 - 3k EUR/year\n* 1000+ - 10k EUR/year\n\nIf you want to sell a module that uses the iOS Security Suite (it is not used directly in your app) - 10k EUR/year\n\n### Notice\n\niOS Security Suite is meant to be used on iOS/iPadOS. It should not be used on Macs with Apple Silicon.\n\n## How to use\n\n### Jailbreak detector module\n\n* **The simplest method** returns True/False if you just want to know if the device is jailbroken or jailed\n\n```Swift\nif IOSSecuritySuite.amIJailbroken() {\n\tprint(\"This device is jailbroken\")\n} else {\n\tprint(\"This device is not jailbroken\")\n}\n```\n\n* **Verbose**, if you also want to know what indicators were identified\n\n```Swift\nlet jailbreakStatus = IOSSecuritySuite.amIJailbrokenWithFailMessage()\nif jailbreakStatus.jailbroken {\n\tprint(\"This device is jailbroken\")\n\tprint(\"Because: \\(jailbreakStatus.failMessage)\")\n} else {\n\tprint(\"This device is not jailbroken\")\n}\n```\nThe failMessage is a String containing comma-separated indicators as shown on the example below:\n`sileo:// URL scheme detected, Suspicious file exists: /Library/MobileSubstrate/MobileSubstrate.dylib, Fork was able to create a new process`\n\n* **Verbose \u0026 filterable**, if you also want to for example identify devices that were jailbroken in the past, but now are jailed\n\n```Swift\nlet jailbreakStatus = IOSSecuritySuite.amIJailbrokenWithFailedChecks()\nif jailbreakStatus.jailbroken {\n   if (jailbreakStatus.failedChecks.contains { $0.check == .existenceOfSuspiciousFiles }) \u0026\u0026 (jailbreakStatus.failedChecks.contains { $0.check == .suspiciousFilesCanBeOpened }) {\n         print(\"This is real jailbroken device\")\n   }\n}\n```\n\n### Debugger detector module\n```Swift\nlet amIDebugged: Bool = IOSSecuritySuite.amIDebugged()\n```\n\n### Deny debugger at all\n```Swift\nIOSSecuritySuite.denyDebugger()\n```\n\n### Emulator detector module\n```Swift\nlet runInEmulator: Bool = IOSSecuritySuite.amIRunInEmulator()\n```\n\n### Reverse engineering tools detector module\n\n* **The simplest method** returns True/False if you just want to know if the device has evidence of reverse engineering\n\n```Swift\nif IOSSecuritySuite.amIReverseEngineered() {\n  print(\"This device has evidence of reverse engineering\")\n} else {\n  print(\"This device hasn't evidence of reverse engineering\")\n}\n```\n\n* **Verbose \u0026 filterable**, if you also want the list of checks done\n\n```Swift\nlet reverseStatus = IOSSecuritySuite.amIReverseEngineeredWithFailedChecks()\nif reverseStatus.reverseEngineered {\n   // check for reverseStatus.failedChecks for more details\n}\n```\n\n### System proxy detector module\n\nNow you can also detect if an app is connected to VPN\n```Swift\nlet amIProxied: Bool = IOSSecuritySuite.amIProxied(considerVPNConnectionAsProxy: true)\n```\n\n### Lockdown mode detector module\n```Swift\nlet amIInLockdownMode: Bool = IOSSecuritySuite.amIInLockdownMode()\n```\n\n## Experimental features\n\n### Runtime hook detector module\n```Swift\nlet amIRuntimeHooked: Bool = amIRuntimeHook(dyldWhiteList: dylds, detectionClass: SomeClass.self, selector: #selector(SomeClass.someFunction), isClassMethod: false)\n```\n### Symbol hook deny module\n```Swift\n// If we want to deny symbol hook of Swift function, we have to pass mangled name of that function\ndenySymbolHook(\"$s10Foundation5NSLogyySS_s7CVarArg_pdtF\")   // denying hooking for the NSLog function\nNSLog(\"Hello Symbol Hook\")\n     \ndenySymbolHook(\"abort\") \nabort()\n```\n\n### MSHook detector module\n```Swift\n// Function declaration\nfunc someFunction(takes: Int) -\u003e Bool {\n\treturn false\n} \n\n// Defining FunctionType : @convention(thin) indicates a “thin” function reference, which uses the Swift calling convention with no special “self” or “context” parameters.\ntypealias FunctionType = @convention(thin) (Int) -\u003e (Bool)\n\n// Getting pointer address of function we want to verify\nfunc getSwiftFunctionAddr(_ function: @escaping FunctionType) -\u003e UnsafeMutableRawPointer {\n\treturn unsafeBitCast(function, to: UnsafeMutableRawPointer.self)\n}\n\nlet funcAddr = getSwiftFunctionAddr(someFunction)\nlet amIMSHooked = IOSSecuritySuite.amIMSHooked(funcAddr)\n```\n\n### MSHook deny module\n```Swift\n// Function declaration\nfunc denyDebugger(value: Int) {\n}\n\n// Defining FunctionType : @convention(thin) indicates a “thin” function reference, which uses the Swift calling convention with no special “self” or “context” parameters.\ntypealias FunctionType = @convention(thin) (Int)-\u003e()\n\n// Getting original function address\nlet funcDenyDebugger: FunctionType = denyDebugger \nlet funcAddr = unsafeBitCast(funcDenyDebugger, to: UnsafeMutableRawPointer.self)\n\n\nif let originalDenyDebugger = denyMSHook(funcAddr) {\n// Call the original function with 1337 as Int argument\n     unsafeBitCast(originalDenyDebugger, to: FunctionType.self)(1337)\n } else {\n     denyDebugger()\n }\n```\n\n### File integrity verifier module\n\n```Swift\n// Determine if application has been tampered with \nif IOSSecuritySuite.amITampered([.bundleID(\"biz.securing.FrameworkClientApp\"),\n    .mobileProvision(\"2976c70b56e9ae1e2c8e8b231bf6b0cff12bbbd0a593f21846d9a004dd181be3\"),\n    .machO(\"IOSSecuritySuite\", \"6d8d460b9a4ee6c0f378e30f137cebaf2ce12bf31a2eef3729c36889158aa7fc\")]).result {\n    print(\"I have been Tampered.\")\n}\nelse {\n    print(\"I have not been Tampered.\")\n}\n\n// Manually verify SHA256 hash value of a loaded dylib\nif let hashValue = IOSSecuritySuite.getMachOFileHashValue(.custom(\"IOSSecuritySuite\")), hashValue == \"6d8d460b9a4ee6c0f378e30f137cebaf2ce12bf31a2eef3729c36889158aa7fc\" {\n    print(\"I have not been Tampered.\")\n}\nelse {\n    print(\"I have been Tampered.\")\n}\n \n// Check SHA256 hash value of the main executable\n// Tip: Your application may retrieve this value from the server\nif let hashValue = IOSSecuritySuite.getMachOFileHashValue(.default), hashValue == \"your-application-executable-hash-value\" {\n    print(\"I have not been Tampered.\")\n}\nelse {\n    print(\"I have been Tampered.\")\n}\n```\n\n### Breakpoint detection module\n\n```Swift\nfunc denyDebugger() {\n    // Set breakpoint here\n}\n     \ntypealias FunctionType = @convention(thin) ()-\u003e()\nlet func_denyDebugger: FunctionType = denyDebugger   // `: FunctionType` is a must\nlet func_addr = unsafeBitCast(func_denyDebugger, to: UnsafeMutableRawPointer.self)\nlet hasBreakpoint = IOSSecuritySuite.hasBreakpointAt(func_addr, functionSize: nil)\n\nif hasBreakpoint {\n    print(\"Breakpoint found in the specified function\")\n} else {\n    print(\"Breakpoint not found in the specified function\")\n}\n```\n\n### Watchpoint detection module\n\n```Swift\n// Set a breakpoint at the testWatchpoint function\nfunc testWatchpoint() -\u003e Bool{\n\t\t// lldb: watchpoint set expression ptr\n    var ptr = malloc(9)\n    // lldb: watchpoint set variable count\n    var count = 3\n    return IOSSecuritySuite.hasWatchpoint()\n}\n```\n\n\n\n## Security considerations\n\nBefore using this and other platform security checkers, you have to understand that:\n\n* Including this tool in your project is not the only thing you should do in order to improve your app security! You can read a general mobile security whitepaper [here](https://www.securing.biz/en/mobile-application-security-best-practices/index.html).\n* Detecting if a device is jailbroken is done locally on the device. It means that every jailbreak detector may be bypassed (even this)! \n* Swift code is considered to be harder to manipulate dynamically than Objective-C. Since this library was written in pure Swift, the IOSSecuritySuite methods shouldn't be exposed to Objective-C runtime (which makes it more difficult to bypass ✅). You have to know that attacker is still able to MSHookFunction/MSFindSymbol Swift symbols and dynamically change Swift code execution flow.\n\n## Contribution ❤️\nYes, please! If you have a better idea or you just want to improve this project, please text me on [Twitter](https://twitter.com/_r3ggi) or [Linkedin](https://www.linkedin.com/in/wojciech-regula/). Pull requests are more than welcome!\n\n### Special thanks: 👏🏻\n\n* [kubajakowski](https://github.com/kubajakowski) for pointing out the problem with ```canOpenURL(_:)``` method\n* [olbartek](https://github.com/olbartek) for code review and pull request \n* [benbahrenburg](https://github.com/benbahrenburg) for various ISS improvements\n* [fotiDim](https://github.com/fotiDim) for adding new file paths to check\n* [gcharita](https://github.com/gcharita) for adding the Swift Package Manager support\n* [rynaardb](https://github.com/rynaardb) for creating the `amIJailbrokenWithFailedChecks()` method\n* [undeaDD](https://github.com/undeaDD) for various ISS improvements\n* [fnxpt](https://github.com/fnxpt) for adding multiple JB detections\n* [TannerJin](https://github.com/TannerJin) for MSHook, RuntimeHook, SymbolHook and Watchpoint Detection modules\n* [NikoXu](https://github.com/NikoXu) for adding file integrity module\n* [hellpf](https://github.com/hellpf) for fixing a dangling socket problem\n* [Ant-tree](https://github.com/Ant-tree) for improving hooking resistence\n* [izmcm](https://github.com/izmcm) for implementing the `amIReverseEngineeredWithFailedChecks()` method\n* [sanu](https://github.com/sanu) for new providing new file checks\n* [marsepu](https://github.com/marsepu) for a well-done PR with new improvements\n* [mkj-is](https://github.com/mkj-is) for a PR improving ISS performance 🚄\n* [LongXiangGuo](https://github.com/LongXiangGuo) for a PR adding the privacy manifest\n\n\n## TODO\n\n* [ ] Research Installer5 and Zebra Package Manager detection ( Cydia Alternatives )\n\n## License\nSee the LICENSE file.\n\n## References\nWhile creating this tool I used:\n\n* 🔗 https://github.com/TheSwiftyCoder/JailBreak-Detection\n* 🔗 https://github.com/abhinashjain/jailbreakdetection \n* 🔗 https://gist.github.com/ddrccw/8412847\n* 🔗 https://gist.github.com/bugaevc/4307eaf045e4b4264d8e395b5878a63b\n* 📚 \"iOS Application Security\" by David Thiel\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsecuring%2Fiossecuritysuite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsecuring%2Fiossecuritysuite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsecuring%2Fiossecuritysuite/lists"}