{"id":24756712,"url":"https://github.com/futurragroup/securitykit","last_synced_at":"2026-03-04T11:05:24.232Z","repository":{"id":273770083,"uuid":"920282455","full_name":"FuturraGroup/SecurityKit","owner":"FuturraGroup","description":"SecurityKit is a lightweight, easy-to-use Swift library that helps protect iOS apps according to the OWASP MASVS standard, chapter v8, providing an advanced security and anti-tampering layer.","archived":false,"fork":false,"pushed_at":"2025-03-13T16:33:20.000Z","size":67,"stargazers_count":19,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-02-25T21:48:59.775Z","etag":null,"topics":["cydia","encryption-decryption","jailbreak","jailbreaking","obfuscation","owasp","reverse-engineering","security","swift","vpn"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FuturraGroup.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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,"zenodo":null}},"created_at":"2025-01-21T21:54:23.000Z","updated_at":"2026-01-12T18:31:07.000Z","dependencies_parsed_at":"2025-07-15T13:54:54.582Z","dependency_job_id":null,"html_url":"https://github.com/FuturraGroup/SecurityKit","commit_stats":null,"previous_names":["futurragroup/securitykit"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/FuturraGroup/SecurityKit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FuturraGroup%2FSecurityKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FuturraGroup%2FSecurityKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FuturraGroup%2FSecurityKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FuturraGroup%2FSecurityKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FuturraGroup","download_url":"https://codeload.github.com/FuturraGroup/SecurityKit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FuturraGroup%2FSecurityKit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30078466,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T08:01:56.766Z","status":"ssl_error","status_checked_at":"2026-03-04T08:00:42.919Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["cydia","encryption-decryption","jailbreak","jailbreaking","obfuscation","owasp","reverse-engineering","security","swift","vpn"],"created_at":"2025-01-28T14:20:07.180Z","updated_at":"2026-03-04T11:05:24.221Z","avatar_url":"https://github.com/FuturraGroup.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SecurityKit\n\u003cp align=\"center\"\u003e\n\u003cimg width=\"300\" alt=\"Icon copy\" src=\"https://github.com/user-attachments/assets/9d00b349-8254-42ab-bb0c-30640218eb2a\" /\u003e\n\u003c/p\u003e\n\n## Overview\nSecurityKit is a lightweight, easy-to-use Swift library that helps protect iOS apps according to the OWASP MASVS standard, chapter v8, providing an advanced security and anti-tampering layer.\n\n## Installation\n\nSecurityKit is available with Swift Package Manager.\n\nThe [Swift Package Manager](https://swift.org/package-manager/) is a tool for automating the distribution of Swift code and is integrated into the `swift` compiler. \n\nOnce you have your Swift package set up, adding SecurityKit as a dependency is as easy as adding it to the `dependencies` value of your `Package.swift`.\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/FuturraGroup/SecurityKit.git\", .branch(\"main\"))\n]\n```\n\n## Usage\n\n### Update Info.plist\nFor jailbreak detection to work correctly, you need to update your main Info.plist.\n```xml\n\u003ckey\u003eLSApplicationQueriesSchemes\u003c/key\u003e\n\u003carray\u003e\n    \u003cstring\u003ecydia\u003c/string\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### Jailbreak detection\n* This type method is used to detect the true/false jailbreak status\n```swift\nif SecurityKit.isJailBroken() {\n    print(\"This device is jailbroken\")\n} else {\n    print(\"This device is not jailbroken\")\n}\n```\n* This type method is used to detect the jailbreak status with a message which jailbreak indicator was detected\n```swift\nlet jailbreakStatus = SecurityKit.isJailBrokenWithErrorMessage()\nif jailbreakStatus.jailbroken {\n    print(\"This device is jailbroken\")\n    print(\"Because: \\(jailbreakStatus.errorMessage)\")\n} else {\n    print(\"This device is not jailbroken\")\n}\n```\n* This type method is used to detect the jailbreak status with a list of failed detects\n```swift\nlet jailbreakStatus = SecurityKit.isJailBrokenWithErrorDetects()\nif jailbreakStatus.jailbroken {\n    print(\"This device is jailbroken\")\n    print(\"The following checks failed: \\(jailbreakStatus.errorDetects)\")\n}\n```\n### XOR String obfuscation\n```swift\n// String Encryption\nlet encrypt = SecurityKit.stringEncryption(plainText: \"plainText\", encryptionKey: \"key\")\n\n// String Decryption\nlet decrypt = SecurityKit.stringDecryption(cypherText: encrypt, decryptionKey: \"key\")\n```\n### AES-GCM encryption\n* AES-256-GCM authenticated encryption via CryptoKit (iOS 13+). Provides both confidentiality and integrity.\n```swift\nlet secret = \"sensitive data\".data(using: .utf8)!\n\n// Encrypt\nif let encrypted = SecurityKit.aesEncrypt(data: secret, key: \"myPassphrase\") {\n    print(\"Encrypted: \\(encrypted.base64EncodedString())\")\n\n    // Decrypt\n    if let decrypted = SecurityKit.aesDecrypt(data: encrypted, key: \"myPassphrase\") {\n        let string = String(data: decrypted, encoding: .utf8)\n        print(\"Decrypted: \\(string ?? \"\")\")\n    }\n}\n```\n### View Protection\n* Protecting a specific UIView from being screenshotted\n```swift\nViewProtection.shared.makeProtection(for: self.view)\n```\n* Remove protection from UIView\n```swift\nViewProtection.shared.removeScreenProtection(for: self.view)\n```\n### Screen recording protection\n* Screen recording protection, the screen will be completely blurred\n```swift\nBlurScreen.shared.start()\n```\n* Stop screen recording protection\n```swift\nBlurScreen.shared.stop()\n```\n### Simulator detection\n* This type method is used to detect if application is run in simulator\n```swift\nif SecurityKit.isSimulator() {\n    print(\"app is running on the simulator\")\n} else {\n    print(\"app is not running on the simulator\")\n}\n```\n### Reverse engineering tools detection\n* This type method is used to detect if there are any popular reverse engineering tools installed on the device\n```swift\nif SecurityKit.isReverseEngineered() {\n    print(\"This device has reverse engineering tools\")\n} else {\n    print(\"This device does not have reverse engineering tools\")\n}\n```\n* This type method is used to detect the reverse engineered status with a list of failed detects\n```swift\nlet reStatus = SecurityKit.isReverseEngineeredWithErrorDetect()\nif reStatus.reverseEngineered {\n    print(\"SecurityKit: This device has evidence of reverse engineering\")\n    print(\"SecurityKit: The following detects failed: \\(reStatus.errorDetect)\")\n}\n```\n### Debugger detection\n* This type method is used to detect if application is being debugged\n```swift\nlet isDebugged: Bool = SecurityKit.isDebugged()\n```\n* This type method is used to deny debugger and improve the application resillency\n```swift\nSecurityKit.denyDebugger()\n```\n* This method is used to detect if application was launched by something other than LaunchD (i.e. the app was launched by a debugger)\n```swift\nlet isNotLaunchD: Bool = SecurityKit.isParentPidUnexpected()\n```\n* This type method is used to detect if there are any breakpoints at the function\n```swift\nfunc denyDebugger() {\n    // add a breakpoint at here to test\n}\n\ntypealias FunctionType = @convention(thin) ()-\u003e()\n\nlet func_denyDebugger: FunctionType = denyDebugger   // `: FunctionType` is a must\nlet func_addr = unsafeBitCast(func_denyDebugger, to: UnsafeMutableRawPointer.self)\nlet hasBreakpoint: Bool = SecurityKit.hasBreakpointAt(func_addr, functionSize: nil)\n```\n* This type method is used to detect if a watchpoint is being used.\nA watchpoint is a type of breakpoint that 'watches' an area of memory associated with a data item.\n```swift\n// Set a breakpoint at the testWatchpoint function\nfunc testWatchpoint() -\u003e Bool{\n    // lldb: watchpoint set expression ptr\n    var ptr = malloc(9)\n    // lldb: watchpoint set variable count\n    var count = 3\n    return SecurityKit.hasWatchpoint()\n}\n```\n* This type method is used to detect if a debugger has registered exception ports on the current task\n```swift\nlet hasExceptionPort: Bool = SecurityKit.isExceptionPortSet()\n```\n### Integrity detection\n* This type method is used to detect if application has been tampered with\n```swift\nif SecurityKit.isTampered(\n    [.bundleID(\"com.app.bundle\"),\n     .mobileProvision(\"your-mobile-provision-sha256-value\")]\n).result {\n    print(\"SecurityKit: I have been Tampered.\")\n} else {\n    print(\"SecurityKit: I have not been Tampered.\")\n}\n```\n* This type method is used to get the SHA256 hash value of the executable file in a specified image\n```swift\n// Manually verify SHA256 hash value of a loaded dylib\nif let hashValue = SecurityKit.getMachOFileHashValue(.custom(\"SecurityKit\")),\n   hashValue == \"6d8d460b9a4ee6c0f378e30f137cebaf2ce12bf31a2eef3729c36889158aa7fc\" {\n    print(\"SecurityKit: I have not been Tampered.\")\n} else {\n    print(\"SecurityKit: I have been Tampered.\")\n}\n```\n* This type method is used to find all loaded dylibs in the specified image\n```swift\nif let loadedDylib = SecurityKit.findLoadedDylibs() {\n    print(\"SecurityKit: Loaded dylibs: \\(loadedDylib)\")\n}\n```\n### Code signature detection\n* This type method is used to detect if the app's code signature directory has been modified or removed\n```swift\nif SecurityKit.isCodeSignatureModified() {\n    print(\"Code signature has been tampered with\")\n}\n```\n* This type method is used to detect if the app is running as a development build\n```swift\nif SecurityKit.isDevelopmentBuild() {\n    print(\"This is a development build\")\n}\n```\n* This type method is used to verify the team identifier from the embedded provisioning profile\n```swift\nif SecurityKit.verifyTeamIdentifier(\"ABCDEF1234\") {\n    print(\"Team identifier is valid\")\n} else {\n    print(\"Team identifier mismatch — app may have been re-signed\")\n}\n```\n### MSHookFunction detection\n* This type method is used to detect if `function_address` has been hooked by `MSHook`\n```swift\nfunc denyDebugger() { ... }\n\ntypealias FunctionType = @convention(thin) ()-\u003e()\n\nlet func_denyDebugger: FunctionType = denyDebugger // `: FunctionType` is must\nlet func_addr = unsafeBitCast(func_denyDebugger, to: UnsafeMutableRawPointer.self)\nlet isMSHooked: Bool = SecurityKit.isMSHooked(func_addr)\n```\n* This type method is used to get original `function_address` which has been hooked by `MSHook`\n```swift\nfunc denyDebugger(value: Int) { ... }\n\ntypealias FunctionType = @convention(thin) (Int)-\u003e()\n\nlet funcDenyDebugger: FunctionType = denyDebugger\nlet funcAddr = unsafeBitCast(funcDenyDebugger, to: UnsafeMutableRawPointer.self)\n\nif let originalDenyDebugger = SecurityKit.denyMSHook(funcAddr) {\n    // Call orignal function with 1337 as Int argument\n    unsafeBitCast(originalDenyDebugger, to: FunctionType.self)(1337)\n} else {\n    denyDebugger()\n}\n```\n### FishHook detection\n* This type method is used to rebind `symbol` which has been hooked by `fishhook`\n```swift\nSecurityKit.denySymbolHook(\"$s10Foundation5NSLogyySS_s7CVarArg_pdtF\") // Foudation's NSlog of Swift\nNSLog(\"Hello Symbol Hook\")\n\nSecurityKit.denySymbolHook(\"abort\")\nabort()\n```\n* This type method is used to rebind `symbol` which has been hooked at one of image by `fishhook`\n```swift\nfor i in 0..\u003c_dyld_image_count() {\n    if let imageName = _dyld_get_image_name(i) {\n        let name = String(cString: imageName)\n        if name.contains(\"SecurityKit\"), let image = _dyld_get_image_header(i) {\n            SecurityKit.denySymbolHook(\"dlsym\", at: image, imageSlide: _dyld_get_image_vmaddr_slide(i))\n            break\n        }\n    }\n}\n```\n### RuntimeHook detection\n* This type method is used to detect if `objc call` has been RuntimeHooked by for example `Flex`\n```swift\nclass SomeClass {\n    @objc dynamic func someFunction() { ... }\n}\n\nlet dylds = [\"SecurityKit\", ...]\n\nlet isRuntimeHook: Bool = SecurityKit.isRuntimeHook(\n    dyldAllowList: dylds,\n    detectionClass: SomeClass.self,\n    selector: #selector(SomeClass.someFunction),\n    isClassMethod: false\n)\n```\n### System proxy and VPN detection\n* This type method is used to detect if HTTP proxy or VPN was set in the iOS Settings.\n```swift\nlet isProxied: Bool = SecurityKit.isProxied()\n```\n### Lockdown mode detection\n* This type method is used to detect if the device has lockdown mode turned on.\n```swift\nlet isLockdownModeEnable: Bool = SecurityKit.isLockdownModeEnable()\n```\n### Environment variables detection\n* This type method is used to detect suspicious environment variables commonly used for code injection (e.g. `DYLD_INSERT_LIBRARIES`, `SUBSTRATE_INSERT_LIBRARIES`)\n```swift\nif SecurityKit.hasSuspiciousEnvironment() {\n    print(\"Suspicious environment variables detected\")\n}\n```\n### Network security detection\n* This type method is used to detect if SSL Kill Switch or similar SSL unpinning tools are loaded\n```swift\nif SecurityKit.isSSLKillSwitchLoaded() {\n    print(\"SSL Kill Switch detected — network traffic may be intercepted\")\n}\n```\n* This type method is used to detect if App Transport Security (ATS) is disabled in Info.plist\n```swift\nif SecurityKit.isATSDisabled() {\n    print(\"ATS is disabled — insecure HTTP connections are allowed\")\n}\n```\n### Device fingerprint\n* This type method generates a unique, stable SHA256 device fingerprint based on vendor ID, Keychain-persisted UUID, and hardware model\n```swift\nlet fingerprint: String = SecurityKit.getDeviceFingerprint()\nprint(\"Device fingerprint: \\(fingerprint)\")\n```\n### Secure Storage\n* A Keychain wrapper for securely storing sensitive data with configurable accessibility levels\n```swift\nlet storage = SecureStorage()\n\n// Save a string\nstorage.save(\"secret-token\", for: \"auth_token\")\n\n// Load a string\nif let token = storage.loadString(for: \"auth_token\") {\n    print(\"Token: \\(token)\")\n}\n\n// Save raw data\nlet data = \"sensitive\".data(using: .utf8)!\nstorage.save(data, for: \"secret_data\")\n\n// Load raw data\nif let loaded = storage.loadData(for: \"secret_data\") {\n    print(\"Data: \\(loaded)\")\n}\n\n// Check existence\nlet exists: Bool = storage.exists(key: \"auth_token\")\n\n// Delete a single item\nstorage.delete(key: \"auth_token\")\n\n// Delete all items for this service\nstorage.deleteAll()\n```\n* Custom access levels for different security requirements\n```swift\n// Most secure — requires passcode, bound to this device\nlet secure = SecureStorage(accessLevel: .whenPasscodeSetThisDeviceOnly)\n\n// Available after first unlock, even when locked (for background tasks)\nlet background = SecureStorage(accessLevel: .afterFirstUnlockThisDeviceOnly)\n\n// Custom service identifier\nlet custom = SecureStorage(service: \"com.myapp.credentials\", accessLevel: .whenUnlockedThisDeviceOnly)\n```\n### Memory Protection\n* Securely wipe sensitive data from memory to prevent forensic recovery\n```swift\nvar secretData = \"password123\".data(using: .utf8)!\nMemoryProtection.wipe(\u0026secretData)\n// secretData is now empty\n\nvar secretBytes: [UInt8] = [0x41, 0x42, 0x43]\nMemoryProtection.wipe(\u0026secretBytes)\n// secretBytes is now empty\n\nvar secretString = \"my-api-key\"\nMemoryProtection.wipe(\u0026secretString)\n// secretString is now \"\"\n```\n### Clipboard Protection\n* Clear the clipboard immediately or after a delay to prevent sensitive data leakage\n```swift\n// Clear clipboard immediately\nClipboardProtection.shared.clearClipboard()\n\n// Clear clipboard after 30 seconds (default)\nClipboardProtection.shared.clearAfterDelay()\n\n// Clear clipboard after custom delay\nClipboardProtection.shared.clearAfterDelay(10)\n\n// Check if clipboard has content\nlet hasContent: Bool = ClipboardProtection.shared.hasContent()\n\n// Cancel pending auto-clear\nClipboardProtection.shared.stopAutoClear()\n```\n## Contribute\n\nContributions for improvements are welcomed. Feel free to submit a pull request to help grow the library. If you have any questions, feature suggestions, or bug reports, please send them to [Issues](https://github.com/FuturraGroup/SecurityKit/issues).\n\n## License\n\n```\nMIT License\n\nCopyright (c) 2025 Futurra Group\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffuturragroup%2Fsecuritykit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffuturragroup%2Fsecuritykit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffuturragroup%2Fsecuritykit/lists"}