1:"$Sreact.fragment" 3:I[76743,["/_next/static/chunks/d7fcf68925eb733d.js?dpl=dpl_A5Z6Ann3qNAotdfdzCfRc27tABUK","/_next/static/chunks/9c4a73c4b42ed60e.js?dpl=dpl_A5Z6Ann3qNAotdfdzCfRc27tABUK"],""] 4:I[90373,["/_next/static/chunks/d7fcf68925eb733d.js?dpl=dpl_A5Z6Ann3qNAotdfdzCfRc27tABUK","/_next/static/chunks/9c4a73c4b42ed60e.js?dpl=dpl_A5Z6Ann3qNAotdfdzCfRc27tABUK"],""] cc:I[11282,["/_next/static/chunks/d5e289bff96cf0c1.js?dpl=dpl_A5Z6Ann3qNAotdfdzCfRc27tABUK","/_next/static/chunks/0eed89cda4daeeed.js?dpl=dpl_A5Z6Ann3qNAotdfdzCfRc27tABUK"],"OutletBoundary"] cd:"$Sreact.suspense" :HL["/articles/exploiting-feature-factory/core-tree.png","image"] :HL["/articles/exploiting-feature-factory/proxy-rule-mr.png","image"] :HL["/articles/exploiting-feature-factory/features-render.png","image"] :HL["/articles/exploiting-feature-factory/github-app.png","image"] :HL["/articles/exploiting-feature-factory/reports.png","image"] 2:T41c,[{"@context":"https://schema.org","@type":"BlogPosting","headline":"Exploiting the Feature Factory","description":"Exploiting the Feature Factory","image":"https://kapeka.dev//articles/exploiting-feature-factory/optimized-cover.jpg","datePublished":"2026-01-25","dateModified":"2026-01-25","author":{"@type":"Person","name":"Kapeka"},"publisher":{"@type":"Organization","name":"Kapeka","logo":{"@type":"ImageObject","url":"https://kapeka.dev//images/logo.png"}},"url":"https://kapeka.dev//articles/exploiting-the-feature-factory","mainEntityOfPage":{"@type":"WebPage","@id":"https://kapeka.dev//articles/exploiting-the-feature-factory"},"keywords":"","inLanguage":"en"},{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://kapeka.dev//"},{"@type":"ListItem","position":2,"name":"Articles","item":"https://kapeka.dev//"},{"@type":"ListItem","position":3,"name":"Exploiting the Feature Factory","item":"https://kapeka.dev//articles/exploiting-the-feature-factory"}]}]0:{"buildId":"ngUq_a8zYAqpUCpKfeNSv","rsc":["$","$1","c",{"children":[[["$","script",null,{"type":"application/ld+json","dangerouslySetInnerHTML":{"__html":"$2"}}],["$","div",null,{"className":"min-h-screen pt-8 sm:pt-10","children":[["$","div",null,{"className":" mx-auto page-fade-in","children":["$","article",null,{"children":[["$","div",null,{"className":"flex w-full flex-col space-y-4","children":[["$","h1",null,{"className":"text-3xl font-semibold text-heading sm:text-4xl","children":"Exploiting the Feature Factory"}],["$","div",null,{"className":"flex flex-wrap items-center gap-2 text-sm font-medium font-mono text-muted","children":[["$","time",null,{"children":"January 25, 2026"}],["$","span",null,{"children":"•"}],["$","span",null,{"children":[20," min read"]}]]}]]}],["$","hr",null,{"className":"my-7 border-secondary-text opacity-50"}],["$","div",null,{"className":"","children":["$","$L3",null,{"src":"/articles/exploiting-feature-factory/optimized-cover.jpg","alt":"Exploiting the Feature Factory","width":800,"height":400,"priority":true,"placeholder":"blur","className":""}]}],["$","div",null,{"className":"prose prose-xl prose-invert max-w-none ","children":[["$","p",null,{"className":" ","children":"Hey hackers!"}],"\n",["$","p",null,{"className":" ","children":["Bug Bounty is one of those fields where you need to reflect a lot. We read tons of articles, listen to the ",["$","$L4",null,{"href":"https://www.criticalthinkingpodcast.io/","target":"_blank","rel":"noopener noreferrer","className":"text-primary font-medium underline ","children":[" ","CTBB Podcast",["$","svg",null,{"xmlns":"http://www.w3.org/2000/svg","width":24,"height":24,"viewBox":"0 0 24 24","fill":"none","stroke":"currentColor","strokeWidth":2,"strokeLinecap":"round","strokeLinejoin":"round","className":"lucide lucide-external-link inline-block relative -top-1 size-3 ml-1","aria-hidden":"true","children":[["$","path","1q9fwt",{"d":"M15 3h6v6"}],["$","path","gplh6r",{"d":"M10 14 21 3"}],["$","path","a6xqqp",{"d":"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"}],"$undefined"]}]]}],", gain experience..."]}],"\n",["$","p",null,{"className":" ","children":"But if we don't keep reflecting and evolving our methodology, what's the point of learning if we keep using our deprecated approach?"}],"\n",["$","p",null,{"className":" ","children":"Personally, every month or so I dedicate some time to reflect on my strategies, methodologies, and performance. I evaluate what things I believe have worked well and what things I feel are leading me to stagnate or get frustrated."}],"\n",["$","p",null,{"className":" ","children":"I implement changes in my methodology and write down the key words I want to make sure I follow on a sticky note on my desk."}],"\n",["$","$L3",null,{"src":"/articles/exploiting-feature-factory/hacker-note.png","alt":""}],"\n","$L5","\n","$L6","\n","$L7","\n","$L8","\n","$L9","\n","$La","\n","$Lb","\n","$Lc","\n","$Ld","\n","$Le","\n","$Lf","\n","$L10","\n","$L11","\n","$L12","\n","$L13","\n","$L14","\n","$L15","\n","$L16","\n","$L17","\n","$L18","\n","$L19","\n","$L1a","\n","$L1b","\n","$L1c","\n","$L1d","\n","$L1e","\n","$L1f","\n","$L20","\n","$L21","\n","$L22","\n","$L23","\n","$L24","\n","$L25","\n","$L26","\n","$L27","\n","$L28","\n","$L29","\n","$L2a","\n","$L2b","\n","$L2c","\n","$L2d","\n","$L2e","\n","$L2f","\n","$L30","\n","$L31","\n","$L32","\n","$L33","\n","$L34","\n","$L35","\n","$L36","\n","$L37","\n","$L38","\n","$L39","\n","$L3a","\n","$L3b","\n","$L3c","\n","$L3d","\n","$L3e","\n","$L3f","\n","$L40","\n","$L41","\n","$L42","\n","$L43","\n","$L44","\n","$L45","\n","$L46","\n","$L47","\n","$L48","\n","$L49","\n","$L4a","\n","$L4b","\n","$L4c","\n","$L4d","\n","$L4e","\n","$L4f","\n","$L50","\n","$L51","\n","$L52","\n","$L53","\n","$L54","\n","$L55","\n","$L56","\n","$L57","\n","$L58","\n","$L59","\n","$L5a","\n","$L5b","\n","$L5c","\n","$L5d","\n","$L5e","\n","$L5f","\n","$L60","\n","$L61","\n","$L62","\n","$L63","\n","$L64","\n","$L65","\n","$L66","\n","$L67","\n","$L68","\n","$L69","\n","$L6a","\n","$L6b","\n","$L6c","\n","$L6d","\n","$L6e","\n","$L6f","\n","$L70","\n","$L71","\n","$L72","\n","$L73","\n","$L74","\n","$L75","\n","$L76","\n","$L77","\n","$L78","\n","$L79","\n","$L7a","\n","$L7b","\n","$L7c","\n","$L7d","\n","$L7e","\n","$L7f","\n","$L80","\n","$L81","\n","$L82","\n","$L83","\n","$L84","\n","$L85","\n","$L86","\n","$L87","\n","$L88","\n","$L89","\n","$L8a","\n","$L8b","\n","$L8c","\n","$L8d","\n","$L8e","\n","$L8f","\n","$L90","\n","$L91","\n","$L92","\n","$L93","\n","$L94","\n","$L95","\n","$L96","\n","$L97","\n","$L98","\n","$L99","\n","$L9a","\n","$L9b","\n","$L9c","\n","$L9d","\n","$L9e","\n","$L9f","\n","$La0","\n","$La1","\n","$La2","\n","$La3","\n","$La4","\n","$La5","\n","$La6","\n","$La7","\n","$La8","\n","$La9","\n","$Laa","\n","$Lab","\n","$Lac","\n","$Lad","\n","$Lae","\n","$Laf","\n","$Lb0","\n","$Lb1","\n","$Lb2","\n","$Lb3","\n","$Lb4","\n","$Lb5","\n","$Lb6","\n","$Lb7","\n","$Lb8","\n","$Lb9","\n","$Lba","\n","$Lbb","\n","$Lbc","\n","$Lbd","\n","$Lbe","\n","$Lbf","\n","$Lc0","\n","$Lc1","\n","$Lc2","\n","$Lc3","\n","$Lc4","\n","$Lc5","\n","$Lc6","\n","$Lc7","\n","$Lc8"]}]]}]}],"$Lc9"]}]],["$Lca"],"$Lcb"]}],"loading":null,"isPartial":false} 5:["$","p",null,{"className":" ","children":"That way, every time I look at the sticky note, it forces me to think about whether I'm living up to what I wrote!"}] 6:["$","p",null,{"className":" ","children":"Lately I've been finding my first high and critical bugs, and although they had significant impact, they weren't exactly rocket science, but about scope selection and critical thinking!"}] 7:["$","p",null,{"className":" ","children":["While reflecting on my methodology and my recent findings, I realized that I was following a pattern, a methodology, so in this article I try to describe that methodology, which I’ve called ",["$","strong",null,{"children":"\"Exploiting the Feature Factory\""}],", which you'll understand later."]}] 8:["$","p",null,{"className":" ","children":"To understand what a Feature Factory is, you first need to understand certain business concepts."}] 9:["$","h2",null,{"className":"text-3xl font-semibold mt-10 mb-4","id":"growing-beyond-the-core","children":[["$","a",null,{"href":"#growing-beyond-the-core","aria-hidden":"true","tabIndex":"-1","className":" underline text-primary font-medium flex items-center gap-1 ","children":["$","span",null,{"className":"icon icon-link"}]}],"Growing beyond the core"]}] a:["$","p",null,{"className":" ","children":"When a company isn't big enough (small or medium), it focuses on a niche and usually doesn't venture beyond it."}] b:["$","p",null,{"className":" ","children":"For example, a small domain hosting company dedicates itself exclusively to domain hosting, focusing all its efforts on improving its product/service in its niche to gain more market share."}] c:["$","p",null,{"className":" ","children":"However, when companies grow enough, they reach a point where to keep growing they need to carve out a space in emerging economies (diversification)."}] d:["$","p",null,{"className":" ","children":"They have one main niche, but they start to offer more and more services in other niches, even some that have nothing to do with their main niche (core)."}] e:["$","p",null,{"className":" ","children":["According to my macroeconomics analyst bureau (",["$","span",null,{"className":"relative inline-flex align-middle group select-none -mt-1","style":{"width":18,"height":18},"tabIndex":-1,"children":[["$","$L3",null,{"src":"/images/logos/openai.svg","alt":"ChatGPT","width":18,"height":18,"className":"block image-icon"}],"$undefined"]}],", ",["$","span",null,{"className":"relative inline-flex align-middle group select-none -mt-1","style":{"width":18,"height":18},"tabIndex":-1,"children":[["$","$L3",null,{"src":"/images/logos/claude.svg","alt":"Claude","width":18,"height":18,"className":"block image-icon"}],"$undefined"]}],", ",["$","span",null,{"className":"relative inline-flex align-middle group select-none -mt-1","style":{"width":18,"height":18},"tabIndex":-1,"children":[["$","$L3",null,{"src":"/images/logos/gemini.svg","alt":"Gemini","width":18,"height":18,"className":"block image-icon"}],"$undefined"]}],"), this is known in economics as:"]}] f:["$","figure",null,{"className":"w-full justify-center items-center flex flex-col","children":["$","p",null,{"className":"font-serif italic leading-relaxed text-foreground text-xl text-center","children":"Growing beyond the core"}]}] 10:["$","p",null,{"className":" ","children":"This strategy is implemented to increase growth opportunities and reduce risks from depending on just one main business."}] 11:["$","p",null,{"className":" ","children":"In this way, when this domain hosting company grows large enough, it dedicates itself to:"}] 12:["$","ul",null,{"className":" space-y-2","children":["\n",["$","li",null,{"children":"hosts domains"}],"\n",["$","li",null,{"children":"hosts websites"}],"\n",["$","li",null,{"children":"has an AI website builder"}],"\n",["$","li",null,{"children":"sells cakes"}],"\n",["$","li",null,{"children":"offers SEO services"}],"\n",["$","li",null,{"children":"offers cloud storage"}],"\n",["$","li",null,{"children":"sells donuts"}],"\n"]}] 13:["$","p",null,{"className":" ","children":"..."}] 14:["$","p",null,{"className":" ","children":"But what does this have to do with the Feature Factory?"}] 15:["$","h2",null,{"className":"text-3xl font-semibold mt-10 mb-4","id":"what-the-hck-is-the-feature-factory","children":[["$","a",null,{"href":"#what-the-hck-is-the-feature-factory","aria-hidden":"true","tabIndex":"-1","className":" underline text-primary font-medium flex items-center gap-1 ","children":["$","span",null,{"className":"icon icon-link"}]}],"What the h*ck is the Feature Factory"]}] 16:["$","p",null,{"className":" ","children":"Now that we understand the diversification strategy companies implement to keep growing, we can see what the Feature Factory is."}] 17:["$","p",null,{"className":" ","children":"Well, the Feature Factory is a concept in product management that refers to a company that doesn't stop releasing features, without evaluating whether they really add value to the user or the business."}] 18:["$","blockquote",null,{"children":["\n",["$","p",null,{"className":" ","children":"\"Make this thing\" VS \"Figure out what we need to make, then make it\""}],"\n"]}] 19:["$","p",null,{"className":" ","children":"However, in this article I'm referring to a different idea."}] 1a:["$","p",null,{"className":" ","children":["Think of the company ",["$","em",null,{"children":"\"My Cool Business & Associates\""}],". This company is dedicated to offering servers (☁️), for example."]}] 1b:["$","p",null,{"className":" ","children":["However, this company has grown enough in its main niche, and its growth now appears to be stagnant or slow, so in order to keep growing, it is going to implement the ",["$","strong",null,{"children":"\"Growing beyond the core\""}]," strategy."]}] 1c:["$","p",null,{"className":" ","children":["As part of this strategy, ",["$","em",null,{"children":"\"My Cool Business & Associates\""}]," is also creating an App Performance Assessment service."]}] 1d:["$","p",null,{"className":" ","children":"We can see this service as a separate branch:"}] 1e:["$","p",null,{"className":" ","children":["$","img",null,{"src":"/articles/exploiting-feature-factory/core-tree.png","alt":""}]}] 1f:["$","p",null,{"className":" ","children":[["$","em",null,{"children":"\"My Cool Business & Associates\""}]," has server hosting as its main business or core, that's where it gets the majority of its profit."]}] 20:["$","p",null,{"className":" ","children":"But since its growth in that niche is already limited, it has created a new branch by opening a new app performance diagnosis business in another niche."}] 21:["$","p",null,{"className":" ","children":"The important thing is that the new branches (services) being created already have an established market (since nowadays everything's already been invented) with strong competitors."}] 22:["$","p",null,{"className":" ","children":["And that's why if ",["$","em",null,{"children":"\"My Cool Business & Associates\""}]," really wants to enter the market, it must implement a very aggressive SDLC."]}] 23:["$","blockquote",null,{"children":["\n",["$","p",null,{"className":" ","children":"In software engineering, Software Development Life Cycle (SDLC) is the process that guides how software is planned, developed, tested, and maintained."}],"\n"]}] 24:["$","p",null,{"className":" ","children":"What it means to have an aggressive SDLC is that the company will release features non-stop, continuously, features and more features..."}] 25:["$","p",null,{"className":" ","children":["As if it were a ",["$","strong",null,{"children":"feature factory"}]," instead of an application/service."]}] 26:["$","p",null,{"className":" ","children":"This approach is closely tied to an aggressive SDLC, where speed and continuous delivery are prioritized over thorough testing and security."}] 27:["$","blockquote",null,{"children":["\n",["$","p",null,{"className":" ","children":"Aggressive SDLC → speed over quality"}],"\n"]}] 28:["$","p",null,{"className":" ","children":["In bug bounty, the less time a feature has been live, the more vulnerable it is, since fewer hackers have exploited it and fewer tests have been done. This is the beauty of ",["$","strong",null,{"children":"Exploiting the Feature Factory"}],"."]}] 29:["$","p",null,{"className":" ","children":"As a result, the company keeps releasing new features to remain competitive, and due to its aggressive SDLC, many of these features are deployed with a significant number of vulnerabilities."}] 2a:["$","p",null,{"className":" ","children":"Additionally, with the rise of agentic/vibe coding, these feature factories will produce new (and even worse-coded) features at an even faster pace."}] 2b:["$","figure",null,{"className":"my-4 flex flex-col items-center gap-2","children":[["$","div",null,{"className":"overflow-hidden rounded-lg","children":["$","$L3",null,{"src":"/articles/exploiting-feature-factory/productivity_impact.png","alt":"","width":1920,"height":1080,"placeholder":"blur","className":"w-full h-auto image-caption"}]}],["$","figcaption",null,{"className":" text-sm text-secondary-text text-center ","children":["$","$L4",null,{"href":"https://www.secondtalent.com/resources/vibe-coding-statistics/","className":"text-primary underline","rel":"noreferrer","children":"https://www.secondtalent.com/resources/vibe-coding-statistics/"}]}]]}] 2c:["$","p",null,{"className":" ","children":"That’s why this methodology focuses on exploiting these applications, rather than the company’s main application or service."}] 2d:["$","p",null,{"className":" ","children":"Normally, some conditions to identify these feature factories are:"}] 2e:["$","ul",null,{"className":" space-y-2","children":["\n",["$","li",null,{"children":"They have between 1-3 years of lifetime"}],"\n",["$","li",null,{"children":"They're not the company's main business/product"}],"\n",["$","li",null,{"children":"They have strong hype marketing campaigns"}],"\n"]}] 2f:["$","p",null,{"className":" ","children":["Note that this article focuses on ",["$","strong",null,{"children":"Feature Factories"}]," because, although the main application also receives new features, the context is very different."]}] 30:["$","p",null,{"className":" ","children":"The key difference is that the core application or service follows a much more stable and long-lived SDLC. It is maintained by a development team that has been working on it for a long time, has already patched numerous bugs, and has built solid systems and processes around it."}] 31:["$","p",null,{"className":" ","children":"And basically they have a strong product (💪)."}] 32:["$","p",null,{"className":" ","children":["In our example, ",["$","em",null,{"children":"\"My Cool Business & Associates\""}]," has likely been working with servers for many years. They are familiar with common vulnerabilities, have established systems to detect and patch security issues within their niche, and even maintain a dedicated cybersecurity team."]}] 33:["$","p",null,{"className":" ","children":"In contrast, Feature Factories are much more immature. They often lack deep experience in the niche, rely on development teams that have not been working together for long, and operate without well-established security processes or defensive maturity."}] 34:["$","p",null,{"className":" ","children":"So, as bug bounty hunters, what should the strategy be after identifying a Feature Factory?"}] 35:["$","p",null,{"className":" ","children":"Should we wait for developers to announce new features?"}] 36:["$","p",null,{"className":" ","children":"Absolutely not."}] 37:["$","p",null,{"className":" ","children":"As we already know, features are more vulnerable the less time they've been live, and the least time they've been live is..."}] 38:["$","p",null,{"className":" ","children":["$","strong",null,{"children":"NOW"}]}] 39:["$","p",null,{"className":" ","children":"When they're still in development!"}] 3a:["$","p",null,{"className":" ","children":"The features are already in production! You just don't see them (yet🙂‍↔️)!"}] 3b:["$","h2",null,{"className":"text-3xl font-semibold mt-10 mb-4","id":"feature-flags","children":[["$","a",null,{"href":"#feature-flags","aria-hidden":"true","tabIndex":"-1","className":" underline text-primary font-medium flex items-center gap-1 ","children":["$","span",null,{"className":"icon icon-link"}]}],"Feature Flags"]}] 3c:["$","p",null,{"className":" ","children":"In an application with a reasonably professional development team, the changes the development team makes aren't exposed to end users just like that."}] 3d:["$","p",null,{"className":" ","children":"In my case, I can afford to push changes to the production environment directly, since I have a team of testers (they're called users)."}] 3e:["$","p",null,{"className":" ","children":["But in an SDLC, a common practice is to use ",["$","strong",null,{"children":"Feature Flags"}]," or ",["$","strong",null,{"children":"Toggles"}],"."]}] 3f:["$","p",null,{"className":" ","children":"These flags are switches in the code that are checked at runtime to enable or disable functionalities."}] 40:["$","p",null,{"className":" ","children":"For example, if a development team has been working on a new search functionality, there might be a flag called:"}] 41:["$","pre",null,{"data-code":"[object Object],\n,[object Object], = ,[object Object],;\n","children":["$","code",null,{"className":"hljs language-javascript","children":[["$","span",null,{"className":"hljs-comment","children":"// .env"}],"\n",["$","span",null,{"className":"hljs-variable constant_","children":"NEW_SEARCH_ENABLED"}]," = ",["$","span",null,{"className":"hljs-literal","children":"false"}],";\n"]}]}] 42:["$","p",null,{"className":" ","children":"and at runtime it's checked to know whether to use the new feature or not:"}] 43:["$","pre",null,{"data-code":"[object Object], (!!process.,[object Object],.,[object Object],) {\n ,[object Object],();\n} ,[object Object], {\n ,[object Object],();\n}\n","children":["$","code",null,{"className":"hljs language-TypeScript","children":[["$","span",null,{"className":"hljs-keyword","children":"if"}]," (!!process.",["$","span",null,{"className":"hljs-property","children":"env"}],".",["$","span",null,{"className":"hljs-property","children":"NEW_SEARCH_ENABLED"}],") {\n ",["$","span",null,{"className":"hljs-title function_","children":"useNewSearch"}],"();\n} ",["$","span",null,{"className":"hljs-keyword","children":"else"}]," {\n ",["$","span",null,{"className":"hljs-title function_","children":"useOldSearch"}],"();\n}\n"]}]}] 44:["$","p",null,{"className":" ","children":"This applies to any type of feature, although they're normally not in code, but in other environments like:"}] 45:["$","ul",null,{"className":" space-y-2","children":["\n",["$","li",null,{"children":"Environment variables"}],"\n",["$","li",null,{"children":"Databases"}],"\n",["$","li",null,{"children":"External services"}],"\n"]}] 46:["$","p",null,{"className":" ","children":["Feature flags allow you to do many things in development like canary launches, A/B testing, kill switches... But what interests us is that a common practice of using them is for ",["$","strong",null,{"children":"Trunk-based development"}],"."]}] 47:["$","h3",null,{"className":"text-2xl font-semibold mt-8 mb-3","id":"trunk-based-development","children":[["$","a",null,{"href":"#trunk-based-development","aria-hidden":"true","tabIndex":"-1","className":" underline text-primary font-medium flex items-center gap-1 ","children":["$","span",null,{"className":"icon icon-link"}]}],"Trunk-based development"]}] 48:["$","p",null,{"className":" ","children":["If you've worked on a team project, you know that the usual practice to maintain good version control (",["$","span",null,{"className":"relative inline-flex align-middle group select-none -mt-1","style":{"width":18,"height":18},"tabIndex":-1,"children":[["$","$L3",null,{"src":"/images/logos/git.svg","alt":"GIT","width":18,"height":18,"className":"block image-icon"}],"$undefined"]}],") is to create branches for each feature being developed:"]}] 49:["$","figure",null,{"className":"my-4 flex flex-col items-center gap-2","children":[["$","div",null,{"className":"overflow-hidden rounded-lg","children":["$","$L3",null,{"src":"/articles/exploiting-feature-factory/feature-branch.jpg","alt":"","width":1920,"height":1080,"placeholder":"blur","className":"w-full h-auto image-caption"}]}],["$","figcaption",null,{"className":" text-sm text-secondary-text text-center ","children":["$","$L4",null,{"href":"https://www.bunnyshell.com/blog/what-is-a-feature-branch/","className":"text-primary underline","rel":"noreferrer","children":"https://www.bunnyshell.com/blog/what-is-a-feature-branch/"}]}]]}] 4a:["$","p",null,{"className":" ","children":"However, in applications that aren't simple and that have an aggressive SDLC (a Feature Factory✨), this methodology causes long development branches, which in turn cause:"}] 4b:["$","ul",null,{"className":" space-y-2","children":["\n",["$","li",null,{"children":"complex merge conflicts"}],"\n",["$","li",null,{"children":"bugs that are difficult to debug"}],"\n",["$","li",null,{"children":"deployment delays"}],"\n"]}] 4c:["$","p",null,{"className":" ","children":"..."}] 4d:["$","p",null,{"className":" ","children":"And basically they complicate continuous integration."}] 4e:["$","p",null,{"className":" ","children":["Trunk-based development consists of using feature flags so that the whole team can work on a single main branch (usually ",["$","code",null,{"children":"main"}]," or ",["$","code",null,{"children":"trunk"}],") and avoid long branches."]}] 4f:["$","p",null,{"className":" ","children":"Feature flags are used, for example, to upload a feature to production but keep it hidden from users."}] 50:["$","figure",null,{"className":"w-full justify-center items-center flex flex-col","children":["$","p",null,{"className":"font-serif italic leading-relaxed text-foreground text-xl text-center","children":"Security by obscurity👁️‍🗨️"}]}] 51:["$","p",null,{"className":" ","children":"For example, if a development team is working on a new feature, a workflow might be:"}] 52:["$","ol",null,{"className":" space-y-2","children":["\n",["$","li",null,{"children":["All developers work on their features on ",["$","code",null,{"children":"main"}]," or in very short branches"]}],"\n",["$","li",null,{"children":"The code is merged quickly to the main branch"}],"\n",["$","li",null,{"children":"The functionality is hidden by a flag (which only activates for developers)"}],"\n",["$","li",null,{"children":"The code is deployed to production continuously"}],"\n",["$","li",null,{"children":"The flag is activated only when the new feature is validated"}],"\n"]}] 53:["$","figure",null,{"className":"my-4 flex flex-col items-center gap-2","children":[["$","div",null,{"className":"overflow-hidden rounded-lg","children":["$","$L3",null,{"src":"/articles/exploiting-feature-factory/trunk-based-development-feature.png","alt":"","width":1920,"height":1080,"placeholder":"blur","className":"w-full h-auto image-caption"}]}],["$","figcaption",null,{"className":" text-sm text-secondary-text text-center ","children":["$","$L4",null,{"href":"https://configcat.com/trunk-based-development/","className":"text-primary underline","rel":"noreferrer","children":"https://configcat.com/trunk-based-development/"}]}]]}] 54:["$","p",null,{"className":" ","children":"However, if we, as attackers, discover a feature flag and manage to activate it, the situation changes completely."}] 55:["$","p",null,{"className":" ","children":"We will likely start seeing new UI elements, newly loaded JavaScript modules, new endpoints, and entirely new flows."}] 56:["$","p",null,{"className":" ","children":"Many of these features (due to an aggressive SDLC) aren’t even production-ready, yet they are pushed to production anyway!"}] 57:["$","$L3",null,{"src":"/articles/exploiting-feature-factory/push-meme.png","alt":""}] 58:["$","p",null,{"className":" ","children":"So now you can start to see the idea!"}] 59:["$","p",null,{"className":" ","children":"Feature factories are products that aren't from the company's main niche, so they need to release many features to gain market share and be competitive."}] 5a:["$","p",null,{"className":" ","children":"Since they have an aggressive SDLC, trunk-based development is usually used, which forces features to reach production when they're still in development."}] 5b:["$","p",null,{"className":" ","children":"Unvalidated features are hidden from users through feature flags until they're ready."}] 5c:["$","pre",null,{"data-code":"Feature Factory\n ↓\nMany features\n ↓\nAggressive SDLC\n ↓\nTrunk-based development\n ↓\nVULNERABLE FEATURES IN PRODUCTION✨\n","children":["$","code",null,{"children":"Feature Factory\n ↓\nMany features\n ↓\nAggressive SDLC\n ↓\nTrunk-based development\n ↓\nVULNERABLE FEATURES IN PRODUCTION✨\n"}]}] 5d:["$","p",null,{"className":" ","children":"Unfortunately, there's only one problem for this development strategy."}] 5e:["$","p",null,{"className":" ","children":["$","strong",null,{"children":"Hackers don't like feature flags🏴‍☠️"}]}] 5f:["$","h2",null,{"className":"text-3xl font-semibold mt-10 mb-4","id":"attacking-feature-flags","children":[["$","a",null,{"href":"#attacking-feature-flags","aria-hidden":"true","tabIndex":"-1","className":" underline text-primary font-medium flex items-center gap-1 ","children":["$","span",null,{"className":"icon icon-link"}]}],"Attacking Feature Flags"]}] 60:["$","p",null,{"className":" ","children":"A feature is more vulnerable the less time it's been live, and as we've seen, in Feature Factories when they're most vulnerable is right now, since they're already in production, yet still partially under development."}] 61:["$","p",null,{"className":" ","children":"We hackers don't like being told what we can't do, and we absolutely refuse to be told whether we have a feature enabled or not, so we just enable it ourselves!"}] 62:["$","p",null,{"className":" ","children":"There are real treasures in these features under development, so as hackers we want to access them."}] 63:["$","p",null,{"className":" ","children":"It’s worth noting that, normally, the main application or service also uses feature flags to hide features under development."}] 64:["$","p",null,{"className":" ","children":"However, the key point is that (at least in my experience) feature factories, due to a rawer development team and a more aggressive SDLC, tend to expose significantly more vulnerable features."}] 65:["$","p",null,{"className":" ","children":"I’ve exploited code that looked more like something an insider had pushed than something produced through a proper development process."}] 66:["$","p",null,{"className":" ","children":"Sometimes I felt that by reporting certain vulnerabilities, a junior developer might get fired or sent to the coffee machine (☕)."}] 67:["$","$L3",null,{"src":"/articles/exploiting-feature-factory/junior-meme.png","alt":""}] 68:["$","p",null,{"className":" ","children":"There are many ways to use feature flags:"}] 69:["$","ul",null,{"className":" space-y-2","children":["\n",["$","li",null,{"children":"Hardcoded"}],"\n",["$","li",null,{"children":"Environment variables"}],"\n",["$","li",null,{"children":"Third-party services\n..."}],"\n"]}] 6a:["$","p",null,{"className":" ","children":"But in the end, they're just boolean variables!"}] 6b:["$","p",null,{"className":" ","children":"A trick that works many times is to design and configure a deliberately complex rule, meticulously crafted and finely tuned in your proxy's match and replace, so that it covers multiple scenarios and possible variations:"}] 6c:["$","p",null,{"className":" ","children":["$","img",null,{"src":"/articles/exploiting-feature-factory/proxy-rule-mr.png","alt":""}]}] 6d:["$","p",null,{"className":" ","children":"Mmm well, that's it..."}] 6e:["$","p",null,{"className":" ","children":["Since they're boolean variables, simply changing ",["$","code",null,{"children":"false"}]," to ",["$","code",null,{"children":"true"}]," we can access most of the time a lot of features under development."]}] 6f:["$","p",null,{"className":" ","children":"It's really not that easy since many times with this rule we'll break the application. A workaround is to do it only on the first request."}] 70:["$","p",null,{"className":" ","children":"Feature flags need to be available from the first render so that the application doesn't have visual glitches and doesn't have to load unnecessary JavaScript."}] 71:["$","p",null,{"className":" ","children":"That’s why they usually appear in the initial HTML, before the JavaScript with the features loads, that is, in the first request."}] 72:["$","p",null,{"className":" ","children":["$","img",null,{"src":"/articles/exploiting-feature-factory/features-render.png","alt":""}]}] 73:["$","p",null,{"className":" ","children":"Feature flags are usually injected in the initial HTML, then the application on the client will read the feature flags and load the necessary JavaScript and display one UI or another."}] 74:["$","p",null,{"className":" ","children":"The first request in modern applications (SPA) is the one that returns the HTML and the request contains a header like this:"}] 75:["$","pre",null,{"data-code":"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\n","children":["$","code",null,{"children":"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\n"}]}] 76:["$","p",null,{"className":" ","children":"So if we set the match and replace rule to:"}] 77:["$","pre",null,{"data-code":"req.raw.cont:,[object Object],\n","children":["$","code",null,{"className":"hljs language-bash","children":["req.raw.cont:",["$","span",null,{"className":"hljs-string","children":"\"text/html\""}],"\n"]}]}] 78:["$","p",null,{"className":" ","children":["We'll only change the boolean values of the feature flags (",["$","code",null,{"children":"false"}]," → ",["$","code",null,{"children":"true"}],"), activating features under development and preventing the application from breaking, by avoiding accidentally intercepting other types of requests like XHR requests."]}] 79:["$","blockquote",null,{"children":["\n",["$","p",null,{"className":" ","children":["Note: Not all feature flags are always delivered in the initial HTML. In some cases, flags are dynamically resolved through XHR requests to the API (for example, user-dependent flags like ",["$","code",null,{"children":"isAdmin"}],", plans, cohorts, etc.).",["$","br",null,{}]," ",["$","br",null,{}],"Each application implements feature flags differently, so there's no universal methodology that works 100% of the time. However, intercepting and modifying only the first HTML response usually covers the most common case, especially in modern SPA applications."]}],"\n"]}] 7a:["$","p",null,{"className":" ","children":"However, leaving that rule enabled can break many parts of the UI and make it unusable."}] 7b:["$","p",null,{"className":" ","children":"Personally, I enable that general rule in the proxy, analyze how the UI behaves, the new modules that are loaded, and the new API requests the application makes, and then focus on a particular feature that might have an impact."}] 7c:["$","p",null,{"className":" ","children":"Once you discover a feature that might be interesting, the next step is to focus on that feature and experiment with the flags to determine which one(s) activate it."}] 7d:["$","p",null,{"className":" ","children":"You should then modify only that specific flag (🚩), in order to avoid breaking the application and to be able to exploit the feature comfortably."}] 7e:["$","p",null,{"className":" ","children":"You can do this by looking at the HTML request in your proxy and comparing the changes from the original request with the one modified by the match and replace rule."}] 7f:["$","p",null,{"className":" ","children":"The truth is that depending on the application, identifying a specific flag can take little time, a lot of time, or be impossible."}] 80:["$","p",null,{"className":" ","children":"Some flags are called:"}] 81:["$","pre",null,{"data-code":"advancedDomainRegistrationEnabled\n","children":["$","code",null,{"children":"advancedDomainRegistrationEnabled\n"}]}] 82:["$","p",null,{"className":" ","children":"and others can be called:"}] 83:["$","pre",null,{"data-code":"adre\n","children":["$","code",null,{"children":"adre\n"}]}] 84:["$","p",null,{"className":" ","children":"From my experience, agents are usually good at identifying these feature flags if you give them the bundles and the HTML, so I recommend using agents like Claude Code or Copilot to deobfuscate a feature and be able to modify only that flag."}] 85:["$","p",null,{"className":" ","children":"Personally, I download all the application bundles into a single folder and run my coworker:"}] 86:["$","pre",null,{"data-code":"claude -c --dangerously-skip-permissions\n","children":["$","code",null,{"className":"hljs language-bash","children":"claude -c --dangerously-skip-permissions\n"}]}] 87:["$","p",null,{"className":" ","children":"My coworker generates Markdown summaries explaining each feature I ask for, including endpoints, deobfuscated and parsed code (it even runs it through ESLint)."}] 88:["$","p",null,{"className":" ","children":"I still need to refine the subagents I’ve created, and once they are properly polished, I’ll publish them."}] 89:["$","h2",null,{"className":"text-3xl font-semibold mt-10 mb-4","id":"exploiting-feature-factories","children":[["$","a",null,{"href":"#exploiting-feature-factories","aria-hidden":"true","tabIndex":"-1","className":" underline text-primary font-medium flex items-center gap-1 ","children":["$","span",null,{"className":"icon icon-link"}]}],"Exploiting Feature Factories"]}] 8a:["$","p",null,{"className":" ","children":"In this section I'm going to narrate some examples of vulnerabilities I've found."}] 8b:["$","p",null,{"className":" ","children":["I was hunting on a company called ",["$","strong",null,{"children":"MegaCorp"}],". This company is dedicated to a specific niche with its ",["$","strong",null,{"children":"primary.app"}]," application."]}] 8c:["$","p",null,{"className":" ","children":["MegaCorp is a very large company in its niche, so some time ago it started with another secondary niche with the ",["$","strong",null,{"children":"secondary.app"}]," application."]}] 8d:["$","p",null,{"className":" ","children":["However, the ",["$","strong",null,{"children":"secondary.app"}]," niche has an already established market and high competition, so if ",["$","strong",null,{"children":"MegaCorp"}]," wants to enter the market, it must turn ",["$","strong",null,{"children":"secondary.app"}]," into a feature factory, for example, by collecting features that users request in other applications on the market."]}] 8e:["$","p",null,{"className":" ","children":"That way it can gain market share and attract users to its application, growing in the niche."}] 8f:["$","p",null,{"className":" ","children":["I'm the ",["$","strong",null,{"children":"main app guy"}],", I don't even do recon. My strategy is to understand an application very deeply, to become one more developer."]}] 90:["$","blockquote",null,{"children":["\n",["$","p",null,{"className":" ","children":"I even follow the developers on X to feel like one of them... I'm not crazy, I promise..."}],"\n"]}] 91:["$","p",null,{"className":" ","children":["Something I recommend for this strategy is to follow ",["$","strong",null,{"children":"MegaCorp"}]," and ",["$","strong",null,{"children":"secondary.app"}]," on all social networks, since feature factories often have strong hype marketing campaigns."]}] 92:["$","p",null,{"className":" ","children":"These campaigns usually have posts like:"}] 93:["$","p",null,{"className":" ","children":["$","em",null,{"children":"\"We're excited to announce a major upgrade coming to Secondary App next week!\""}]}] 94:["$","p",null,{"className":" ","children":"This already tells you that they've probably pushed hidden features with flags to production."}] 95:["$","p",null,{"className":" ","children":"This was my case a few weeks ago..."}] 96:["$","p",null,{"className":" ","children":["I was procrastinating watching a movie after a long day of disastrous hunting. However, since I'm subscribed to notifications on all social networks for ",["$","strong",null,{"children":"secondary.app"}],", I got a notification from X."]}] 97:["$","$L3",null,{"src":"/articles/exploiting-feature-factory/fake-notification.png","alt":"Notification"}] 98:["$","p",null,{"className":" ","children":"I immediately opened Caido and went to the application to investigate the features."}] 99:["$","p",null,{"className":" ","children":["This Feature Factory hunting strategy is effective if you know the application. Since I already knew it like one more developer, when I made the change from ",["$","code",null,{"children":"false"}]," to ",["$","code",null,{"children":"true"}],", I immediately started seeing requests to new endpoints I had never seen before!"]}] 9a:["$","p",null,{"className":" ","children":"In my case, I focused on one particular feature."}] 9b:["$","p",null,{"className":" ","children":["One of the features I discovered was ",["$","em",null,{"children":"\"Import from GitHub\""}],". You could say it was impact at first sight💘."]}] 9c:["$","p",null,{"className":" ","children":"That's where I thought there could be more impact, so I started working on that feature."}] 9d:["$","p",null,{"className":" ","children":[["$","strong",null,{"children":"primary.app"}]," allowed GitHub integration, and most of its users were alredy using that integration (since it’s the standard), so it was only a matter of time before ",["$","strong",null,{"children":"secondary.app"}]," integrated it as well."]}] 9e:["$","p",null,{"className":" ","children":"There are two ways to efficiently allow GitHub integration in your application:"}] 9f:["$","ul",null,{"className":" space-y-2","children":["\n",["$","li",null,{"children":"GitHub OAuth"}],"\n",["$","li",null,{"children":"GitHub App"}],"\n"]}] a0:["$","p",null,{"className":" ","children":"Using GitHub OAuth is the correct way to ensure that GitHub RBAC is applied, since all operations are performed with the permissions granted by the user’s access token."}] a1:["$","p",null,{"className":" ","children":["However, many third party apps need to implement bots and background tasks on users' repositories, and that's why many applications, in addition to GitHub OAuth, implement their own ",["$","$L4",null,{"href":"https://github.com/marketplace?type=apps","target":"_blank","rel":"noopener noreferrer","className":"text-primary font-medium underline ","children":[" ","GitHub App",["$","svg",null,{"xmlns":"http://www.w3.org/2000/svg","width":24,"height":24,"viewBox":"0 0 24 24","fill":"none","stroke":"currentColor","strokeWidth":2,"strokeLinecap":"round","strokeLinejoin":"round","className":"lucide lucide-external-link inline-block relative -top-1 size-3 ml-1","aria-hidden":"true","children":[["$","path","1q9fwt",{"d":"M15 3h6v6"}],["$","path","gplh6r",{"d":"M10 14 21 3"}],["$","path","a6xqqp",{"d":"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"}],"$undefined"]}]]}],"."]}] a2:["$","p",null,{"className":" ","children":"A GitHub App acts on your GitHub resources with the permissions you grant it when installing it, which by default is full access (read & write) to all repositories (root💀)."}] a3:["$","p",null,{"className":" ","children":["$","img",null,{"src":"/articles/exploiting-feature-factory/github-app.png","alt":""}]}] a4:["$","p",null,{"className":" ","children":"So my idea was clear: try to exploit the application’s background tasks to see if I could interact with other users’ private repositories (who had installed the GitHub App) with elevated privileges (GitHub App permissions)."}] a5:["$","p",null,{"className":" ","children":"Well, to my surprise, I didn't even have to complicate things looking for background task flows. I found an endpoint the frontend used to view a user's repositories:"}] a6:["$","pre",null,{"data-code":"[object Object], /git/repos?user=,[object Object],\n","children":["$","code",null,{"className":"hljs language-JavaScript","children":[["$","span",null,{"className":"hljs-variable constant_","children":"GET"}]," /git/repos?user=",["$","span",null,{"className":"hljs-variable constant_","children":"PRIMARY_APP_USERNAME"}],"\n"]}]}] a7:["$","p",null,{"className":" ","children":["Just like that, no complications, an IDOR that allowed me to see the title, description, and metadata of private repositories of any user who had ",["$","strong",null,{"children":"MegaCorp's GitHub App"}],"."]}] a8:["$","blockquote",null,{"children":["\n",["$","p",null,{"className":" ","children":"Never grant full read access to your repositories for any GitHub App; eventually, the app is going to be hacked."}],"\n"]}] a9:["$","p",null,{"className":" ","children":["Since usernames in ",["$","strong",null,{"children":"primary.app"}]," are public, I could enumerate private repositories belonging to any user. For example, I could do a quick search on ",["$","span",null,{"className":"relative inline-flex align-middle group select-none","style":{"width":18,"height":18},"tabIndex":-1,"children":[["$","$L3",null,{"src":"/images/logos/x.svg","alt":"ImageIcon","width":18,"height":18,"className":"block image-icon"}],"$undefined"]}]," and collect tons of usernames, including the company’s CEO!"]}] aa:["$","p",null,{"className":" ","children":"This was cool, but it didn’t have much impact either (aside from seeing which private projects people were working on)."}] ab:["$","p",null,{"className":" ","children":"However a while later I found a way to interact with the private repositories, clone them and push changes!"}] ac:["$","pre",null,{"data-code":"[object Object],\n,[object Object], /git/repo\n\n{\n ,[object Object],: ,[object Object],,\n ,[object Object],: ,[object Object],\n}\n","children":["$","code",null,{"className":"hljs language-JavaScript","children":[["$","span",null,{"className":"hljs-comment","children":"// import repo"}],"\n",["$","span",null,{"className":"hljs-variable constant_","children":"POST"}]," /git/repo\n\n{\n ",["$","span",null,{"className":"hljs-string","children":"\"namespace\""}],": ",["$","span",null,{"className":"hljs-variable constant_","children":"GITHUB_USERNAME"}],",\n ",["$","span",null,{"className":"hljs-string","children":"\"repo\""}],": ",["$","span",null,{"className":"hljs-variable constant_","children":"GITHUB_REPO_NAME"}],"\n}\n"]}]}] ad:["$","pre",null,{"data-code":"[object Object],\n,[object Object], /git/repo\n\n{\n ,[object Object],: ,[object Object],\n ,[object Object],\n}\n","children":["$","code",null,{"className":"hljs language-JavaScript","children":[["$","span",null,{"className":"hljs-comment","children":"// push changes"}],"\n",["$","span",null,{"className":"hljs-variable constant_","children":"PATCH"}]," /git/repo\n\n{\n ",["$","span",null,{"className":"hljs-string","children":"\"branch\""}],": ",["$","span",null,{"className":"hljs-variable constant_","children":"REPO_BRANCH"}],"\n ",["$","span",null,{"className":"hljs-comment","children":"// complex body that doesn't matter"}],"\n}\n"]}]}] ae:["$","p",null,{"className":" ","children":"I could clone and interact with a user’s private repository (push changes, create branches, PRs…) just by knowing their username and repository name, which I could obtain from the previous IDOR!"}] af:["$","p",null,{"className":" ","children":"This had a brutal impact. Imagine being able to clone and push changes to any private GitHub repository using the vendor GitHub App as a bridge to bypass GitHub RBAC!"}] b0:["$","p",null,{"className":" ","children":"Imagine pushing changes to the main branch of a large OSS project/library (💀)!"}] b1:["$","h3",null,{"className":"text-2xl font-semibold mt-8 mb-3","id":"key-takeaways","children":[["$","a",null,{"href":"#key-takeaways","aria-hidden":"true","tabIndex":"-1","className":" underline text-primary font-medium flex items-center gap-1 ","children":["$","span",null,{"className":"icon icon-link"}]}],"Key Takeaways"]}] b2:["$","p",null,{"className":" ","children":"I’ve found many more bugs using a very similar approach, some of them with even higher impact in terms of CVSS metrics."}] b3:["$","p",null,{"className":" ","children":"However, this one felt like the coolest and silliest example, since, as you can see, these aren’t complicated bugs or crazy workflows, just a matter of understanding the software, its lifecycle, and knowing where to look."}] b4:["$","p",null,{"className":" ","children":"From all of them, I ended up extracting the following methodology:"}] b5:["$","ul",null,{"className":" space-y-2","children":["\n",["$","li",null,{"children":["\n",["$","p",null,{"className":" ","children":[["$","strong",null,{"children":"Identify the Feature Factory:"}]," First, you need to identify your target’s Feature Factory. This is usually a secondary product or feature where the company is pushing hard to gain market share. It is the area where growth, experimentation, and rapid development are most visible."]}],"\n"]}],"\n",["$","li",null,{"children":["\n",["$","p",null,{"className":" ","children":[["$","strong",null,{"children":"Know the application:"}]," Become an expert on the application. You should understand it as if you were another developer working on the project. This allows you to notice even subtle changes and puts you in a position to hunt issues before others do."]}],"\n"]}],"\n",["$","li",null,{"children":["\n",["$","p",null,{"className":" ","children":[["$","strong",null,{"children":"Monitor social media:"}]," Keep a close eye on the company’s and developers’ social media accounts. Marketing campaigns and update announcements often indicate that new features have been pushed (not yet visible to users), many of which may remain hidden behind feature flags until tested by the dev team."]}],"\n"]}],"\n",["$","li",null,{"children":["\n",["$","p",null,{"className":" ","children":[["$","strong",null,{"children":"Understand the flag system:"}]," Learn how the application implements and manages feature flags, and what each one activates. This way, when you discover a new flag, you can focus on exploiting it directly and comfortably, without breaking the application in the process."]}],"\n"]}],"\n",["$","li",null,{"children":["\n",["$","p",null,{"className":" ","children":[["$","strong",null,{"children":"Monitor Flags:"}]," Every application has a flag system that comes in different formats, so you can easily write a script in 15 minutes to extract them and get notified when a new one appears. I’m currently building a tool for this, but I haven’t had time to finish it yet, once it’s done, I’ll update the article."]}],"\n"]}],"\n",["$","li",null,{"children":["\n",["$","p",null,{"className":" ","children":["$","strong",null,{"children":"Think critically (🧠) !"}]}],"\n"]}],"\n"]}] b6:["$","h2",null,{"className":"text-3xl font-semibold mt-10 mb-4","id":"disadvantages-of-feature-factories","children":[["$","a",null,{"href":"#disadvantages-of-feature-factories","aria-hidden":"true","tabIndex":"-1","className":" underline text-primary font-medium flex items-center gap-1 ","children":["$","span",null,{"className":"icon icon-link"}]}],"Disadvantages of feature factories"]}] b7:["$","p",null,{"className":" ","children":"There are certain disadvantages of attacking Feature Factories. The main one is that by having an aggressive SDLC, changes are pushed to production constantly and very quickly."}] b8:["$","p",null,{"className":" ","children":["$","strong",null,{"children":"They even deploy on Fridays 💀"}]}] b9:["$","p",null,{"className":" ","children":["$","em",null,{"children":"\"like, who the hell deploys on Fridays???\""}]}] ba:["$","p",null,{"className":" ","children":"These changes don't just implement features, they also modify them."}] bb:["$","p",null,{"className":" ","children":"Which means that one day there might be a bug, and the next day it's gone...🥲"}] bc:["$","p",null,{"className":" ","children":"That's why it's important that you make a descriptive and very simple report so the triager can validate it quickly. Otherwise, the vulnerability might get fixed before the triage attempt and you'll get a:"}] bd:["$","figure",null,{"className":"w-full justify-center items-center flex flex-col","children":["$","p",null,{"className":"font-serif italic leading-relaxed text-foreground text-xl text-center","children":"🌷Issue is not reproducible🌷"}]}] be:["$","p",null,{"className":" ","children":"In my case, I made a very confusing report on the GitHub vulnerability and it took a month and a half to triage!"}] bf:["$","p",null,{"className":" ","children":["During that month and a half, the vendor was implementing changes and patches. Fortunately, I was able to bypass them all, but the severity ended up dropping from ",["$","strong",null,{"children":"Critical"}]," to ",["$","strong",null,{"children":"High"}],"😒."]}] c0:["$","p",null,{"className":" ","children":"But this is exactly what I mean in this article, Feature Factories are so focused on shipping feature after feature that they sometimes push absolute monstrosities straight into production."}] c1:["$","p",null,{"className":" ","children":"In many cases, because the development team hasn’t been around for long, there’s a significant lack of coordination between the security and development teams."}] c2:["$","p",null,{"className":" ","children":["This often leads to bugs being marked as ",["$","strong",null,{"children":"RESOLVED"}]," even though there’s either no real patch at all, or the fix is very weak and easy to bypass."]}] c3:["$","p",null,{"className":" ","children":["$","img",null,{"src":"/articles/exploiting-feature-factory/reports.png","alt":""}]}] c4:["$","h2",null,{"className":"text-3xl font-semibold mt-10 mb-4","id":"conclusion","children":[["$","a",null,{"href":"#conclusion","aria-hidden":"true","tabIndex":"-1","className":" underline text-primary font-medium flex items-center gap-1 ","children":["$","span",null,{"className":"icon icon-link"}]}],"Conclusion"]}] c5:["$","p",null,{"className":" ","children":"I hope this article has been helpful to someone in some way."}] c6:["$","p",null,{"className":" ","children":"I hope the idea comes across and at the very least makes you reflect and improve your methodology!"}] c7:["$","p",null,{"className":" ","children":["Feel free to ",["$","$L4",null,{"href":"https://x.com/kapeka0?ref=kapeka.dev","target":"_blank","rel":"noopener noreferrer","className":"text-primary font-medium underline ","children":[" ","follow me on X",["$","svg",null,{"xmlns":"http://www.w3.org/2000/svg","width":24,"height":24,"viewBox":"0 0 24 24","fill":"none","stroke":"currentColor","strokeWidth":2,"strokeLinecap":"round","strokeLinejoin":"round","className":"lucide lucide-external-link inline-block relative -top-1 size-3 ml-1","aria-hidden":"true","children":[["$","path","1q9fwt",{"d":"M15 3h6v6"}],["$","path","gplh6r",{"d":"M10 14 21 3"}],["$","path","a6xqqp",{"d":"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"}],"$undefined"]}]]}]," if you want, and happy hacking!"]}] c8:["$","p",null,{"className":" ","children":"Thanks for reading!"}] c9:["$","div",null,{"className":"flex w-full pt-10","children":["$","$L4",null,{"href":"/blog","className":"text-sm mx-auto mb-10 text-muted hover:text-white transition-colors duration-200 flex items-center ease-in","children":[["$","svg",null,{"xmlns":"http://www.w3.org/2000/svg","width":24,"height":24,"viewBox":"0 0 24 24","fill":"none","stroke":"currentColor","strokeWidth":2,"strokeLinecap":"round","strokeLinejoin":"round","className":"lucide lucide-arrow-left size-4 mr-2","aria-hidden":"true","children":[["$","path","1l729n",{"d":"m12 19-7-7 7-7"}],["$","path","x3x0zl",{"d":"M19 12H5"}],"$undefined"]}]," ","blog"]}]}] ca:["$","script","script-0",{"src":"/_next/static/chunks/9c4a73c4b42ed60e.js?dpl=dpl_A5Z6Ann3qNAotdfdzCfRc27tABUK","async":true}] cb:["$","$Lcc",null,{"children":["$","$cd",null,{"name":"Next.MetadataOutlet","children":"$@ce"}]}] ce:null