[{"data":1,"prerenderedAt":350},["ShallowReactive",2],{"slides-dodging-a-critical-cve-with-zta":3,"meta":330},{"id":4,"title":5,"body":6,"created":314,"description":315,"extension":316,"meta":317,"navigation":318,"path":319,"post":320,"seo":321,"stem":322,"tags":323,"thumbnail":328,"__hash__":329},"slides\u002Fslides\u002Fdodging-a-critical-cve-with-zta.md","Trust No 1: The Middleware Bypass Pattern",{"type":7,"value":8,"toc":303},"minimark",[9,14,22,89,93,128,138,142,153,157,177,181,184,187,209,215,219,225,235,239,252,272,276,282],[10,11,13],"h2",{"id":12},"background","Background",[15,16,17],"p",{},[18,19],"img",{"alt":20,"src":21},"OpenSSH","\u002Fassets\u002Fopenssh.gif",[23,24,25],"notes",{},[26,27,28,32,55,75,78],"ul",{},[29,30,31],"li",{},"SSH Bastion Server",[29,33,34,35],{},"WHY?\n",[26,36,37,40,43,46,49,52],{},[29,38,39],{},"Disgruntled TS",[29,41,42],{},"Distributed Workforce",[29,44,45],{},"Ebury rootkit",[29,47,48],{},"Conceal credentials",[29,50,51],{},"Audit",[29,53,54],{},"Chokehold",[29,56,57,58],{},"Existing products\n",[26,59,60,63,66,69,72],{},[29,61,62],{},"ContainerSSH",[29,64,65],{},"OVH Bastion",[29,67,68],{},"Teleport",[29,70,71],{},"HashiCorp Boundary",[29,73,74],{},"OPKSSH",[29,76,77],{},"All lack B2B & B2C workflows",[29,79,80,81],{},"Add support for sister companies\n",[26,82,83,86],{},[29,84,85],{},"Decouple legacy logic",[29,87,88],{},"OCI-runtime compatible, k3s\u002Fk8s",[10,90,92],{"id":91},"authorization-bypass","Authorization Bypass",[94,95,97,121],"block-quote",{"link":96},"https:\u002F\u002Fnvd.nist.gov\u002Fvuln\u002Fdetail\u002Fcve-2026-33186",[15,98,99,100,104,105,108,109,112,113,116,117,120],{},"The gRPC-Go server was too lenient in its routing logic, accepting requests where the ",[101,102,103],"code",{},":path"," omitted the mandatory leading slash (e.g., ",[101,106,107],{},"Service\u002FMethod"," instead of ",[101,110,111],{},"\u002FService\u002FMethod","). While the server successfully routed these requests to the correct handler, authorization interceptors (including the official ",[101,114,115],{},"grpc\u002Fauthz"," package) evaluated the raw, non-canonical path string. Consequently, \"deny\" rules defined using canonical paths (starting with ",[101,118,119],{},"\u002F",") failed to match the incoming request, allowing it to bypass the policy if a fallback \"allow\" rule was present.",[122,123,125],"template",{"v-slot:cite":124},"",[15,126,127],{},"NIST NVD CVE-2026-33186",[23,129,130],{},[26,131,132,135],{},[29,133,134],{},"Middle of security review for refactor of this project",[29,136,137],{},"How did I dodge this?",[10,139,141],{"id":140},"experimental","EXPERIMENTAL",[94,143,145,148],{"link":144},"https:\u002F\u002Fpkg.go.dev\u002Fgoogle.golang.org\u002Fgrpc\u002Fauthz",[15,146,147],{},"Notice: This package is EXPERIMENTAL and may be changed or removed in a later release.",[122,149,150],{"v-slot:cite":124},[15,151,152],{},"Documentation",[10,154,156],{"id":155},"deny-by-default","Deny by Default",[158,159,160,166],"with-caption",{},[15,161,162],{},[18,163],{"alt":164,"src":165},"ElectroBOOM","\u002Fassets\u002Felectroboom-spark_lg.webp",[122,167,168],{"v-slot:caption":124},[15,169,170],{},[171,172,164],"a",{"href":173,"rel":174,"target":176},"https:\u002F\u002Fwww.electroboom.com",[175],"nofollow","_blank",[10,178,180],{"id":179},"the-middleware-bypass-pattern","The Middleware Bypass Pattern",[15,182,183],{},"Forward-thinking developers wish to write code that is flexible and\neasy to maintain.\nSeparating logic into domains with pluggable interfaces helps us focus\non a single aspect of the design, allows us to rearrange the parts,\ndiscard and add new ones, more easily test and assert their logic.",[15,185,186],{},"The middleware pattern is often a simple function chain, kind of like\nan onion of wrapped closure functions, each layer calling the next.\nA more naive approach is dropping the request directly into a large\nfunction responsible for auth, request tagging, logging, rate-limiting,\ntransport logic, API logic, business logic, etc.\nGrasping the logic of such a function or altering one aspect could\nbring the whole house down.",[15,188,189,190,194,195,198,199,204,205,208],{},"So most developers have pushed auth to a middleware, which ",[191,192,193],"em",{},"should","\nbail before ever reaching a handler to fulfill the request.\nPerhaps a zealous adherence to this ",[191,196,197],{},"Separation of Concerns"," has\nconvinced developers that it’s poor design for handlers to concern\nthemselves with auth.\nThere has been a litany of auth bypass vulnerabilities in these\nmiddlewares, probably most notably,\n",[171,200,203],{"href":201,"rel":202,"target":176},"https:\u002F\u002Fnvd.nist.gov\u002Fvuln\u002Fdetail\u002FCVE-2025-29927",[175],"Next.js CVE-2025-29927","\nvia header “x-middleware-subrequest”, an actual ",[191,206,207],{},"feature"," of the\nframework.",[23,210,211],{},[26,212,213],{},[29,214,197],{},[10,216,218],{"id":217},"no-ticket","No Ticket",[15,220,221],{},[18,222],{"alt":223,"src":224},"Indiana Jones - No Ticket","\u002Fassets\u002Findiana-jones-no-ticket_lg.webp",[23,226,227],{},[26,228,229,232],{},[29,230,231],{},"If auth happened and nobody saw it, did it really happen?",[29,233,234],{},"Trust but verify",[10,236,238],{"id":237},"zero-trust-architecture","Zero Trust Architecture",[158,240,241,247],{},[15,242,243],{},[18,244],{"alt":245,"src":246},"The X-Files","\u002Fassets\u002Fthe-x-files_lg.webp",[122,248,249],{"v-slot:caption":124},[15,250,251],{},"“Trust No 1” - The X-Files Season 9 Episode 6",[23,253,254],{},[26,255,256,259,266,269],{},[29,257,258],{},"Every request passes a Policy Enforcement Point",[29,260,261,262,265],{},"The un-authenticated get a ",[191,263,264],{},"role",", not a bypass",[29,267,268],{},"Deny by default",[29,270,271],{},"Check again at the point of use",[10,273,275],{"id":274},"just-in-time","Just In Time",[15,277,278],{},[18,279],{"alt":280,"src":281},"Dante's Inferno","\u002Fassets\u002Fdantes-inferno.jpg",[23,283,284],{},[26,285,286,289,292],{},[29,287,288],{},"Technical Debt",[29,290,291],{},"Inheritance Hell",[29,293,294,295],{},"Where to assert that logic?\n",[26,296,297,300],{},[29,298,299],{},"Point of Entry",[29,301,302],{},"Pint of Use",{"title":124,"searchDepth":304,"depth":304,"links":305},2,[306,307,308,309,310,311,312,313],{"id":12,"depth":304,"text":13},{"id":91,"depth":304,"text":92},{"id":140,"depth":304,"text":141},{"id":155,"depth":304,"text":156},{"id":179,"depth":304,"text":180},{"id":217,"depth":304,"text":218},{"id":237,"depth":304,"text":238},{"id":274,"depth":304,"text":275},"2026-10-29","March 2026, a critical CVE in gRPC-go lead to an authorization bypass in Google’s own authz package. Why do developers keep stumbling into this pitfall?","md",{},true,"\u002Fslides\u002Fdodging-a-critical-cve-with-zta","\u002Fblog\u002Fdodging-a-critical-cve-with-zta",{"title":5,"description":315},"slides\u002Fdodging-a-critical-cve-with-zta",[324,325,326,327],"grpc","go","cve","zta","\u002Fassets\u002Fthe-x-files_md.webp","KLVL16lcDdpq8rP9iwtoI2DOCA-x40J9U4FpBhHSBRw",{"id":331,"title":332,"author":333,"description":341,"extension":342,"meta":343,"repository":344,"stem":348,"__hash__":349},"meta\u002Fmeta.yml","bmo.dev",{"name":334,"github":335,"gitlab":336,"email":337,"linkedin":338,"mastodon":339,"bio":340},"William Little","https:\u002F\u002Fgithub.com\u002Fbmodotdev\u002F","https:\u002F\u002Fgitlab.com\u002Fbmodotdev\u002F","L29hqTSwqROvoJ8hMTI2","https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fwilliam-e-little-jr\u002F","https:\u002F\u002Fdefcon.social\u002F@bmodotdev","I am a Full Stack Software & DevOps Engineer who loves building and experimenting with Software, Linux, & electronics.\n","A personal blog where I share my thoughts, projects, and anything I might find interesting or helpful.\n","yml",{},{"url":345,"git":346,"branch":347},"https:\u002F\u002Fgitlab.com\u002Fbmodotdev\u002Fbmo.dev\u002F","git@gitlab.com:bmodotdev\u002Fbmo.dev.git","main","meta","MPtcc2KHfBCBy4V4SDhZFIvjyZ_Ba4e-yDnx_Ok_KOs",1793313045359]