{
	"id": "22805ed3-139d-443b-b575-79c26dc4c0b6",
	"created_at": "2026-04-06T00:07:37.852738Z",
	"updated_at": "2026-04-10T03:20:51.820243Z",
	"deleted_at": null,
	"sha1_hash": "6ed75a2f7b433056d1e768e8bbd3d53d0be23f82",
	"title": "User Approved Kernel Extension Loading…",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 314282,
	"plain_text": "User Approved Kernel Extension Loading…\r\nPublished: 2017-08-29 · Archived: 2026-04-02 11:37:47 UTC\r\nApple is trying to improve security on the Mac, and starting with macOS High Sierra,\r\nkernel extensions that are installed with or after the installation of macOS High Sierra, will require user consent in\r\norder to load signed kernel extensions. This new feature should also make us more aware about the kernel\r\nextensions that we have installed. Some of which we may no longer need. After all. Not every uninstaller does\r\nwhat it should do.\r\nOk. Let me start with an example:\r\nThis is what I got when I tried to load the Intel kernel extension (with sudo kextload EnergyDriver.kext) from a\r\nterminal window.\r\nPlease note that there is nothing wrong with this extension. It simply wasn’t there, because I did a fresh\r\ninstallation of macOS High Sierra (a Developer Beta) and thus I had to allow it.\r\nAnyway. Let’s have a look at the updated Security and Privacy preference panel, with a new button to allow\r\nblocked kernel extension. Here it is:\r\nhttps://pikeralpha.wordpress.com/2017/08/29/user-approved-kernel-extension-loading/\r\nPage 1 of 10\n\nIt shows you the name of the developer. In this example it’s one from ‘Intel Corporation Apps’. And when you\r\n‘Allow’ a blocked kernel extension, then the entry in the SQL database (KextPolicy) for this developer (per\r\nTeamID) will be updated accordantly.\r\nOk. Everything so far should be clear. Oh. One more thing. This feature is also known as User Approved Kernel\r\nExtension Loading. And any user can approve a kernel extension, even one without administrator privileges. Wait.\r\nWhat? Yup. Read this:\r\nKernel extensions don’t require authorization if they:\r\nWere on the Mac before the upgrade to macOS High Sierra.\r\nAre replacing previously approved extensions.\r\nThis also explains why I had to allow the Intel kernel extension. Because it wasn’t there before, and I had not\r\napproved it already. You may now wonder if we can we disable this new feature. No worries. You can. Here’s\r\nwhat Apple has to say about disabling this feature:\r\nhttps://pikeralpha.wordpress.com/2017/08/29/user-approved-kernel-extension-loading/\r\nPage 2 of 10\n\nIf you want to disable User Approved Kernel Extension Loading, boot into macOS Recovery and use the spctl\r\ncommand. Run the command by itself to get more information about how to use the spctl command.\r\nThat’s it. You’re on your own. There is no detailed information about what you can, should and should not (try to)\r\ndo. Great.\r\nLet’s start with the output of it\r\nApple-iMacPro:~ Apple$ spctl\r\nSystem Policy Basic Usage:\r\n spctl --assess [--type type] [-v] path ... # assessment\r\n spctl --add [--type type] [--path|--requirement|--anchor|--hash] spec ... # add rule(s)\r\n spctl [--enable|--disable|--remove] [--type type] [--path|--requirement|--anchor|--hash|--rule]\r\n spctl --status | --master-enable | --master-disable # system master switch\r\nKernel Extension User Consent Usage:\r\n spctl kext-consent ** Modifications only available in Recovery OS **\r\n status\r\n Print whether kernel extension user consent is enabled or disabled.\r\n enable\r\n Enable requiring user consent for kernel extensions.\r\n disable\r\n Disable requiring user consent for kernel extensions.\r\n add\r\n Insert a new Team Identifier into the list allowed to load kernel extensions without user c\r\n list\r\n Print the list of Team Identifiers allowed to load without user consent.\r\n remove\r\n Remove a Team Identifier from the list allowed to load kernel extensions without user conse\r\nApple-iMacPro:~ Apple$ spctl kext-consent status\r\nKernel Extension User Consent: ENABLED\r\nApple-iMacPro:~ Apple$ spctl kext-consent disable\r\nspctl: failed to store new configuration.\r\nApple-iMacPro:~ Apple$ sudo spctl kext-consent disable\r\nKernel Extension User Consent: DISABLED\r\nPlease restart for changes to take effect.\r\nhttps://pikeralpha.wordpress.com/2017/08/29/user-approved-kernel-extension-loading/\r\nPage 3 of 10\n\nApple-iMacPro:~ Apple$ sudo spctl kext-consent enable\r\nKernel Extension User Consent: ENABLED\r\nPlease restart for changes to take effect.\r\nApple-iMacPro:~ Apple$ spctl kext-consent list\r\nspctl: no kext consent configuration found.\r\nApple-iMacPro:~ Apple$ sudo spctl kext-consent add 0123456789\r\nApple-iMacPro:~ Apple$ spctl kext-consent list\r\nAllowed Team Identifiers:\r\n0123456789\r\nApple-iMacPro:~ Apple$ sudo spctl kext-consent remove 0123456789\r\nApple-iMacPro:~ Apple$ spctl kext-consent list\r\nLocating Your Team ID\r\nThe Team ID is a unique 10+ character string generated by Apple that’s assigned to your team. You can find your\r\nTeam ID using your developer account.\r\nTo locate your Team ID\r\nSign in to developer.apple.com/account and click Membership in the sidebar. Your Team ID appears in the\r\nMembership Information section under the team name.\r\nNVRAM data\r\nThere are two properties that I would like to mention here. The first one being csr-active-config and the second\r\none being csr-data. Let’s first have a look at a snippet from the output of\r\nApple-iMacPro:~ Apple$ nvram -xp\r\n1\r\n2\r\n3\r\n4\r\n5\r\n\u003c key \u003ecsr-active-config\u003c/ key \u003e\r\n\u003c data \u003e\r\ngAIAAA==\r\n\u003c/ data \u003e\r\n\u003c key \u003ecsr-data\u003c/ key \u003e\r\nhttps://pikeralpha.wordpress.com/2017/08/29/user-approved-kernel-extension-loading/\r\nPage 4 of 10\n\n6\r\n7\r\n8\r\n9\r\n\u003c data \u003e\r\nPGRpY3Q+PGtleT5rZXh0LWFsbG93ZWQtdGVhbXM8L2tleT48YXJyYXk+PHN0cmluZz4w\r\nMTIzNDU2Nzg5PC9zdHJpbmc+PC9hcnJheT48L2RpY3Q+AA==\r\n\u003c/ data \u003e\r\nApple-iMacPro:~ Apple$ echo -n gAIAAA==|base64 --decode|xxd -ps\r\n0x80020000 (feature disabled)\r\nApple-iMacPro:~ Apple$ echo -n gAAAAA==|base64 --decode|xxd -ps\r\n0x80000000 (feature enabled)\r\nNote: You can use my csrstat command line tool to check the status of all SIP settings!\r\nThe base64 data of csr-data property is a dictionary with an array of all allowed team identifiers. Here is the one\r\nfrom our example\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n\u003c dict \u003e\r\n\u003c key \u003ekext-allowed-teams\u003c/ key \u003e\r\n\u003c array \u003e\r\n\u003c string \u003e0123456789\u003c/ string \u003e\r\n\u003c/ array \u003e\r\n\u003c/ dict \u003e\r\nAnd the csr-data property will still be there when you removed all team identifiers, but then with an empty array.\r\nLike this.\r\n1\r\n2\r\n3\r\n4\r\n\u003c dict \u003e\r\n\u003c key \u003ekext-allowed-teams\u003c/ key \u003e\r\n\u003c array \u003e\r\n\u003c/ array \u003e\r\nhttps://pikeralpha.wordpress.com/2017/08/29/user-approved-kernel-extension-loading/\r\nPage 5 of 10\n\n5 \u003c/ dict \u003e\r\nReset NVRAM will revert to its default state with User Approved Kernel Extension Loading enabled.\r\nEnrolling in Mobile Device Management (MDM) automatically disables User Approved Kernel Extension\r\nLoading. The behavior for loading kernel extensions will be the same as macOS Sierra.\r\nA future update to macOS High Sierra will allow you to use MDM to enable or disable User Approved Kernel\r\nExtension Loading, and to manage the list of kernel extensions which are allowed to load without user consent. If\r\nthat is before or after the official release of macOS High Sierra is not known.\r\nBut you know what. All extensions in the prelinkedkernel are stripped. There is no data of the signature. Apple\r\n(still) relies on tools to check the kexts signature, before inclusion in the prelinkedkernel, and somehow, that\r\ndoesn’t feel right.\r\nUpdate: The configuration is stored in: /var/db/SystemPolicyConfiguration/KextPolicy. I also found the SQL\r\nstatements that spctl and systempolicyd are using to initialise and update the database:\r\nDROP TABLE IF EXISTS kext_load_history\r\nDROP TABLE IF EXISTS kext_load_history_v2\r\nDROP TABLE IF EXISTS policy_by_team\r\nDROP TABLE IF EXISTS policy_by_team_v2\r\nDROP TABLE IF EXISTS policy_by_cdhash\r\nDROP TABLE IF EXISTS policy_by_cdhash_v2\r\nDELETE FROM kext_policy WHERE team_id = ?1 AND bundle_id = ?2\r\nDELETE FROM kext_load_history_v3 WHERE team_id = ?1 AND bundle_id = ?2\r\nSELECT bundle_id, developer_name FROM kext_policy WHERE team_id IS NULL\r\nUPDATE kext_policy SET developer_name = ?1 WHERE team_id IS NULL and bundle_id = ?2\r\nCREATE TABLE IF NOT EXISTS kext_load_history_v3 ( path TEXT PRIMARY KEY, team_id TEXT, bundle_id TEXT\r\nCREATE TABLE IF NOT EXISTS kext_policy ( team_id TEXT, bundle_id TEXT, allowed BOOLEAN, developer_nam\r\nSELECT allowed, flags FROM kext_policy WHERE team_id = ?1 AND bundle_id = ?2\r\nSELECT allowed, flags FROM kext_policy WHERE team_id IS NULL AND bundle_id = ?2\r\nhttps://pikeralpha.wordpress.com/2017/08/29/user-approved-kernel-extension-loading/\r\nPage 6 of 10\n\nSELECT allowed FROM kext_policy WHERE team_id = ?1\", 0\r\nINSERT INTO kext_policy (team_id, bundle_id, allowed, developer_name, flags) VALUES (?1, ?2, ?3, ?4,\r\nUPDATE kext_policy SET allowed = ?3, flags = ((flags \u0026 ~?4) | ?5) WHERE team_id = ?1 AND bundle_id =\r\nUPDATE kext_policy SET allowed = ?3, flags = ((flags \u0026 ~?4) | ?5) WHERE team_id IS NULL AND bundle_id\r\nUPDATE kext_policy SET flags = (flags | ?3) WHERE team_id = ?1\r\nUPDATE kext_policy SET flags = (flags | ?3) WHERE team_id IS NULL AND bundle_id = ?2\r\nSELECT 1 FROM kext_load_history_v3 WHERE path = ?1\r\nSELECT flags FROM kext_load_history_v3 WHERE path = ?1\r\nUPDATE kext_load_history_v3 SET team_id = ?2, bundle_id = ?3, flags = ?4, last_seen = datetime('now'\r\nINSERT INTO kext_load_history_v3 (path, team_id, bundle_id, boot_uuid, created_at, last_seen, flags)\r\nSELECT created_at FROM kext_load_history_v3 WHERE team_id = ?1 AND bundle_id = ?2\r\nSELECT created_at FROM kext_load_history_v3 WHERE team_id IS NULL AND bundle_id = ?2\r\nSELECT last_seen FROM kext_load_history_v3 WHERE team_id = ?1 AND bundle_id = ?2\r\nSELECT last_seen FROM kext_load_history_v3 WHERE team_id IS NULL AND bundle_id = ?2\r\nSELECT 1 FROM kext_load_history_v3 WHERE team_id = ?1 AND bundle_id = ?2 AND (flags \u0026 ?3) = ?3 AND bo\r\nSELECT 1 FROM kext_load_history_v3 WHERE team_id IS NULL AND bundle_id = ?2 AND (flags \u0026 ?3) = ?3 AND\r\nSELECT DISTINCT team_id FROM kext_policy WHERE team_id IS NOT NULL\r\nSELECT bundle_id, developer_name, allowed FROM kext_policy WHERE team_id = ?1\r\nSELECT bundle_id, developer_name, allowed FROM kext_policy WHERE team_id IS NULL\r\nSELECT path, flags FROM kext_load_history_v3 WHERE team_id = ?1 AND bundle_id = ?2\r\nSELECT path, flags FROM kext_load_history_v3 WHERE team_id IS NULL AND bundle_id = ?2\r\nSELECT 1 FROM kext_policy WHERE flags \u0026 ?1 = ?1\r\nUPDATE kext_policy SET allowed = 0, flags = ((flags \u0026 ~?1) | ?2) WHERE allowed = 1\r\nhttps://pikeralpha.wordpress.com/2017/08/29/user-approved-kernel-extension-loading/\r\nPage 7 of 10\n\nYou can use the above SQL statements with either /usr/bin/sqlite3 or some GUI app. Here is an example of the\r\nKextPolicy database:\r\nEdit: The SQL database has two tables (kext_load_history_v3 and kext_policy). Let’s get going:\r\n1.) open a terminal window and enter:\r\n/usr/bin/sqlite3 /var/db/SystemPolicyConfiguration/KextPolicy\r\n2.) Enter:\r\nsqlite\u003e .tables\r\nThe result should be: kext_load_history_v3, kext_policy The two tables in the policy database.\r\nWe’re now going to get some data from the database. Enter one, or both, of the following SQL statements:\r\nsqlite\u003e SELECT path, bundle_id, team_id, boot_uuid, created_at, last_seen, flags FROM kext_load_histo\r\nResult:\r\n/Library/Extensions/CIJUSBLoad.kext|jp.co.canon.ij.print.CIJUSBLoad|XE2XNRRXZ5|D2E6A228-1C85-4138-9CC\r\n/Library/Extensions/BJUSBLoad.kext|jp.co.canon.bj.print.BJUSBLoad|XE2XNRRXZ5|D2E6A228-1C85-4138-9CC5-\r\n/Library/Extensions/EnergyDriver.kext|com.intel.driver.EnergyDriver|Z3L495V9L4|D4829428-7105-425D-830\r\n/Applications/Intel Power Gadget/EnergyDriver.kext|com.intel.driver.EnergyDriver|Z3L495V9L4|D4829428-\r\nOr just:\r\nSELECT * FROM kext_load_history_v3;\r\nGiving you the same output. Let’s do that for the policy table as well.\r\n3.) Enter:\r\nsqlite\u003e SELECT team_id, bundle_id, allowed, developer_name, flags FROM kext_policy;\r\nhttps://pikeralpha.wordpress.com/2017/08/29/user-approved-kernel-extension-loading/\r\nPage 8 of 10\n\nResult:\r\nXE2XNRRXZ5|jp.co.canon.bj.print.BJUSBLoad|1|Canon Inc.|0\r\nXE2XNRRXZ5|jp.co.canon.ij.print.CIJUSBLoad|1|Canon Inc.|0\r\nZ3L495V9L4|com.intel.driver.EnergyDriver|1|Intel Corporation Apps|1\r\nOr just:\r\nSELECT * FROM kext_policy;\r\nAgain. Giving you the same kind of output. And with this information we can delete the history of a kext. Let’s do\r\nthat for the Intel EnergyDriver.kext If you do not have this driver installed, then just pick another.\r\n4.) Enter:\r\nsqlite\u003e DELETE FROM kext_load_history_v3 WHERE team_id = 'Z3L495V9L4';\r\nDone. Let’s also delete the policy for this kext.\r\n5.) Enter:\r\nsqlite\u003e DELETE FROM kext_policy WHERE team_id = 'Z3L495V9L4';\r\nPlease note that I used the team_id in my examples, but you can also use the bundle_id or developer_name.\r\n6.) you can now exit sqlite3 by entering:\r\n.quit\r\nCurrently there is (still) no formal way to change the data, but that should change in a future update of High\r\nSierra.\r\nPlease note that you can only change the data from the RecoveryOS. Please do not mess with the data. This is just\r\na reference for developers and hackers alike. This is not intended for end users!\r\np.s. I love this one:\r\n“You can set a firmware password on your Mac to prevent unauthorized changes to NVRAM.”\r\nYes. You better do that. Or wait. Just look at that command prompt (Apple-iMacPro:~ Apple) showing you that I\r\nchanged the setting from a macOS High Sierra terminal window, as administrator 🙂\r\nBUG… BUG… BUGREPORTER !!!\r\nhttps://pikeralpha.wordpress.com/2017/08/29/user-approved-kernel-extension-loading/\r\nPage 9 of 10\n\nSource: https://pikeralpha.wordpress.com/2017/08/29/user-approved-kernel-extension-loading/\r\nhttps://pikeralpha.wordpress.com/2017/08/29/user-approved-kernel-extension-loading/\r\nPage 10 of 10",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://pikeralpha.wordpress.com/2017/08/29/user-approved-kernel-extension-loading/"
	],
	"report_names": [
		"user-approved-kernel-extension-loading"
	],
	"threat_actors": [],
	"ts_created_at": 1775434057,
	"ts_updated_at": 1775791251,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/6ed75a2f7b433056d1e768e8bbd3d53d0be23f82.pdf",
		"text": "https://archive.orkl.eu/6ed75a2f7b433056d1e768e8bbd3d53d0be23f82.txt",
		"img": "https://archive.orkl.eu/6ed75a2f7b433056d1e768e8bbd3d53d0be23f82.jpg"
	}
}