- Add .distignore (operator-private files excluded) - Add build.sh for WordPress-installable release ZIPs - Update CLAUDE.md references (now operator-private only)
1 line
444 KiB
JSON
1 line
444 KiB
JSON
[["Map",1,2,7,8],"meta::meta",["Map",3,4,5,6],"astro-version","5.13.8","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"where\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true,\"allowedHosts\":[]},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[],\"remotePatterns\":[],\"responsiveStyles\":false},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":false,\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[null,null,null],\"rehypePlugins\":[null,[null,{\"experimentalHeadingIdCompat\":false}],null,[null,{\"themes\":[{\"name\":\"Night Owl No Italics\",\"type\":\"dark\",\"colors\":{\"focusBorder\":\"#122d42\",\"foreground\":\"#d6deeb\",\"disabledForeground\":\"#cccccc80\",\"descriptionForeground\":\"#d6deebb3\",\"errorForeground\":\"#ef5350\",\"icon.foreground\":\"#c5c5c5\",\"contrastActiveBorder\":null,\"contrastBorder\":\"#122d42\",\"textBlockQuote.background\":\"#7f7f7f1a\",\"textBlockQuote.border\":\"#007acc80\",\"textCodeBlock.background\":\"#4f4f4f\",\"textLink.activeForeground\":\"#3794ff\",\"textLink.foreground\":\"#3794ff\",\"textPreformat.foreground\":\"#d7ba7d\",\"textSeparator.foreground\":\"#ffffff2e\",\"editor.background\":\"#23262f\",\"editor.foreground\":\"#d6deeb\",\"editorLineNumber.foreground\":\"#4b6479\",\"editorLineNumber.activeForeground\":\"#c5e4fd\",\"editorActiveLineNumber.foreground\":\"#c6c6c6\",\"editor.selectionBackground\":\"#1d3b53\",\"editor.inactiveSelectionBackground\":\"#7e57c25a\",\"editor.selectionHighlightBackground\":\"#5f7e9779\",\"editorError.foreground\":\"#ef5350\",\"editorWarning.foreground\":\"#b39554\",\"editorInfo.foreground\":\"#3794ff\",\"editorHint.foreground\":\"#eeeeeeb2\",\"problemsErrorIcon.foreground\":\"#ef5350\",\"problemsWarningIcon.foreground\":\"#b39554\",\"problemsInfoIcon.foreground\":\"#3794ff\",\"editor.findMatchBackground\":\"#5f7e9779\",\"editor.findMatchHighlightBackground\":\"#1085bb5d\",\"editor.findRangeHighlightBackground\":\"#3a3d4166\",\"editorLink.activeForeground\":\"#4e94ce\",\"editorLightBulb.foreground\":\"#ffcc00\",\"editorLightBulbAutoFix.foreground\":\"#75beff\",\"diffEditor.insertedTextBackground\":\"#99b76d23\",\"diffEditor.insertedTextBorder\":\"#c5e47833\",\"diffEditor.removedTextBackground\":\"#ef535033\",\"diffEditor.removedTextBorder\":\"#ef53504d\",\"diffEditor.insertedLineBackground\":\"#9bb95533\",\"diffEditor.removedLineBackground\":\"#ff000033\",\"editorStickyScroll.background\":\"#011627\",\"editorStickyScrollHover.background\":\"#2a2d2e\",\"editorInlayHint.background\":\"#5f7e97cc\",\"editorInlayHint.foreground\":\"#ffffff\",\"editorInlayHint.typeBackground\":\"#5f7e97cc\",\"editorInlayHint.typeForeground\":\"#ffffff\",\"editorInlayHint.parameterBackground\":\"#5f7e97cc\",\"editorInlayHint.parameterForeground\":\"#ffffff\",\"editorPane.background\":\"#011627\",\"editorGroup.emptyBackground\":\"#011627\",\"editorGroup.focusedEmptyBorder\":null,\"editorGroupHeader.tabsBackground\":\"var(--sl-color-black)\",\"editorGroupHeader.tabsBorder\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"editorGroupHeader.noTabsBackground\":\"#011627\",\"editorGroupHeader.border\":null,\"editorGroup.border\":\"#011627\",\"editorGroup.dropBackground\":\"#7e57c273\",\"editorGroup.dropIntoPromptForeground\":\"#d6deeb\",\"editorGroup.dropIntoPromptBackground\":\"#021320\",\"editorGroup.dropIntoPromptBorder\":null,\"sideBySideEditor.horizontalBorder\":\"#011627\",\"sideBySideEditor.verticalBorder\":\"#011627\",\"scrollbar.shadow\":\"#010b14\",\"scrollbarSlider.background\":\"#ffffff17\",\"scrollbarSlider.hoverBackground\":\"#ffffff40\",\"scrollbarSlider.activeBackground\":\"#084d8180\",\"panel.background\":\"#011627\",\"panel.border\":\"#5f7e97\",\"panelTitle.activeBorder\":\"#5f7e97\",\"panelTitle.activeForeground\":\"#ffffffcc\",\"panelTitle.inactiveForeground\":\"#d6deeb80\",\"panelSectionHeader.background\":\"#80808051\",\"terminal.background\":\"#011627\",\"widget.shadow\":\"#011627\",\"editorWidget.background\":\"#021320\",\"editorWidget.foreground\":\"#d6deeb\",\"editorWidget.border\":\"#5f7e97\",\"quickInput.background\":\"#021320\",\"quickInput.foreground\":\"#d6deeb\",\"quickInputTitle.background\":\"#ffffff1a\",\"pickerGroup.foreground\":\"#d1aaff\",\"pickerGroup.border\":\"#011627\",\"editor.hoverHighlightBackground\":\"#7e57c25a\",\"editorHoverWidget.background\":\"#011627\",\"editorHoverWidget.foreground\":\"#d6deeb\",\"editorHoverWidget.border\":\"#5f7e97\",\"editorHoverWidget.statusBarBackground\":\"#011a2f\",\"titleBar.activeBackground\":\"var(--sl-color-black)\",\"titleBar.activeForeground\":\"var(--sl-color-text)\",\"titleBar.inactiveBackground\":\"#010e1a\",\"titleBar.inactiveForeground\":\"#eeefff99\",\"titleBar.border\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"toolbar.hoverBackground\":\"#5a5d5e50\",\"toolbar.activeBackground\":\"#63666750\",\"tab.activeBackground\":\"#0b2942\",\"tab.unfocusedActiveBackground\":\"#0b2942\",\"tab.inactiveBackground\":\"#01111d\",\"tab.unfocusedInactiveBackground\":\"#01111d\",\"tab.activeForeground\":\"var(--sl-color-text)\",\"tab.inactiveForeground\":\"#5f7e97\",\"tab.unfocusedActiveForeground\":\"#5f7e97\",\"tab.unfocusedInactiveForeground\":\"#5f7e97\",\"tab.hoverBackground\":null,\"tab.unfocusedHoverBackground\":null,\"tab.hoverForeground\":null,\"tab.unfocusedHoverForeground\":null,\"tab.border\":\"#272b3b\",\"tab.lastPinnedBorder\":\"#585858\",\"tab.activeBorder\":\"transparent\",\"tab.unfocusedActiveBorder\":\"#262a39\",\"tab.activeBorderTop\":\"var(--sl-color-accent-high)\",\"tab.unfocusedActiveBorderTop\":null,\"tab.hoverBorder\":null,\"tab.unfocusedHoverBorder\":null,\"tab.activeModifiedBorder\":\"#3399cc\",\"tab.inactiveModifiedBorder\":\"#3399cc80\",\"tab.unfocusedActiveModifiedBorder\":\"#3399cc80\",\"tab.unfocusedInactiveModifiedBorder\":\"#3399cc40\",\"badge.background\":\"#5f7e97\",\"badge.foreground\":\"#ffffff\",\"button.background\":\"#7e57c2cc\",\"button.foreground\":\"#ffffffcc\",\"button.border\":\"#122d42\",\"button.separator\":\"#ffffff52\",\"button.hoverBackground\":\"#7e57c2\",\"button.secondaryBackground\":\"#3a3d41\",\"button.secondaryForeground\":\"#ffffff\",\"button.secondaryHoverBackground\":\"#46494e\",\"dropdown.background\":\"#011627\",\"dropdown.foreground\":\"#ffffffcc\",\"dropdown.border\":\"#5f7e97\",\"list.activeSelectionBackground\":\"#234d708c\",\"list.activeSelectionForeground\":\"#ffffff\",\"tree.indentGuidesStroke\":\"#585858\",\"input.background\":\"#0b253a\",\"input.foreground\":\"#ffffffcc\",\"input.placeholderForeground\":\"#5f7e97\",\"inputOption.activeBorder\":\"#ffffffcc\",\"inputOption.hoverBackground\":\"#5a5d5e80\",\"inputOption.activeBackground\":\"#122d4266\",\"inputOption.activeForeground\":\"#ffffff\",\"inputValidation.infoBackground\":\"#00589ef2\",\"inputValidation.infoBorder\":\"#64b5f6\",\"inputValidation.warningBackground\":\"#675700f2\",\"inputValidation.warningBorder\":\"#ffca28\",\"inputValidation.errorBackground\":\"#ab0300f2\",\"inputValidation.errorBorder\":\"#ef5350\",\"keybindingLabel.background\":\"#8080802b\",\"keybindingLabel.foreground\":\"#cccccc\",\"keybindingLabel.border\":\"#33333399\",\"keybindingLabel.bottomBorder\":\"#44444499\",\"menu.foreground\":\"#ffffffcc\",\"menu.background\":\"#011627\",\"menu.selectionForeground\":\"#ffffff\",\"menu.selectionBackground\":\"#234d708c\",\"menu.separatorBackground\":\"#606060\",\"editor.snippetTabstopHighlightBackground\":\"#7c7c74c\",\"editor.snippetFinalTabstopHighlightBorder\":\"#525252\",\"terminal.ansiBlack\":\"#011627\",\"terminal.ansiRed\":\"#ef5350\",\"terminal.ansiGreen\":\"#22da6e\",\"terminal.ansiYellow\":\"#c5e478\",\"terminal.ansiBlue\":\"#82aaff\",\"terminal.ansiMagenta\":\"#c792ea\",\"terminal.ansiCyan\":\"#21c7a8\",\"terminal.ansiWhite\":\"#ffffff\",\"terminal.ansiBrightBlack\":\"#575656\",\"terminal.ansiBrightRed\":\"#ef5350\",\"terminal.ansiBrightGreen\":\"#22da6e\",\"terminal.ansiBrightYellow\":\"#ffeb95\",\"terminal.ansiBrightBlue\":\"#82aaff\",\"terminal.ansiBrightMagenta\":\"#c792ea\",\"terminal.ansiBrightCyan\":\"#7fdbca\",\"terminal.ansiBrightWhite\":\"#ffffff\",\"selection.background\":\"#4373c2\",\"input.border\":\"#5f7e97\",\"punctuation.definition.generic.begin.html\":\"#ef5350f2\",\"progress.background\":\"#7e57c2\",\"breadcrumb.foreground\":\"#a599e9\",\"breadcrumb.focusForeground\":\"#ffffff\",\"breadcrumb.activeSelectionForeground\":\"#ffffff\",\"breadcrumbPicker.background\":\"#001122\",\"list.invalidItemForeground\":\"#975f94\",\"list.dropBackground\":\"#011627\",\"list.focusBackground\":\"#010d18\",\"list.focusForeground\":\"#ffffff\",\"list.highlightForeground\":\"#ffffff\",\"list.hoverBackground\":\"#011627\",\"list.hoverForeground\":\"#ffffff\",\"list.inactiveSelectionBackground\":\"#0e293f\",\"list.inactiveSelectionForeground\":\"#5f7e97\",\"activityBar.background\":\"#011627\",\"activityBar.dropBackground\":\"#5f7e97\",\"activityBar.foreground\":\"#5f7e97\",\"activityBar.border\":\"#011627\",\"activityBarBadge.background\":\"#44596b\",\"activityBarBadge.foreground\":\"#ffffff\",\"sideBar.background\":\"#011627\",\"sideBar.foreground\":\"#89a4bb\",\"sideBar.border\":\"#011627\",\"sideBarTitle.foreground\":\"#5f7e97\",\"sideBarSectionHeader.background\":\"#011627\",\"sideBarSectionHeader.foreground\":\"#5f7e97\",\"editorCursor.foreground\":\"#80a4c2\",\"editor.wordHighlightBackground\":\"#f6bbe533\",\"editor.wordHighlightStrongBackground\":\"#e2a2f433\",\"editor.lineHighlightBackground\":\"#0003\",\"editor.rangeHighlightBackground\":\"#7e57c25a\",\"editorIndentGuide.background\":\"#5e81ce52\",\"editorIndentGuide.activeBackground\":\"#7e97ac\",\"editorRuler.foreground\":\"#5e81ce52\",\"editorCodeLens.foreground\":\"#5e82ceb4\",\"editorBracketMatch.background\":\"#5f7e974d\",\"editorOverviewRuler.currentContentForeground\":\"#7e57c2\",\"editorOverviewRuler.incomingContentForeground\":\"#7e57c2\",\"editorOverviewRuler.commonContentForeground\":\"#7e57c2\",\"editorGutter.background\":\"#011627\",\"editorGutter.modifiedBackground\":\"#e2b93d\",\"editorGutter.addedBackground\":\"#9ccc65\",\"editorGutter.deletedBackground\":\"#ef5350\",\"editorSuggestWidget.background\":\"#2c3043\",\"editorSuggestWidget.border\":\"#2b2f40\",\"editorSuggestWidget.foreground\":\"#d6deeb\",\"editorSuggestWidget.highlightForeground\":\"#ffffff\",\"editorSuggestWidget.selectedBackground\":\"#5f7e97\",\"debugExceptionWidget.background\":\"#011627\",\"debugExceptionWidget.border\":\"#5f7e97\",\"editorMarkerNavigation.background\":\"#0b2942\",\"editorMarkerNavigationError.background\":\"#ef5350\",\"editorMarkerNavigationWarning.background\":\"#ffca28\",\"peekView.border\":\"#5f7e97\",\"peekViewEditor.background\":\"#011627\",\"peekViewEditor.matchHighlightBackground\":\"#7e57c25a\",\"peekViewResult.background\":\"#011627\",\"peekViewResult.fileForeground\":\"#5f7e97\",\"peekViewResult.lineForeground\":\"#5f7e97\",\"peekViewResult.matchHighlightBackground\":\"#ffffffcc\",\"peekViewResult.selectionBackground\":\"#2e3250\",\"peekViewResult.selectionForeground\":\"#5f7e97\",\"peekViewTitle.background\":\"#011627\",\"peekViewTitleDescription.foreground\":\"#697098\",\"peekViewTitleLabel.foreground\":\"#5f7e97\",\"merge.currentHeaderBackground\":\"#5f7e97\",\"merge.incomingHeaderBackground\":\"#7e57c25a\",\"statusBar.background\":\"#011627\",\"statusBar.foreground\":\"#5f7e97\",\"statusBar.border\":\"#262a39\",\"statusBar.debuggingBackground\":\"#202431\",\"statusBar.debuggingBorder\":\"#1f2330\",\"statusBar.noFolderBackground\":\"#011627\",\"statusBar.noFolderBorder\":\"#25293a\",\"statusBarItem.activeBackground\":\"#202431\",\"statusBarItem.hoverBackground\":\"#202431\",\"statusBarItem.prominentBackground\":\"#202431\",\"statusBarItem.prominentHoverBackground\":\"#202431\",\"notifications.background\":\"#01111d\",\"notifications.border\":\"#262a39\",\"notificationCenter.border\":\"#262a39\",\"notificationToast.border\":\"#262a39\",\"notifications.foreground\":\"#ffffffcc\",\"notificationLink.foreground\":\"#80cbc4\",\"extensionButton.prominentForeground\":\"#ffffffcc\",\"extensionButton.prominentBackground\":\"#7e57c2cc\",\"extensionButton.prominentHoverBackground\":\"#7e57c2\",\"terminal.selectionBackground\":\"#1b90dd4d\",\"terminalCursor.background\":\"#234d70\",\"debugToolBar.background\":\"#011627\",\"welcomePage.buttonBackground\":\"#011627\",\"welcomePage.buttonHoverBackground\":\"#011627\",\"walkThrough.embeddedEditorBackground\":\"#011627\",\"gitDecoration.modifiedResourceForeground\":\"#a2bffc\",\"gitDecoration.deletedResourceForeground\":\"#ef535090\",\"gitDecoration.untrackedResourceForeground\":\"#c5e478ff\",\"gitDecoration.ignoredResourceForeground\":\"#395a75\",\"gitDecoration.conflictingResourceForeground\":\"#ffeb95cc\",\"source.elm\":\"#5f7e97\",\"string.quoted.single.js\":\"#ffffff\",\"meta.objectliteral.js\":\"#82aaff\"},\"fg\":\"#d6deeb\",\"bg\":\"#23262f\",\"semanticHighlighting\":false,\"settings\":[{\"name\":\"Changed\",\"scope\":[\"markup.changed\",\"meta.diff.header.git\",\"meta.diff.header.from-file\",\"meta.diff.header.to-file\"],\"settings\":{\"foreground\":\"#a2bffc\"}},{\"name\":\"Deleted\",\"scope\":[\"markup.deleted.diff\"],\"settings\":{\"foreground\":\"#f27775fe\"}},{\"name\":\"Inserted\",\"scope\":[\"markup.inserted.diff\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Global settings\",\"settings\":{\"background\":\"#011627\",\"foreground\":\"#d6deeb\"}},{\"name\":\"Comment\",\"scope\":[\"comment\"],\"settings\":{\"foreground\":\"#919f9f\",\"fontStyle\":\"\"}},{\"name\":\"String\",\"scope\":[\"string\"],\"settings\":{\"foreground\":\"#ecc48d\"}},{\"name\":\"String Quoted\",\"scope\":[\"string.quoted\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#ecc48d\"}},{\"name\":\"Support Constant Math\",\"scope\":[\"support.constant.math\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Number\",\"scope\":[\"constant.numeric\",\"constant.character.numeric\"],\"settings\":{\"foreground\":\"#f78c6c\",\"fontStyle\":\"\"}},{\"name\":\"Built-in constant\",\"scope\":[\"constant.language\",\"punctuation.definition.constant\",\"variable.other.constant\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"User-defined constant\",\"scope\":[\"constant.character\",\"constant.other\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Constant Character Escape\",\"scope\":[\"constant.character.escape\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"RegExp String\",\"scope\":[\"string.regexp\",\"string.regexp keyword.other\"],\"settings\":{\"foreground\":\"#5ca7e4\"}},{\"name\":\"Comma in functions\",\"scope\":[\"meta.function punctuation.separator.comma\"],\"settings\":{\"foreground\":\"#889fb2\"}},{\"name\":\"Variable\",\"scope\":[\"variable\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Keyword\",\"scope\":[\"punctuation.accessor\",\"keyword\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Storage\",\"scope\":[\"storage\",\"meta.var.expr\",\"meta.class meta.method.declaration meta.var.expr storage.type.js\",\"storage.type.property.js\",\"storage.type.property.ts\",\"storage.type.property.tsx\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type.function.arrow.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Class name\",\"scope\":[\"entity.name.class\",\"meta.class entity.name.type.class\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Inherited class\",\"scope\":[\"entity.other.inherited-class\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Function name\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Meta Tag\",\"scope\":[\"punctuation.definition.tag\",\"meta.tag\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"HTML Tag names\",\"scope\":[\"entity.name.tag\",\"meta.tag.other.html\",\"meta.tag.other.js\",\"meta.tag.other.tsx\",\"entity.name.tag.tsx\",\"entity.name.tag.js\",\"entity.name.tag\",\"meta.tag.js\",\"meta.tag.tsx\",\"meta.tag.html\"],\"settings\":{\"foreground\":\"#caece6\",\"fontStyle\":\"\"}},{\"name\":\"Tag attribute\",\"scope\":[\"entity.other.attribute-name\"],\"settings\":{\"fontStyle\":\"\",\"foreground\":\"#c5e478\"}},{\"name\":\"Entity Name Tag Custom\",\"scope\":[\"entity.name.tag.custom\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Library (function & constant)\",\"scope\":[\"support.function\",\"support.constant\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Support Constant Property Value meta\",\"scope\":[\"support.constant.meta.property-value\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Library class/type\",\"scope\":[\"support.type\",\"support.class\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Support Variable DOM\",\"scope\":[\"support.variable.dom\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Invalid\",\"scope\":[\"invalid\"],\"settings\":{\"background\":\"#ff2c83\",\"foreground\":\"#ffffff\"}},{\"name\":\"Invalid deprecated\",\"scope\":[\"invalid.deprecated\"],\"settings\":{\"foreground\":\"#ffffff\",\"background\":\"#d3423e\"}},{\"name\":\"Keyword Operator\",\"scope\":[\"keyword.operator\"],\"settings\":{\"foreground\":\"#7fdbca\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Relational\",\"scope\":[\"keyword.operator.relational\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Assignment\",\"scope\":[\"keyword.operator.assignment\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Arithmetic\",\"scope\":[\"keyword.operator.arithmetic\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Bitwise\",\"scope\":[\"keyword.operator.bitwise\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Increment\",\"scope\":[\"keyword.operator.increment\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Ternary\",\"scope\":[\"keyword.operator.ternary\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Double-Slashed Comment\",\"scope\":[\"comment.line.double-slash\"],\"settings\":{\"foreground\":\"#919f9f\"}},{\"name\":\"Object\",\"scope\":[\"object\"],\"settings\":{\"foreground\":\"#cdebf7\"}},{\"name\":\"Null\",\"scope\":[\"constant.language.null\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Meta Brace\",\"scope\":[\"meta.brace\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Meta Delimiter Period\",\"scope\":[\"meta.delimiter.period\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Punctuation Definition String\",\"scope\":[\"punctuation.definition.string\"],\"settings\":{\"foreground\":\"#d9f5dd\"}},{\"name\":\"Punctuation Definition String Markdown\",\"scope\":[\"punctuation.definition.string.begin.markdown\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Boolean\",\"scope\":[\"constant.language.boolean\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Object Comma\",\"scope\":[\"object.comma\"],\"settings\":{\"foreground\":\"#ffffff\"}},{\"name\":\"Variable Parameter Function\",\"scope\":[\"variable.parameter.function\"],\"settings\":{\"foreground\":\"#7fdbca\",\"fontStyle\":\"\"}},{\"name\":\"Support Type Property Name & entity name tags\",\"scope\":[\"support.type.vendor.property-name\",\"support.constant.vendor.property-value\",\"support.type.property-name\",\"meta.property-list entity.name.tag\"],\"settings\":{\"foreground\":\"#80cbc4\",\"fontStyle\":\"\"}},{\"name\":\"Entity Name tag reference in stylesheets\",\"scope\":[\"meta.property-list entity.name.tag.reference\"],\"settings\":{\"foreground\":\"#57eaf1\"}},{\"name\":\"Constant Other Color RGB Value Punctuation Definition Constant\",\"scope\":[\"constant.other.color.rgb-value punctuation.definition.constant\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Constant Other Color\",\"scope\":[\"constant.other.color\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Keyword Other Unit\",\"scope\":[\"keyword.other.unit\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Meta Selector\",\"scope\":[\"meta.selector\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Entity Other Attribute Name Id\",\"scope\":[\"entity.other.attribute-name.id\"],\"settings\":{\"foreground\":\"#fad430\"}},{\"name\":\"Meta Property Name\",\"scope\":[\"meta.property-name\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"Doctypes\",\"scope\":[\"entity.name.tag.doctype\",\"meta.tag.sgml.doctype\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Punctuation Definition Parameters\",\"scope\":[\"punctuation.definition.parameters\"],\"settings\":{\"foreground\":\"#d9f5dd\"}},{\"name\":\"Keyword Control Operator\",\"scope\":[\"keyword.control.operator\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Keyword Operator Logical\",\"scope\":[\"keyword.operator.logical\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Variable Instances\",\"scope\":[\"variable.instance\",\"variable.other.instance\",\"variable.readwrite.instance\",\"variable.other.readwrite.instance\",\"variable.other.property\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Variable Property Other object property\",\"scope\":[\"variable.other.object.property\"],\"settings\":{\"foreground\":\"#faf39f\",\"fontStyle\":\"\"}},{\"name\":\"Variable Property Other object\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Entity Name Function\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#82aaff\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Comparison, returns, imports, and Keyword Operator Ruby\",\"scope\":[\"keyword.control.conditional.js\",\"keyword.operator.comparison\",\"keyword.control.flow.js\",\"keyword.control.flow.ts\",\"keyword.control.flow.tsx\",\"keyword.control.ruby\",\"keyword.control.def.ruby\",\"keyword.control.loop.js\",\"keyword.control.loop.ts\",\"keyword.control.import.js\",\"keyword.control.import.ts\",\"keyword.control.import.tsx\",\"keyword.control.from.js\",\"keyword.control.from.ts\",\"keyword.control.from.tsx\",\"keyword.control.conditional.js\",\"keyword.control.conditional.ts\",\"keyword.control.switch.js\",\"keyword.control.switch.ts\",\"keyword.operator.instanceof.js\",\"keyword.operator.expression.instanceof.ts\",\"keyword.operator.expression.instanceof.tsx\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Support Constant, `new` keyword, Special Method Keyword, `debugger`, other keywords\",\"scope\":[\"support.constant\",\"keyword.other.special-method\",\"keyword.other.new\",\"keyword.other.debugger\",\"keyword.control\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Support Function\",\"scope\":[\"support.function\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Invalid Broken\",\"scope\":[\"invalid.broken\"],\"settings\":{\"foreground\":\"#989da0\",\"background\":\"#F78C6C\"}},{\"name\":\"Invalid Unimplemented\",\"scope\":[\"invalid.unimplemented\"],\"settings\":{\"background\":\"#8BD649\",\"foreground\":\"#ffffff\"}},{\"name\":\"Invalid Illegal\",\"scope\":[\"invalid.illegal\"],\"settings\":{\"foreground\":\"#ffffff\",\"background\":\"#ec5f67\"}},{\"name\":\"Language Variable\",\"scope\":[\"variable.language\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Support Variable Property\",\"scope\":[\"support.variable.property\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Variable Function\",\"scope\":[\"variable.function\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Variable Interpolation\",\"scope\":[\"variable.interpolation\"],\"settings\":{\"foreground\":\"#ef787f\"}},{\"name\":\"Meta Function Call\",\"scope\":[\"meta.function-call\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Punctuation Section Embedded\",\"scope\":[\"punctuation.section.embedded\"],\"settings\":{\"foreground\":\"#e2817f\"}},{\"name\":\"Punctuation Tweaks\",\"scope\":[\"punctuation.terminator.expression\",\"punctuation.definition.arguments\",\"punctuation.definition.array\",\"punctuation.section.array\",\"meta.array\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"More Punctuation Tweaks\",\"scope\":[\"punctuation.definition.list.begin\",\"punctuation.definition.list.end\",\"punctuation.separator.arguments\",\"punctuation.definition.list\"],\"settings\":{\"foreground\":\"#d9f5dd\"}},{\"name\":\"Template Strings\",\"scope\":[\"string.template meta.template.expression\"],\"settings\":{\"foreground\":\"#e2817f\"}},{\"name\":\"Backtics(``) in Template Strings\",\"scope\":[\"string.template punctuation.definition.string\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Italics\",\"scope\":[\"italic\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"italic\"}},{\"name\":\"Bold\",\"scope\":[\"bold\"],\"settings\":{\"foreground\":\"#c5e478\",\"fontStyle\":\"bold\"}},{\"name\":\"Quote\",\"scope\":[\"quote\"],\"settings\":{\"foreground\":\"#969bb7\",\"fontStyle\":\"\"}},{\"name\":\"Raw Code\",\"scope\":[\"raw\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"CoffeScript Variable Assignment\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#31e1eb\"}},{\"name\":\"CoffeScript Parameter Function\",\"scope\":[\"variable.parameter.function.coffee\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"CoffeeScript Assignments\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"C# Readwrite Variables\",\"scope\":[\"variable.other.readwrite.cs\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"C# Classes & Storage types\",\"scope\":[\"entity.name.type.class.cs\",\"storage.type.cs\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"C# Namespaces\",\"scope\":[\"entity.name.type.namespace.cs\"],\"settings\":{\"foreground\":\"#b2ccd6\"}},{\"name\":\"C# Unquoted String Zone\",\"scope\":[\"string.unquoted.preprocessor.message.cs\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"C# Region\",\"scope\":[\"punctuation.separator.hash.cs\",\"keyword.preprocessor.region.cs\",\"keyword.preprocessor.endregion.cs\"],\"settings\":{\"foreground\":\"#ffcb8b\",\"fontStyle\":\"bold\"}},{\"name\":\"C# Other Variables\",\"scope\":[\"variable.other.object.cs\"],\"settings\":{\"foreground\":\"#b2ccd6\"}},{\"name\":\"C# Enum\",\"scope\":[\"entity.name.type.enum.cs\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Dart String\",\"scope\":[\"string.interpolated.single.dart\",\"string.interpolated.double.dart\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Dart Class\",\"scope\":[\"support.class.dart\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Tag names in Stylesheets\",\"scope\":[\"entity.name.tag.css\",\"entity.name.tag.less\",\"entity.name.tag.custom.css\",\"support.constant.property-value.css\"],\"settings\":{\"foreground\":\"#ff6d6d\",\"fontStyle\":\"\"}},{\"name\":\"Wildcard(*) selector in Stylesheets\",\"scope\":[\"entity.name.tag.wildcard.css\",\"entity.name.tag.wildcard.less\",\"entity.name.tag.wildcard.scss\",\"entity.name.tag.wildcard.sass\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"CSS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Attribute Name for CSS\",\"scope\":[\"meta.attribute-selector.css entity.other.attribute-name.attribute\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Elixir Classes\",\"scope\":[\"source.elixir support.type.elixir\",\"source.elixir meta.module.elixir entity.name.class.elixir\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Elixir Functions\",\"scope\":[\"source.elixir entity.name.function\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Elixir Constants\",\"scope\":[\"source.elixir constant.other.symbol.elixir\",\"source.elixir constant.other.keywords.elixir\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Elixir String Punctuations\",\"scope\":[\"source.elixir punctuation.definition.string\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Elixir\",\"scope\":[\"source.elixir variable.other.readwrite.module.elixir\",\"source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Elixir Binary Punctuations\",\"scope\":[\"source.elixir .punctuation.binary.elixir\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Closure Constant Keyword\",\"scope\":[\"constant.keyword.clojure\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Go Function Calls\",\"scope\":[\"source.go meta.function-call.go\"],\"settings\":{\"foreground\":\"#dddddd\"}},{\"name\":\"Go Keywords\",\"scope\":[\"source.go keyword.package.go\",\"source.go keyword.import.go\",\"source.go keyword.function.go\",\"source.go keyword.type.go\",\"source.go keyword.struct.go\",\"source.go keyword.interface.go\",\"source.go keyword.const.go\",\"source.go keyword.var.go\",\"source.go keyword.map.go\",\"source.go keyword.channel.go\",\"source.go keyword.control.go\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Go Constants e.g. nil, string format (%s, %d, etc.)\",\"scope\":[\"source.go constant.language.go\",\"source.go constant.other.placeholder.go\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"C++ Functions\",\"scope\":[\"entity.name.function.preprocessor.cpp\",\"entity.scope.name.cpp\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"C++ Meta Namespace\",\"scope\":[\"meta.namespace-block.cpp\"],\"settings\":{\"foreground\":\"#e0dec6\"}},{\"name\":\"C++ Language Primitive Storage\",\"scope\":[\"storage.type.language.primitive.cpp\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"C++ Preprocessor Macro\",\"scope\":[\"meta.preprocessor.macro.cpp\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"C++ Variable Parameter\",\"scope\":[\"variable.parameter\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Powershell Variables\",\"scope\":[\"variable.other.readwrite.powershell\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Powershell Function\",\"scope\":[\"support.function.powershell\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"ID Attribute Name in HTML\",\"scope\":[\"entity.other.attribute-name.id.html\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"HTML Punctuation Definition Tag\",\"scope\":[\"punctuation.definition.tag.html\"],\"settings\":{\"foreground\":\"#6ae9f0\"}},{\"name\":\"HTML Doctype\",\"scope\":[\"meta.tag.sgml.doctype.html\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"JavaScript Classes\",\"scope\":[\"meta.class entity.name.type.class.js\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"JavaScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.js\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"JavaScript Terminator\",\"scope\":[\"terminator.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Meta Punctuation Definition\",\"scope\":[\"meta.js punctuation.definition.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Entity Names in Code Documentations\",\"scope\":[\"entity.name.type.instance.jsdoc\",\"entity.name.type.instance.phpdoc\"],\"settings\":{\"foreground\":\"#889fb2\"}},{\"name\":\"Other Variables in Code Documentations\",\"scope\":[\"variable.other.jsdoc\",\"variable.other.phpdoc\"],\"settings\":{\"foreground\":\"#78ccf0\"}},{\"name\":\"JavaScript module imports and exports\",\"scope\":[\"variable.other.meta.import.js\",\"meta.import.js variable.other\",\"variable.other.meta.export.js\",\"meta.export.js variable.other\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Variable Parameter Function\",\"scope\":[\"variable.parameter.function.js\"],\"settings\":{\"foreground\":\"#8b96ea\"}},{\"name\":\"JavaScript[React] Variable Other Object\",\"scope\":[\"variable.other.object.js\",\"variable.other.object.jsx\",\"variable.object.property.js\",\"variable.object.property.jsx\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Variables\",\"scope\":[\"variable.js\",\"variable.other.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Entity Name Type\",\"scope\":[\"entity.name.type.js\",\"entity.name.type.module.js\"],\"settings\":{\"foreground\":\"#ffcb8b\",\"fontStyle\":\"\"}},{\"name\":\"JavaScript Support Classes\",\"scope\":[\"support.class.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JSON Property Names\",\"scope\":[\"support.type.property-name.json\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"JSON Support Constants\",\"scope\":[\"support.constant.json\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"JSON Property values (string)\",\"scope\":[\"meta.structure.dictionary.value.json string.quoted.double\"],\"settings\":{\"foreground\":\"#c789d6\"}},{\"name\":\"Strings in JSON values\",\"scope\":[\"string.quoted.double.json punctuation.definition.string.json\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"Specific JSON Property values like null\",\"scope\":[\"meta.structure.dictionary.json meta.structure.dictionary.value constant.language\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"JavaScript Other Variable\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Ruby Variables\",\"scope\":[\"variable.other.ruby\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Ruby Class\",\"scope\":[\"entity.name.type.class.ruby\"],\"settings\":{\"foreground\":\"#ecc48d\"}},{\"name\":\"Ruby Hashkeys\",\"scope\":[\"constant.language.symbol.hashkey.ruby\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"LESS Tag names\",\"scope\":[\"entity.name.tag.less\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"LESS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Attribute Name for LESS\",\"scope\":[\"meta.attribute-selector.less entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Markdown Headings\",\"scope\":[\"markup.heading.markdown\",\"markup.heading.setext.1.markdown\",\"markup.heading.setext.2.markdown\"],\"settings\":{\"foreground\":\"#82b1ff\"}},{\"name\":\"Markdown Italics\",\"scope\":[\"markup.italic.markdown\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"italic\"}},{\"name\":\"Markdown Bold\",\"scope\":[\"markup.bold.markdown\"],\"settings\":{\"foreground\":\"#c5e478\",\"fontStyle\":\"bold\"}},{\"name\":\"Markdown Quote + others\",\"scope\":[\"markup.quote.markdown\"],\"settings\":{\"foreground\":\"#969bb7\",\"fontStyle\":\"\"}},{\"name\":\"Markdown Raw Code + others\",\"scope\":[\"markup.inline.raw.markdown\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"Markdown Links\",\"scope\":[\"markup.underline.link.markdown\",\"markup.underline.link.image.markdown\"],\"settings\":{\"foreground\":\"#ff869a\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Link Title and Description\",\"scope\":[\"string.other.link.title.markdown\",\"string.other.link.description.markdown\"],\"settings\":{\"foreground\":\"#d6deeb\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Punctuation\",\"scope\":[\"punctuation.definition.string.markdown\",\"punctuation.definition.string.begin.markdown\",\"punctuation.definition.string.end.markdown\",\"meta.link.inline.markdown punctuation.definition.string\"],\"settings\":{\"foreground\":\"#82b1ff\"}},{\"name\":\"Markdown MetaData Punctuation\",\"scope\":[\"punctuation.definition.metadata.markdown\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Markdown List Punctuation\",\"scope\":[\"beginning.punctuation.definition.list.markdown\"],\"settings\":{\"foreground\":\"#82b1ff\"}},{\"name\":\"Markdown Inline Raw String\",\"scope\":[\"markup.inline.raw.string.markdown\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"PHP Variables\",\"scope\":[\"variable.other.php\"],\"settings\":{\"foreground\":\"#bec5d4\"}},{\"name\":\"Support Classes in PHP\",\"scope\":[\"support.class.php\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Punctuations in PHP function calls\",\"scope\":[\"meta.function-call.php punctuation\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"PHP Global Variables\",\"scope\":[\"variable.other.global.php\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Declaration Punctuation in PHP Global Variables\",\"scope\":[\"variable.other.global.php punctuation.definition.variable\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Language Constants in Python\",\"scope\":[\"constant.language.python\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Python Function Parameter and Arguments\",\"scope\":[\"variable.parameter.function.python\",\"meta.function-call.arguments.python\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Python Function Call\",\"scope\":[\"meta.function-call.python\",\"meta.function-call.generic.python\"],\"settings\":{\"foreground\":\"#b2ccd6\"}},{\"name\":\"Punctuations in Python\",\"scope\":[\"punctuation.python\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Decorator Functions in Python\",\"scope\":[\"entity.name.function.decorator.python\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Python Language Variable\",\"scope\":[\"source.python variable.language.special\"],\"settings\":{\"foreground\":\"#8eace3\"}},{\"name\":\"Python import control keyword\",\"scope\":[\"keyword.control\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"SCSS Variable\",\"scope\":[\"variable.scss\",\"variable.sass\",\"variable.parameter.url.scss\",\"variable.parameter.url.sass\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#bec5d4\"}},{\"name\":\"Attribute Name for SASS\",\"scope\":[\"meta.attribute-selector.scss entity.other.attribute-name.attribute\",\"meta.attribute-selector.sass entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Tag names in SASS\",\"scope\":[\"entity.name.tag.scss\",\"entity.name.tag.sass\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"SASS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.scss\",\"keyword.other.unit.sass\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"TypeScript[React] Variables and Object Properties\",\"scope\":[\"variable.other.readwrite.alias.ts\",\"variable.other.readwrite.alias.tsx\",\"variable.other.readwrite.ts\",\"variable.other.readwrite.tsx\",\"variable.other.object.ts\",\"variable.other.object.tsx\",\"variable.object.property.ts\",\"variable.object.property.tsx\",\"variable.other.ts\",\"variable.other.tsx\",\"variable.tsx\",\"variable.ts\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"TypeScript[React] Entity Name Types\",\"scope\":[\"entity.name.type.ts\",\"entity.name.type.tsx\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"TypeScript[React] Node Classes\",\"scope\":[\"support.class.node.ts\",\"support.class.node.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"TypeScript[React] Entity Name Types as Parameters\",\"scope\":[\"meta.type.parameters.ts entity.name.type\",\"meta.type.parameters.tsx entity.name.type\"],\"settings\":{\"foreground\":\"#889fb2\"}},{\"name\":\"TypeScript[React] Import/Export Punctuations\",\"scope\":[\"meta.import.ts punctuation.definition.block\",\"meta.import.tsx punctuation.definition.block\",\"meta.export.ts punctuation.definition.block\",\"meta.export.tsx punctuation.definition.block\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.decorator punctuation.decorator.ts\",\"meta.decorator punctuation.decorator.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.tag.js meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"YAML Entity Name Tags\",\"scope\":[\"entity.name.tag.yaml\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"JavaScript Variable Other ReadWrite\",\"scope\":[\"variable.other.readwrite.js\",\"variable.parameter\"],\"settings\":{\"foreground\":\"#d7dbe0\"}},{\"name\":\"Support Class Component\",\"scope\":[\"support.class.component.js\",\"support.class.component.tsx\"],\"settings\":{\"foreground\":\"#f78c6c\",\"fontStyle\":\"\"}},{\"name\":\"Text nested in React tags\",\"scope\":[\"meta.jsx.children\",\"meta.jsx.children.js\",\"meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"TypeScript Classes\",\"scope\":[\"meta.class entity.name.type.class.tsx\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"TypeScript Entity Name Type\",\"scope\":[\"entity.name.type.tsx\",\"entity.name.type.module.tsx\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"TypeScript Class Variable Keyword\",\"scope\":[\"meta.class.ts meta.var.expr.ts storage.type.ts\",\"meta.class.tsx meta.var.expr.tsx storage.type.tsx\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"TypeScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.ts\",\"meta.method.declaration storage.type.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"normalize font style of certain components\",\"scope\":[\"meta.property-list.css meta.property-value.css variable.other.less\",\"meta.property-list.scss variable.scss\",\"meta.property-list.sass variable.sass\",\"meta.brace\",\"keyword.operator.operator\",\"keyword.operator.or.regexp\",\"keyword.operator.expression.in\",\"keyword.operator.relational\",\"keyword.operator.assignment\",\"keyword.operator.comparison\",\"keyword.operator.type\",\"keyword.operator\",\"keyword\",\"punctuation.definintion.string\",\"punctuation\",\"variable.other.readwrite.js\",\"storage.type\",\"source.css\",\"string.quoted\"],\"settings\":{\"fontStyle\":\"\"}}],\"styleOverrides\":{\"frames\":{\"editorBackground\":\"var(--sl-color-gray-6)\",\"terminalBackground\":\"var(--sl-color-gray-6)\",\"editorActiveTabBackground\":\"var(--sl-color-gray-6)\",\"terminalTitlebarDotsForeground\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"terminalTitlebarDotsOpacity\":\"0.75\",\"inlineButtonForeground\":\"var(--sl-color-text)\",\"frameBoxShadowCssValue\":\"none\"},\"textMarkers\":{\"markBackground\":\"#ffffff17\",\"markBorderColor\":\"#ffffff40\"}}},{\"name\":\"Night Owl Light\",\"type\":\"light\",\"colors\":{\"focusBorder\":\"#93a1a1\",\"foreground\":\"#403f53\",\"disabledForeground\":\"#61616180\",\"descriptionForeground\":\"#403f53\",\"errorForeground\":\"#403f53\",\"icon.foreground\":\"#424242\",\"contrastActiveBorder\":null,\"contrastBorder\":null,\"textBlockQuote.background\":\"#7f7f7f1a\",\"textBlockQuote.border\":\"#007acc80\",\"textCodeBlock.background\":\"#dcdcdc66\",\"textLink.activeForeground\":\"#006ab1\",\"textLink.foreground\":\"#006ab1\",\"textPreformat.foreground\":\"#a31515\",\"textSeparator.foreground\":\"#0000002e\",\"editor.background\":\"#f6f7f9\",\"editor.foreground\":\"#403f53\",\"editorLineNumber.foreground\":\"#90a7b2\",\"editorLineNumber.activeForeground\":\"#403f53\",\"editorActiveLineNumber.foreground\":\"#0b216f\",\"editor.selectionBackground\":\"#e0e0e0\",\"editor.inactiveSelectionBackground\":\"#e0e0e080\",\"editor.selectionHighlightBackground\":\"#339cec33\",\"editorError.foreground\":\"#e64d49\",\"editorWarning.foreground\":\"#daaa01\",\"editorInfo.foreground\":\"#1a85ff\",\"editorHint.foreground\":\"#6c6c6c\",\"problemsErrorIcon.foreground\":\"#e64d49\",\"problemsWarningIcon.foreground\":\"#daaa01\",\"problemsInfoIcon.foreground\":\"#1a85ff\",\"editor.findMatchBackground\":\"#93a1a16c\",\"editor.findMatchHighlightBackground\":\"#93a1a16c\",\"editor.findRangeHighlightBackground\":\"#7497a633\",\"editorLink.activeForeground\":\"#0000ff\",\"editorLightBulb.foreground\":\"#ddb100\",\"editorLightBulbAutoFix.foreground\":\"#007acc\",\"diffEditor.insertedTextBackground\":\"#9ccc2c40\",\"diffEditor.insertedTextBorder\":null,\"diffEditor.removedTextBackground\":\"#ff000033\",\"diffEditor.removedTextBorder\":null,\"diffEditor.insertedLineBackground\":\"#9bb95533\",\"diffEditor.removedLineBackground\":\"#ff000033\",\"editorStickyScroll.background\":\"#fbfbfb\",\"editorStickyScrollHover.background\":\"#f0f0f0\",\"editorInlayHint.background\":\"#2aa29899\",\"editorInlayHint.foreground\":\"#f0f0f0\",\"editorInlayHint.typeBackground\":\"#2aa29899\",\"editorInlayHint.typeForeground\":\"#f0f0f0\",\"editorInlayHint.parameterBackground\":\"#2aa29899\",\"editorInlayHint.parameterForeground\":\"#f0f0f0\",\"editorPane.background\":\"#fbfbfb\",\"editorGroup.emptyBackground\":null,\"editorGroup.focusedEmptyBorder\":null,\"editorGroupHeader.tabsBackground\":\"var(--sl-color-gray-6)\",\"editorGroupHeader.tabsBorder\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"editorGroupHeader.noTabsBackground\":\"#f0f0f0\",\"editorGroupHeader.border\":null,\"editorGroup.border\":\"#f0f0f0\",\"editorGroup.dropBackground\":\"#2677cb2d\",\"editorGroup.dropIntoPromptForeground\":\"#403f53\",\"editorGroup.dropIntoPromptBackground\":\"#f0f0f0\",\"editorGroup.dropIntoPromptBorder\":null,\"sideBySideEditor.horizontalBorder\":\"#f0f0f0\",\"sideBySideEditor.verticalBorder\":\"#f0f0f0\",\"scrollbar.shadow\":\"#cccccc\",\"scrollbarSlider.background\":\"#0000001a\",\"scrollbarSlider.hoverBackground\":\"#00000055\",\"scrollbarSlider.activeBackground\":\"#00000099\",\"panel.background\":\"#f0f0f0\",\"panel.border\":\"#d9d9d9\",\"panelTitle.activeBorder\":\"#424242\",\"panelTitle.activeForeground\":\"#424242\",\"panelTitle.inactiveForeground\":\"#424242bf\",\"panelSectionHeader.background\":\"#80808051\",\"terminal.background\":\"#f6f6f6\",\"widget.shadow\":\"#d9d9d9\",\"editorWidget.background\":\"#f0f0f0\",\"editorWidget.foreground\":\"#403f53\",\"editorWidget.border\":\"#d9d9d9\",\"quickInput.background\":\"#f0f0f0\",\"quickInput.foreground\":\"#403f53\",\"quickInputTitle.background\":\"#0000000f\",\"pickerGroup.foreground\":\"#403f53\",\"pickerGroup.border\":\"#d9d9d9\",\"editor.hoverHighlightBackground\":\"#339cec33\",\"editorHoverWidget.background\":\"#f0f0f0\",\"editorHoverWidget.foreground\":\"#403f53\",\"editorHoverWidget.border\":\"#d9d9d9\",\"editorHoverWidget.statusBarBackground\":\"#e4e4e4\",\"titleBar.activeBackground\":\"var(--sl-color-gray-6)\",\"titleBar.activeForeground\":\"var(--sl-color-text)\",\"titleBar.inactiveBackground\":\"#f0f0f099\",\"titleBar.inactiveForeground\":\"#33333399\",\"titleBar.border\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"toolbar.hoverBackground\":\"#b8b8b850\",\"toolbar.activeBackground\":\"#a6a6a650\",\"tab.activeBackground\":\"#f6f6f6\",\"tab.unfocusedActiveBackground\":\"#f6f6f6\",\"tab.inactiveBackground\":\"#f0f0f0\",\"tab.unfocusedInactiveBackground\":\"#f0f0f0\",\"tab.activeForeground\":\"var(--sl-color-text)\",\"tab.inactiveForeground\":\"#403f53\",\"tab.unfocusedActiveForeground\":\"#403f53b3\",\"tab.unfocusedInactiveForeground\":\"#403f5380\",\"tab.hoverBackground\":null,\"tab.unfocusedHoverBackground\":null,\"tab.hoverForeground\":null,\"tab.unfocusedHoverForeground\":null,\"tab.border\":\"#f0f0f0\",\"tab.lastPinnedBorder\":\"#a9a9a9\",\"tab.activeBorder\":\"transparent\",\"tab.unfocusedActiveBorder\":null,\"tab.activeBorderTop\":\"var(--sl-color-accent)\",\"tab.unfocusedActiveBorderTop\":null,\"tab.hoverBorder\":null,\"tab.unfocusedHoverBorder\":null,\"tab.activeModifiedBorder\":\"#2aa298\",\"tab.inactiveModifiedBorder\":\"#93a1a1\",\"tab.unfocusedActiveModifiedBorder\":\"#93a1a1\",\"tab.unfocusedInactiveModifiedBorder\":\"#93a1a1\",\"badge.background\":\"#2aa298\",\"badge.foreground\":\"#f0f0f0\",\"button.background\":\"#2aa298\",\"button.foreground\":\"#f0f0f0\",\"button.border\":null,\"button.separator\":\"#f0f0f066\",\"button.hoverBackground\":\"#22827a\",\"button.secondaryBackground\":\"#5f6a79\",\"button.secondaryForeground\":\"#ffffff\",\"button.secondaryHoverBackground\":\"#4c5561\",\"dropdown.background\":\"#f0f0f0\",\"dropdown.foreground\":\"#403f53\",\"dropdown.border\":\"#d9d9d9\",\"list.activeSelectionBackground\":\"#d3e8f8\",\"list.activeSelectionForeground\":\"#403f53\",\"tree.indentGuidesStroke\":\"#a9a9a9\",\"input.background\":\"#f0f0f0\",\"input.foreground\":\"#403f53\",\"input.placeholderForeground\":\"#93a1a1\",\"inputOption.activeBorder\":\"#2aa298\",\"inputOption.hoverBackground\":\"#b8b8b850\",\"inputOption.activeBackground\":\"#93a1a133\",\"inputOption.activeForeground\":\"#000000\",\"inputValidation.infoBackground\":\"#f0f0f0\",\"inputValidation.infoBorder\":\"#d0d0d0\",\"inputValidation.warningBackground\":\"#daaa01\",\"inputValidation.warningBorder\":\"#e0af02\",\"inputValidation.errorBackground\":\"#f76e6e\",\"inputValidation.errorBorder\":\"#de3d3b\",\"keybindingLabel.background\":\"#dddddd66\",\"keybindingLabel.foreground\":\"#555555\",\"keybindingLabel.border\":\"#cccccc66\",\"keybindingLabel.bottomBorder\":\"#bbbbbb66\",\"menu.foreground\":\"#403f53\",\"menu.background\":\"#f0f0f0\",\"menu.selectionForeground\":\"#403f53\",\"menu.selectionBackground\":\"#d3e8f8\",\"menu.separatorBackground\":\"#d4d4d4\",\"editor.snippetTabstopHighlightBackground\":\"#0a326433\",\"editor.snippetFinalTabstopHighlightBorder\":\"#0a326480\",\"terminal.ansiBlack\":\"#403f53\",\"terminal.ansiRed\":\"#de3d3b\",\"terminal.ansiGreen\":\"#08916a\",\"terminal.ansiYellow\":\"#e0af02\",\"terminal.ansiBlue\":\"#288ed7\",\"terminal.ansiMagenta\":\"#d6438a\",\"terminal.ansiCyan\":\"#2aa298\",\"terminal.ansiWhite\":\"#f0f0f0\",\"terminal.ansiBrightBlack\":\"#403f53\",\"terminal.ansiBrightRed\":\"#de3d3b\",\"terminal.ansiBrightGreen\":\"#08916a\",\"terminal.ansiBrightYellow\":\"#daaa01\",\"terminal.ansiBrightBlue\":\"#288ed7\",\"terminal.ansiBrightMagenta\":\"#d6438a\",\"terminal.ansiBrightCyan\":\"#2aa298\",\"terminal.ansiBrightWhite\":\"#f0f0f0\",\"selection.background\":\"#7a8181ad\",\"notifications.background\":\"#f0f0f0\",\"notifications.foreground\":\"#403f53\",\"notificationLink.foreground\":\"#994cc3\",\"notifications.border\":\"#cccccc\",\"notificationCenter.border\":\"#cccccc\",\"notificationToast.border\":\"#cccccc\",\"notificationCenterHeader.foreground\":\"#403f53\",\"notificationCenterHeader.background\":\"#f0f0f0\",\"input.border\":\"#d9d9d9\",\"progressBar.background\":\"#2aa298\",\"list.inactiveSelectionBackground\":\"#e0e7ea\",\"list.inactiveSelectionForeground\":\"#403f53\",\"list.focusBackground\":\"#d3e8f8\",\"list.hoverBackground\":\"#d3e8f8\",\"list.focusForeground\":\"#403f53\",\"list.hoverForeground\":\"#403f53\",\"list.highlightForeground\":\"#403f53\",\"list.errorForeground\":\"#e64d49\",\"list.warningForeground\":\"#daaa01\",\"activityBar.background\":\"#f0f0f0\",\"activityBar.foreground\":\"#403f53\",\"activityBar.dropBackground\":\"#d0d0d0\",\"activityBarBadge.background\":\"#403f53\",\"activityBarBadge.foreground\":\"#f0f0f0\",\"activityBar.border\":\"#f0f0f0\",\"sideBar.background\":\"#f0f0f0\",\"sideBar.foreground\":\"#403f53\",\"sideBarTitle.foreground\":\"#403f53\",\"sideBar.border\":\"#f0f0f0\",\"editorGroup.background\":\"#f6f6f6\",\"editorCursor.foreground\":\"#90a7b2\",\"editor.wordHighlightBackground\":\"#339cec33\",\"editor.wordHighlightStrongBackground\":\"#007dd659\",\"editor.lineHighlightBackground\":\"#f0f0f0\",\"editor.rangeHighlightBackground\":\"#7497a633\",\"editorWhitespace.foreground\":\"#d9d9d9\",\"editorIndentGuide.background\":\"#d9d9d9\",\"editorCodeLens.foreground\":\"#403f53\",\"editorBracketMatch.background\":\"#d3e8f8\",\"editorBracketMatch.border\":\"#2aa298\",\"editorError.border\":\"#fbfbfb\",\"editorWarning.border\":\"#daaa01\",\"editorGutter.addedBackground\":\"#49d0c5\",\"editorGutter.modifiedBackground\":\"#6fbef6\",\"editorGutter.deletedBackground\":\"#f76e6e\",\"editorRuler.foreground\":\"#d9d9d9\",\"editorOverviewRuler.errorForeground\":\"#e64d49\",\"editorOverviewRuler.warningForeground\":\"#daaa01\",\"editorSuggestWidget.background\":\"#f0f0f0\",\"editorSuggestWidget.foreground\":\"#403f53\",\"editorSuggestWidget.highlightForeground\":\"#403f53\",\"editorSuggestWidget.selectedBackground\":\"#d3e8f8\",\"editorSuggestWidget.border\":\"#d9d9d9\",\"debugExceptionWidget.background\":\"#f0f0f0\",\"debugExceptionWidget.border\":\"#d9d9d9\",\"editorMarkerNavigation.background\":\"#d0d0d0\",\"editorMarkerNavigationError.background\":\"#f76e6e\",\"editorMarkerNavigationWarning.background\":\"#daaa01\",\"debugToolBar.background\":\"#f0f0f0\",\"extensionButton.prominentBackground\":\"#2aa298\",\"extensionButton.prominentForeground\":\"#f0f0f0\",\"statusBar.background\":\"#f0f0f0\",\"statusBar.border\":\"#f0f0f0\",\"statusBar.debuggingBackground\":\"#f0f0f0\",\"statusBar.debuggingForeground\":\"#403f53\",\"statusBar.foreground\":\"#403f53\",\"statusBar.noFolderBackground\":\"#f0f0f0\",\"statusBar.noFolderForeground\":\"#403f53\",\"peekView.border\":\"#d9d9d9\",\"peekViewEditor.background\":\"#f6f6f6\",\"peekViewEditorGutter.background\":\"#f6f6f6\",\"peekViewEditor.matchHighlightBackground\":\"#49d0c5\",\"peekViewResult.background\":\"#f0f0f0\",\"peekViewResult.fileForeground\":\"#403f53\",\"peekViewResult.lineForeground\":\"#403f53\",\"peekViewResult.matchHighlightBackground\":\"#49d0c5\",\"peekViewResult.selectionBackground\":\"#e0e7ea\",\"peekViewResult.selectionForeground\":\"#403f53\",\"peekViewTitle.background\":\"#f0f0f0\",\"peekViewTitleLabel.foreground\":\"#403f53\",\"peekViewTitleDescription.foreground\":\"#403f53\",\"terminal.foreground\":\"#403f53\"},\"fg\":\"#403f53\",\"bg\":\"#f6f7f9\",\"semanticHighlighting\":false,\"settings\":[{\"name\":\"Changed\",\"scope\":[\"markup.changed\",\"meta.diff.header.git\",\"meta.diff.header.from-file\",\"meta.diff.header.to-file\"],\"settings\":{\"foreground\":\"#556484\"}},{\"name\":\"Deleted\",\"scope\":[\"markup.deleted.diff\"],\"settings\":{\"foreground\":\"#ae3c3afd\"}},{\"name\":\"Inserted\",\"scope\":[\"markup.inserted.diff\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Global settings\",\"settings\":{\"background\":\"#011627\",\"foreground\":\"#403f53\"}},{\"name\":\"Comment\",\"scope\":[\"comment\"],\"settings\":{\"foreground\":\"#5f636f\"}},{\"name\":\"String\",\"scope\":[\"string\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"String Quoted\",\"scope\":[\"string.quoted\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#984e4d\"}},{\"name\":\"Support Constant Math\",\"scope\":[\"support.constant.math\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Number\",\"scope\":[\"constant.numeric\",\"constant.character.numeric\"],\"settings\":{\"foreground\":\"#aa0982\",\"fontStyle\":\"\"}},{\"name\":\"Built-in constant\",\"scope\":[\"constant.language\",\"punctuation.definition.constant\",\"variable.other.constant\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"User-defined constant\",\"scope\":[\"constant.character\",\"constant.other\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Constant Character Escape\",\"scope\":[\"constant.character.escape\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"RegExp String\",\"scope\":[\"string.regexp\",\"string.regexp keyword.other\"],\"settings\":{\"foreground\":\"#3a688f\"}},{\"name\":\"Comma in functions\",\"scope\":[\"meta.function punctuation.separator.comma\"],\"settings\":{\"foreground\":\"#4d667b\"}},{\"name\":\"Variable\",\"scope\":[\"variable\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Keyword\",\"scope\":[\"punctuation.accessor\",\"keyword\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Storage\",\"scope\":[\"storage\",\"meta.var.expr\",\"meta.class meta.method.declaration meta.var.expr storage.type.js\",\"storage.type.property.js\",\"storage.type.property.ts\",\"storage.type.property.tsx\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type.function.arrow.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Class name\",\"scope\":[\"entity.name.class\",\"meta.class entity.name.type.class\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Inherited class\",\"scope\":[\"entity.other.inherited-class\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Function name\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Meta Tag\",\"scope\":[\"punctuation.definition.tag\",\"meta.tag\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"HTML Tag names\",\"scope\":[\"entity.name.tag\",\"meta.tag.other.html\",\"meta.tag.other.js\",\"meta.tag.other.tsx\",\"entity.name.tag.tsx\",\"entity.name.tag.js\",\"entity.name.tag\",\"meta.tag.js\",\"meta.tag.tsx\",\"meta.tag.html\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Tag attribute\",\"scope\":[\"entity.other.attribute-name\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Entity Name Tag Custom\",\"scope\":[\"entity.name.tag.custom\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Library (function & constant)\",\"scope\":[\"support.function\",\"support.constant\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Support Constant Property Value meta\",\"scope\":[\"support.constant.meta.property-value\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Library class/type\",\"scope\":[\"support.type\",\"support.class\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Support Variable DOM\",\"scope\":[\"support.variable.dom\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Invalid\",\"scope\":[\"invalid\"],\"settings\":{\"foreground\":\"#bb2060\"}},{\"name\":\"Invalid deprecated\",\"scope\":[\"invalid.deprecated\"],\"settings\":{\"foreground\":\"#b23834\"}},{\"name\":\"Keyword Operator\",\"scope\":[\"keyword.operator\"],\"settings\":{\"foreground\":\"#096e72\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Relational\",\"scope\":[\"keyword.operator.relational\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Assignment\",\"scope\":[\"keyword.operator.assignment\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Arithmetic\",\"scope\":[\"keyword.operator.arithmetic\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Bitwise\",\"scope\":[\"keyword.operator.bitwise\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Increment\",\"scope\":[\"keyword.operator.increment\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Ternary\",\"scope\":[\"keyword.operator.ternary\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Double-Slashed Comment\",\"scope\":[\"comment.line.double-slash\"],\"settings\":{\"foreground\":\"#5d6376\"}},{\"name\":\"Object\",\"scope\":[\"object\"],\"settings\":{\"foreground\":\"#58656a\"}},{\"name\":\"Null\",\"scope\":[\"constant.language.null\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Meta Brace\",\"scope\":[\"meta.brace\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Meta Delimiter Period\",\"scope\":[\"meta.delimiter.period\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Punctuation Definition String\",\"scope\":[\"punctuation.definition.string\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Punctuation Definition String Markdown\",\"scope\":[\"punctuation.definition.string.begin.markdown\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Boolean\",\"scope\":[\"constant.language.boolean\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Object Comma\",\"scope\":[\"object.comma\"],\"settings\":{\"foreground\":\"#646464\"}},{\"name\":\"Variable Parameter Function\",\"scope\":[\"variable.parameter.function\"],\"settings\":{\"foreground\":\"#096e72\",\"fontStyle\":\"\"}},{\"name\":\"Support Type Property Name & entity name tags\",\"scope\":[\"support.type.vendor.property-name\",\"support.constant.vendor.property-value\",\"support.type.property-name\",\"meta.property-list entity.name.tag\"],\"settings\":{\"foreground\":\"#096e72\",\"fontStyle\":\"\"}},{\"name\":\"Entity Name tag reference in stylesheets\",\"scope\":[\"meta.property-list entity.name.tag.reference\"],\"settings\":{\"foreground\":\"#286d70\"}},{\"name\":\"Constant Other Color RGB Value Punctuation Definition Constant\",\"scope\":[\"constant.other.color.rgb-value punctuation.definition.constant\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Constant Other Color\",\"scope\":[\"constant.other.color\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Keyword Other Unit\",\"scope\":[\"keyword.other.unit\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Meta Selector\",\"scope\":[\"meta.selector\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Entity Other Attribute Name Id\",\"scope\":[\"entity.other.attribute-name.id\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Meta Property Name\",\"scope\":[\"meta.property-name\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Doctypes\",\"scope\":[\"entity.name.tag.doctype\",\"meta.tag.sgml.doctype\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Punctuation Definition Parameters\",\"scope\":[\"punctuation.definition.parameters\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Keyword Control Operator\",\"scope\":[\"keyword.control.operator\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Keyword Operator Logical\",\"scope\":[\"keyword.operator.logical\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"\"}},{\"name\":\"Variable Instances\",\"scope\":[\"variable.instance\",\"variable.other.instance\",\"variable.readwrite.instance\",\"variable.other.readwrite.instance\",\"variable.other.property\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Variable Property Other object property\",\"scope\":[\"variable.other.object.property\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Variable Property Other object\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Entity Name Function\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Keyword Operator Comparison, imports, returns and Keyword Operator Ruby\",\"scope\":[\"keyword.operator.comparison\",\"keyword.control.flow.js\",\"keyword.control.flow.ts\",\"keyword.control.flow.tsx\",\"keyword.control.ruby\",\"keyword.control.module.ruby\",\"keyword.control.class.ruby\",\"keyword.control.def.ruby\",\"keyword.control.loop.js\",\"keyword.control.loop.ts\",\"keyword.control.import.js\",\"keyword.control.import.ts\",\"keyword.control.import.tsx\",\"keyword.control.from.js\",\"keyword.control.from.ts\",\"keyword.control.from.tsx\",\"keyword.operator.instanceof.js\",\"keyword.operator.expression.instanceof.ts\",\"keyword.operator.expression.instanceof.tsx\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Control Conditional\",\"scope\":[\"keyword.control.conditional.js\",\"keyword.control.conditional.ts\",\"keyword.control.switch.js\",\"keyword.control.switch.ts\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"\"}},{\"name\":\"Support Constant, `new` keyword, Special Method Keyword, `debugger`, other keywords\",\"scope\":[\"support.constant\",\"keyword.other.special-method\",\"keyword.other.new\",\"keyword.other.debugger\",\"keyword.control\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Support Function\",\"scope\":[\"support.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Invalid Broken\",\"scope\":[\"invalid.broken\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Invalid Unimplemented\",\"scope\":[\"invalid.unimplemented\"],\"settings\":{\"foreground\":\"#486e26\"}},{\"name\":\"Invalid Illegal\",\"scope\":[\"invalid.illegal\"],\"settings\":{\"foreground\":\"#984e4d\"}},{\"name\":\"Language Variable\",\"scope\":[\"variable.language\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Support Variable Property\",\"scope\":[\"support.variable.property\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Variable Function\",\"scope\":[\"variable.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Variable Interpolation\",\"scope\":[\"variable.interpolation\"],\"settings\":{\"foreground\":\"#a64348\"}},{\"name\":\"Meta Function Call\",\"scope\":[\"meta.function-call\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Punctuation Section Embedded\",\"scope\":[\"punctuation.section.embedded\"],\"settings\":{\"foreground\":\"#b23834\"}},{\"name\":\"Punctuation Tweaks\",\"scope\":[\"punctuation.terminator.expression\",\"punctuation.definition.arguments\",\"punctuation.definition.array\",\"punctuation.section.array\",\"meta.array\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"More Punctuation Tweaks\",\"scope\":[\"punctuation.definition.list.begin\",\"punctuation.definition.list.end\",\"punctuation.separator.arguments\",\"punctuation.definition.list\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Template Strings\",\"scope\":[\"string.template meta.template.expression\"],\"settings\":{\"foreground\":\"#b23834\"}},{\"name\":\"Backtics(``) in Template Strings\",\"scope\":[\"string.template punctuation.definition.string\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Italics\",\"scope\":[\"italic\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"italic\"}},{\"name\":\"Bold\",\"scope\":[\"bold\"],\"settings\":{\"foreground\":\"#3b61b0\",\"fontStyle\":\"bold\"}},{\"name\":\"Quote\",\"scope\":[\"quote\"],\"settings\":{\"foreground\":\"#5c6285\"}},{\"name\":\"Raw Code\",\"scope\":[\"raw\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"CoffeScript Variable Assignment\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#186e73\"}},{\"name\":\"CoffeScript Parameter Function\",\"scope\":[\"variable.parameter.function.coffee\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"CoffeeScript Assignments\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"C# Readwrite Variables\",\"scope\":[\"variable.other.readwrite.cs\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"C# Classes & Storage types\",\"scope\":[\"entity.name.type.class.cs\",\"storage.type.cs\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"C# Namespaces\",\"scope\":[\"entity.name.type.namespace.cs\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Tag names in Stylesheets\",\"scope\":[\"entity.name.tag.css\",\"entity.name.tag.less\",\"entity.name.tag.custom.css\",\"support.constant.property-value.css\"],\"settings\":{\"foreground\":\"#984e4d\",\"fontStyle\":\"\"}},{\"name\":\"Wildcard(*) selector in Stylesheets\",\"scope\":[\"entity.name.tag.wildcard.css\",\"entity.name.tag.wildcard.less\",\"entity.name.tag.wildcard.scss\",\"entity.name.tag.wildcard.sass\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"CSS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Attribute Name for CSS\",\"scope\":[\"meta.attribute-selector.css entity.other.attribute-name.attribute\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Elixir Classes\",\"scope\":[\"source.elixir support.type.elixir\",\"source.elixir meta.module.elixir entity.name.class.elixir\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir Functions\",\"scope\":[\"source.elixir entity.name.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir Constants\",\"scope\":[\"source.elixir constant.other.symbol.elixir\",\"source.elixir constant.other.keywords.elixir\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir String Punctuations\",\"scope\":[\"source.elixir punctuation.definition.string\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir\",\"scope\":[\"source.elixir variable.other.readwrite.module.elixir\",\"source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir Binary Punctuations\",\"scope\":[\"source.elixir .punctuation.binary.elixir\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Closure Constant Keyword\",\"scope\":[\"constant.keyword.clojure\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Go Function Calls\",\"scope\":[\"source.go meta.function-call.go\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Go Keywords\",\"scope\":[\"source.go keyword.package.go\",\"source.go keyword.import.go\",\"source.go keyword.function.go\",\"source.go keyword.type.go\",\"source.go keyword.struct.go\",\"source.go keyword.interface.go\",\"source.go keyword.const.go\",\"source.go keyword.var.go\",\"source.go keyword.map.go\",\"source.go keyword.channel.go\",\"source.go keyword.control.go\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Go Constants e.g. nil, string format (%s, %d, etc.)\",\"scope\":[\"source.go constant.language.go\",\"source.go constant.other.placeholder.go\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"C++ Functions\",\"scope\":[\"entity.name.function.preprocessor.cpp\",\"entity.scope.name.cpp\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"C++ Meta Namespace\",\"scope\":[\"meta.namespace-block.cpp\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"C++ Language Primitive Storage\",\"scope\":[\"storage.type.language.primitive.cpp\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"C++ Preprocessor Macro\",\"scope\":[\"meta.preprocessor.macro.cpp\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"C++ Variable Parameter\",\"scope\":[\"variable.parameter\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Powershell Variables\",\"scope\":[\"variable.other.readwrite.powershell\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Powershell Function\",\"scope\":[\"support.function.powershell\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"ID Attribute Name in HTML\",\"scope\":[\"entity.other.attribute-name.id.html\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"HTML Punctuation Definition Tag\",\"scope\":[\"punctuation.definition.tag.html\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"HTML Doctype\",\"scope\":[\"meta.tag.sgml.doctype.html\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"JavaScript Classes\",\"scope\":[\"meta.class entity.name.type.class.js\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"JavaScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.js\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"JavaScript Terminator\",\"scope\":[\"terminator.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Meta Punctuation Definition\",\"scope\":[\"meta.js punctuation.definition.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Entity Names in Code Documentations\",\"scope\":[\"entity.name.type.instance.jsdoc\",\"entity.name.type.instance.phpdoc\"],\"settings\":{\"foreground\":\"#4d667b\"}},{\"name\":\"Other Variables in Code Documentations\",\"scope\":[\"variable.other.jsdoc\",\"variable.other.phpdoc\"],\"settings\":{\"foreground\":\"#3e697c\"}},{\"name\":\"JavaScript module imports and exports\",\"scope\":[\"variable.other.meta.import.js\",\"meta.import.js variable.other\",\"variable.other.meta.export.js\",\"meta.export.js variable.other\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Variable Parameter Function\",\"scope\":[\"variable.parameter.function.js\"],\"settings\":{\"foreground\":\"#555ea2\"}},{\"name\":\"JavaScript[React] Variable Other Object\",\"scope\":[\"variable.other.object.js\",\"variable.other.object.jsx\",\"variable.object.property.js\",\"variable.object.property.jsx\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Variables\",\"scope\":[\"variable.js\",\"variable.other.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Entity Name Type\",\"scope\":[\"entity.name.type.js\",\"entity.name.type.module.js\"],\"settings\":{\"foreground\":\"#111111\",\"fontStyle\":\"\"}},{\"name\":\"JavaScript Support Classes\",\"scope\":[\"support.class.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JSON Property Names\",\"scope\":[\"support.type.property-name.json\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"JSON Support Constants\",\"scope\":[\"support.constant.json\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"JSON Property values (string)\",\"scope\":[\"meta.structure.dictionary.value.json string.quoted.double\"],\"settings\":{\"foreground\":\"#7c5686\"}},{\"name\":\"Strings in JSON values\",\"scope\":[\"string.quoted.double.json punctuation.definition.string.json\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Specific JSON Property values like null\",\"scope\":[\"meta.structure.dictionary.json meta.structure.dictionary.value constant.language\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"JavaScript Other Variable\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Ruby Variables\",\"scope\":[\"variable.other.ruby\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Ruby Class\",\"scope\":[\"entity.name.type.class.ruby\"],\"settings\":{\"foreground\":\"#984e4d\"}},{\"name\":\"Ruby Hashkeys\",\"scope\":[\"constant.language.symbol.hashkey.ruby\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Ruby Symbols\",\"scope\":[\"constant.language.symbol.ruby\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"LESS Tag names\",\"scope\":[\"entity.name.tag.less\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"LESS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Attribute Name for LESS\",\"scope\":[\"meta.attribute-selector.less entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Markdown Headings\",\"scope\":[\"markup.heading.markdown\",\"markup.heading.setext.1.markdown\",\"markup.heading.setext.2.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Markdown Italics\",\"scope\":[\"markup.italic.markdown\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"italic\"}},{\"name\":\"Markdown Bold\",\"scope\":[\"markup.bold.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\",\"fontStyle\":\"bold\"}},{\"name\":\"Markdown Quote + others\",\"scope\":[\"markup.quote.markdown\"],\"settings\":{\"foreground\":\"#5c6285\"}},{\"name\":\"Markdown Raw Code + others\",\"scope\":[\"markup.inline.raw.markdown\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Markdown Links\",\"scope\":[\"markup.underline.link.markdown\",\"markup.underline.link.image.markdown\"],\"settings\":{\"foreground\":\"#954f5a\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Link Title and Description\",\"scope\":[\"string.other.link.title.markdown\",\"string.other.link.description.markdown\"],\"settings\":{\"foreground\":\"#403f53\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Punctuation\",\"scope\":[\"punctuation.definition.string.markdown\",\"punctuation.definition.string.begin.markdown\",\"punctuation.definition.string.end.markdown\",\"meta.link.inline.markdown punctuation.definition.string\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Markdown MetaData Punctuation\",\"scope\":[\"punctuation.definition.metadata.markdown\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Markdown List Punctuation\",\"scope\":[\"beginning.punctuation.definition.list.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Markdown Inline Raw String\",\"scope\":[\"markup.inline.raw.string.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"PHP Variables\",\"scope\":[\"variable.other.php\",\"variable.other.property.php\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Support Classes in PHP\",\"scope\":[\"support.class.php\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Punctuations in PHP function calls\",\"scope\":[\"meta.function-call.php punctuation\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"PHP Global Variables\",\"scope\":[\"variable.other.global.php\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Declaration Punctuation in PHP Global Variables\",\"scope\":[\"variable.other.global.php punctuation.definition.variable\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Language Constants in Python\",\"scope\":[\"constant.language.python\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Python Function Parameter and Arguments\",\"scope\":[\"variable.parameter.function.python\",\"meta.function-call.arguments.python\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Python Function Call\",\"scope\":[\"meta.function-call.python\",\"meta.function-call.generic.python\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Punctuations in Python\",\"scope\":[\"punctuation.python\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Decorator Functions in Python\",\"scope\":[\"entity.name.function.decorator.python\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Python Language Variable\",\"scope\":[\"source.python variable.language.special\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Python import control keyword\",\"scope\":[\"keyword.control\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"SCSS Variable\",\"scope\":[\"variable.scss\",\"variable.sass\",\"variable.parameter.url.scss\",\"variable.parameter.url.sass\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Attribute Name for SASS\",\"scope\":[\"meta.attribute-selector.scss entity.other.attribute-name.attribute\",\"meta.attribute-selector.sass entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Tag names in SASS\",\"scope\":[\"entity.name.tag.scss\",\"entity.name.tag.sass\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"SASS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.scss\",\"keyword.other.unit.sass\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"TypeScript[React] Variables and Object Properties\",\"scope\":[\"variable.other.readwrite.alias.ts\",\"variable.other.readwrite.alias.tsx\",\"variable.other.readwrite.ts\",\"variable.other.readwrite.tsx\",\"variable.other.object.ts\",\"variable.other.object.tsx\",\"variable.object.property.ts\",\"variable.object.property.tsx\",\"variable.other.ts\",\"variable.other.tsx\",\"variable.tsx\",\"variable.ts\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"TypeScript[React] Entity Name Types\",\"scope\":[\"entity.name.type.ts\",\"entity.name.type.tsx\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"TypeScript[React] Node Classes\",\"scope\":[\"support.class.node.ts\",\"support.class.node.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"TypeScript[React] Entity Name Types as Parameters\",\"scope\":[\"meta.type.parameters.ts entity.name.type\",\"meta.type.parameters.tsx entity.name.type\"],\"settings\":{\"foreground\":\"#4d667b\"}},{\"name\":\"TypeScript[React] Import/Export Punctuations\",\"scope\":[\"meta.import.ts punctuation.definition.block\",\"meta.import.tsx punctuation.definition.block\",\"meta.export.ts punctuation.definition.block\",\"meta.export.tsx punctuation.definition.block\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.decorator punctuation.decorator.ts\",\"meta.decorator punctuation.decorator.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.tag.js meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"YAML Entity Name Tags\",\"scope\":[\"entity.name.tag.yaml\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"JavaScript Variable Other ReadWrite\",\"scope\":[\"variable.other.readwrite.js\",\"variable.parameter\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Support Class Component\",\"scope\":[\"support.class.component.js\",\"support.class.component.tsx\"],\"settings\":{\"foreground\":\"#aa0982\",\"fontStyle\":\"\"}},{\"name\":\"Text nested in React tags\",\"scope\":[\"meta.jsx.children\",\"meta.jsx.children.js\",\"meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"TypeScript Classes\",\"scope\":[\"meta.class entity.name.type.class.tsx\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"TypeScript Entity Name Type\",\"scope\":[\"entity.name.type.tsx\",\"entity.name.type.module.tsx\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"TypeScript Class Variable Keyword\",\"scope\":[\"meta.class.ts meta.var.expr.ts storage.type.ts\",\"meta.class.tsx meta.var.expr.tsx storage.type.tsx\"],\"settings\":{\"foreground\":\"#76578b\"}},{\"name\":\"TypeScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.ts\",\"meta.method.declaration storage.type.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"normalize font style of certain components\",\"scope\":[\"meta.property-list.css meta.property-value.css variable.other.less\",\"meta.property-list.scss variable.scss\",\"meta.property-list.sass variable.sass\",\"meta.brace\",\"keyword.operator.operator\",\"keyword.operator.or.regexp\",\"keyword.operator.expression.in\",\"keyword.operator.relational\",\"keyword.operator.assignment\",\"keyword.operator.comparison\",\"keyword.operator.type\",\"keyword.operator\",\"keyword\",\"punctuation.definintion.string\",\"punctuation\",\"variable.other.readwrite.js\",\"storage.type\",\"source.css\",\"string.quoted\"],\"settings\":{\"fontStyle\":\"\"}}],\"styleOverrides\":{\"frames\":{\"editorBackground\":\"var(--sl-color-gray-7)\",\"terminalBackground\":\"var(--sl-color-gray-7)\",\"editorActiveTabBackground\":\"var(--sl-color-gray-7)\",\"terminalTitlebarDotsForeground\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"terminalTitlebarDotsOpacity\":\"0.75\",\"inlineButtonForeground\":\"var(--sl-color-text)\",\"frameBoxShadowCssValue\":\"none\"},\"textMarkers\":{\"markBackground\":\"#0000001a\",\"markBorderColor\":\"#00000055\"}}}],\"defaultLocale\":\"en\",\"cascadeLayer\":\"starlight.components\",\"styleOverrides\":{\"borderRadius\":\"0px\",\"borderWidth\":\"1px\",\"codePaddingBlock\":\"0.75rem\",\"codePaddingInline\":\"1rem\",\"codeFontFamily\":\"var(--__sl-font-mono)\",\"codeFontSize\":\"var(--sl-text-code)\",\"codeLineHeight\":\"var(--sl-line-height)\",\"uiFontFamily\":\"var(--__sl-font)\",\"textMarkers\":{\"lineDiffIndicatorMarginLeft\":\"0.25rem\",\"defaultChroma\":\"45\",\"backgroundOpacity\":\"60%\"}},\"plugins\":[{\"name\":\"Starlight Plugin\",\"hooks\":{}},{\"name\":\"astro-expressive-code\",\"hooks\":{}}]}]],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"security\":{\"checkOrigin\":true},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"headingIdCompat\":false,\"preserveScriptOrder\":false,\"liveContentCollections\":false,\"csp\":false,\"staticImportMetaEnv\":false,\"chromeDevtoolsWorkspace\":false},\"legacy\":{\"collections\":false},\"prefetch\":{\"prefetchAll\":true},\"i18n\":{\"defaultLocale\":\"en\",\"locales\":[\"en\"],\"routing\":{\"prefixDefaultLocale\":false,\"redirectToDefaultLocale\":false,\"fallbackType\":\"redirect\"}}}","docs",["Map",9,10,32,33,42,43,98,99,220,221,338,339],"index",{"id":9,"data":11,"body":27,"filePath":28,"digest":29,"legacyId":30,"deferredRender":31},{"title":12,"description":13,"template":14,"hero":15},"TigerStyle Scent OAuth2","The WordPress community's security exemplar - Enterprise-grade OAuth2 authorization server plugin with uncompromising security standards.","splash",{"tagline":16,"actions":17},"Enterprise-grade OAuth2 security for WordPress with cat-themed excellence",[18,23],{"text":19,"link":20,"icon":21,"variant":22},"Quick Start Guide","/getting-started/quick-start/","right-arrow","primary",{"text":24,"link":25,"icon":26},"View Security Features","/security/overview/","external","import { Card, CardGrid } from '@astrojs/starlight/components';\n\n## 🦸♂️ WordPress Security Exemplar\n\nTigerStyle Scent OAuth2 isn't just another WordPress plugin - it's a **security manifesto** that demonstrates what enterprise-grade protection looks like in the WordPress ecosystem.\n\n\u003CCardGrid stagger>\n \u003CCard title=\"🔐 Zero Critical Vulnerabilities\" icon=\"approve-check\">\n Every vulnerability eliminated with enterprise-grade defensive measures. SQL injection prevention, authorization header protection, and secure token storage.\n \u003C/Card>\n \u003CCard title=\"⚡ 7-Layer Security Architecture\" icon=\"rocket\">\n Progressive rate limiting, maximum entropy tokens, comprehensive input validation, and real-time threat monitoring.\n \u003C/Card>\n \u003CCard title=\"🎯 Secure-by-Default\" icon=\"setting\">\n 30+ hardened security settings activated out-of-the-box. HTTPS enforcement, conservative token lifetimes, and WordPress best practices.\n \u003C/Card>\n \u003CCard title=\"📚 Educational Impact\" icon=\"open-book\">\n Complete documentation and code examples that teach secure development practices to the WordPress community.\n \u003C/Card>\n\u003C/CardGrid>\n\n## 🚀 Why TigerStyle Scent?\n\n### **Mission: Counter WordPress Plugin Insecurity**\n\nThe WordPress ecosystem has been \"pillaged\" by insecure plugins that put users at risk. TigerStyle Scent OAuth2 exists to prove that WordPress plugins can achieve **bank-level security** without sacrificing functionality or usability.\n\n### **Cat-Themed Excellence**\n\n- **Scent Tokens** (Access Tokens) - Your applications catch the scent of authorization\n- **Territory Codes** (Authorization Codes) - Mark your security territory \n- **Pride Authentication** (Client Authentication) - Join the security pride\n- **ScentBearer** Headers - OAuth2 compliant with feline flair\n\n## 🎯 Perfect For\n\n- **WordPress Developers** building secure OAuth2 integrations\n- **Security Engineers** implementing enterprise authentication\n- **Plugin Authors** learning security best practices \n- **System Administrators** deploying production OAuth2 servers\n\n## 🛡️ Security Standards\n\nTigerStyle Scent exceeds industry security standards:\n\n- **OWASP Compliant** - Addresses all top 10 web security risks\n- **OAuth2 RFC Compliant** - Exceeds OAuth2 security recommendations \n- **WordPress Coding Standards** - Follows all WordPress security guidelines\n- **Enterprise Ready** - Bank-level security measures throughout\n\n---\n\n**Ready to experience uncompromising WordPress security?** Start with our [Quick Start Guide](/getting-started/quick-start/) or explore our comprehensive [Security Overview](/security/overview/).","src/content/docs/index.mdx","ae01e3ec7ff77cef","index.mdx",true,"getting-started/quick-start",{"id":32,"data":34,"body":38,"filePath":39,"digest":40,"legacyId":41,"deferredRender":31},{"title":19,"description":35,"sidebar":36},"Get TigerStyle Scent OAuth2 running in 5 minutes with enterprise-grade security",{"order":37},1,"import { Card, CardGrid, Steps, Aside } from '@astrojs/starlight/components';\n\n# Quick Start Guide\n\nGet TigerStyle Scent OAuth2 running in 5 minutes with enterprise-grade security. This guide gets you from zero to working OAuth2 server with minimal setup.\n\n## Prerequisites\n\n- WordPress 5.8 or higher\n- PHP 8.0 or higher \n- HTTPS enabled (required for production)\n- 5 minutes of your time\n\n## Installation\n\n\u003CSteps>\n\n1. **Download TigerStyle Scent**\n\n Download the latest release from [GitHub releases](https://github.com/tigerstyle/scent-oauth2/releases) or clone the repository:\n\n ```bash\n git clone https://github.com/tigerstyle/scent-oauth2.git\n ```\n\n2. **Upload to WordPress**\n\n Copy the plugin files to your WordPress plugins directory:\n\n ```bash\n # Via FTP/SFTP\n Upload tigerstyle-scent/ folder to /wp-content/plugins/\n\n # Via command line (if you have server access)\n cp -r tigerstyle-scent /path/to/wordpress/wp-content/plugins/\n ```\n\n3. **Activate the plugin**\n\n In WordPress admin:\n - Go to **Plugins** → **Installed Plugins**\n - Find **TigerStyle Scent OAuth2**\n - Click **Activate**\n\n4. **Verify installation**\n\n You should see a new **OAuth2 Server** menu item in your WordPress admin sidebar.\n\n\u003C/Steps>\n\n## Quick Configuration\n\nTigerStyle Scent comes with secure-by-default settings, but let's verify the configuration:\n\n\u003CSteps>\n\n1. **Check security settings**\n\n Go to **OAuth2 Server** → **Settings** and verify:\n - ✅ **HTTPS Required**: Enabled\n - ✅ **Rate Limiting**: Enabled \n - ✅ **Security Logging**: Enabled\n - ✅ **Input Validation**: Enabled\n\n2. **Create your first client**\n\n Go to **OAuth2 Server** → **Manage Clients** → **Add New Client**:\n\n - **Client Name**: `My Test Application`\n - **Redirect URI**: `https://httpbin.org/anything`\n - **Grant Types**: `authorization_code`\n - **Scope**: `basic`\n - **Client Type**: `Confidential`\n\n3. **Save client credentials**\n\n After saving, copy your:\n - **Client ID** (starts with `client_`)\n - **Client Secret** (long random string)\n\n \u003CAside type=\"caution\">\n **Important:** The client secret is only shown once! Save it securely.\n \u003C/Aside>\n\n\u003C/Steps>\n\n## Test OAuth2 Flow\n\nLet's test your OAuth2 server with an interactive demonstration:\n\nimport OAuth2FlowDemo from '../../../components/OAuth2FlowDemo.astro';\n\n\u003COAuth2FlowDemo />\n\n## Security Checklist\n\nVerify your installation meets security standards:\n\nimport SecurityChecklist from '../../../components/SecurityChecklist.astro';\n\n\u003CSecurityChecklist />\n\n## What's Next?\n\n\u003CCardGrid>\n \u003CCard title=\"📚 Learn by Building\" icon=\"open-book\">\n Follow our comprehensive [OAuth2 Flow Tutorial](/tutorials/first-oauth2-flow/) to build your first complete integration.\n \u003C/Card>\n \n \u003CCard title=\"🔧 Solve Real Problems\" icon=\"setting\">\n Jump into our [How-to Guides](/how-to/configure-clients/) for practical solutions to common OAuth2 challenges.\n \u003C/Card>\n \n \u003CCard title=\"🧠 Understand the Architecture\" icon=\"information\">\n Read about our [Security Architecture](/explanation/oauth2-architecture/) to understand the defense-in-depth approach.\n \u003C/Card>\n \n \u003CCard title=\"📖 API Reference\" icon=\"document\">\n Bookmark our [API Documentation](/api/authorization/) for quick technical reference while building.\n \u003C/Card>\n\u003C/CardGrid>\n\n## Troubleshooting\n\n**Plugin activation fails?**\n- Verify PHP 8.0+ and WordPress 5.8+ requirements\n- Check file permissions (644 for files, 755 for directories)\n\n**OAuth2 endpoints return 404?**\n- Ensure WordPress permalinks are set to \"Post name\" structure\n- Go to Settings → Permalinks and click \"Save Changes\"\n\n**HTTPS certificate errors?**\n- For development: Use `--insecure` flag with curl commands\n- For production: Ensure valid SSL certificate is installed\n\n**Rate limiting too aggressive?**\n- Adjust limits in OAuth2 Server → Settings → Rate Limiting\n- Default: 30 requests/hour for authorization, 60 requests/hour for tokens\n\n---\n\n🚀 **Ready to build?** You now have a secure OAuth2 server with enterprise-grade protection. Start with the [complete tutorial](/tutorials/first-oauth2-flow/) or jump into [specific how-to guides](/how-to/configure-clients/) based on your needs.","src/content/docs/getting-started/quick-start.mdx","abcc394684f34430","getting-started/quick-start.mdx","tutorials/first-oauth2-flow",{"id":42,"data":44,"body":48,"filePath":49,"digest":50,"rendered":51,"legacyId":97},{"title":45,"description":46,"sidebar":47},"Your First Secure OAuth2 Server in WordPress","Build a working OAuth2 authorization server with enterprise-grade security in 45 minutes",{"order":37},"import { Card, CardGrid, Code, Steps } from '@astrojs/starlight/components';\n\n# Your First Secure OAuth2 Server in WordPress\n\nWelcome to your first hands-on experience with enterprise-grade OAuth2 security! In the next 45 minutes, we'll build a complete OAuth2 authorization server that demonstrates what WordPress plugins can achieve when security comes first.\n\n## What You'll Build\n\nBy the end of this tutorial, you'll have:\n\n- ✅ A working OAuth2 authorization server in WordPress\n- ✅ A test client application that authenticates users \n- ✅ Understanding of the authorization code flow with PKCE\n- ✅ Real experience with enterprise-grade security measures\n\n## Prerequisites\n\n- WordPress development environment (we'll provide Docker setup)\n- Basic understanding of PHP and HTTP requests\n- 45 minutes of focused time\n- Coffee ☕ (optional but recommended)\n\n:::tip[Learning Approach]\nThis tutorial follows the \"learning by doing\" principle. We'll build first, understand later. Each step produces immediate, visible results.\n:::\n\n## Step 1: Set Up Your Development Environment\n\nLet's start by creating a secure development environment using Docker:\n\n\u003CSteps>\n\n1. **Clone the TigerStyle Scent repository**\n\n ```bash\n git clone https://github.com/tigerstyle/scent-oauth2.git\n cd scent-oauth2\n ```\n\n2. **Start the Docker environment**\n\n ```bash\n docker compose up -d\n ```\n\n3. **Verify WordPress is running**\n\n Open your browser to `https://localhost` - you should see the WordPress setup screen.\n\n4. **Complete WordPress setup**\n\n - Database Name: `wordpress`\n - Username: `wordpress` \n - Password: `wordpress`\n - Database Host: `db`\n\n\u003C/Steps>\n\nYou now have a containerized WordPress environment ready for OAuth2 development!\n\n## Step 2: Install TigerStyle Scent Plugin\n\nNow we'll install our security exemplar plugin:\n\n\u003CSteps>\n\n1. **Copy plugin to WordPress**\n\n ```bash\n sudo cp -r /home/rpm/wp-robbie/src/tigerstyle-scent/* /path/to/wordpress/wp-content/plugins/tigerstyle-scent/\n ```\n\n2. **Activate the plugin**\n\n In WordPress admin:\n - Go to Plugins → Installed Plugins\n - Find \"TigerStyle Scent OAuth2\"\n - Click \"Activate\"\n\n3. **Verify activation**\n\n You should see a new \"OAuth2 Server\" menu item in your WordPress admin sidebar.\n\n\u003C/Steps>\n\n## Step 3: Create Your First OAuth2 Client\n\nEvery OAuth2 system needs clients (applications that want to authenticate users). Let's create one:\n\n\u003CSteps>\n\n1. **Navigate to client management**\n\n In WordPress admin: OAuth2 Server → Manage Clients\n\n2. **Add new client**\n\n Click \"Add New Client\" and fill in:\n - **Client Name**: `My Test App`\n - **Redirect URI**: `https://httpbin.org/anything`\n - **Grant Types**: `authorization_code`\n - **Scope**: `basic`\n\n3. **Save and copy credentials**\n\n After saving, copy your:\n - **Client ID** (starts with `client_`)\n - **Client Secret** (long random string)\n\n ⚠️ **Important**: The client secret is only shown once!\n\n\u003C/Steps>\n\n:::note[Security First]\nNotice how TigerStyle Scent immediately uses secure patterns:\n- Client secrets are hashed with Argon2ID (industry-leading algorithm)\n- Client IDs use cryptographically secure random generation\n- All input is sanitized using WordPress security functions\n:::\n\n## Step 4: Test the Authorization Flow\n\nNow for the exciting part - let's see OAuth2 in action! We'll walk through the complete authorization code flow.\n\n\u003CSteps>\n\n1. **Build authorization URL**\n\n Create this URL (replace `YOUR_CLIENT_ID` with your actual client ID):\n\n ```\n https://localhost/oauth/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=https://httpbin.org/anything&scope=basic&state=test123\n ```\n\n2. **Visit the authorization URL**\n\n Paste the URL in your browser. You should see:\n - WordPress login screen (if not logged in)\n - OAuth2 consent screen asking for permission\n\n3. **Grant permission**\n\n Click \"Allow\" to grant permission to your test application.\n\n4. **Capture the authorization code**\n\n You'll be redirected to httpbin.org with a URL like:\n ```\n https://httpbin.org/anything?code=territory_abc123&state=test123\n ```\n\n Copy the `code` parameter - this is your authorization code!\n\n\u003C/Steps>\n\n## Step 5: Exchange Code for Access Token\n\nNow we'll exchange the authorization code for an access token:\n\n\u003CSteps>\n\n1. **Prepare token request**\n\n We'll use curl to make a POST request to the token endpoint:\n\n ```bash\n curl -X POST https://localhost/oauth/token \\\n -H \"Content-Type: application/x-www-form-urlencoded\" \\\n -d \"grant_type=authorization_code\" \\\n -d \"code=YOUR_AUTHORIZATION_CODE\" \\\n -d \"client_id=YOUR_CLIENT_ID\" \\\n -d \"client_secret=YOUR_CLIENT_SECRET\" \\\n -d \"redirect_uri=https://httpbin.org/anything\"\n ```\n\n2. **Execute the request**\n\n Replace the placeholders with your actual values and run the command.\n\n3. **Receive your Scent Token**\n\n You should get a JSON response like:\n\n ```json\n {\n \"access_token\": \"scent_xyz789abc...\",\n \"token_type\": \"Bearer\",\n \"expires_in\": 1800,\n \"scope\": \"basic\"\n }\n ```\n\n 🎉 **Success!** You now have a working OAuth2 access token!\n\n\u003C/Steps>\n\n## Step 6: Use Your Scent Token\n\nLet's use your new token to access WordPress resources:\n\n\u003CSteps>\n\n1. **Test with WordPress REST API**\n\n ```bash\n curl -H \"Authorization: ScentBearer YOUR_ACCESS_TOKEN\" \\\n https://localhost/wp-json/wp/v2/users/me\n ```\n\n2. **See your user information**\n\n You should receive your WordPress user data in JSON format.\n\n3. **Try standard OAuth2 format too**\n\n TigerStyle Scent supports both cat-themed and standard formats:\n\n ```bash\n curl -H \"Authorization: Bearer YOUR_ACCESS_TOKEN\" \\\n https://localhost/wp-json/wp/v2/users/me\n ```\n\n\u003C/Steps>\n\n## What You Just Built\n\nCongratulations! You've successfully:\n\n\u003CCardGrid>\n \u003CCard title=\"🔐 Secure OAuth2 Server\" icon=\"approve-check\">\n Built an authorization server with enterprise-grade security measures including Argon2ID password hashing and secure token generation.\n \u003C/Card>\n \u003CCard title=\"⚡ Complete Authorization Flow\" icon=\"rocket\">\n Walked through the entire OAuth2 authorization code flow from initial request to authenticated API access.\n \u003C/Card>\n \u003CCard title=\"🎯 Security Best Practices\" icon=\"setting\">\n Experienced secure-by-default configuration with HTTPS enforcement, input validation, and WordPress integration.\n \u003C/Card>\n \u003CCard title=\"🐱 Cat-Themed Excellence\" icon=\"star\">\n Used \"Scent Tokens\" and \"ScentBearer\" headers while maintaining full OAuth2 compliance and backward compatibility.\n \u003C/Card>\n\u003C/CardGrid>\n\n## Security Features You Experienced\n\nDuring this tutorial, you experienced these security measures working behind the scenes:\n\n- **Input Validation**: Every parameter was validated using comprehensive security rules\n- **Rate Limiting**: Progressive throttling protected against abuse attempts\n- **Secure Token Generation**: Your tokens used 384 bits of entropy from multiple sources\n- **Authorization Header Protection**: Strict regex validation prevented injection attacks\n- **HTTPS Enforcement**: All OAuth2 operations required secure connections\n- **Client Authentication**: Argon2ID hashing protected your client credentials\n\n## Next Steps\n\nNow that you have a working OAuth2 server, you can:\n\n1. **Learn Advanced Security** → [Securing Your Implementation](/tutorials/security-setup/)\n2. **Solve Real Problems** → [Configure Client Applications](/how-to/configure-clients/)\n3. **Understand the Architecture** → [OAuth2 Security Architecture](/explanation/oauth2-architecture/)\n4. **Look Up Technical Details** → [Authorization Endpoint Reference](/api/authorization/)\n\n## Troubleshooting\n\n**Authorization endpoint returns 404?**\n- Check that WordPress permalinks are set to \"Post name\" structure\n- Verify the plugin is activated\n\n**SSL certificate errors?**\n- Add `--insecure` flag to curl commands for development\n- Or set up proper SSL certificates for your domain\n\n**Client authentication fails?**\n- Double-check you copied the client secret correctly\n- Ensure there are no extra spaces in your credentials\n\n---\n\n**🎉 Great work!** You've built your first secure OAuth2 server with enterprise-grade protection. The WordPress community needs more developers who prioritize security - you're now one of them!","src/content/docs/tutorials/first-oauth2-flow.md","9c03aa5aeaf239c5",{"html":52,"metadata":53},"\u003Cp>import { Card, CardGrid, Code, Steps } from ‘@astrojs/starlight/components’;\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"your-first-secure-oauth2-server-in-wordpress\">Your First Secure OAuth2 Server in WordPress\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#your-first-secure-oauth2-server-in-wordpress\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Your First Secure OAuth2 Server in WordPress”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Welcome to your first hands-on experience with enterprise-grade OAuth2 security! In the next 45 minutes, we’ll build a complete OAuth2 authorization server that demonstrates what WordPress plugins can achieve when security comes first.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-youll-build\">What You’ll Build\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-youll-build\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What You’ll Build”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>By the end of this tutorial, you’ll have:\u003C/p>\n\u003Cul>\n\u003Cli>✅ A working OAuth2 authorization server in WordPress\u003C/li>\n\u003Cli>✅ A test client application that authenticates users\u003C/li>\n\u003Cli>✅ Understanding of the authorization code flow with PKCE\u003C/li>\n\u003Cli>✅ Real experience with enterprise-grade security measures\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"prerequisites\">Prerequisites\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#prerequisites\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Prerequisites”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>WordPress development environment (we’ll provide Docker setup)\u003C/li>\n\u003Cli>Basic understanding of PHP and HTTP requests\u003C/li>\n\u003Cli>45 minutes of focused time\u003C/li>\n\u003Cli>Coffee ☕ (optional but recommended)\u003C/li>\n\u003C/ul>\n\u003Caside aria-label=\"Learning Approach\" class=\"starlight-aside starlight-aside--tip\">\u003Cp class=\"starlight-aside__title\" aria-hidden=\"true\">\u003Csvg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"starlight-aside__icon\">\u003Cpath fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M1.43909 8.85483L1.44039 8.85354L4.96668 5.33815C5.30653 4.99386 5.7685 4.79662 6.2524 4.78972L6.26553 4.78963L12.9014 4.78962L13.8479 3.84308C16.9187 0.772319 20.0546 0.770617 21.4678 0.975145C21.8617 1.02914 22.2271 1.21053 22.5083 1.4917C22.7894 1.77284 22.9708 2.13821 23.0248 2.53199C23.2294 3.94517 23.2278 7.08119 20.1569 10.1521L19.2107 11.0983V17.7338L19.2106 17.7469C19.2037 18.2308 19.0067 18.6933 18.6624 19.0331L15.1456 22.5608C14.9095 22.7966 14.6137 22.964 14.29 23.0449C13.9663 23.1259 13.6267 23.1174 13.3074 23.0204C12.9881 22.9235 12.7011 22.7417 12.4771 22.4944C12.2533 22.2473 12.1006 21.9441 12.0355 21.6171L11.1783 17.3417L6.65869 12.822L4.34847 12.3589L2.38351 11.965C2.05664 11.8998 1.75272 11.747 1.50564 11.5232C1.25835 11.2992 1.07653 11.0122 0.979561 10.6929C0.882595 10.3736 0.874125 10.034 0.955057 9.7103C1.03599 9.38659 1.20328 9.09092 1.43909 8.85483ZM6.8186 10.8724L2.94619 10.096L6.32006 6.73268H10.9583L6.8186 10.8724ZM15.2219 5.21703C17.681 2.75787 20.0783 2.75376 21.1124 2.8876C21.2462 3.92172 21.2421 6.31895 18.783 8.77812L12.0728 15.4883L8.51172 11.9272L15.2219 5.21703ZM13.9042 21.0538L13.1279 17.1811L17.2676 13.0414V17.68L13.9042 21.0538Z\">\u003C/path>\u003Cpath d=\"M9.31827 18.3446C9.45046 17.8529 9.17864 17.3369 8.68945 17.1724C8.56178 17.1294 8.43145 17.1145 8.30512 17.1243C8.10513 17.1398 7.91519 17.2172 7.76181 17.3434C7.62613 17.455 7.51905 17.6048 7.45893 17.7835C6.97634 19.2186 5.77062 19.9878 4.52406 20.4029C4.08525 20.549 3.6605 20.644 3.29471 20.7053C3.35607 20.3395 3.45098 19.9148 3.59711 19.476C4.01221 18.2294 4.78141 17.0237 6.21648 16.5411C6.39528 16.481 6.54504 16.3739 6.65665 16.2382C6.85126 16.0016 6.92988 15.678 6.84417 15.3647C6.83922 15.3466 6.83373 15.3286 6.82767 15.3106C6.74106 15.053 6.55701 14.8557 6.33037 14.7459C6.10949 14.6389 5.84816 14.615 5.59715 14.6994C5.47743 14.7397 5.36103 14.7831 5.24786 14.8294C3.22626 15.6569 2.2347 17.4173 1.75357 18.8621C1.49662 19.6337 1.36993 20.3554 1.30679 20.8818C1.27505 21.1464 1.25893 21.3654 1.25072 21.5213C1.24662 21.5993 1.24448 21.6618 1.24337 21.7066L1.243 21.7226L1.24235 21.7605L1.2422 21.7771L1.24217 21.7827L1.24217 21.7856C1.24217 22.3221 1.67703 22.7579 2.2137 22.7579L2.2155 22.7579L2.22337 22.7578L2.23956 22.7577C2.25293 22.7575 2.27096 22.7572 2.29338 22.7567C2.33821 22.7555 2.40073 22.7534 2.47876 22.7493C2.63466 22.7411 2.85361 22.725 3.11822 22.6932C3.64462 22.6301 4.36636 22.5034 5.13797 22.2464C6.58274 21.7653 8.3431 20.7738 9.17063 18.7522C9.21696 18.639 9.26037 18.5226 9.30064 18.4029C9.30716 18.3835 9.31304 18.364 9.31827 18.3446Z\">\u003C/path>\u003C/svg>Learning Approach\u003C/p>\u003Cdiv class=\"starlight-aside__content\">\u003Cp>This tutorial follows the “learning by doing” principle. We’ll build first, understand later. Each step produces immediate, visible results.\u003C/p>\u003C/div>\u003C/aside>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-1-set-up-your-development-environment\">Step 1: Set Up Your Development Environment\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-1-set-up-your-development-environment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 1: Set Up Your Development Environment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Let’s start by creating a secure development environment using Docker:\u003C/p>\n\u003Csteps>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Clone the TigerStyle Scent repository\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.p1z7b.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">git\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">clone\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">https://github.com/tigerstyle/scent-oauth2.git\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">cd\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">scent-oauth2\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"git clone https://github.com/tigerstyle/scent-oauth2.gitcd scent-oauth2\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Start the Docker environment\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">docker\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">compose\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">up\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-d\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"docker compose up -d\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Verify WordPress is running\u003C/strong>\u003C/p>\n\u003Cp>Open your browser to \u003Ccode dir=\"auto\">https://localhost\u003C/code> - you should see the WordPress setup screen.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Complete WordPress setup\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Database Name: \u003Ccode dir=\"auto\">wordpress\u003C/code>\u003C/li>\n\u003Cli>Username: \u003Ccode dir=\"auto\">wordpress\u003C/code>\u003C/li>\n\u003Cli>Password: \u003Ccode dir=\"auto\">wordpress\u003C/code>\u003C/li>\n\u003Cli>Database Host: \u003Ccode dir=\"auto\">db\u003C/code>\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003C/steps>\n\u003Cp>You now have a containerized WordPress environment ready for OAuth2 development!\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-2-install-tigerstyle-scent-plugin\">Step 2: Install TigerStyle Scent Plugin\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-2-install-tigerstyle-scent-plugin\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 2: Install TigerStyle Scent Plugin”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Now we’ll install our security exemplar plugin:\u003C/p>\n\u003Csteps>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Copy plugin to WordPress\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sudo\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">cp\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-r\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">/home/rpm/wp-robbie/src/tigerstyle-scent/\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">/path/to/wordpress/wp-content/plugins/tigerstyle-scent/\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"sudo cp -r /home/rpm/wp-robbie/src/tigerstyle-scent/* /path/to/wordpress/wp-content/plugins/tigerstyle-scent/\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Activate the plugin\u003C/strong>\u003C/p>\n\u003Cp>In WordPress admin:\u003C/p>\n\u003Cul>\n\u003Cli>Go to Plugins → Installed Plugins\u003C/li>\n\u003Cli>Find “TigerStyle Scent OAuth2”\u003C/li>\n\u003Cli>Click “Activate”\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Verify activation\u003C/strong>\u003C/p>\n\u003Cp>You should see a new “OAuth2 Server” menu item in your WordPress admin sidebar.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003C/steps>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-3-create-your-first-oauth2-client\">Step 3: Create Your First OAuth2 Client\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-3-create-your-first-oauth2-client\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 3: Create Your First OAuth2 Client”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Every OAuth2 system needs clients (applications that want to authenticate users). Let’s create one:\u003C/p>\n\u003Csteps>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Navigate to client management\u003C/strong>\u003C/p>\n\u003Cp>In WordPress admin: OAuth2 Server → Manage Clients\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Add new client\u003C/strong>\u003C/p>\n\u003Cp>Click “Add New Client” and fill in:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Client Name\u003C/strong>: \u003Ccode dir=\"auto\">My Test App\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Redirect URI\u003C/strong>: \u003Ccode dir=\"auto\">https://httpbin.org/anything\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Grant Types\u003C/strong>: \u003Ccode dir=\"auto\">authorization_code\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Scope\u003C/strong>: \u003Ccode dir=\"auto\">basic\u003C/code>\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Save and copy credentials\u003C/strong>\u003C/p>\n\u003Cp>After saving, copy your:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Client ID\u003C/strong> (starts with \u003Ccode dir=\"auto\">client_\u003C/code>)\u003C/li>\n\u003Cli>\u003Cstrong>Client Secret\u003C/strong> (long random string)\u003C/li>\n\u003C/ul>\n\u003Cp>⚠️ \u003Cstrong>Important\u003C/strong>: The client secret is only shown once!\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003C/steps>\n\u003Caside aria-label=\"Security First\" class=\"starlight-aside starlight-aside--note\">\u003Cp class=\"starlight-aside__title\" aria-hidden=\"true\">\u003Csvg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"starlight-aside__icon\">\u003Cpath d=\"M12 11C11.7348 11 11.4804 11.1054 11.2929 11.2929C11.1054 11.4804 11 11.7348 11 12V16C11 16.2652 11.1054 16.5196 11.2929 16.7071C11.4804 16.8946 11.7348 17 12 17C12.2652 17 12.5196 16.8946 12.7071 16.7071C12.8946 16.5196 13 16.2652 13 16V12C13 11.7348 12.8946 11.4804 12.7071 11.2929C12.5196 11.1054 12.2652 11 12 11ZM12.38 7.08C12.1365 6.97998 11.8635 6.97998 11.62 7.08C11.4973 7.12759 11.3851 7.19896 11.29 7.29C11.2017 7.3872 11.1306 7.49882 11.08 7.62C11.024 7.73868 10.9966 7.86882 11 8C10.9992 8.13161 11.0245 8.26207 11.0742 8.38391C11.124 8.50574 11.1973 8.61656 11.29 8.71C11.3872 8.79833 11.4988 8.86936 11.62 8.92C11.7715 8.98224 11.936 9.00632 12.099 8.99011C12.2619 8.97391 12.4184 8.91792 12.5547 8.82707C12.691 8.73622 12.8029 8.61328 12.8805 8.46907C12.9582 8.32486 12.9992 8.16378 13 8C12.9963 7.73523 12.8927 7.48163 12.71 7.29C12.6149 7.19896 12.5028 7.12759 12.38 7.08ZM12 2C10.0222 2 8.08879 2.58649 6.4443 3.6853C4.79981 4.78412 3.51809 6.3459 2.76121 8.17317C2.00433 10.0004 1.8063 12.0111 2.19215 13.9509C2.578 15.8907 3.53041 17.6725 4.92894 19.0711C6.32746 20.4696 8.10929 21.422 10.0491 21.8079C11.9889 22.1937 13.9996 21.9957 15.8268 21.2388C17.6541 20.4819 19.2159 19.2002 20.3147 17.5557C21.4135 15.9112 22 13.9778 22 12C22 10.6868 21.7413 9.38642 21.2388 8.17317C20.7363 6.95991 19.9997 5.85752 19.0711 4.92893C18.1425 4.00035 17.0401 3.26375 15.8268 2.7612C14.6136 2.25866 13.3132 2 12 2ZM12 20C10.4178 20 8.87104 19.5308 7.55544 18.6518C6.23985 17.7727 5.21447 16.5233 4.60897 15.0615C4.00347 13.5997 3.84504 11.9911 4.15372 10.4393C4.4624 8.88743 5.22433 7.46197 6.34315 6.34315C7.46197 5.22433 8.88743 4.4624 10.4393 4.15372C11.9911 3.84504 13.5997 4.00346 15.0615 4.60896C16.5233 5.21447 17.7727 6.23984 18.6518 7.55544C19.5308 8.87103 20 10.4177 20 12C20 14.1217 19.1572 16.1566 17.6569 17.6569C16.1566 19.1571 14.1217 20 12 20Z\">\u003C/path>\u003C/svg>Security First\u003C/p>\u003Cdiv class=\"starlight-aside__content\">\u003Cp>Notice how TigerStyle Scent immediately uses secure patterns:\u003C/p>\u003Cul>\n\u003Cli>Client secrets are hashed with Argon2ID (industry-leading algorithm)\u003C/li>\n\u003Cli>Client IDs use cryptographically secure random generation\u003C/li>\n\u003Cli>All input is sanitized using WordPress security functions\u003C/li>\n\u003C/ul>\u003C/div>\u003C/aside>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-4-test-the-authorization-flow\">Step 4: Test the Authorization Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-4-test-the-authorization-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 4: Test the Authorization Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Now for the exciting part - let’s see OAuth2 in action! We’ll walk through the complete authorization code flow.\u003C/p>\n\u003Csteps>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Build authorization URL\u003C/strong>\u003C/p>\n\u003Cp>Create this URL (replace \u003Ccode dir=\"auto\">YOUR_CLIENT_ID\u003C/code> with your actual client ID):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">https://localhost/oauth/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=https://httpbin.org/anything&scope=basic&state=test123\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"https://localhost/oauth/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=https://httpbin.org/anything&scope=basic&state=test123\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Visit the authorization URL\u003C/strong>\u003C/p>\n\u003Cp>Paste the URL in your browser. You should see:\u003C/p>\n\u003Cul>\n\u003Cli>WordPress login screen (if not logged in)\u003C/li>\n\u003Cli>OAuth2 consent screen asking for permission\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Grant permission\u003C/strong>\u003C/p>\n\u003Cp>Click “Allow” to grant permission to your test application.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Capture the authorization code\u003C/strong>\u003C/p>\n\u003Cp>You’ll be redirected to httpbin.org with a URL like:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">https://httpbin.org/anything?code=territory_abc123&state=test123\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"https://httpbin.org/anything?code=territory_abc123&state=test123\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Copy the \u003Ccode dir=\"auto\">code\u003C/code> parameter - this is your authorization code!\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003C/steps>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-5-exchange-code-for-access-token\">Step 5: Exchange Code for Access Token\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-5-exchange-code-for-access-token\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 5: Exchange Code for Access Token”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Now we’ll exchange the authorization code for an access token:\u003C/p>\n\u003Csteps>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Prepare token request\u003C/strong>\u003C/p>\n\u003Cp>We’ll use curl to make a POST request to the token endpoint:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">curl\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-X\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">POST\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">https://localhost/oauth/token\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-H\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Content-Type: application/x-www-form-urlencoded\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-d\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">grant_type=authorization_code\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-d\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">code=YOUR_AUTHORIZATION_CODE\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-d\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">client_id=YOUR_CLIENT_ID\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-d\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">client_secret=YOUR_CLIENT_SECRET\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-d\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">redirect_uri=https://httpbin.org/anything\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"curl -X POST https://localhost/oauth/token \\ -H "Content-Type: application/x-www-form-urlencoded" \\ -d "grant_type=authorization_code" \\ -d "code=YOUR_AUTHORIZATION_CODE" \\ -d "client_id=YOUR_CLIENT_ID" \\ -d "client_secret=YOUR_CLIENT_SECRET" \\ -d "redirect_uri=https://httpbin.org/anything"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Execute the request\u003C/strong>\u003C/p>\n\u003Cp>Replace the placeholders with your actual values and run the command.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Receive your Scent Token\u003C/strong>\u003C/p>\n\u003Cp>You should get a JSON response like:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"json\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"access_token\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">scent_xyz789abc...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"token_type\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">Bearer\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"expires_in\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1800\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"scope\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">basic\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"{ "access_token": "scent_xyz789abc...", "token_type": "Bearer", "expires_in": 1800, "scope": "basic"}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>🎉 \u003Cstrong>Success!\u003C/strong> You now have a working OAuth2 access token!\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003C/steps>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-6-use-your-scent-token\">Step 6: Use Your Scent Token\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-6-use-your-scent-token\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 6: Use Your Scent Token”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Let’s use your new token to access WordPress resources:\u003C/p>\n\u003Csteps>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Test with WordPress REST API\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">curl\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-H\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Authorization: ScentBearer YOUR_ACCESS_TOKEN\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">https://localhost/wp-json/wp/v2/users/me\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"curl -H "Authorization: ScentBearer YOUR_ACCESS_TOKEN" \\ https://localhost/wp-json/wp/v2/users/me\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>See your user information\u003C/strong>\u003C/p>\n\u003Cp>You should receive your WordPress user data in JSON format.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Try standard OAuth2 format too\u003C/strong>\u003C/p>\n\u003Cp>TigerStyle Scent supports both cat-themed and standard formats:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">curl\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-H\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Authorization: Bearer YOUR_ACCESS_TOKEN\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">https://localhost/wp-json/wp/v2/users/me\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \\ https://localhost/wp-json/wp/v2/users/me\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003C/ol>\n\u003C/steps>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-you-just-built\">What You Just Built\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-you-just-built\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What You Just Built”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Congratulations! You’ve successfully:\u003C/p>\n\u003Ccardgrid>\n \u003Ccard title=\"🔐 Secure OAuth2 Server\" icon=\"approve-check\">\n Built an authorization server with enterprise-grade security measures including Argon2ID password hashing and secure token generation.\n \u003C/card>\n \u003Ccard title=\"⚡ Complete Authorization Flow\" icon=\"rocket\">\n Walked through the entire OAuth2 authorization code flow from initial request to authenticated API access.\n \u003C/card>\n \u003Ccard title=\"🎯 Security Best Practices\" icon=\"setting\">\n Experienced secure-by-default configuration with HTTPS enforcement, input validation, and WordPress integration.\n \u003C/card>\n \u003Ccard title=\"🐱 Cat-Themed Excellence\" icon=\"star\">\n Used \"Scent Tokens\" and \"ScentBearer\" headers while maintaining full OAuth2 compliance and backward compatibility.\n \u003C/card>\n\u003C/cardgrid>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"security-features-you-experienced\">Security Features You Experienced\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#security-features-you-experienced\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Security Features You Experienced”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>During this tutorial, you experienced these security measures working behind the scenes:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Input Validation\u003C/strong>: Every parameter was validated using comprehensive security rules\u003C/li>\n\u003Cli>\u003Cstrong>Rate Limiting\u003C/strong>: Progressive throttling protected against abuse attempts\u003C/li>\n\u003Cli>\u003Cstrong>Secure Token Generation\u003C/strong>: Your tokens used 384 bits of entropy from multiple sources\u003C/li>\n\u003Cli>\u003Cstrong>Authorization Header Protection\u003C/strong>: Strict regex validation prevented injection attacks\u003C/li>\n\u003Cli>\u003Cstrong>HTTPS Enforcement\u003C/strong>: All OAuth2 operations required secure connections\u003C/li>\n\u003Cli>\u003Cstrong>Client Authentication\u003C/strong>: Argon2ID hashing protected your client credentials\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"next-steps\">Next Steps\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#next-steps\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Next Steps”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Now that you have a working OAuth2 server, you can:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Learn Advanced Security\u003C/strong> → \u003Ca href=\"/tutorials/security-setup/\">Securing Your Implementation\u003C/a>\u003C/li>\n\u003Cli>\u003Cstrong>Solve Real Problems\u003C/strong> → \u003Ca href=\"/how-to/configure-clients/\">Configure Client Applications\u003C/a>\u003C/li>\n\u003Cli>\u003Cstrong>Understand the Architecture\u003C/strong> → \u003Ca href=\"/explanation/oauth2-architecture/\">OAuth2 Security Architecture\u003C/a>\u003C/li>\n\u003Cli>\u003Cstrong>Look Up Technical Details\u003C/strong> → \u003Ca href=\"/api/authorization/\">Authorization Endpoint Reference\u003C/a>\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"troubleshooting\">Troubleshooting\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#troubleshooting\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Troubleshooting”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Authorization endpoint returns 404?\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Check that WordPress permalinks are set to “Post name” structure\u003C/li>\n\u003Cli>Verify the plugin is activated\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>SSL certificate errors?\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Add \u003Ccode dir=\"auto\">--insecure\u003C/code> flag to curl commands for development\u003C/li>\n\u003Cli>Or set up proper SSL certificates for your domain\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Client authentication fails?\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Double-check you copied the client secret correctly\u003C/li>\n\u003Cli>Ensure there are no extra spaces in your credentials\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cp>\u003Cstrong>🎉 Great work!\u003C/strong> You’ve built your first secure OAuth2 server with enterprise-grade protection. The WordPress community needs more developers who prioritize security - you’re now one of them!\u003C/p>",{"headings":54,"localImagePaths":94,"remoteImagePaths":95,"frontmatter":44,"imagePaths":96},[55,57,61,64,67,70,73,76,79,82,85,88,91],{"depth":37,"slug":56,"text":45},"your-first-secure-oauth2-server-in-wordpress",{"depth":58,"slug":59,"text":60},2,"what-youll-build","What You’ll Build",{"depth":58,"slug":62,"text":63},"prerequisites","Prerequisites",{"depth":58,"slug":65,"text":66},"step-1-set-up-your-development-environment","Step 1: Set Up Your Development Environment",{"depth":58,"slug":68,"text":69},"step-2-install-tigerstyle-scent-plugin","Step 2: Install TigerStyle Scent Plugin",{"depth":58,"slug":71,"text":72},"step-3-create-your-first-oauth2-client","Step 3: Create Your First OAuth2 Client",{"depth":58,"slug":74,"text":75},"step-4-test-the-authorization-flow","Step 4: Test the Authorization Flow",{"depth":58,"slug":77,"text":78},"step-5-exchange-code-for-access-token","Step 5: Exchange Code for Access Token",{"depth":58,"slug":80,"text":81},"step-6-use-your-scent-token","Step 6: Use Your Scent Token",{"depth":58,"slug":83,"text":84},"what-you-just-built","What You Just Built",{"depth":58,"slug":86,"text":87},"security-features-you-experienced","Security Features You Experienced",{"depth":58,"slug":89,"text":90},"next-steps","Next Steps",{"depth":58,"slug":92,"text":93},"troubleshooting","Troubleshooting",[],[],[],"tutorials/first-oauth2-flow.md","explanation/oauth2-architecture",{"id":98,"data":100,"body":104,"filePath":105,"digest":106,"rendered":107,"legacyId":219},{"title":101,"description":102,"sidebar":103},"Understanding OAuth2 Security Architecture","Deep dive into the seven-layer security model that makes TigerStyle Scent a WordPress security exemplar",{"order":37},"import { Card, CardGrid, Aside } from '@astrojs/starlight/components';\n\n# Understanding OAuth2 Security Architecture\n\nOAuth2 is powerful, but power without security is dangerous. Understanding **why** security measures exist helps you make better implementation decisions and avoid the pitfalls that have plagued countless WordPress plugins.\n\n## The OAuth2 Security Challenge\n\nOAuth2 was designed for a simpler web - before mobile apps, before sophisticated attacks, before the WordPress ecosystem became a prime target for bad actors. Today's OAuth2 implementations must defend against threats the original RFC authors never imagined.\n\n**The fundamental tension:** OAuth2 prioritizes developer convenience over security. This makes it easy to implement, but also easy to implement *badly*.\n\n## Why WordPress OAuth2 Plugins Fail at Security\n\nThe WordPress plugin ecosystem has been \"pillaged\" by insecure implementations because:\n\n### 1. **The Copy-Paste Culture**\nDevelopers copy vulnerable examples from outdated tutorials, perpetuating security anti-patterns across thousands of plugins.\n\n### 2. **The \"Good Enough\" Mindset** \nBasic OAuth2 functionality *appears* to work fine, hiding critical security flaws until it's too late.\n\n### 3. **WordPress-Specific Blind Spots**\nDevelopers familiar with WordPress often miss OAuth2-specific security requirements, while OAuth2 experts don't understand WordPress security patterns.\n\n### 4. **The Security-Performance Trade-off**\nShared hosting environments discourage robust security measures that might impact performance.\n\n## The TigerStyle Seven-Layer Security Model\n\nTigerStyle Scent addresses these challenges with a comprehensive **defense-in-depth** approach. Each layer provides independent protection, ensuring that even if one layer fails, others maintain security.\n\n\u003CCardGrid>\n \u003CCard title=\"🌐 Layer 1: Transport Security\" icon=\"laptop\">\n **HTTPS Enforcement + Security Headers**\n \n Ensures all OAuth2 communication happens over encrypted channels with comprehensive browser security policies.\n \u003C/Card>\n \n \u003CCard title=\"🛡️ Layer 2: Input Validation\" icon=\"approve-check\">\n **Multi-Pattern Validation Framework**\n \n Every input undergoes type validation, length checking, pattern matching, and security scanning before processing.\n \u003C/Card>\n \n \u003CCard title=\"⚡ Layer 3: Rate Limiting\" icon=\"rocket\">\n **Progressive Throttling System**\n \n HMAC-based client fingerprinting with exponential backoff prevents abuse while maintaining usability.\n \u003C/Card>\n \n \u003CCard title=\"🔐 Layer 4: Authentication\" icon=\"lock\">\n **Secure Client Verification**\n \n Argon2ID password hashing and comprehensive token validation protect against credential attacks.\n \u003C/Card>\n \n \u003CCard title=\"📊 Layer 5: Monitoring\" icon=\"information\">\n **Real-time Threat Detection**\n \n Structured logging and pattern analysis automatically identify and respond to security threats.\n \u003C/Card>\n \n \u003CCard title=\"🎯 Layer 6: Authorization\" icon=\"setting\">\n **Scope-based Access Control**\n \n Granular permissions with PKCE enforcement ensure clients only access approved resources.\n \u003C/Card>\n \n \u003CCard title=\"🔒 Layer 7: Data Protection\" icon=\"star\">\n **Encrypted Storage + Secure Generation**\n \n Maximum entropy tokens and encrypted client credentials protect sensitive data at rest.\n \u003C/Card>\n\u003C/CardGrid>\n\n## Security-First Design Principles\n\n### **Secure by Default**\nEvery security feature is enabled out-of-the-box. Users must explicitly *disable* security measures, not remember to enable them.\n\n**Why this matters:** Most security breaches happen because developers forget to enable protection, not because protection fails.\n\n### **Fail Secure**\nWhen something goes wrong, the system fails to a secure state, never fails \"open\" to convenience.\n\n**Example:** If rate limiting data is corrupted, the system blocks requests rather than allowing unlimited access.\n\n### **Zero Trust**\nEvery input is validated, every output is sanitized, every request is authenticated. Trust must be explicitly granted, never assumed.\n\n**WordPress connection:** This aligns with WordPress's capability system - specific permissions for specific actions.\n\n### **Observable Security**\nEvery security decision creates an audit trail. Attack attempts are logged, patterns are detected, administrators are alerted.\n\n**Why this matters:** You can't defend against what you can't see.\n\n### **Minimal Attack Surface**\nOnly essential functionality is exposed. Every endpoint, every parameter, every feature is justified by necessity.\n\n**Trade-off:** Slightly more restrictive than permissive OAuth2 servers, but dramatically more secure.\n\n## The Threat Landscape Evolution\n\nUnderstanding why these security layers exist requires understanding how threats have evolved:\n\n### **2012: Basic OAuth2 Threats**\n- Credential theft through HTTP interception\n- Authorization code replay attacks\n- Simple redirect URI manipulation\n\n### **2018: Sophisticated Attacks** \n- SQL injection through OAuth parameters\n- Cross-site scripting via malformed requests\n- Brute force attacks on client credentials\n- Advanced persistent threats targeting OAuth infrastructure\n\n### **2024: State-Sponsored and AI-Enhanced Attacks**\n- Automated vulnerability discovery\n- Large-scale credential stuffing\n- Supply chain attacks targeting OAuth libraries\n- AI-generated attack patterns that bypass traditional defenses\n\n**TigerStyle Scent was designed for the 2024 threat landscape while maintaining compatibility with 2012 OAuth2 standards.**\n\n## Security Architecture Deep Dive\n\n### **Layer Interaction Patterns**\n\nThe seven layers don't just provide independent protection - they work together to create emergent security properties:\n\n```mermaid\ngraph TD\n A[Incoming Request] --> B[Transport Security]\n B --> C[Input Validation]\n C --> D[Rate Limiting Check]\n D --> E[Authentication]\n E --> F[Authorization]\n F --> G[Business Logic]\n G --> H[Response Generation]\n H --> I[Monitoring & Logging]\n \n I --> J[Security Pattern Analysis]\n J --> K[Threat Response]\n K --> L[Adaptive Security Adjustments]\n```\n\n### **Cascading Protection**\nWhen one layer detects a threat, it can trigger enhanced protection in other layers:\n\n- **Input validation failure** → Increased rate limiting sensitivity\n- **Authentication anomalies** → Enhanced monitoring and logging\n- **Pattern detection** → Temporary IP blocking and admin alerts\n\n### **Performance-Security Balance**\nEach layer is optimized for both security and performance:\n\n- **Caching:** Security decisions are cached to avoid repeated computation\n- **Lazy evaluation:** Expensive security checks only run when necessary\n- **WordPress integration:** Uses WordPress's built-in caching and database layers\n\n## The WordPress Integration Philosophy\n\nTigerStyle Scent doesn't just run *on* WordPress - it's designed to be a *WordPress citizen*:\n\n### **Capability Integration**\nOAuth2 scopes map to WordPress capabilities, leveraging WordPress's mature permission system:\n\n```php\n// OAuth2 scope \"posts:read\" maps to WordPress capability \"read\"\n// OAuth2 scope \"posts:write\" maps to WordPress capability \"edit_posts\"\n```\n\n### **Hook System Integration**\nSecurity events integrate with WordPress's action/filter system:\n\n```php\n// Other plugins can respond to security events\ndo_action('tigerstyle_scent_security_event', $event_type, $details);\n\n// Security policies can be modified by themes/plugins\n$policy = apply_filters('tigerstyle_scent_security_policy', $default_policy);\n```\n\n### **Database Pattern Compliance**\nAll security data uses WordPress database patterns:\n\n- Custom tables follow WordPress naming conventions\n- All queries use `$wpdb->prepare()` for injection prevention\n- Caching uses WordPress transients for scalability\n\n## Security vs. Usability Trade-offs\n\nEvery security decision involves trade-offs. TigerStyle Scent makes these consciously:\n\n### **Stricter Than Standard OAuth2**\n- **PKCE required** for all public clients (OAuth2 makes it optional)\n- **HTTPS enforced** for all operations (OAuth2 allows HTTP in development)\n- **Conservative token lifetimes** (30 minutes vs. industry standard 1 hour)\n\n**Reasoning:** WordPress sites often run on shared hosting with limited security monitoring. Conservative defaults protect users who can't implement comprehensive security monitoring.\n\n### **More Verbose Error Handling**\n- **Development mode:** Detailed error messages for debugging\n- **Production mode:** Generic error messages that don't leak information\n\n**Reasoning:** Debugging OAuth2 is notoriously difficult. Clear error messages in development speed up legitimate development while generic messages in production prevent information disclosure.\n\n### **Performance Impact**\n- **5-10ms additional latency** per OAuth2 request for security processing\n- **Database overhead** for comprehensive logging and monitoring\n\n**Reasoning:** The performance cost is minimal compared to the business impact of a security breach.\n\n## The Security Exemplar Mission\n\nTigerStyle Scent exists to prove a point: **WordPress plugins can achieve enterprise-grade security without sacrificing functionality or usability.**\n\n### **Educational Impact**\nEvery security decision is documented and explained, creating a learning resource for the WordPress community.\n\n### **Standard Setting**\nBy implementing comprehensive security measures, TigerStyle Scent demonstrates what's possible when developers prioritize user protection.\n\n### **Ecosystem Improvement**\nOpen-source security patterns that other plugin developers can adapt and implement.\n\n## Lessons for Your Implementation\n\nWhether you're building OAuth2 systems or any security-sensitive WordPress functionality, these architectural principles apply:\n\n1. **Design for the current threat landscape**, not outdated examples\n2. **Layer your defenses** - don't rely on single points of protection \n3. **Integrate with WordPress patterns** rather than fighting them\n4. **Make security observable** through comprehensive logging\n5. **Default to secure** and require explicit action to reduce protection\n6. **Document your security decisions** for future maintainers\n\n---\n\n\u003CAside type=\"tip\">\n**Going Deeper**\n\nThis explanation provides the conceptual foundation. To see these principles in action:\n\n- **Build it yourself:** [Your First OAuth2 Server Tutorial](/tutorials/first-oauth2-flow/)\n- **Solve specific problems:** [How-to Guides](/how-to/fix-sql-injection/) \n- **Look up technical details:** [API Reference](/api/authorization/)\n\u003C/Aside>\n\nUnderstanding OAuth2 security architecture helps you make informed decisions about implementation trade-offs, threat modeling, and security investments. Security isn't just about following checklists - it's about understanding the *why* behind each protection measure.","src/content/docs/explanation/oauth2-architecture.md","0bdb56e0f3343b17",{"html":108,"metadata":109},"\u003Cp>import { Card, CardGrid, Aside } from ‘@astrojs/starlight/components’;\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"understanding-oauth2-security-architecture\">Understanding OAuth2 Security Architecture\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#understanding-oauth2-security-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Understanding OAuth2 Security Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>OAuth2 is powerful, but power without security is dangerous. Understanding \u003Cstrong>why\u003C/strong> security measures exist helps you make better implementation decisions and avoid the pitfalls that have plagued countless WordPress plugins.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-oauth2-security-challenge\">The OAuth2 Security Challenge\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-oauth2-security-challenge\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The OAuth2 Security Challenge”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>OAuth2 was designed for a simpler web - before mobile apps, before sophisticated attacks, before the WordPress ecosystem became a prime target for bad actors. Today’s OAuth2 implementations must defend against threats the original RFC authors never imagined.\u003C/p>\n\u003Cp>\u003Cstrong>The fundamental tension:\u003C/strong> OAuth2 prioritizes developer convenience over security. This makes it easy to implement, but also easy to implement \u003Cem>badly\u003C/em>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"why-wordpress-oauth2-plugins-fail-at-security\">Why WordPress OAuth2 Plugins Fail at Security\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#why-wordpress-oauth2-plugins-fail-at-security\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why WordPress OAuth2 Plugins Fail at Security”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The WordPress plugin ecosystem has been “pillaged” by insecure implementations because:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-the-copy-paste-culture\">1. \u003Cstrong>The Copy-Paste Culture\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-the-copy-paste-culture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. The Copy-Paste Culture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Developers copy vulnerable examples from outdated tutorials, perpetuating security anti-patterns across thousands of plugins.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2-the-good-enough-mindset\">2. \u003Cstrong>The “Good Enough” Mindset\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2-the-good-enough-mindset\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. The “Good Enough” Mindset”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Basic OAuth2 functionality \u003Cem>appears\u003C/em> to work fine, hiding critical security flaws until it’s too late.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"3-wordpress-specific-blind-spots\">3. \u003Cstrong>WordPress-Specific Blind Spots\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#3-wordpress-specific-blind-spots\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. WordPress-Specific Blind Spots”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Developers familiar with WordPress often miss OAuth2-specific security requirements, while OAuth2 experts don’t understand WordPress security patterns.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"4-the-security-performance-trade-off\">4. \u003Cstrong>The Security-Performance Trade-off\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#4-the-security-performance-trade-off\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4. The Security-Performance Trade-off”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Shared hosting environments discourage robust security measures that might impact performance.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-tigerstyle-seven-layer-security-model\">The TigerStyle Seven-Layer Security Model\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-tigerstyle-seven-layer-security-model\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The TigerStyle Seven-Layer Security Model”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>TigerStyle Scent addresses these challenges with a comprehensive \u003Cstrong>defense-in-depth\u003C/strong> approach. Each layer provides independent protection, ensuring that even if one layer fails, others maintain security.\u003C/p>\n\u003Ccardgrid>\n \u003Ccard title=\"🌐 Layer 1: Transport Security\" icon=\"laptop\">\n **HTTPS Enforcement + Security Headers**\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.p1z7b.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Ensures all OAuth2 communication happens over encrypted channels with comprehensive browser security policies.\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Ensures all OAuth2 communication happens over encrypted channels with comprehensive browser security policies.\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n \u003C/card>\n \u003Ccard title=\"🛡️ Layer 2: Input Validation\" icon=\"approve-check\">\n **Multi-Pattern Validation Framework**\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Every input undergoes type validation, length checking, pattern matching, and security scanning before processing.\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Every input undergoes type validation, length checking, pattern matching, and security scanning before processing.\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n \u003C/card>\n \u003Ccard title=\"⚡ Layer 3: Rate Limiting\" icon=\"rocket\">\n **Progressive Throttling System**\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">HMAC-based client fingerprinting with exponential backoff prevents abuse while maintaining usability.\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"HMAC-based client fingerprinting with exponential backoff prevents abuse while maintaining usability.\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n \u003C/card>\n \u003Ccard title=\"🔐 Layer 4: Authentication\" icon=\"lock\">\n **Secure Client Verification**\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Argon2ID password hashing and comprehensive token validation protect against credential attacks.\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Argon2ID password hashing and comprehensive token validation protect against credential attacks.\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n \u003C/card>\n \u003Ccard title=\"📊 Layer 5: Monitoring\" icon=\"information\">\n **Real-time Threat Detection**\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Structured logging and pattern analysis automatically identify and respond to security threats.\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Structured logging and pattern analysis automatically identify and respond to security threats.\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n \u003C/card>\n \u003Ccard title=\"🎯 Layer 6: Authorization\" icon=\"setting\">\n **Scope-based Access Control**\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Granular permissions with PKCE enforcement ensure clients only access approved resources.\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Granular permissions with PKCE enforcement ensure clients only access approved resources.\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n \u003C/card>\n \u003Ccard title=\"🔒 Layer 7: Data Protection\" icon=\"star\">\n **Encrypted Storage + Secure Generation**\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Maximum entropy tokens and encrypted client credentials protect sensitive data at rest.\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Maximum entropy tokens and encrypted client credentials protect sensitive data at rest.\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n \u003C/card>\n\u003C/cardgrid>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"security-first-design-principles\">Security-First Design Principles\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#security-first-design-principles\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Security-First Design Principles”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"secure-by-default\">\u003Cstrong>Secure by Default\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#secure-by-default\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Secure by Default”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Every security feature is enabled out-of-the-box. Users must explicitly \u003Cem>disable\u003C/em> security measures, not remember to enable them.\u003C/p>\n\u003Cp>\u003Cstrong>Why this matters:\u003C/strong> Most security breaches happen because developers forget to enable protection, not because protection fails.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"fail-secure\">\u003Cstrong>Fail Secure\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#fail-secure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Fail Secure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When something goes wrong, the system fails to a secure state, never fails “open” to convenience.\u003C/p>\n\u003Cp>\u003Cstrong>Example:\u003C/strong> If rate limiting data is corrupted, the system blocks requests rather than allowing unlimited access.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"zero-trust\">\u003Cstrong>Zero Trust\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#zero-trust\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Zero Trust”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Every input is validated, every output is sanitized, every request is authenticated. Trust must be explicitly granted, never assumed.\u003C/p>\n\u003Cp>\u003Cstrong>WordPress connection:\u003C/strong> This aligns with WordPress’s capability system - specific permissions for specific actions.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"observable-security\">\u003Cstrong>Observable Security\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#observable-security\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Observable Security”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Every security decision creates an audit trail. Attack attempts are logged, patterns are detected, administrators are alerted.\u003C/p>\n\u003Cp>\u003Cstrong>Why this matters:\u003C/strong> You can’t defend against what you can’t see.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"minimal-attack-surface\">\u003Cstrong>Minimal Attack Surface\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#minimal-attack-surface\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Minimal Attack Surface”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Only essential functionality is exposed. Every endpoint, every parameter, every feature is justified by necessity.\u003C/p>\n\u003Cp>\u003Cstrong>Trade-off:\u003C/strong> Slightly more restrictive than permissive OAuth2 servers, but dramatically more secure.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-threat-landscape-evolution\">The Threat Landscape Evolution\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-threat-landscape-evolution\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Threat Landscape Evolution”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Understanding why these security layers exist requires understanding how threats have evolved:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2012-basic-oauth2-threats\">\u003Cstrong>2012: Basic OAuth2 Threats\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2012-basic-oauth2-threats\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2012: Basic OAuth2 Threats”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Credential theft through HTTP interception\u003C/li>\n\u003Cli>Authorization code replay attacks\u003C/li>\n\u003Cli>Simple redirect URI manipulation\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2018-sophisticated-attacks\">\u003Cstrong>2018: Sophisticated Attacks\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2018-sophisticated-attacks\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2018: Sophisticated Attacks”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>SQL injection through OAuth parameters\u003C/li>\n\u003Cli>Cross-site scripting via malformed requests\u003C/li>\n\u003Cli>Brute force attacks on client credentials\u003C/li>\n\u003Cli>Advanced persistent threats targeting OAuth infrastructure\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2024-state-sponsored-and-ai-enhanced-attacks\">\u003Cstrong>2024: State-Sponsored and AI-Enhanced Attacks\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2024-state-sponsored-and-ai-enhanced-attacks\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2024: State-Sponsored and AI-Enhanced Attacks”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Automated vulnerability discovery\u003C/li>\n\u003Cli>Large-scale credential stuffing\u003C/li>\n\u003Cli>Supply chain attacks targeting OAuth libraries\u003C/li>\n\u003Cli>AI-generated attack patterns that bypass traditional defenses\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>TigerStyle Scent was designed for the 2024 threat landscape while maintaining compatibility with 2012 OAuth2 standards.\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"security-architecture-deep-dive\">Security Architecture Deep Dive\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#security-architecture-deep-dive\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Security Architecture Deep Dive”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"layer-interaction-patterns\">\u003Cstrong>Layer Interaction Patterns\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#layer-interaction-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Layer Interaction Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The seven layers don’t just provide independent protection - they work together to create emergent security properties:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"mermaid\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">graph TD\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">A[Incoming Request] --> B[Transport Security]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">B --> C[Input Validation]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">C --> D[Rate Limiting Check]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">D --> E[Authentication]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">E --> F[Authorization]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">F --> G[Business Logic]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">G --> H[Response Generation]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">H --> I[Monitoring & Logging]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">I --> J[Security Pattern Analysis]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">J --> K[Threat Response]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">K --> L[Adaptive Security Adjustments]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"graph TD A[Incoming Request] --> B[Transport Security] B --> C[Input Validation] C --> D[Rate Limiting Check] D --> E[Authentication] E --> F[Authorization] F --> G[Business Logic] G --> H[Response Generation] H --> I[Monitoring & Logging] I --> J[Security Pattern Analysis] J --> K[Threat Response] K --> L[Adaptive Security Adjustments]\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"cascading-protection\">\u003Cstrong>Cascading Protection\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#cascading-protection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cascading Protection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When one layer detects a threat, it can trigger enhanced protection in other layers:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Input validation failure\u003C/strong> → Increased rate limiting sensitivity\u003C/li>\n\u003Cli>\u003Cstrong>Authentication anomalies\u003C/strong> → Enhanced monitoring and logging\u003C/li>\n\u003Cli>\u003Cstrong>Pattern detection\u003C/strong> → Temporary IP blocking and admin alerts\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"performance-security-balance\">\u003Cstrong>Performance-Security Balance\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#performance-security-balance\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance-Security Balance”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each layer is optimized for both security and performance:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Caching:\u003C/strong> Security decisions are cached to avoid repeated computation\u003C/li>\n\u003Cli>\u003Cstrong>Lazy evaluation:\u003C/strong> Expensive security checks only run when necessary\u003C/li>\n\u003Cli>\u003Cstrong>WordPress integration:\u003C/strong> Uses WordPress’s built-in caching and database layers\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-wordpress-integration-philosophy\">The WordPress Integration Philosophy\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-wordpress-integration-philosophy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The WordPress Integration Philosophy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>TigerStyle Scent doesn’t just run \u003Cem>on\u003C/em> WordPress - it’s designed to be a \u003Cem>WordPress citizen\u003C/em>:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"capability-integration\">\u003Cstrong>Capability Integration\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#capability-integration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Capability Integration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>OAuth2 scopes map to WordPress capabilities, leveraging WordPress’s mature permission system:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// OAuth2 scope \"posts:read\" maps to WordPress capability \"read\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// OAuth2 scope \"posts:write\" maps to WordPress capability \"edit_posts\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// OAuth2 scope "posts:read" maps to WordPress capability "read"// OAuth2 scope "posts:write" maps to WordPress capability "edit_posts"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"hook-system-integration\">\u003Cstrong>Hook System Integration\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#hook-system-integration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Hook System Integration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Security events integrate with WordPress’s action/filter system:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Other plugins can respond to security events\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">do_action\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">tigerstyle_scent_security_event\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">$\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">event_type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">$\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">details\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Security policies can be modified by themes/plugins\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$policy\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">apply_filters\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">tigerstyle_scent_security_policy\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">$\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">default_policy\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Other plugins can respond to security eventsdo_action('tigerstyle_scent_security_event', $event_type, $details);// Security policies can be modified by themes/plugins$policy = apply_filters('tigerstyle_scent_security_policy', $default_policy);\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"database-pattern-compliance\">\u003Cstrong>Database Pattern Compliance\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#database-pattern-compliance\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Database Pattern Compliance”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All security data uses WordPress database patterns:\u003C/p>\n\u003Cul>\n\u003Cli>Custom tables follow WordPress naming conventions\u003C/li>\n\u003Cli>All queries use \u003Ccode dir=\"auto\">$wpdb->prepare()\u003C/code> for injection prevention\u003C/li>\n\u003Cli>Caching uses WordPress transients for scalability\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"security-vs-usability-trade-offs\">Security vs. Usability Trade-offs\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#security-vs-usability-trade-offs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Security vs. Usability Trade-offs”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Every security decision involves trade-offs. TigerStyle Scent makes these consciously:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"stricter-than-standard-oauth2\">\u003Cstrong>Stricter Than Standard OAuth2\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#stricter-than-standard-oauth2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Stricter Than Standard OAuth2”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>PKCE required\u003C/strong> for all public clients (OAuth2 makes it optional)\u003C/li>\n\u003Cli>\u003Cstrong>HTTPS enforced\u003C/strong> for all operations (OAuth2 allows HTTP in development)\u003C/li>\n\u003Cli>\u003Cstrong>Conservative token lifetimes\u003C/strong> (30 minutes vs. industry standard 1 hour)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Reasoning:\u003C/strong> WordPress sites often run on shared hosting with limited security monitoring. Conservative defaults protect users who can’t implement comprehensive security monitoring.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"more-verbose-error-handling\">\u003Cstrong>More Verbose Error Handling\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#more-verbose-error-handling\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “More Verbose Error Handling”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Development mode:\u003C/strong> Detailed error messages for debugging\u003C/li>\n\u003Cli>\u003Cstrong>Production mode:\u003C/strong> Generic error messages that don’t leak information\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Reasoning:\u003C/strong> Debugging OAuth2 is notoriously difficult. Clear error messages in development speed up legitimate development while generic messages in production prevent information disclosure.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"performance-impact\">\u003Cstrong>Performance Impact\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#performance-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance Impact”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>5-10ms additional latency\u003C/strong> per OAuth2 request for security processing\u003C/li>\n\u003Cli>\u003Cstrong>Database overhead\u003C/strong> for comprehensive logging and monitoring\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Reasoning:\u003C/strong> The performance cost is minimal compared to the business impact of a security breach.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-security-exemplar-mission\">The Security Exemplar Mission\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-security-exemplar-mission\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Security Exemplar Mission”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>TigerStyle Scent exists to prove a point: \u003Cstrong>WordPress plugins can achieve enterprise-grade security without sacrificing functionality or usability.\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"educational-impact\">\u003Cstrong>Educational Impact\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#educational-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Educational Impact”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Every security decision is documented and explained, creating a learning resource for the WordPress community.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"standard-setting\">\u003Cstrong>Standard Setting\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#standard-setting\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard Setting”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>By implementing comprehensive security measures, TigerStyle Scent demonstrates what’s possible when developers prioritize user protection.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"ecosystem-improvement\">\u003Cstrong>Ecosystem Improvement\u003C/strong>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#ecosystem-improvement\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Ecosystem Improvement”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Open-source security patterns that other plugin developers can adapt and implement.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"lessons-for-your-implementation\">Lessons for Your Implementation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#lessons-for-your-implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Lessons for Your Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Whether you’re building OAuth2 systems or any security-sensitive WordPress functionality, these architectural principles apply:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Design for the current threat landscape\u003C/strong>, not outdated examples\u003C/li>\n\u003Cli>\u003Cstrong>Layer your defenses\u003C/strong> - don’t rely on single points of protection\u003C/li>\n\u003Cli>\u003Cstrong>Integrate with WordPress patterns\u003C/strong> rather than fighting them\u003C/li>\n\u003Cli>\u003Cstrong>Make security observable\u003C/strong> through comprehensive logging\u003C/li>\n\u003Cli>\u003Cstrong>Default to secure\u003C/strong> and require explicit action to reduce protection\u003C/li>\n\u003Cli>\u003Cstrong>Document your security decisions\u003C/strong> for future maintainers\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Caside type=\"tip\">\n**Going Deeper**\n\u003Cp>This explanation provides the conceptual foundation. To see these principles in action:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Build it yourself:\u003C/strong> \u003Ca href=\"/tutorials/first-oauth2-flow/\">Your First OAuth2 Server Tutorial\u003C/a>\u003C/li>\n\u003Cli>\u003Cstrong>Solve specific problems:\u003C/strong> \u003Ca href=\"/how-to/fix-sql-injection/\">How-to Guides\u003C/a>\u003C/li>\n\u003Cli>\u003Cstrong>Look up technical details:\u003C/strong> \u003Ca href=\"/api/authorization/\">API Reference\u003C/a>\u003C/li>\n\u003C/ul>\n\u003C/aside>\n\u003Cp>Understanding OAuth2 security architecture helps you make informed decisions about implementation trade-offs, threat modeling, and security investments. Security isn’t just about following checklists - it’s about understanding the \u003Cem>why\u003C/em> behind each protection measure.\u003C/p>",{"headings":110,"localImagePaths":216,"remoteImagePaths":217,"frontmatter":100,"imagePaths":218},[111,113,116,119,123,126,129,132,135,138,141,144,147,150,153,156,159,162,165,168,171,174,177,180,183,186,189,192,195,198,201,204,207,210,213],{"depth":37,"slug":112,"text":101},"understanding-oauth2-security-architecture",{"depth":58,"slug":114,"text":115},"the-oauth2-security-challenge","The OAuth2 Security Challenge",{"depth":58,"slug":117,"text":118},"why-wordpress-oauth2-plugins-fail-at-security","Why WordPress OAuth2 Plugins Fail at Security",{"depth":120,"slug":121,"text":122},3,"1-the-copy-paste-culture","1. The Copy-Paste Culture",{"depth":120,"slug":124,"text":125},"2-the-good-enough-mindset","2. The “Good Enough” Mindset",{"depth":120,"slug":127,"text":128},"3-wordpress-specific-blind-spots","3. WordPress-Specific Blind Spots",{"depth":120,"slug":130,"text":131},"4-the-security-performance-trade-off","4. The Security-Performance Trade-off",{"depth":58,"slug":133,"text":134},"the-tigerstyle-seven-layer-security-model","The TigerStyle Seven-Layer Security Model",{"depth":58,"slug":136,"text":137},"security-first-design-principles","Security-First Design Principles",{"depth":120,"slug":139,"text":140},"secure-by-default","Secure by Default",{"depth":120,"slug":142,"text":143},"fail-secure","Fail Secure",{"depth":120,"slug":145,"text":146},"zero-trust","Zero Trust",{"depth":120,"slug":148,"text":149},"observable-security","Observable Security",{"depth":120,"slug":151,"text":152},"minimal-attack-surface","Minimal Attack Surface",{"depth":58,"slug":154,"text":155},"the-threat-landscape-evolution","The Threat Landscape Evolution",{"depth":120,"slug":157,"text":158},"2012-basic-oauth2-threats","2012: Basic OAuth2 Threats",{"depth":120,"slug":160,"text":161},"2018-sophisticated-attacks","2018: Sophisticated Attacks",{"depth":120,"slug":163,"text":164},"2024-state-sponsored-and-ai-enhanced-attacks","2024: State-Sponsored and AI-Enhanced Attacks",{"depth":58,"slug":166,"text":167},"security-architecture-deep-dive","Security Architecture Deep Dive",{"depth":120,"slug":169,"text":170},"layer-interaction-patterns","Layer Interaction Patterns",{"depth":120,"slug":172,"text":173},"cascading-protection","Cascading Protection",{"depth":120,"slug":175,"text":176},"performance-security-balance","Performance-Security Balance",{"depth":58,"slug":178,"text":179},"the-wordpress-integration-philosophy","The WordPress Integration Philosophy",{"depth":120,"slug":181,"text":182},"capability-integration","Capability Integration",{"depth":120,"slug":184,"text":185},"hook-system-integration","Hook System Integration",{"depth":120,"slug":187,"text":188},"database-pattern-compliance","Database Pattern Compliance",{"depth":58,"slug":190,"text":191},"security-vs-usability-trade-offs","Security vs. Usability Trade-offs",{"depth":120,"slug":193,"text":194},"stricter-than-standard-oauth2","Stricter Than Standard OAuth2",{"depth":120,"slug":196,"text":197},"more-verbose-error-handling","More Verbose Error Handling",{"depth":120,"slug":199,"text":200},"performance-impact","Performance Impact",{"depth":58,"slug":202,"text":203},"the-security-exemplar-mission","The Security Exemplar Mission",{"depth":120,"slug":205,"text":206},"educational-impact","Educational Impact",{"depth":120,"slug":208,"text":209},"standard-setting","Standard Setting",{"depth":120,"slug":211,"text":212},"ecosystem-improvement","Ecosystem Improvement",{"depth":58,"slug":214,"text":215},"lessons-for-your-implementation","Lessons for Your Implementation",[],[],[],"explanation/oauth2-architecture.md","api/authorization",{"id":220,"data":222,"body":226,"filePath":227,"digest":228,"rendered":229,"legacyId":337},{"title":223,"description":224,"sidebar":225},"Authorization Endpoint Reference","Technical specification for the OAuth2 authorization endpoint with security parameters and response formats",{"order":37},"import { Code, Aside } from '@astrojs/starlight/components';\n\n# Authorization Endpoint Reference\n\n## Endpoint URL\n\n```\nGET /oauth/authorize\n```\n\n**Base URL:** `https://yourwordpress.com/oauth/authorize`\n\n## Required Parameters\n\n| Parameter | Type | Description | Validation |\n|-----------|------|-------------|------------|\n| `response_type` | string | Must be `code` for authorization code flow | Enum: `[\"code\"]` |\n| `client_id` | string | Client identifier issued during registration | Regex: `^[a-zA-Z0-9._-]+$`\u003Cbr>Max length: 255 |\n| `redirect_uri` | string | Client redirect URI (must match registered URI) | Must be HTTPS in production\u003Cbr>WordPress `esc_url_raw()` validation |\n\n## Optional Parameters\n\n| Parameter | Type | Description | Validation |\n|-----------|------|-------------|------------|\n| `scope` | string | Space-delimited list of access scopes | Regex: `^[a-zA-Z0-9 ._-]+$`\u003Cbr>Max length: 500 |\n| `state` | string | Opaque value for CSRF protection | Max length: 255\u003Cbr>Recommended for security |\n\n## PKCE Parameters (Required for Public Clients)\n\n| Parameter | Type | Description | Validation |\n|-----------|------|-------------|------------|\n| `code_challenge` | string | Base64url-encoded SHA256 hash of code verifier | Base64url format\u003Cbr>Length: 43 characters |\n| `code_challenge_method` | string | Method used to derive code challenge | Enum: `[\"S256\"]` |\n\n## Security Headers\n\n### Required Request Headers\n\n```http\nHost: yourwordpress.com\nUser-Agent: YourApp/1.0\nAccept: text/html,application/xhtml+xml\n```\n\n### Required Response Headers\n\nAll authorization responses include security headers:\n\n```http\nX-Frame-Options: DENY\nX-XSS-Protection: 1; mode=block\nX-Content-Type-Options: nosniff\nContent-Security-Policy: default-src 'none'; script-src 'none'\nStrict-Transport-Security: max-age=31536000; includeSubDomains\nCache-Control: no-store, no-cache, must-revalidate\n```\n\n## Response Types\n\n### Success Response (Authorization Granted)\n\n**HTTP 302 Redirect**\n\n```http\nLocation: https://client.example.com/callback?code=territory_abc123&state=xyz\n```\n\n**Query Parameters:**\n\n| Parameter | Description |\n|-----------|-------------|\n| `code` | Authorization code (prefixed with `territory_`) |\n| `state` | Echo of the state parameter from request |\n\n### Error Responses\n\n**HTTP 302 Redirect with Error**\n\n```http\nLocation: https://client.example.com/callback?error=invalid_request&error_description=Missing+client_id&state=xyz\n```\n\n**Error Codes:**\n\n| Error Code | Description | HTTP Status |\n|------------|-------------|-------------|\n| `invalid_request` | Missing or malformed required parameter | 302 |\n| `unauthorized_client` | Client not authorized for this grant type | 302 |\n| `access_denied` | User denied the authorization request | 302 |\n| `unsupported_response_type` | Response type not supported | 302 |\n| `invalid_scope` | Requested scope invalid or unknown | 302 |\n| `server_error` | Internal server error occurred | 302 |\n| `temporarily_unavailable` | Service temporarily overloaded | 302 |\n\n### Direct Error Responses (No Redirect)\n\nWhen redirect_uri is invalid or missing:\n\n**HTTP 400 Bad Request**\n\n```json\n{\n \"error\": \"invalid_request\",\n \"error_description\": \"Invalid redirect_uri parameter\"\n}\n```\n\n## Example Requests\n\n### Basic Authorization Request\n\n```http\nGET /oauth/authorize?response_type=code&client_id=client_abc123&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback&scope=basic&state=random123 HTTP/1.1\nHost: wordpress.example.com\n```\n\n### PKCE-Enhanced Request (Recommended)\n\n```http\nGET /oauth/authorize?response_type=code&client_id=client_abc123&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback&scope=basic&state=random123&code_challenge=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk&code_challenge_method=S256 HTTP/1.1\nHost: wordpress.example.com\n```\n\n## Rate Limiting\n\n**Limits:**\n- 30 requests per hour per client IP\n- 60 requests per hour per client_id\n\n**Rate Limit Headers:**\n\n```http\nX-RateLimit-Limit: 30\nX-RateLimit-Remaining: 25\nX-RateLimit-Reset: 1640995200\n```\n\n**Rate Limit Exceeded Response:**\n\n```http\nHTTP/1.1 429 Too Many Requests\nRetry-After: 3600\n\n{\n \"error\": \"rate_limit_exceeded\",\n \"error_description\": \"Too many authorization requests\"\n}\n```\n\n## Security Validations\n\n### Input Validation\n\nAll parameters undergo comprehensive validation:\n\n1. **Type validation** - Correct data types\n2. **Length validation** - Within specified limits \n3. **Pattern validation** - Regex format checking\n4. **Security validation** - SQL injection, XSS, attack pattern detection\n5. **Business validation** - Client exists, redirect URI matches\n\n### Authorization Header Protection\n\n\u003CAside type=\"caution\">\n**Security Feature:** The authorization endpoint validates all HTTP headers to prevent injection attacks.\n\nInvalid authorization headers are rejected:\n```http\nAuthorization: Bearer '; DROP TABLE users; --\n```\nResults in immediate request termination with security logging.\n\u003C/Aside>\n\n### PKCE Validation\n\nFor public clients (JavaScript apps, mobile apps):\n\n1. **code_challenge required** - Must be present\n2. **S256 method enforced** - Plain text challenges rejected\n3. **Length validation** - Must be exactly 43 characters\n4. **Format validation** - Base64url encoding verified\n\n## WordPress Integration\n\n### User Authentication\n\nAuthorization requests require user authentication:\n\n1. **Not logged in:** Redirected to WordPress login\n2. **Logged in:** Proceeds to consent screen\n3. **Consent required:** User must explicitly approve each client\n\n### Capability Checks\n\nOAuth2 scopes map to WordPress capabilities:\n\n| OAuth2 Scope | WordPress Capability | Description |\n|--------------|---------------------|-------------|\n| `basic` | `read` | Read user profile |\n| `posts:read` | `read` | Read published posts |\n| `posts:write` | `edit_posts` | Create/edit posts |\n| `admin` | `manage_options` | Administrative access |\n\n### Database Operations\n\nAll database queries use WordPress prepared statements:\n\n```php\n$client = $wpdb->get_row($wpdb->prepare(\n \"SELECT * FROM {$wpdb->prefix}oauth_clients WHERE client_id = %s\",\n $client_id\n));\n```\n\n## Testing Examples\n\n### cURL Examples\n\n**Basic authorization request:**\n```bash\ncurl -v \"https://wordpress.example.com/oauth/authorize?response_type=code&client_id=client_abc123&redirect_uri=https%3A%2F%2Fhttpbin.org%2Fanything&scope=basic&state=test123\"\n```\n\n**With PKCE:**\n```bash\n# Generate code verifier and challenge first\nCODE_VERIFIER=$(openssl rand -base64 32 | tr -d \"=+/\" | cut -c1-43)\nCODE_CHALLENGE=$(echo -n $CODE_VERIFIER | openssl dgst -sha256 -binary | openssl base64 | tr -d \"=+/\" | cut -c1-43)\n\ncurl -v \"https://wordpress.example.com/oauth/authorize?response_type=code&client_id=client_abc123&redirect_uri=https%3A%2F%2Fhttpbin.org%2Fanything&scope=basic&state=test123&code_challenge=$CODE_CHALLENGE&code_challenge_method=S256\"\n```\n\n### JavaScript Example\n\n```javascript\n// Construct authorization URL\nconst params = new URLSearchParams({\n response_type: 'code',\n client_id: 'client_abc123',\n redirect_uri: 'https://app.example.com/callback',\n scope: 'basic',\n state: generateRandomState(),\n code_challenge: await generatePKCE(),\n code_challenge_method: 'S256'\n});\n\n// Redirect user to authorization endpoint\nwindow.location = `https://wordpress.example.com/oauth/authorize?${params}`;\n```\n\n## Error Handling\n\n### Client-Side Error Handling\n\n```javascript\n// Parse callback URL for errors\nconst urlParams = new URLSearchParams(window.location.search);\n\nif (urlParams.has('error')) {\n const error = urlParams.get('error');\n const description = urlParams.get('error_description');\n \n switch (error) {\n case 'access_denied':\n // User denied authorization\n showMessage('Authorization was denied');\n break;\n case 'invalid_scope':\n // Requested scope not available\n showMessage('Invalid permissions requested');\n break;\n default:\n showMessage(`Authorization error: ${description}`);\n }\n}\n```\n\n### Server-Side Validation\n\n```php\n// Validate authorization response\nif (isset($_GET['error'])) {\n $error = sanitize_text_field($_GET['error']);\n $description = sanitize_text_field($_GET['error_description']);\n \n switch ($error) {\n case 'access_denied':\n // Handle user denial\n break;\n case 'invalid_client':\n // Handle client configuration error\n break;\n default:\n // Handle other errors\n }\n}\n```\n\n## Security Considerations\n\n### Redirect URI Validation\n\n- **Exact match required** - No partial matching\n- **HTTPS enforced** - HTTP only allowed for localhost in development\n- **No wildcards** - Subdomains must be explicitly registered\n- **Fragment validation** - Fragments are stripped and validated\n\n### State Parameter Best Practices\n\n- **Always use state** - Prevents CSRF attacks\n- **Cryptographically random** - Use secure random generation\n- **Session binding** - Tie state to user session\n- **Single use** - Validate and invalidate after use\n\n### PKCE Implementation\n\n- **Code verifier:** 43-128 characters, base64url-encoded\n- **Code challenge:** SHA256 hash of verifier, base64url-encoded\n- **Method:** Only S256 supported (plain text rejected)\n- **Storage:** Store challenge with authorization code\n\n---\n\n**Related References:**\n- [Token Endpoint](/api/token/) - Exchange authorization codes for access tokens\n- [Introspection Endpoint](/api/introspection/) - Validate access tokens\n- [Error Code Reference](/api/errors/) - Complete error code documentation","src/content/docs/api/authorization.md","865ba7bbe0897abf",{"html":230,"metadata":231},"\u003Cp>import { Code, Aside } from ‘@astrojs/starlight/components’;\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"authorization-endpoint-reference\">Authorization Endpoint Reference\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#authorization-endpoint-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Authorization Endpoint Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"endpoint-url\">Endpoint URL\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#endpoint-url\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Endpoint URL”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.p1z7b.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">GET /oauth/authorize\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"GET /oauth/authorize\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Base URL:\u003C/strong> \u003Ccode dir=\"auto\">https://yourwordpress.com/oauth/authorize\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"required-parameters\">Required Parameters\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#required-parameters\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Required Parameters”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Parameter\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003Cth>Validation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">response_type\u003C/code>\u003C/td>\u003Ctd>string\u003C/td>\u003Ctd>Must be \u003Ccode dir=\"auto\">code\u003C/code> for authorization code flow\u003C/td>\u003Ctd>Enum: \u003Ccode dir=\"auto\">[\"code\"]\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">client_id\u003C/code>\u003C/td>\u003Ctd>string\u003C/td>\u003Ctd>Client identifier issued during registration\u003C/td>\u003Ctd>Regex: \u003Ccode dir=\"auto\">^[a-zA-Z0-9._-]+$\u003C/code>\u003Cbr>Max length: 255\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">redirect_uri\u003C/code>\u003C/td>\u003Ctd>string\u003C/td>\u003Ctd>Client redirect URI (must match registered URI)\u003C/td>\u003Ctd>Must be HTTPS in production\u003Cbr>WordPress \u003Ccode dir=\"auto\">esc_url_raw()\u003C/code> validation\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"optional-parameters\">Optional Parameters\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#optional-parameters\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Optional Parameters”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Parameter\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003Cth>Validation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">scope\u003C/code>\u003C/td>\u003Ctd>string\u003C/td>\u003Ctd>Space-delimited list of access scopes\u003C/td>\u003Ctd>Regex: \u003Ccode dir=\"auto\">^[a-zA-Z0-9 ._-]+$\u003C/code>\u003Cbr>Max length: 500\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">state\u003C/code>\u003C/td>\u003Ctd>string\u003C/td>\u003Ctd>Opaque value for CSRF protection\u003C/td>\u003Ctd>Max length: 255\u003Cbr>Recommended for security\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"pkce-parameters-required-for-public-clients\">PKCE Parameters (Required for Public Clients)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#pkce-parameters-required-for-public-clients\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PKCE Parameters (Required for Public Clients)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Parameter\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003Cth>Validation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">code_challenge\u003C/code>\u003C/td>\u003Ctd>string\u003C/td>\u003Ctd>Base64url-encoded SHA256 hash of code verifier\u003C/td>\u003Ctd>Base64url format\u003Cbr>Length: 43 characters\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">code_challenge_method\u003C/code>\u003C/td>\u003Ctd>string\u003C/td>\u003Ctd>Method used to derive code challenge\u003C/td>\u003Ctd>Enum: \u003Ccode dir=\"auto\">[\"S256\"]\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"security-headers\">Security Headers\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#security-headers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Security Headers”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"required-request-headers\">Required Request Headers\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#required-request-headers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Required Request Headers”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"http\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#CAECE6\">Host\u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">yourwordpress.com\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#CAECE6\">User-Agent\u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">YourApp/1.0\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#CAECE6\">Accept\u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">text/html,application/xhtml+xml\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Host: yourwordpress.comUser-Agent: YourApp/1.0Accept: text/html,application/xhtml+xml\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"required-response-headers\">Required Response Headers\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#required-response-headers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Required Response Headers”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All authorization responses include security headers:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"http\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#CAECE6\">X-Frame-Options\u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">DENY\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#CAECE6\">X-XSS-Protection\u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">1; mode=block\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#CAECE6\">X-Content-Type-Options\u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">nosniff\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#CAECE6\">Content-Security-Policy\u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">default-src 'none'; script-src 'none'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#CAECE6\">Strict-Transport-Security\u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">max-age=31536000; includeSubDomains\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#CAECE6\">Cache-Control\u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">no-store, no-cache, must-revalidate\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"X-Frame-Options: DENYX-XSS-Protection: 1; mode=blockX-Content-Type-Options: nosniffContent-Security-Policy: default-src 'none'; script-src 'none'Strict-Transport-Security: max-age=31536000; includeSubDomainsCache-Control: no-store, no-cache, must-revalidate\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"response-types\">Response Types\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#response-types\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Response Types”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"success-response-authorization-granted\">Success Response (Authorization Granted)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#success-response-authorization-granted\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Response (Authorization Granted)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>HTTP 302 Redirect\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"http\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#CAECE6\">Location\u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">https://client.example.com/callback?code=territory_abc123&state=xyz\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Location: https://client.example.com/callback?code=territory_abc123&state=xyz\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Query Parameters:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Parameter\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">code\u003C/code>\u003C/td>\u003Ctd>Authorization code (prefixed with \u003Ccode dir=\"auto\">territory_\u003C/code>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">state\u003C/code>\u003C/td>\u003Ctd>Echo of the state parameter from request\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"error-responses\">Error Responses\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#error-responses\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Error Responses”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>HTTP 302 Redirect with Error\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"http\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#CAECE6\">Location\u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">https://client.example.com/callback?error=invalid_request&error_description=Missing+client_id&state=xyz\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Location: https://client.example.com/callback?error=invalid_request&error_description=Missing+client_id&state=xyz\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Error Codes:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Error Code\u003C/th>\u003Cth>Description\u003C/th>\u003Cth>HTTP Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">invalid_request\u003C/code>\u003C/td>\u003Ctd>Missing or malformed required parameter\u003C/td>\u003Ctd>302\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">unauthorized_client\u003C/code>\u003C/td>\u003Ctd>Client not authorized for this grant type\u003C/td>\u003Ctd>302\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">access_denied\u003C/code>\u003C/td>\u003Ctd>User denied the authorization request\u003C/td>\u003Ctd>302\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">unsupported_response_type\u003C/code>\u003C/td>\u003Ctd>Response type not supported\u003C/td>\u003Ctd>302\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">invalid_scope\u003C/code>\u003C/td>\u003Ctd>Requested scope invalid or unknown\u003C/td>\u003Ctd>302\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">server_error\u003C/code>\u003C/td>\u003Ctd>Internal server error occurred\u003C/td>\u003Ctd>302\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">temporarily_unavailable\u003C/code>\u003C/td>\u003Ctd>Service temporarily overloaded\u003C/td>\u003Ctd>302\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"direct-error-responses-no-redirect\">Direct Error Responses (No Redirect)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#direct-error-responses-no-redirect\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Direct Error Responses (No Redirect)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When redirect_uri is invalid or missing:\u003C/p>\n\u003Cp>\u003Cstrong>HTTP 400 Bad Request\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"json\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"error\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">invalid_request\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"error_description\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">Invalid redirect_uri parameter\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"{ "error": "invalid_request", "error_description": "Invalid redirect_uri parameter"}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"example-requests\">Example Requests\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#example-requests\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example Requests”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"basic-authorization-request\">Basic Authorization Request\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#basic-authorization-request\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Basic Authorization Request”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"http\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">GET\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> /oauth/authorize?response_type=code&client_id=client_abc123&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback&scope=basic&state=random123 \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">HTTP\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">/\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1.1\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#CAECE6\">Host\u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">wordpress.example.com\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"GET /oauth/authorize?response_type=code&client_id=client_abc123&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback&scope=basic&state=random123 HTTP/1.1Host: wordpress.example.com\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pkce-enhanced-request-recommended\">PKCE-Enhanced Request (Recommended)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pkce-enhanced-request-recommended\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PKCE-Enhanced Request (Recommended)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"http\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">GET\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> /oauth/authorize?response_type=code&client_id=client_abc123&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback&scope=basic&state=random123&code_challenge=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk&code_challenge_method=S256 \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">HTTP\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">/\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1.1\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#CAECE6\">Host\u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">wordpress.example.com\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"GET /oauth/authorize?response_type=code&client_id=client_abc123&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback&scope=basic&state=random123&code_challenge=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk&code_challenge_method=S256 HTTP/1.1Host: wordpress.example.com\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"rate-limiting\">Rate Limiting\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#rate-limiting\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Rate Limiting”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Limits:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>30 requests per hour per client IP\u003C/li>\n\u003Cli>60 requests per hour per client_id\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Rate Limit Headers:\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"http\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#CAECE6\">X-RateLimit-Limit\u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">30\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#CAECE6\">X-RateLimit-Remaining\u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">25\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#CAECE6\">X-RateLimit-Reset\u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">1640995200\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"X-RateLimit-Limit: 30X-RateLimit-Remaining: 25X-RateLimit-Reset: 1640995200\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Rate Limit Exceeded Response:\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"http\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">HTTP\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">/\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1.1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">429\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Too Many Requests\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#CAECE6\">Retry-After\u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">3600\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"error\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">rate_limit_exceeded\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"error_description\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">Too many authorization requests\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"HTTP/1.1 429 Too Many RequestsRetry-After: 3600{ "error": "rate_limit_exceeded", "error_description": "Too many authorization requests"}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"security-validations\">Security Validations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#security-validations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Security Validations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"input-validation\">Input Validation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#input-validation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Input Validation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All parameters undergo comprehensive validation:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Type validation\u003C/strong> - Correct data types\u003C/li>\n\u003Cli>\u003Cstrong>Length validation\u003C/strong> - Within specified limits\u003C/li>\n\u003Cli>\u003Cstrong>Pattern validation\u003C/strong> - Regex format checking\u003C/li>\n\u003Cli>\u003Cstrong>Security validation\u003C/strong> - SQL injection, XSS, attack pattern detection\u003C/li>\n\u003Cli>\u003Cstrong>Business validation\u003C/strong> - Client exists, redirect URI matches\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"authorization-header-protection\">Authorization Header Protection\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#authorization-header-protection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Authorization Header Protection”\u003C/span>\u003C/a>\u003C/div>\n\u003Caside type=\"caution\">\n**Security Feature:** The authorization endpoint validates all HTTP headers to prevent injection attacks.\n\u003Cp>Invalid authorization headers are rejected:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"http\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#CAECE6\">Authorization\u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Bearer '; DROP TABLE users; --\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Authorization: Bearer '; DROP TABLE users; --\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Results in immediate request termination with security logging.\u003C/p>\n\u003C/aside>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pkce-validation\">PKCE Validation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pkce-validation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PKCE Validation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For public clients (JavaScript apps, mobile apps):\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>code_challenge required\u003C/strong> - Must be present\u003C/li>\n\u003Cli>\u003Cstrong>S256 method enforced\u003C/strong> - Plain text challenges rejected\u003C/li>\n\u003Cli>\u003Cstrong>Length validation\u003C/strong> - Must be exactly 43 characters\u003C/li>\n\u003Cli>\u003Cstrong>Format validation\u003C/strong> - Base64url encoding verified\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"wordpress-integration\">WordPress Integration\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#wordpress-integration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “WordPress Integration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"user-authentication\">User Authentication\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#user-authentication\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Authentication”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Authorization requests require user authentication:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Not logged in:\u003C/strong> Redirected to WordPress login\u003C/li>\n\u003Cli>\u003Cstrong>Logged in:\u003C/strong> Proceeds to consent screen\u003C/li>\n\u003Cli>\u003Cstrong>Consent required:\u003C/strong> User must explicitly approve each client\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"capability-checks\">Capability Checks\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#capability-checks\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Capability Checks”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>OAuth2 scopes map to WordPress capabilities:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>OAuth2 Scope\u003C/th>\u003Cth>WordPress Capability\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">basic\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">read\u003C/code>\u003C/td>\u003Ctd>Read user profile\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">posts:read\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">read\u003C/code>\u003C/td>\u003Ctd>Read published posts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">posts:write\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">edit_posts\u003C/code>\u003C/td>\u003Ctd>Create/edit posts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">admin\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">manage_options\u003C/code>\u003C/td>\u003Ctd>Administrative access\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"database-operations\">Database Operations\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#database-operations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Database Operations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All database queries use WordPress prepared statements:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$client\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">get_row\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">prepare\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">SELECT\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">FROM\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> {\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#111111\">prefix\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">}oauth_clients \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">WHERE\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> client_id \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> %s\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$client_id\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">));\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"$client = $wpdb->get_row($wpdb->prepare( "SELECT * FROM {$wpdb->prefix}oauth_clients WHERE client_id = %s", $client_id));\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"testing-examples\">Testing Examples\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#testing-examples\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Testing Examples”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"curl-examples\">cURL Examples\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#curl-examples\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “cURL Examples”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Basic authorization request:\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">curl\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-v\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">https://wordpress.example.com/oauth/authorize?response_type=code&client_id=client_abc123&redirect_uri=https%3A%2F%2Fhttpbin.org%2Fanything&scope=basic&state=test123\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"curl -v "https://wordpress.example.com/oauth/authorize?response_type=code&client_id=client_abc123&redirect_uri=https%3A%2F%2Fhttpbin.org%2Fanything&scope=basic&state=test123"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>With PKCE:\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Generate code verifier and challenge first\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">CODE_VERIFIER\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">$(\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">openssl\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rand\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-base64\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">32\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">tr\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-d\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">=+/\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">cut\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-c1-43\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">CODE_CHALLENGE\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">$(\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">echo\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-n\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$CODE_VERIFIER\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">openssl\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">dgst\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-sha256\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-binary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">openssl\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">base64\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">tr\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-d\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">=+/\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">cut\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-c1-43\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">curl\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-v\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">https://wordpress.example.com/oauth/authorize?response_type=code&client_id=client_abc123&redirect_uri=https%3A%2F%2Fhttpbin.org%2Fanything&scope=basic&state=test123&code_challenge=\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$CODE_CHALLENGE\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">&code_challenge_method=S256\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"CODE_VERIFIER=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-43)CODE_CHALLENGE=$(echo -n $CODE_VERIFIER | openssl dgst -sha256 -binary | openssl base64 | tr -d "=+/" | cut -c1-43)curl -v "https://wordpress.example.com/oauth/authorize?response_type=code&client_id=client_abc123&redirect_uri=https%3A%2F%2Fhttpbin.org%2Fanything&scope=basic&state=test123&code_challenge=$CODE_CHALLENGE&code_challenge_method=S256"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"javascript-example\">JavaScript Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#javascript-example\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “JavaScript Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Construct authorization URL\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">params\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">URLSearchParams\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">response_type: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">code\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">client_id: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">client_abc123\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">redirect_uri: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">https://app.example.com/callback\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">scope: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">basic\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">state: \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">generateRandomState\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">code_challenge: await \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">generatePKCE\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">code_challenge_method: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">S256\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Redirect user to authorization endpoint\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">window\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">location\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">https://wordpress.example.com/oauth/authorize?\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">params\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Construct authorization URLconst params = new URLSearchParams({ response_type: 'code', client_id: 'client_abc123', redirect_uri: 'https://app.example.com/callback', scope: 'basic', state: generateRandomState(), code_challenge: await generatePKCE(), code_challenge_method: 'S256'});// Redirect user to authorization endpointwindow.location = `https://wordpress.example.com/oauth/authorize?${params}`;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"error-handling\">Error Handling\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#error-handling\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Error Handling”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"client-side-error-handling\">Client-Side Error Handling\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#client-side-error-handling\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Client-Side Error Handling”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Parse callback URL for errors\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">urlParams\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">URLSearchParams\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">window\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">location\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">search\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">urlParams\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">has\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">error\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">urlParams\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">get\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">error\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">description\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">urlParams\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">get\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">error_description\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">switch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> (\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">case\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">access_denied\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// User denied authorization\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">showMessage\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Authorization was denied\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">break\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">case\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">invalid_scope\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Requested scope not available\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">showMessage\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Invalid permissions requested\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">break\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">default\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">showMessage\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Authorization error: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">description\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Parse callback URL for errorsconst urlParams = new URLSearchParams(window.location.search);if (urlParams.has('error')) { const error = urlParams.get('error'); const description = urlParams.get('error_description'); switch (error) { case 'access_denied': // User denied authorization showMessage('Authorization was denied'); break; case 'invalid_scope': // Requested scope not available showMessage('Invalid permissions requested'); break; default: showMessage(`Authorization error: ${description}`); }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"server-side-validation\">Server-Side Validation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#server-side-validation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Server-Side Validation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Validate authorization response\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">isset\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$_GET\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">error\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">])) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sanitize_text_field\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$_GET\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">error\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$description\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sanitize_text_field\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$_GET\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">error_description\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">switch\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">case\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">access_denied\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Handle user denial\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">break\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">case\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">invalid_client\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Handle client configuration error\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">break\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">default\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Handle other errors\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Validate authorization responseif (isset($_GET['error'])) { $error = sanitize_text_field($_GET['error']); $description = sanitize_text_field($_GET['error_description']); switch ($error) { case 'access_denied': // Handle user denial break; case 'invalid_client': // Handle client configuration error break; default: // Handle other errors }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"security-considerations\">Security Considerations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#security-considerations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Security Considerations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"redirect-uri-validation\">Redirect URI Validation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#redirect-uri-validation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Redirect URI Validation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Exact match required\u003C/strong> - No partial matching\u003C/li>\n\u003Cli>\u003Cstrong>HTTPS enforced\u003C/strong> - HTTP only allowed for localhost in development\u003C/li>\n\u003Cli>\u003Cstrong>No wildcards\u003C/strong> - Subdomains must be explicitly registered\u003C/li>\n\u003Cli>\u003Cstrong>Fragment validation\u003C/strong> - Fragments are stripped and validated\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"state-parameter-best-practices\">State Parameter Best Practices\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#state-parameter-best-practices\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “State Parameter Best Practices”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Always use state\u003C/strong> - Prevents CSRF attacks\u003C/li>\n\u003Cli>\u003Cstrong>Cryptographically random\u003C/strong> - Use secure random generation\u003C/li>\n\u003Cli>\u003Cstrong>Session binding\u003C/strong> - Tie state to user session\u003C/li>\n\u003Cli>\u003Cstrong>Single use\u003C/strong> - Validate and invalidate after use\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pkce-implementation\">PKCE Implementation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pkce-implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PKCE Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Code verifier:\u003C/strong> 43-128 characters, base64url-encoded\u003C/li>\n\u003Cli>\u003Cstrong>Code challenge:\u003C/strong> SHA256 hash of verifier, base64url-encoded\u003C/li>\n\u003Cli>\u003Cstrong>Method:\u003C/strong> Only S256 supported (plain text rejected)\u003C/li>\n\u003Cli>\u003Cstrong>Storage:\u003C/strong> Store challenge with authorization code\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cp>\u003Cstrong>Related References:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"/api/token/\">Token Endpoint\u003C/a> - Exchange authorization codes for access tokens\u003C/li>\n\u003Cli>\u003Ca href=\"/api/introspection/\">Introspection Endpoint\u003C/a> - Validate access tokens\u003C/li>\n\u003Cli>\u003Ca href=\"/api/errors/\">Error Code Reference\u003C/a> - Complete error code documentation\u003C/li>\n\u003C/ul>",{"headings":232,"localImagePaths":334,"remoteImagePaths":335,"frontmatter":222,"imagePaths":336},[233,235,238,241,244,247,250,253,256,259,262,265,268,271,274,277,280,283,286,289,292,295,298,301,304,307,310,313,316,319,322,325,328,331],{"depth":37,"slug":234,"text":223},"authorization-endpoint-reference",{"depth":58,"slug":236,"text":237},"endpoint-url","Endpoint URL",{"depth":58,"slug":239,"text":240},"required-parameters","Required Parameters",{"depth":58,"slug":242,"text":243},"optional-parameters","Optional Parameters",{"depth":58,"slug":245,"text":246},"pkce-parameters-required-for-public-clients","PKCE Parameters (Required for Public Clients)",{"depth":58,"slug":248,"text":249},"security-headers","Security Headers",{"depth":120,"slug":251,"text":252},"required-request-headers","Required Request Headers",{"depth":120,"slug":254,"text":255},"required-response-headers","Required Response Headers",{"depth":58,"slug":257,"text":258},"response-types","Response Types",{"depth":120,"slug":260,"text":261},"success-response-authorization-granted","Success Response (Authorization Granted)",{"depth":120,"slug":263,"text":264},"error-responses","Error Responses",{"depth":120,"slug":266,"text":267},"direct-error-responses-no-redirect","Direct Error Responses (No Redirect)",{"depth":58,"slug":269,"text":270},"example-requests","Example Requests",{"depth":120,"slug":272,"text":273},"basic-authorization-request","Basic Authorization Request",{"depth":120,"slug":275,"text":276},"pkce-enhanced-request-recommended","PKCE-Enhanced Request (Recommended)",{"depth":58,"slug":278,"text":279},"rate-limiting","Rate Limiting",{"depth":58,"slug":281,"text":282},"security-validations","Security Validations",{"depth":120,"slug":284,"text":285},"input-validation","Input Validation",{"depth":120,"slug":287,"text":288},"authorization-header-protection","Authorization Header Protection",{"depth":120,"slug":290,"text":291},"pkce-validation","PKCE Validation",{"depth":58,"slug":293,"text":294},"wordpress-integration","WordPress Integration",{"depth":120,"slug":296,"text":297},"user-authentication","User Authentication",{"depth":120,"slug":299,"text":300},"capability-checks","Capability Checks",{"depth":120,"slug":302,"text":303},"database-operations","Database Operations",{"depth":58,"slug":305,"text":306},"testing-examples","Testing Examples",{"depth":120,"slug":308,"text":309},"curl-examples","cURL Examples",{"depth":120,"slug":311,"text":312},"javascript-example","JavaScript Example",{"depth":58,"slug":314,"text":315},"error-handling","Error Handling",{"depth":120,"slug":317,"text":318},"client-side-error-handling","Client-Side Error Handling",{"depth":120,"slug":320,"text":321},"server-side-validation","Server-Side Validation",{"depth":58,"slug":323,"text":324},"security-considerations","Security Considerations",{"depth":120,"slug":326,"text":327},"redirect-uri-validation","Redirect URI Validation",{"depth":120,"slug":329,"text":330},"state-parameter-best-practices","State Parameter Best Practices",{"depth":120,"slug":332,"text":333},"pkce-implementation","PKCE Implementation",[],[],[],"api/authorization.md","how-to/fix-sql-injection",{"id":338,"data":340,"body":344,"filePath":345,"digest":346,"rendered":347,"legacyId":392},{"title":341,"description":342,"sidebar":343},"How to Fix SQL Injection in OAuth2 Plugins","Step-by-step guide to eliminate SQL injection vulnerabilities in WordPress OAuth2 implementations",{"order":37},"import { Card, Code, Steps, Aside } from '@astrojs/starlight/components';\n\n# How to Fix SQL Injection in OAuth2 Plugins\n\n## Problem\n\nYour security audit identified SQL injection vulnerabilities in OAuth2 authentication flows. These critical vulnerabilities (CVSS 9.8) allow attackers to execute arbitrary SQL commands, potentially compromising your entire WordPress database.\n\n**Common vulnerable patterns found in OAuth2 plugins:**\n- Direct string concatenation in SQL queries\n- Unsanitized user input in database operations \n- Missing WordPress `$wpdb->prepare()` usage\n- Improper handling of client credentials\n\n## Solution Overview\n\nWe'll secure all database queries using WordPress prepared statements and proper input validation. This approach provides bulletproof protection against SQL injection while maintaining OAuth2 functionality.\n\n## Before You Start\n\n\u003CAside type=\"caution\">\n**Always backup your database before applying security fixes!**\n\n```bash\n# Create database backup\nmysqldump -u username -p database_name > oauth2_backup.sql\n```\n\u003C/Aside>\n\n**You'll need:**\n- WordPress admin access\n- FTP/SSH access to your server\n- Text editor or IDE\n- Database backup (created above)\n\n## Step 1: Identify Vulnerable Queries\n\nFirst, let's find the problematic code patterns. Search your OAuth2 plugin files for these dangerous patterns:\n\n\u003CSteps>\n\n1. **Search for direct SQL concatenation**\n\n Look for code like this in your plugin files:\n\n ```php\n // ❌ VULNERABLE - Direct string concatenation\n $query = \"SELECT * FROM {$wpdb->prefix}oauth_clients WHERE client_id = '$client_id'\";\n $client = $wpdb->get_row($query);\n ```\n\n2. **Check admin table operations**\n\n OAuth2 admin interfaces often contain vulnerable queries:\n\n ```php\n // ❌ VULNERABLE - User input directly in query\n $search = $_GET['s'];\n $query = \"SELECT * FROM {$wpdb->prefix}posts WHERE post_title LIKE '%$search%'\";\n ```\n\n3. **Review client authentication code**\n\n Client credential verification is commonly vulnerable:\n\n ```php\n // ❌ VULNERABLE - Client secret in direct query\n $query = \"SELECT * FROM clients WHERE client_secret = '$secret'\";\n ```\n\n\u003C/Steps>\n\n## Step 2: Replace with Prepared Statements\n\nNow we'll fix each vulnerable query using WordPress `$wpdb->prepare()`:\n\n\u003CSteps>\n\n1. **Fix client lookup queries**\n\n **Before (Vulnerable):**\n ```php\n $query = \"SELECT * FROM {$wpdb->prefix}oauth_clients WHERE client_id = '$client_id'\";\n $client = $wpdb->get_row($query);\n ```\n\n **After (Secure):**\n ```php\n $client = $wpdb->get_row($wpdb->prepare(\n \"SELECT * FROM {$wpdb->prefix}oauth_clients WHERE client_id = %s\",\n $client_id\n ));\n ```\n\n2. **Fix search functionality**\n\n **Before (Vulnerable):**\n ```php\n $search = $_GET['s'];\n $query = \"SELECT * FROM {$wpdb->prefix}posts WHERE post_title LIKE '%$search%'\";\n ```\n\n **After (Secure):**\n ```php\n $search = sanitize_text_field($_GET['s']);\n $results = $wpdb->get_results($wpdb->prepare(\n \"SELECT * FROM {$wpdb->prefix}posts WHERE post_title LIKE %s\",\n '%' . $wpdb->esc_like($search) . '%'\n ));\n ```\n\n3. **Fix token validation**\n\n **Before (Vulnerable):**\n ```php\n $query = \"SELECT * FROM tokens WHERE access_token = '$token' AND expires > NOW()\";\n ```\n\n **After (Secure):**\n ```php\n $token_data = $wpdb->get_row($wpdb->prepare(\n \"SELECT * FROM {$wpdb->prefix}oauth_access_tokens \n WHERE access_token = %s AND expires > NOW()\",\n $token\n ));\n ```\n\n\u003C/Steps>\n\n## Step 3: Implement Comprehensive Input Validation\n\nBeyond prepared statements, add proper input validation:\n\n\u003CSteps>\n\n1. **Validate OAuth2 parameters**\n\n ```php\n // ✅ SECURE - Comprehensive validation\n function validate_client_id($client_id) {\n if (empty($client_id)) {\n return false;\n }\n \n // Sanitize using WordPress function\n $client_id = sanitize_text_field($client_id);\n \n // Validate format (alphanumeric, underscore, hyphen only)\n if (!preg_match('/^[a-zA-Z0-9._-]+$/', $client_id)) {\n return false;\n }\n \n // Check length constraints\n if (strlen($client_id) > 255) {\n return false;\n }\n \n return $client_id;\n }\n ```\n\n2. **Sanitize redirect URIs**\n\n ```php\n // ✅ SECURE - URL validation and sanitization\n function validate_redirect_uri($uri) {\n if (empty($uri)) {\n return false;\n }\n \n // WordPress URL sanitization\n $uri = esc_url_raw($uri);\n \n // Ensure HTTPS in production\n if (!is_ssl() && strpos($uri, 'https://') !== 0) {\n return false;\n }\n \n return $uri;\n }\n ```\n\n3. **Validate authorization codes**\n\n ```php\n // ✅ SECURE - Authorization code validation\n function validate_authorization_code($code) {\n if (empty($code)) {\n return false;\n }\n \n // Sanitize\n $code = sanitize_text_field($code);\n \n // Validate format (base64url characters only)\n if (!preg_match('/^[A-Za-z0-9+\\/=._-]+$/', $code)) {\n return false;\n }\n \n return $code;\n }\n ```\n\n\u003C/Steps>\n\n## Step 4: Update Admin Interface Queries\n\nOAuth2 admin interfaces are common injection points. Here's how to secure them:\n\n\u003CSteps>\n\n1. **Fix client listing with search**\n\n **Before (Vulnerable):**\n ```php\n $search_query = \"WHERE post_title LIKE '%{$_GET['s']}%'\";\n $query = \"SELECT * FROM {$wpdb->prefix}posts {$search_query}\";\n ```\n\n **After (Secure):**\n ```php\n $search = '';\n $search_params = [];\n \n if (!empty($_GET['s'])) {\n $search_term = sanitize_text_field($_GET['s']);\n $search = \"WHERE post_title LIKE %s\";\n $search_params[] = '%' . $wpdb->esc_like($search_term) . '%';\n }\n \n $query = $wpdb->prepare(\n \"SELECT * FROM {$wpdb->prefix}posts {$search}\",\n $search_params\n );\n ```\n\n2. **Secure pagination queries**\n\n **Before (Vulnerable):**\n ```php\n $offset = $_GET['paged'] * $per_page;\n $query = \"SELECT * FROM clients LIMIT $per_page OFFSET $offset\";\n ```\n\n **After (Secure):**\n ```php\n $page = max(1, intval($_GET['paged']));\n $per_page = 20; // Fixed value, not user input\n $offset = ($page - 1) * $per_page;\n \n $results = $wpdb->get_results($wpdb->prepare(\n \"SELECT * FROM {$wpdb->prefix}oauth_clients \n ORDER BY created_at DESC \n LIMIT %d OFFSET %d\",\n $per_page,\n $offset\n ));\n ```\n\n\u003C/Steps>\n\n## Step 5: Test Your Fixes\n\nVerify that your SQL injection fixes work correctly:\n\n\u003CSteps>\n\n1. **Test normal functionality**\n\n - Create a new OAuth2 client\n - Perform authorization flow\n - Exchange tokens\n - Access protected resources\n\n2. **Test injection attempts**\n\n Try these malicious inputs to ensure they're blocked:\n\n ```bash\n # Test client_id injection\n curl \"https://yoursite.com/oauth/authorize?client_id=test'; DROP TABLE users; --\"\n \n # Test search injection \n curl \"https://yoursite.com/wp-admin/admin.php?page=oauth-clients&s='; DELETE FROM wp_posts; --\"\n \n # Test token injection\n curl -H \"Authorization: Bearer '; DROP TABLE oauth_tokens; --\" \\\n \"https://yoursite.com/oauth/introspect\"\n ```\n\n **Expected result:** All requests should be safely handled without SQL injection.\n\n3. **Check error logs**\n\n Monitor WordPress error logs for any SQL errors:\n\n ```bash\n tail -f /path/to/wordpress/wp-content/debug.log\n ```\n\n\u003C/Steps>\n\n## Step 6: Add Ongoing Protection\n\nImplement additional security measures to prevent future vulnerabilities:\n\n\u003CSteps>\n\n1. **Enable WordPress debugging (development only)**\n\n Add to `wp-config.php`:\n\n ```php\n define('WP_DEBUG', true);\n define('WP_DEBUG_LOG', true);\n define('WP_DEBUG_DISPLAY', false);\n ```\n\n2. **Add input validation helpers**\n\n Create reusable validation functions:\n\n ```php\n class OAuth2_Security_Validator {\n \n public static function validate_oauth_param($param, $type) {\n switch ($type) {\n case 'client_id':\n return self::validate_client_id($param);\n case 'redirect_uri':\n return self::validate_redirect_uri($param);\n case 'scope':\n return self::validate_scope($param);\n default:\n return sanitize_text_field($param);\n }\n }\n \n // ... validation methods\n }\n ```\n\n3. **Add security logging**\n\n Log potential injection attempts:\n\n ```php\n function log_security_event($event_type, $details) {\n if (defined('WP_DEBUG') && WP_DEBUG) {\n error_log(sprintf(\n '[OAuth2 Security] %s: %s',\n $event_type,\n json_encode($details)\n ));\n }\n }\n ```\n\n\u003C/Steps>\n\n## Common Pitfalls to Avoid\n\n\u003CCard title=\"❌ Don't escape manually\" icon=\"warning\">\nNever try to manually escape SQL strings. Always use `$wpdb->prepare()` with proper placeholders.\n\n```php\n// ❌ WRONG - Manual escaping is insufficient\n$safe_input = addslashes($user_input);\n$query = \"SELECT * FROM table WHERE field = '$safe_input'\";\n\n// ✅ CORRECT - Use prepared statements\n$result = $wpdb->get_row($wpdb->prepare(\n \"SELECT * FROM table WHERE field = %s\",\n $user_input\n));\n```\n\u003C/Card>\n\n\u003CCard title=\"❌ Don't trust sanitize functions for SQL\" icon=\"warning\">\nWordPress sanitization functions are for display, not SQL safety.\n\n```php\n// ❌ WRONG - sanitize_text_field doesn't prevent SQL injection\n$clean = sanitize_text_field($_POST['client_id']);\n$query = \"SELECT * FROM clients WHERE client_id = '$clean'\";\n\n// ✅ CORRECT - Use prepared statements\n$client = $wpdb->get_row($wpdb->prepare(\n \"SELECT * FROM clients WHERE client_id = %s\",\n $_POST['client_id']\n));\n```\n\u003C/Card>\n\n## Verification Checklist\n\nAfter implementing these fixes, verify:\n\n- [ ] All database queries use `$wpdb->prepare()` with placeholders\n- [ ] No direct string concatenation in SQL statements\n- [ ] Input validation applied before database operations\n- [ ] Search functionality uses `$wpdb->esc_like()` for LIKE queries\n- [ ] Admin interfaces properly sanitize user input\n- [ ] Error logging captures potential injection attempts\n- [ ] Functionality testing confirms everything works\n- [ ] Injection testing confirms vulnerabilities are fixed\n\n## Impact Assessment\n\n**Before fixes:**\n- CVSS Score: 9.8 (Critical)\n- Risk: Complete database compromise possible\n- Attack vector: Any OAuth2 parameter\n\n**After fixes:**\n- CVSS Score: 0.0 (Resolved)\n- Risk: SQL injection eliminated\n- Protection: Bulletproof prepared statements\n\n---\n\n**🛡️ Congratulations!** You've eliminated critical SQL injection vulnerabilities from your OAuth2 implementation. Your WordPress site is now protected against one of the most dangerous attack vectors. \n\n**Next:** Consider implementing [rate limiting protection](/how-to/implement-rate-limiting/) to defend against brute force attacks.","src/content/docs/how-to/fix-sql-injection.md","839213794b795b8a",{"html":348,"metadata":349},"\u003Cp>import { Card, Code, Steps, Aside } from ‘@astrojs/starlight/components’;\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"how-to-fix-sql-injection-in-oauth2-plugins\">How to Fix SQL Injection in OAuth2 Plugins\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#how-to-fix-sql-injection-in-oauth2-plugins\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How to Fix SQL Injection in OAuth2 Plugins”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"problem\">Problem\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#problem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Problem”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Your security audit identified SQL injection vulnerabilities in OAuth2 authentication flows. These critical vulnerabilities (CVSS 9.8) allow attackers to execute arbitrary SQL commands, potentially compromising your entire WordPress database.\u003C/p>\n\u003Cp>\u003Cstrong>Common vulnerable patterns found in OAuth2 plugins:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Direct string concatenation in SQL queries\u003C/li>\n\u003Cli>Unsanitized user input in database operations\u003C/li>\n\u003Cli>Missing WordPress \u003Ccode dir=\"auto\">$wpdb->prepare()\u003C/code> usage\u003C/li>\n\u003Cli>Improper handling of client credentials\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"solution-overview\">Solution Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#solution-overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Solution Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>We’ll secure all database queries using WordPress prepared statements and proper input validation. This approach provides bulletproof protection against SQL injection while maintaining OAuth2 functionality.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"before-you-start\">Before You Start\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#before-you-start\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Before You Start”\u003C/span>\u003C/a>\u003C/div>\n\u003Caside type=\"caution\">\n**Always backup your database before applying security fixes!**\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.p1z7b.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Create database backup\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">mysqldump\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-u\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">username\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-p\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">database_name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">oauth2_backup.sql\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"mysqldump -u username -p database_name > oauth2_backup.sql\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/aside>\n\u003Cp>\u003Cstrong>You’ll need:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>WordPress admin access\u003C/li>\n\u003Cli>FTP/SSH access to your server\u003C/li>\n\u003Cli>Text editor or IDE\u003C/li>\n\u003Cli>Database backup (created above)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-1-identify-vulnerable-queries\">Step 1: Identify Vulnerable Queries\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-1-identify-vulnerable-queries\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 1: Identify Vulnerable Queries”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>First, let’s find the problematic code patterns. Search your OAuth2 plugin files for these dangerous patterns:\u003C/p>\n\u003Csteps>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Search for direct SQL concatenation\u003C/strong>\u003C/p>\n\u003Cp>Look for code like this in your plugin files:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ❌ VULNERABLE - Direct string concatenation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$query\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">SELECT\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">FROM\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> {\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#111111\">prefix\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">}oauth_clients \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">WHERE\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> client_id \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> '\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$client_id\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">'\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$client\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">get_row\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$query\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// ❌ VULNERABLE - Direct string concatenation$query = "SELECT * FROM {$wpdb->prefix}oauth_clients WHERE client_id = '$client_id'";$client = $wpdb->get_row($query);\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Check admin table operations\u003C/strong>\u003C/p>\n\u003Cp>OAuth2 admin interfaces often contain vulnerable queries:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ❌ VULNERABLE - User input directly in query\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$search\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$_GET\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">s\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$query\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">SELECT\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">FROM\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> {\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#111111\">prefix\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">}posts \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">WHERE\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> post_title \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">LIKE\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> '%\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$search\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">%'\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// ❌ VULNERABLE - User input directly in query$search = $_GET['s'];$query = "SELECT * FROM {$wpdb->prefix}posts WHERE post_title LIKE '%$search%'";\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Review client authentication code\u003C/strong>\u003C/p>\n\u003Cp>Client credential verification is commonly vulnerable:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ❌ VULNERABLE - Client secret in direct query\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$query\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">SELECT\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">FROM\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> clients \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">WHERE\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> client_secret \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> '\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$secret\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">'\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// ❌ VULNERABLE - Client secret in direct query$query = "SELECT * FROM clients WHERE client_secret = '$secret'";\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003C/ol>\n\u003C/steps>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-2-replace-with-prepared-statements\">Step 2: Replace with Prepared Statements\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-2-replace-with-prepared-statements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 2: Replace with Prepared Statements”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Now we’ll fix each vulnerable query using WordPress \u003Ccode dir=\"auto\">$wpdb->prepare()\u003C/code>:\u003C/p>\n\u003Csteps>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Fix client lookup queries\u003C/strong>\u003C/p>\n\u003Cp>\u003Cstrong>Before (Vulnerable):\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$query\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">SELECT\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">FROM\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> {\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#111111\">prefix\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">}oauth_clients \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">WHERE\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> client_id \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> '\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$client_id\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">'\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$client\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">get_row\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$query\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"$query = "SELECT * FROM {$wpdb->prefix}oauth_clients WHERE client_id = '$client_id'";$client = $wpdb->get_row($query);\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>After (Secure):\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$client\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">get_row\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">prepare\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">SELECT\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">FROM\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> {\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#111111\">prefix\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">}oauth_clients \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">WHERE\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> client_id \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> %s\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$client_id\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">));\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"$client = $wpdb->get_row($wpdb->prepare( "SELECT * FROM {$wpdb->prefix}oauth_clients WHERE client_id = %s", $client_id));\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Fix search functionality\u003C/strong>\u003C/p>\n\u003Cp>\u003Cstrong>Before (Vulnerable):\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$search\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$_GET\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">s\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$query\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">SELECT\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">FROM\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> {\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#111111\">prefix\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">}posts \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">WHERE\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> post_title \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">LIKE\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> '%\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$search\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">%'\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"$search = $_GET['s'];$query = "SELECT * FROM {$wpdb->prefix}posts WHERE post_title LIKE '%$search%'";\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>After (Secure):\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$search\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sanitize_text_field\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$_GET\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">s\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$results\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">get_results\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">prepare\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">SELECT\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">FROM\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> {\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#111111\">prefix\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">}posts \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">WHERE\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> post_title \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">LIKE\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> %s\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">%\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">.\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">esc_like\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$search\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">.\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">%\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">));\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"$search = sanitize_text_field($_GET['s']);$results = $wpdb->get_results($wpdb->prepare( "SELECT * FROM {$wpdb->prefix}posts WHERE post_title LIKE %s", '%' . $wpdb->esc_like($search) . '%'));\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Fix token validation\u003C/strong>\u003C/p>\n\u003Cp>\u003Cstrong>Before (Vulnerable):\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$query\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">SELECT\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">FROM\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> tokens \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">WHERE\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> access_token \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> '\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$token\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">' \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">AND\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> expires \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">NOW\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">()\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"$query = "SELECT * FROM tokens WHERE access_token = '$token' AND expires > NOW()";\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>After (Secure):\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$token_data\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">get_row\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">prepare\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">SELECT\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">FROM\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> {\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#111111\">prefix\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">}oauth_access_tokens\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">WHERE\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> access_token \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> %s \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">AND\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> expires \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">NOW\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">()\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$token\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">));\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"$token_data = $wpdb->get_row($wpdb->prepare( "SELECT * FROM {$wpdb->prefix}oauth_access_tokens WHERE access_token = %s AND expires > NOW()", $token));\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003C/ol>\n\u003C/steps>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-3-implement-comprehensive-input-validation\">Step 3: Implement Comprehensive Input Validation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-3-implement-comprehensive-input-validation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 3: Implement Comprehensive Input Validation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Beyond prepared statements, add proper input validation:\u003C/p>\n\u003Csteps>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Validate OAuth2 parameters\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ✅ SECURE - Comprehensive validation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">function\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">validate_client_id\u003C/span>\u003Cspan style=\"--1:#111111\">\u003Cspan style=\"--0:#D9F5DD\">(\u003C/span>\u003Cspan style=\"--0:#BEC5D4\">$client_id\u003C/span>\u003Cspan style=\"--0:#D9F5DD\">)\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">empty\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">($\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">client_id\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">false\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Sanitize using WordPress function\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$client_id\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sanitize_text_field\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">($\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">client_id\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Validate format (alphanumeric, underscore, hyphen only)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">preg_match\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'/\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">^\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003Cspan style=\"--0:#5CA7E4;--1:#3A688F\">a-zA-Z0-9._-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">+$\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">/'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">$\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">client_id\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">false\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Check length constraints\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strlen\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">($\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">client_id\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">255\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">false\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$client_id\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// ✅ SECURE - Comprehensive validationfunction validate_client_id($client_id) { if (empty($client_id)) { return false; } // Sanitize using WordPress function $client_id = sanitize_text_field($client_id); // Validate format (alphanumeric, underscore, hyphen only) if (!preg_match('/^[a-zA-Z0-9._-]+$/', $client_id)) { return false; } // Check length constraints if (strlen($client_id) > 255) { return false; } return $client_id;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Sanitize redirect URIs\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ✅ SECURE - URL validation and sanitization\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">function\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">validate_redirect_uri\u003C/span>\u003Cspan style=\"--1:#111111\">\u003Cspan style=\"--0:#D9F5DD\">(\u003C/span>\u003Cspan style=\"--0:#BEC5D4\">$uri\u003C/span>\u003Cspan style=\"--0:#D9F5DD\">)\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">empty\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">($\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">uri\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">false\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// WordPress URL sanitization\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$uri\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">esc_url_raw\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">($\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">uri\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Ensure HTTPS in production\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">is_ssl\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">&&\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strpos\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">($\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">uri\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">https://\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!==\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">false\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$uri\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// ✅ SECURE - URL validation and sanitizationfunction validate_redirect_uri($uri) { if (empty($uri)) { return false; } // WordPress URL sanitization $uri = esc_url_raw($uri); // Ensure HTTPS in production if (!is_ssl() && strpos($uri, 'https://') !== 0) { return false; } return $uri;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Validate authorization codes\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ✅ SECURE - Authorization code validation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">function\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">validate_authorization_code\u003C/span>\u003Cspan style=\"--1:#111111\">\u003Cspan style=\"--0:#D9F5DD\">(\u003C/span>\u003Cspan style=\"--0:#BEC5D4\">$code\u003C/span>\u003Cspan style=\"--0:#D9F5DD\">)\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">empty\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">($\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">code\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">false\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Sanitize\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$code\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sanitize_text_field\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">($\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">code\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Validate format (base64url characters only)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">preg_match\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'/\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">^\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003Cspan style=\"--0:#5CA7E4;--1:#3A688F\">A-Za-z0-9+\\/=._-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">+$\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">/'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">$\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">code\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">false\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$code\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// ✅ SECURE - Authorization code validationfunction validate_authorization_code($code) { if (empty($code)) { return false; } // Sanitize $code = sanitize_text_field($code); // Validate format (base64url characters only) if (!preg_match('/^[A-Za-z0-9+\\/=._-]+$/', $code)) { return false; } return $code;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003C/ol>\n\u003C/steps>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-4-update-admin-interface-queries\">Step 4: Update Admin Interface Queries\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-4-update-admin-interface-queries\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 4: Update Admin Interface Queries”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>OAuth2 admin interfaces are common injection points. Here’s how to secure them:\u003C/p>\n\u003Csteps>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Fix client listing with search\u003C/strong>\u003C/p>\n\u003Cp>\u003Cstrong>Before (Vulnerable):\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$search_query\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">WHERE post_title LIKE '%{\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$_GET\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">s\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">}%'\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$query\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">SELECT\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">FROM\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> {\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#111111\">prefix\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">}posts {\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$search_query\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">}\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"$search_query = "WHERE post_title LIKE '%{$_GET['s']}%'";$query = "SELECT * FROM {$wpdb->prefix}posts {$search_query}";\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>After (Secure):\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$search\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">''\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$search_params\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> [];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">empty\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$_GET\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">s\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">])) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$search_term\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sanitize_text_field\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$_GET\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">s\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$search\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">WHERE post_title LIKE %s\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$search_params\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[] \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">%\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">.\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">esc_like\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$search_term\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">.\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">%\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$query\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">prepare\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">SELECT\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">FROM\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> {\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#111111\">prefix\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">}posts {\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$search\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">}\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$search_params\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"$search = '';$search_params = [];if (!empty($_GET['s'])) { $search_term = sanitize_text_field($_GET['s']); $search = "WHERE post_title LIKE %s"; $search_params[] = '%' . $wpdb->esc_like($search_term) . '%';}$query = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}posts {$search}", $search_params);\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Secure pagination queries\u003C/strong>\u003C/p>\n\u003Cp>\u003Cstrong>Before (Vulnerable):\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$offset\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$_GET\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">paged\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">] \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">*\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$per_page\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$query\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">SELECT\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">FROM\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> clients \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">LIMIT\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$per_page\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> OFFSET \u003C/span>\u003Cspan style=\"--1:#111111\">\u003Cspan style=\"--0:#BEC5D4\">$offset\u003C/span>\u003Cspan style=\"--0:#D9F5DD\">\"\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"$offset = $_GET['paged'] * $per_page;$query = "SELECT * FROM clients LIMIT $per_page OFFSET $offset";\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>After (Secure):\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$page\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">max\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003Cspan style=\"--1:#3B61B0\">\u003Cspan style=\"--0:#82AAFF\"> \u003C/span>\u003Cspan style=\"--0:#C5E478\">intval\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$_GET\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">paged\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]));\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$per_page\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">20\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Fixed value, not user input\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$offset\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$page\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">*\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$per_page\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$results\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">get_results\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">prepare\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">SELECT\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">FROM\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> {\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#111111\">prefix\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">}oauth_clients\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">ORDER BY\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> created_at \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">DESC\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">LIMIT\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> %d OFFSET %d\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$per_page\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$offset\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">));\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"$page = max(1, intval($_GET['paged']));$per_page = 20; // Fixed value, not user input$offset = ($page - 1) * $per_page;$results = $wpdb->get_results($wpdb->prepare( "SELECT * FROM {$wpdb->prefix}oauth_clients ORDER BY created_at DESC LIMIT %d OFFSET %d", $per_page, $offset));\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003C/ol>\n\u003C/steps>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-5-test-your-fixes\">Step 5: Test Your Fixes\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-5-test-your-fixes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 5: Test Your Fixes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Verify that your SQL injection fixes work correctly:\u003C/p>\n\u003Csteps>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Test normal functionality\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Create a new OAuth2 client\u003C/li>\n\u003Cli>Perform authorization flow\u003C/li>\n\u003Cli>Exchange tokens\u003C/li>\n\u003Cli>Access protected resources\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Test injection attempts\u003C/strong>\u003C/p>\n\u003Cp>Try these malicious inputs to ensure they’re blocked:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Test client_id injection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">curl\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">https://yoursite.com/oauth/authorize?client_id=test'; DROP TABLE users; --\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Test search injection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">curl\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">https://yoursite.com/wp-admin/admin.php?page=oauth-clients&s='; DELETE FROM wp_posts; --\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Test token injection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">curl\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-H\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Authorization: Bearer '; DROP TABLE oauth_tokens; --\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">https://yoursite.com/oauth/introspect\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"curl "https://yoursite.com/oauth/authorize?client_id=test'; DROP TABLE users; --"curl "https://yoursite.com/wp-admin/admin.php?page=oauth-clients&s='; DELETE FROM wp_posts; --"curl -H "Authorization: Bearer '; DROP TABLE oauth_tokens; --" \\ "https://yoursite.com/oauth/introspect"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Expected result:\u003C/strong> All requests should be safely handled without SQL injection.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Check error logs\u003C/strong>\u003C/p>\n\u003Cp>Monitor WordPress error logs for any SQL errors:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">tail\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-f\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">/path/to/wordpress/wp-content/debug.log\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"tail -f /path/to/wordpress/wp-content/debug.log\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003C/ol>\n\u003C/steps>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-6-add-ongoing-protection\">Step 6: Add Ongoing Protection\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-6-add-ongoing-protection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 6: Add Ongoing Protection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Implement additional security measures to prevent future vulnerabilities:\u003C/p>\n\u003Csteps>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Enable WordPress debugging (development only)\u003C/strong>\u003C/p>\n\u003Cp>Add to \u003Ccode dir=\"auto\">wp-config.php\u003C/code>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">define\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">WP_DEBUG\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\"> true\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">define\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">WP_DEBUG_LOG\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\"> true\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">define\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">WP_DEBUG_DISPLAY\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\"> false\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"define('WP_DEBUG', true);define('WP_DEBUG_LOG', true);define('WP_DEBUG_DISPLAY', false);\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Add input validation helpers\u003C/strong>\u003C/p>\n\u003Cp>Create reusable validation functions:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">class\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">OAuth2_Security_Validator\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">public\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">static\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">function\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">validate_oauth_param\u003C/span>\u003Cspan style=\"--1:#111111\">\u003Cspan style=\"--0:#D9F5DD\">(\u003C/span>\u003Cspan style=\"--0:#BEC5D4\">$param\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--1:#111111\">\u003Cspan style=\"--0:#BEC5D4\">$type\u003C/span>\u003Cspan style=\"--0:#D9F5DD\">)\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">switch\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">case\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">client_id\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">self\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">::\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">validate_client_id\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$param\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">case\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">redirect_uri\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">self\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">::\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">validate_redirect_uri\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$param\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">case\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">scope\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">self\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">::\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">validate_scope\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$param\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">default\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sanitize_text_field\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">($\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">param\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ... validation methods\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"class OAuth2_Security_Validator { public static function validate_oauth_param($param, $type) { switch ($type) { case 'client_id': return self::validate_client_id($param); case 'redirect_uri': return self::validate_redirect_uri($param); case 'scope': return self::validate_scope($param); default: return sanitize_text_field($param); } } // ... validation methods}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Add security logging\u003C/strong>\u003C/p>\n\u003Cp>Log potential injection attempts:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">function\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log_security_event\u003C/span>\u003Cspan style=\"--1:#111111\">\u003Cspan style=\"--0:#D9F5DD\">(\u003C/span>\u003Cspan style=\"--0:#BEC5D4\">$event_type\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--1:#111111\">\u003Cspan style=\"--0:#BEC5D4\">$details\u003C/span>\u003Cspan style=\"--0:#D9F5DD\">)\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">defined\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">WP_DEBUG\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">&&\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">WP_DEBUG\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">error_log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">sprintf\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">[OAuth2 Security] %s: %s\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">$\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">event_type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--1:#3B61B0\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">json_encode\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">($\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">details\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">));\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"function log_security_event($event_type, $details) { if (defined('WP_DEBUG') && WP_DEBUG) { error_log(sprintf( '[OAuth2 Security] %s: %s', $event_type, json_encode($details) )); }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003C/ol>\n\u003C/steps>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"common-pitfalls-to-avoid\">Common Pitfalls to Avoid\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#common-pitfalls-to-avoid\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Common Pitfalls to Avoid”\u003C/span>\u003C/a>\u003C/div>\n\u003Ccard title=\"❌ Don't escape manually\" icon=\"warning\">\nNever try to manually escape SQL strings. Always use `$wpdb->prepare()` with proper placeholders.\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ❌ WRONG - Manual escaping is insufficient\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$safe_input\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">addslashes\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">($\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">user_input\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$query\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">SELECT\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">FROM\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">table\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">WHERE\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> field \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> '\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$safe_input\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">'\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ✅ CORRECT - Use prepared statements\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$result\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">get_row\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">prepare\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">SELECT\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">FROM\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">table\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">WHERE\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> field \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> %s\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$user_input\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">));\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// ❌ WRONG - Manual escaping is insufficient$safe_input = addslashes($user_input);$query = "SELECT * FROM table WHERE field = '$safe_input'";// ✅ CORRECT - Use prepared statements$result = $wpdb->get_row($wpdb->prepare( "SELECT * FROM table WHERE field = %s", $user_input));\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/card>\n\u003Ccard title=\"❌ Don't trust sanitize functions for SQL\" icon=\"warning\">\nWordPress sanitization functions are for display, not SQL safety.\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"php\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ❌ WRONG - sanitize_text_field doesn't prevent SQL injection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$clean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sanitize_text_field\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$_POST\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">client_id\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$query\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">SELECT\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">FROM\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> clients \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">WHERE\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> client_id \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> '\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$clean\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">'\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ✅ CORRECT - Use prepared statements\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$client\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">get_row\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#BEC5D4;--1:#111111\">$wpdb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">->\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">prepare\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">SELECT\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">FROM\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> clients \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">WHERE\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> client_id \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> %s\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$_POST\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">client_id\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">));\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// ❌ WRONG - sanitize_text_field doesn't prevent SQL injection$clean = sanitize_text_field($_POST['client_id']);$query = "SELECT * FROM clients WHERE client_id = '$clean'";// ✅ CORRECT - Use prepared statements$client = $wpdb->get_row($wpdb->prepare( "SELECT * FROM clients WHERE client_id = %s", $_POST['client_id']));\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/card>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"verification-checklist\">Verification Checklist\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#verification-checklist\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Verification Checklist”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>After implementing these fixes, verify:\u003C/p>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> All database queries use \u003Ccode dir=\"auto\">$wpdb->prepare()\u003C/code> with placeholders\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> No direct string concatenation in SQL statements\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Input validation applied before database operations\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Search functionality uses \u003Ccode dir=\"auto\">$wpdb->esc_like()\u003C/code> for LIKE queries\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Admin interfaces properly sanitize user input\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Error logging captures potential injection attempts\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Functionality testing confirms everything works\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Injection testing confirms vulnerabilities are fixed\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"impact-assessment\">Impact Assessment\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#impact-assessment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Impact Assessment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Before fixes:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>CVSS Score: 9.8 (Critical)\u003C/li>\n\u003Cli>Risk: Complete database compromise possible\u003C/li>\n\u003Cli>Attack vector: Any OAuth2 parameter\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>After fixes:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>CVSS Score: 0.0 (Resolved)\u003C/li>\n\u003Cli>Risk: SQL injection eliminated\u003C/li>\n\u003Cli>Protection: Bulletproof prepared statements\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cp>\u003Cstrong>🛡️ Congratulations!\u003C/strong> You’ve eliminated critical SQL injection vulnerabilities from your OAuth2 implementation. Your WordPress site is now protected against one of the most dangerous attack vectors.\u003C/p>\n\u003Cp>\u003Cstrong>Next:\u003C/strong> Consider implementing \u003Ca href=\"/how-to/implement-rate-limiting/\">rate limiting protection\u003C/a> to defend against brute force attacks.\u003C/p>",{"headings":350,"localImagePaths":389,"remoteImagePaths":390,"frontmatter":340,"imagePaths":391},[351,353,356,359,362,365,368,371,374,377,380,383,386],{"depth":37,"slug":352,"text":341},"how-to-fix-sql-injection-in-oauth2-plugins",{"depth":58,"slug":354,"text":355},"problem","Problem",{"depth":58,"slug":357,"text":358},"solution-overview","Solution Overview",{"depth":58,"slug":360,"text":361},"before-you-start","Before You Start",{"depth":58,"slug":363,"text":364},"step-1-identify-vulnerable-queries","Step 1: Identify Vulnerable Queries",{"depth":58,"slug":366,"text":367},"step-2-replace-with-prepared-statements","Step 2: Replace with Prepared Statements",{"depth":58,"slug":369,"text":370},"step-3-implement-comprehensive-input-validation","Step 3: Implement Comprehensive Input Validation",{"depth":58,"slug":372,"text":373},"step-4-update-admin-interface-queries","Step 4: Update Admin Interface Queries",{"depth":58,"slug":375,"text":376},"step-5-test-your-fixes","Step 5: Test Your Fixes",{"depth":58,"slug":378,"text":379},"step-6-add-ongoing-protection","Step 6: Add Ongoing Protection",{"depth":58,"slug":381,"text":382},"common-pitfalls-to-avoid","Common Pitfalls to Avoid",{"depth":58,"slug":384,"text":385},"verification-checklist","Verification Checklist",{"depth":58,"slug":387,"text":388},"impact-assessment","Impact Assessment",[],[],[],"how-to/fix-sql-injection.md"] |