[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"sanity-qY5kdUeCDEhU4p5hGB3t78x4TIDY1P7_raqbKkqXJAE":3,"sanity-4U-5slvaJ06rNYNyOouNl3RK6Ye4XdcHrjRAvvymMPo":588},{"data":4,"sourceMap":-1},{"latestPodcast":5,"latestReleases":14,"post":39,"recent":563},[6],{"_id":7,"publishedAt":8,"slug":9,"sponsored":12,"title":13},"d53f9358-3bb2-4f69-aebe-d31d19522cd4","2026-07-10T07:40:00.000Z",{"_type":10,"current":11},"slug","building-more-than-just-an-agent-harness",null,"Building more than just an agent harness",[15,21,27,33],{"_id":16,"publishedAt":17,"slug":18,"title":20},"eb5b66eb-9410-4329-83bb-22bbff39402a","2026-04-28T13:00:00.000Z",{"_type":10,"current":19},"turn-scattered-knowledge-into-trusted-intelligence","Turning scattered knowledge into trusted intelligence: Stack Internal 2026.3",{"_id":22,"publishedAt":23,"slug":24,"title":26},"369c2401-b62e-4a37-8ff8-bf603023ecad","2026-03-02T15:03:00.988Z",{"_type":10,"current":25},"what-s-new-at-stack-overflow-march-2026","What’s new at Stack Overflow: March 2026",{"_id":28,"publishedAt":29,"slug":30,"title":32},"5e9053a4-07ea-447c-91ea-29e0b6228537","2026-02-02T15:00:00.000Z",{"_type":10,"current":31},"what-s-new-at-stack-overflow-february-2026","What’s new at Stack Overflow: February 2026",{"_id":34,"publishedAt":35,"slug":36,"title":38},"a1b538eb-a8a6-46d0-80a1-ac70ec9bb935","2026-01-05T10:00:00.000-05:00",{"_type":10,"current":37},"what-s-new-at-stack-overflow-january-2026","What’s new at Stack Overflow: January 2026",{"_createdAt":40,"_id":41,"_rev":42,"_system":43,"_type":46,"_updatedAt":47,"author":48,"body":68,"comments":537,"dateUrl":538,"excerpt":539,"image":540,"legacyBody":543,"product":12,"publishedAt":546,"slug":547,"sponsored":12,"tags":549,"title":562,"visible":537},"2023-05-24T12:28:24Z","wp-post-21611","nvZcks16ldBXxsacAEi28i",{"base":44},{"id":41,"rev":45},"LIB4H7UiOBRX1pcyre0E58","blogPost","2026-05-11T18:31:29Z",[49],{"_createdAt":50,"_id":51,"_rev":52,"_system":53,"_type":56,"_updatedAt":57,"avatar":58,"bio":63,"employee":64,"name":65,"slug":66},"2023-05-23T16:27:18Z","wp-author-cap-21217","trel0PQL1Lkhwvb53Vx4Sh",{"base":54},{"id":51,"rev":55},"07ZbrKPSUrjrV4wQ6fDtDP","blogAuthor","2025-08-19T14:50:48Z",{"_type":59,"asset":60},"image",{"_ref":61,"_type":62},"image-1368d2b465e1de8630a16d34bf006e750ca3bca8-400x400-jpg","reference","Tanya Janca, aka SheHacksPurple, is the best-selling author of 'Alice and Bob Learn Secure Coding’ and 'Alice and Bob Learn Application Security’. She is currently the CEO and secure coding trainer at She Hacks Purple Consulting. Over her 28-year IT career she has won countless awards (including OWASP Lifetime Distinguished Member and Hacker of the Year), spoken all over the planet, and is a prolific blogger. Tanya has trained thousands of software developers and IT security professionals, via her online academies (We Hack Purple and Semgrep Academy), and her live training programs. Having performed counter-terrorism, led security for the 52nd Canadian general election, developed or secured countless applications, Tanya Janca is widely considered an international authority on the security of software.\n","none","Tanya Janca",{"current":67},"tanya-janca",[69,80,88,97,117,134,143,151,159,185,197,220,232,255,271,287,322,330,346,354,378,386,394,402,410,418,426,442,450,458,470,482,497,505,513,521,529],{"_key":70,"_type":71,"children":72,"markDefs":78,"style":79},"83e5699eaa40","block",[73],{"_key":74,"_type":75,"marks":76,"text":77},"83e5699eaa400","span",[],"Every year, universities, colleges, and bootcamps around the world graduate brand new software developers who have never taken a course on secure coding or application security. In fact, they may not have been taught anything about security at all.",[],"normal",{"_key":81,"_type":71,"children":82,"markDefs":87,"style":79},"06f9e570b8c5",[83],{"_key":84,"_type":75,"marks":85,"text":86},"06f9e570b8c50",[],"This lack of security understanding has implications for software development on three layers: the individual developer writing insecure code, the engineering team blindly trusting their dependencies, and the organization thinking that their best bet is to roll their own security controls. In this article, I’ll talk about each of these layers, how a lack of security knowledge affects it, and how individuals and organizations can create software that follows security best practices.",[],{"_key":89,"_type":71,"children":90,"markDefs":95,"style":96},"1b466318116c",[91],{"_key":92,"_type":75,"marks":93,"text":94},"1b466318116c0",[],"Hello (insecure) world",[],"h2",{"_key":98,"_type":71,"children":99,"markDefs":113,"style":79},"1613f2eede72",[100,104,109],{"_key":101,"_type":75,"marks":102,"text":103},"1613f2eede720",[],"From the very first lesson, we are taught to code insecurely and incorrectly. The first thing we do in the famous ",{"_key":105,"_type":75,"marks":106,"text":108},"1613f2eede721",[107],"2acf0ab7208b","‘hello world’",{"_key":110,"_type":75,"marks":111,"text":112},"1613f2eede722",[]," lesson is to put data on the screen: “Hello world!” The second thing is we ask the user for their name: “What is your name?” The user enters their name, we take that data and reflect it back to the screen to say “Hello \u003Cinsert user’s text here>”. There is no mention of validating the user input to see if it’s potentially malicious, nor is the learner taught to output encode the information, which would disable any potential code the user has entered.",[114],{"_key":107,"_type":115,"href":116,"reference":12},"link","https:\u002F\u002Fstackoverflow.blog\u002F2020\u002F03\u002F05\u002Fa-modern-hello-world-program-needs-more-than-just-code\u002F",{"_key":118,"_type":71,"children":119,"markDefs":133,"style":79},"c46e52d3d398",[120,124,129],{"_key":121,"_type":75,"marks":122,"text":123},"c46e52d3d3980",[],"If we added more to the lesson, validating the input (and rejecting it if it was bad) and then output encoding the data before mirroring it to the screen, then we would be teaching every new coder how to avoid cross-site scripting (XSS). But we don’t teach that as part of the lesson. We show them how to do it ",{"_key":125,"_type":75,"marks":126,"text":128},"c46e52d3d3981",[127],"em","insecurely",{"_key":130,"_type":75,"marks":131,"text":132},"c46e52d3d3982",[],". I suspect this is part of the reason that XSS is so prevalent across the internet: we’ve been drilling it into new coders how to create this vulnerability from the very first day.",[],{"_key":135,"_type":71,"children":136,"markDefs":141,"style":142},"ce168ab4013c",[137],{"_key":138,"_type":75,"marks":139,"text":140},"ce168ab4013c0",[],"Secure coding best practices",[],"h3",{"_key":144,"_type":71,"children":145,"markDefs":150,"style":79},"f19091045093",[146],{"_key":147,"_type":75,"marks":148,"text":149},"f190910450930",[],"If everyone is learning the wrong way from the start, how can we fix this? There are several things, but let’s start with how we build software: the system development life cycle (SDLC).",[],{"_key":152,"_type":71,"children":153,"markDefs":158,"style":79},"93066a54f10a",[154],{"_key":155,"_type":75,"marks":156,"text":157},"93066a54f10a0",[],"Some common security activities that can be added to the SDLC include:",[],{"_key":160,"_type":71,"children":161,"level":180,"listItem":181,"markDefs":182,"style":79},"5e87f537190a",[162,167,171,176],{"_key":163,"_type":75,"marks":164,"text":166},"5e87f537190a0",[165],"strong","Security requirements",{"_key":168,"_type":75,"marks":169,"text":170},"5e87f537190a1",[],": The measures that need to be put in place for the application to be considered secure. You’re building a ",{"_key":172,"_type":75,"marks":173,"text":175},"5e87f537190a2",[174],"99f44320bca9","serverless",{"_key":177,"_type":75,"marks":178,"text":179},"5e87f537190a3",[]," app? Cool! Here’s a list of security requirements we need you to add to your project’s requirements document to ensure it’s safe enough to put it on the internet.",1,"bullet",[183],{"_key":174,"_type":115,"href":184,"reference":12},"https:\u002F\u002Fstackoverflow.blog\u002F2020\u002F05\u002F18\u002Fyou-want-efficient-application-scaling-go-serverless\u002F",{"_key":186,"_type":71,"children":187,"level":180,"listItem":181,"markDefs":196,"style":79},"2841d0fdc57e",[188,192],{"_key":189,"_type":75,"marks":190,"text":191},"2841d0fdc57e0",[165],"Threat modeling",{"_key":193,"_type":75,"marks":194,"text":195},"2841d0fdc57e1",[],": A brainstorming session that includes at least one security professional, a product owner and\u002For business representative, and a member of the technical team. The goal is to identify as many potential threats to the product as possible, then work to mitigate the ones that seem the most damaging or dangerous. This is often done in the design phase, but it could be done at any point afterwards if you didn’t have time earlier in the SDLC.",[],{"_key":198,"_type":71,"children":199,"level":180,"listItem":181,"markDefs":217,"style":79},"0bdc8dfa0774",[200,204,208,213],{"_key":201,"_type":75,"marks":202,"text":203},"0bdc8dfa07740",[165],"Code scans",{"_key":205,"_type":75,"marks":206,"text":207},"0bdc8dfa07741",[],": During the coding phase, you could scan your own code with a static application security testing tool (SAST) or a software composition analysis tool (SCA) or throw your app on a dev server and scan it with a ",{"_key":209,"_type":75,"marks":210,"text":212},"0bdc8dfa07742",[211],"ec9355a8ee2d","DAST",{"_key":214,"_type":75,"marks":215,"text":216},"0bdc8dfa07743",[]," tool.",[218],{"_key":211,"_type":115,"href":219,"reference":12},"https:\u002F\u002Fstackoverflow.blog\u002F2022\u002F11\u002F30\u002Fcontinuous-delivery-meet-continuous-security\u002F",{"_key":221,"_type":71,"children":222,"level":180,"listItem":181,"markDefs":231,"style":79},"62155cc33151",[223,227],{"_key":224,"_type":75,"marks":225,"text":226},"62155cc331510",[165],"Break it early",{"_key":228,"_type":75,"marks":229,"text":230},"62155cc331511",[],": During the testing phase, you could hire a penetration tester to perform thorough automated and manual testing of your entire system.",[],{"_key":233,"_type":71,"children":234,"level":180,"listItem":181,"markDefs":252,"style":79},"484f7ad3789c",[235,239,243,248],{"_key":236,"_type":75,"marks":237,"text":238},"484f7ad3789c0",[165],"Protect code in production",{"_key":240,"_type":75,"marks":241,"text":242},"484f7ad3789c1",[],": During the release phase, you could set up ",{"_key":244,"_type":75,"marks":245,"text":247},"484f7ad3789c2",[246],"a9481be26f70","monitoring, logging, and alerting",{"_key":249,"_type":75,"marks":250,"text":251},"484f7ad3789c3",[]," for your application. You could install it behind a runtime application security protection (RASP) or web application firewall (WAF).",[253],{"_key":246,"_type":115,"href":254,"reference":12},"https:\u002F\u002Fstackoverflow.blog\u002F2022\u002F10\u002F12\u002Fhow-observability-driven-development-creates-elite-performers\u002F",{"_key":256,"_type":71,"children":257,"markDefs":270,"style":79},"460b86d9fecc",[258,262,266],{"_key":259,"_type":75,"marks":260,"text":261},"460b86d9fecc0",[],"All the items listed above are just the beginning: you can organize your secure SDLC in any way that works for your organization and teams. You can use some of these or none of these; the key is finding activities and tooling that work for ",{"_key":263,"_type":75,"marks":264,"text":265},"460b86d9fecc1",[127],"your",{"_key":267,"_type":75,"marks":268,"text":269},"460b86d9fecc2",[]," organization.",[],{"_key":272,"_type":71,"children":273,"markDefs":286,"style":79},"35d8bba6faac",[274,278,282],{"_key":275,"_type":75,"marks":276,"text":277},"35d8bba6faac0",[],"We can create a ",{"_key":279,"_type":75,"marks":280,"text":281},"35d8bba6faac1",[127],"secure",{"_key":283,"_type":75,"marks":284,"text":285},"35d8bba6faac2",[]," SDLC by adding security activities throughout out processes. That said, we have to follow the security steps every time, not just sometimes or when it’s convenient if we want to reliably produce secure software.",[],{"_key":288,"_type":71,"children":289,"markDefs":319,"style":79},"e54d500f783f",[290,294,298,302,307,311,315],{"_key":291,"_type":75,"marks":292,"text":293},"e54d500f783f0",[],"If you add one single security step or verification to your SDLC, you will create more secure applications. If you add more than one step, you will create ",{"_key":295,"_type":75,"marks":296,"text":297},"e54d500f783f1",[127],"even better",{"_key":299,"_type":75,"marks":300,"text":301},"e54d500f783f2",[]," applications. ",{"_key":303,"_type":75,"marks":304,"text":306},"e54d500f783f3",[305],"22f67a38cb62","Software is always a tradeoff",{"_key":308,"_type":75,"marks":309,"text":310},"e54d500f783f4",[],": we don’t want to spend a million dollars on security for an application that will only earn h a couple thousand dollars worth of value. We ",{"_key":312,"_type":75,"marks":313,"text":314},"e54d500f783f5",[127],"do ",{"_key":316,"_type":75,"marks":317,"text":318},"e54d500f783f6",[],"want to ensure we are protecting our systems such that they meet the risk tolerance of our organization. In more plain language, we should work with the security team to decide exactly how much security is required, but generally it’s safe to assume that ‘more is more’ when it comes to security.",[320],{"_key":305,"_type":115,"href":321,"reference":12},"https:\u002F\u002Fstackoverflow.blog\u002F2022\u002F01\u002F17\u002Fplan-for-tradeoffs-you-cant-optimize-all-software-quality-attributes\u002F",{"_key":323,"_type":71,"children":324,"markDefs":329,"style":96},"979b1e253e25",[325],{"_key":326,"_type":75,"marks":327,"text":328},"979b1e253e250",[],"Zero trust, but not the marketing version",[],{"_key":331,"_type":71,"children":332,"markDefs":345,"style":79},"e935efef6c8d",[333,337,341],{"_key":334,"_type":75,"marks":335,"text":336},"e935efef6c8d0",[],"Quite often when designing systems, we create ‘implied trust’; that is, one or more parts of the system don’t verify something they should or could. When someone logs into a system, a security control verifies the user’s identity (via the username and password combination) and then grants them access to the parts they are allowed to access. In programming, we generally call the first part authentication (who are you?) and the second part authorization (should you be here?). If we skip this step, we are creating ",{"_key":338,"_type":75,"marks":339,"text":340},"e935efef6c8d1",[127],"implied trust",{"_key":342,"_type":75,"marks":343,"text":344},"e935efef6c8d2",[],". We don’t care who the person is and are assuming that the person is allowed to be there.",[],{"_key":347,"_type":71,"children":348,"markDefs":353,"style":79},"9af7324fc8cb",[349],{"_key":350,"_type":75,"marks":351,"text":352},"9af7324fc8cb0",[],"Zero trust means never, ever, having any implied trust. Every single possible part of a system is locked down and only opened if it must be. This means closing all ports except the ones you need. It means blocking all connections except the ones you know you need. It means always verifying everything before using it. No trust in anything at all, even the other systems you have as dependencies.",[],{"_key":355,"_type":71,"children":356,"markDefs":377,"style":79},"7a0f37e89123",[357,361,365,369,373],{"_key":358,"_type":75,"marks":359,"text":360},"7a0f37e891230",[],"Although zero trust is quite a lot of work to implement, it ",{"_key":362,"_type":75,"marks":363,"text":364},"7a0f37e891231",[127],"works",{"_key":366,"_type":75,"marks":367,"text":368},"7a0f37e891232",[],". And it works ",{"_key":370,"_type":75,"marks":371,"text":372},"7a0f37e891233",[127],"well",{"_key":374,"_type":75,"marks":375,"text":376},"7a0f37e891234",[],".",[],{"_key":379,"_type":71,"children":380,"markDefs":385,"style":79},"161e9b738b97",[381],{"_key":382,"_type":75,"marks":383,"text":384},"161e9b738b970",[],"Examples of zero trust that you could implement in programming:",[],{"_key":387,"_type":71,"children":388,"level":180,"listItem":181,"markDefs":393,"style":79},"9759d9a842e1",[389],{"_key":390,"_type":75,"marks":391,"text":392},"9759d9a842e10",[],"Validating, sanitizing, and escaping all inputs (in that order)",[],{"_key":395,"_type":71,"children":396,"level":180,"listItem":181,"markDefs":401,"style":79},"1c90fd64cf9d",[397],{"_key":398,"_type":75,"marks":399,"text":400},"1c90fd64cf9d0",[],"Each API, serverless, container, and app is an island; treat them like that. They should not trust each other!",[],{"_key":403,"_type":71,"children":404,"level":180,"listItem":181,"markDefs":409,"style":79},"10a7d0122ef2",[405],{"_key":406,"_type":75,"marks":407,"text":408},"10a7d0122ef20",[],"Authentication and authorization for everyone! Every single integration, even with systems built and maintained by your team, requires authentication and authorization, for every single connection.",[],{"_key":411,"_type":71,"children":412,"level":180,"listItem":181,"markDefs":417,"style":79},"ca11d9ab7e91",[413],{"_key":414,"_type":75,"marks":415,"text":416},"ca11d9ab7e910",[],"Output encoding, because you never know if someone changed something. Do not trust your user’s input or input that may have been tampered with!",[],{"_key":419,"_type":71,"children":420,"markDefs":425,"style":79},"45c27a176223",[421],{"_key":422,"_type":75,"marks":423,"text":424},"45c27a1762230",[],"I have never seen an organization implement every single possible variation of zero trust, but that’s okay. Applying zero trust principles to as many systems as possible is good enough.",[],{"_key":427,"_type":71,"children":428,"markDefs":441,"style":96},"258b5a217bf8",[429,433,437],{"_key":430,"_type":75,"marks":431,"text":432},"258b5a217bf80",[],"Buy, borrow, ",{"_key":434,"_type":75,"marks":435,"text":436},"258b5a217bf81",[127],"then",{"_key":438,"_type":75,"marks":439,"text":440},"258b5a217bf82",[]," build",[],{"_key":443,"_type":71,"children":444,"markDefs":449,"style":79},"c1b86db5ac4f",[445],{"_key":446,"_type":75,"marks":447,"text":448},"c1b86db5ac4f0",[],"Building security controls is hard. They are complex in nature to build, they are tested far more often and more aggressively than any other feature (thanks to malicious actors), and there are few public examples to work from due to companies wanting to protect their intellectual property. This puts us in a situation where building our own custom security control ends up being expensive, time consuming, and potentially even dangerous.",[],{"_key":451,"_type":71,"children":452,"markDefs":457,"style":79},"90376a22e1cd",[453],{"_key":454,"_type":75,"marks":455,"text":456},"90376a22e1cd0",[],"With this in mind, security professionals (and software architects, for that matter) often recommend we go in this order when we decide if we will use a pre-existing component or write our own:",[],{"_key":459,"_type":71,"children":460,"level":180,"listItem":181,"markDefs":469,"style":79},"c87f47493eaf",[461,465],{"_key":462,"_type":75,"marks":463,"text":464},"c87f47493eaf0",[165],"Buy it ",{"_key":466,"_type":75,"marks":467,"text":468},"c87f47493eaf1",[],"if we can afford it with the budget we have. The reason for this is that it’s available immediately, we don’t need to assign resources to create and thus they are free for other work, we don’t need to maintain it ourselves (which is almost always the reason custom software costs more than buying it), and it is very likely to have had significantly more security testing performed against it (big customers demand intensive testing and high security assurance). Although the price tag may seem steep, when you calculate the risk, the wait, and the long-term cost of maintaining the system, it is almost always cheaper to buy than build.",[],{"_key":471,"_type":71,"children":472,"level":180,"listItem":181,"markDefs":481,"style":79},"e13a5fad667f",[473,477],{"_key":474,"_type":75,"marks":475,"text":476},"e13a5fad667f0",[165],"Borrow it.",{"_key":478,"_type":75,"marks":479,"text":480},"e13a5fad667f1",[]," This can mean open source software, online examples, code from other teams, using the features in your framework, or even having an entire system supplied (this happens in government and nonprofit organizations more often than for-profit\u002Fprivate). Borrowing it is more of an expression than a reality, we mean ‘use code that is open source or other code you can use for free, but that you did not write’. The advantages of this are similar to the ‘buy’ section: the borrowed code is available immediately, it’s free, and we don’t have to maintain it ourselves. That said, if it’s given for free, it might not have had any security testing on it, meaning you should verify that it’s secure before using it if at all possible.",[],{"_key":483,"_type":71,"children":484,"level":180,"listItem":181,"markDefs":496,"style":79},"df8de05cc238",[485,489,493],{"_key":486,"_type":75,"marks":487,"text":488},"df8de05cc2380",[],"If neither of those is an option, we ",{"_key":490,"_type":75,"marks":491,"text":492},"df8de05cc2381",[165],"build it",{"_key":494,"_type":75,"marks":495,"text":376},"df8de05cc2382",[],[],{"_key":498,"_type":71,"children":499,"markDefs":504,"style":79},"b6acbd3ea9bf",[500],{"_key":501,"_type":75,"marks":502,"text":503},"b6acbd3ea9bf0",[],"This saves our organizations money, time and risk, despite the fact that building our own from scratch is usually way more fun.",[],{"_key":506,"_type":71,"children":507,"markDefs":512,"style":79},"cb1ed3209b91",[508],{"_key":509,"_type":75,"marks":510,"text":511},"cb1ed3209b910",[],"With this in mind, whenever possible, use the security features found within your programming framework, such as: encryption, authentication, and session management. They are tried, tested, and true!",[],{"_key":514,"_type":71,"children":515,"markDefs":520,"style":79},"a47e5381e648",[516],{"_key":517,"_type":75,"marks":518,"text":519},"a47e5381e6480",[],"Next, use third-party components (libraries, packages, gems, etc.), as they have (usually) been tested quite thoroughly. Verify third-party code and components via a software composition analysis (SCA) tool and reverify often.",[],{"_key":522,"_type":71,"children":523,"markDefs":528,"style":79},"832bd287107a",[524],{"_key":525,"_type":75,"marks":526,"text":527},"832bd287107a0",[],"To summarize the buy\u002Fborrow\u002Fbuild philosophy: don’t write your own security features unless you absolutely have to. It’s hard to get right!",[],{"_key":530,"_type":71,"children":531,"markDefs":536,"style":79},"666fd2a8c76a",[532],{"_key":533,"_type":75,"marks":534,"text":535},"666fd2a8c76a0",[],"In closing, although we may not have been taught it in school, we can start with the steps above to begin creating more secure applications and code. By creating a secure system development lifecycle, avoiding implied trust within the systems we build, and only creating our own security controls when it is absolutely necessary, we will reduce the risk to our organizations in a consistently positive way. The organizations we work for are counting on us to be their first line of defense, and with these new strategies, you should be up to the task!",[],true,"2023\u002F02\u002F09","This affects the individual developer writing insecure code, the engineering team blindly trusting their dependencies, and the organization thinking that their best bet is to roll their own security controls.",{"_type":59,"asset":541},{"_ref":542,"_type":62},"image-bde1a3319a7757c0b9a6de450f0708eb7f008350-2560x1344-jpg",{"code":544,"language":545},"\u003C!-- wp:paragraph -->\n\u003Cp>Every year, universities, colleges, and bootcamps around the world graduate brand new software developers who have never taken a course on secure coding or application security. In fact, they may not have been taught anything about security at all.&nbsp;\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->\n\n\u003C!-- wp:paragraph -->\n\u003Cp>This lack of security understanding has implications for software development on three layers: the individual developer writing insecure code, the engineering team blindly trusting their dependencies, and the organization thinking that their best bet is to roll their own security controls. In this article, I’ll talk about each of these layers, how a lack of security knowledge affects it, and how individuals and organizations can create software that follows security best practices.&nbsp;\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->\n\n\u003C!-- wp:heading -->\n\u003Ch2 id=\"h-hello-insecure-world\">Hello (insecure) world\u003C\u002Fh2>\n\u003C!-- \u002Fwp:heading -->\n\n\u003C!-- wp:paragraph -->\n\u003Cp>From the very first lesson, we are taught to code insecurely and incorrectly. The first thing we do in the famous \u003Ca href=\"https:\u002F\u002Fstackoverflow.blog\u002F2020\u002F03\u002F05\u002Fa-modern-hello-world-program-needs-more-than-just-code\u002F\">‘hello world’\u003C\u002Fa> lesson is to put data on the screen: “Hello world!” The second thing is we ask the user for their name: “What is your name?” The user enters their name, we take that data and reflect it back to the screen to say “Hello &lt;insert user’s text here&gt;”. There is no mention of validating the user input to see if it’s potentially malicious, nor is the learner taught to output encode the information, which would disable any potential code the user has entered.&nbsp;\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->\n\n\u003C!-- wp:paragraph -->\n\u003Cp>If we added more to the lesson, validating the input (and rejecting it if it was bad) and then output encoding the data before mirroring it to the screen, then we would be teaching every new coder how to avoid cross-site scripting (XSS). But we don’t teach that as part of the lesson. We show them how to do it \u003Cem>insecurely\u003C\u002Fem>. I suspect this is part of the reason that XSS is so prevalent across the internet: we’ve been drilling it into new coders how to create this vulnerability from the very first day.\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->\n\n\u003C!-- wp:heading {\"level\":3} -->\n\u003Ch3 id=\"h-secure-coding-best-practices\">Secure coding best practices\u003C\u002Fh3>\n\u003C!-- \u002Fwp:heading -->\n\n\u003C!-- wp:paragraph -->\n\u003Cp>If everyone is learning the wrong way from the start, how can we fix this? There are several things, but let’s start with how we build software: the system development life cycle (SDLC).\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->\n\n\u003C!-- wp:paragraph -->\n\u003Cp>Some common security activities that can be added to the SDLC include:\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->\n\n\u003C!-- wp:list -->\n\u003Cul>\u003C!-- wp:list-item -->\n\u003Cli>\u003Cstrong>Security requirements\u003C\u002Fstrong>: The measures that need to be put in place for the application to be considered secure. You’re building a \u003Ca href=\"https:\u002F\u002Fstackoverflow.blog\u002F2020\u002F05\u002F18\u002Fyou-want-efficient-application-scaling-go-serverless\u002F\">serverless\u003C\u002Fa> app? Cool! Here’s a list of security requirements we need you to add to your project’s requirements document to ensure it’s safe enough to put it on the internet.\u003C\u002Fli>\n\u003C!-- \u002Fwp:list-item -->\n\n\u003C!-- wp:list-item -->\n\u003Cli>\u003Cstrong>Threat modeling\u003C\u002Fstrong>: A brainstorming session that includes at least one security professional, a product owner and\u002For business representative, and a member of the technical team. The goal is to identify as many potential threats to the product as possible, then work to mitigate the ones that seem the most damaging or dangerous. This is often done in the design phase, but it could be done at any point afterwards if you didn’t have time earlier in the SDLC.&nbsp;\u003C\u002Fli>\n\u003C!-- \u002Fwp:list-item -->\n\n\u003C!-- wp:list-item -->\n\u003Cli>\u003Cstrong>Code scans\u003C\u002Fstrong>: During the coding phase, you could scan your own code with a static application security testing tool (SAST) or a software composition analysis tool (SCA) or throw your app on a dev server and scan it with a \u003Ca href=\"https:\u002F\u002Fstackoverflow.blog\u002F2022\u002F11\u002F30\u002Fcontinuous-delivery-meet-continuous-security\u002F\">DAST\u003C\u002Fa> tool.\u003C\u002Fli>\n\u003C!-- \u002Fwp:list-item -->\n\n\u003C!-- wp:list-item -->\n\u003Cli>\u003Cstrong>Break it early\u003C\u002Fstrong>: During the testing phase, you could hire a penetration tester to perform thorough automated and manual testing of your entire system.\u003C\u002Fli>\n\u003C!-- \u002Fwp:list-item -->\n\n\u003C!-- wp:list-item -->\n\u003Cli>\u003Cstrong>Protect code in production\u003C\u002Fstrong>: During the release phase, you could set up \u003Ca href=\"https:\u002F\u002Fstackoverflow.blog\u002F2022\u002F10\u002F12\u002Fhow-observability-driven-development-creates-elite-performers\u002F\">monitoring, logging, and alerting\u003C\u002Fa> for your application. You could install it behind a runtime application security protection (RASP) or web application firewall (WAF).&nbsp;\u003C\u002Fli>\n\u003C!-- \u002Fwp:list-item -->\u003C\u002Ful>\n\u003C!-- \u002Fwp:list -->\n\n\u003C!-- wp:paragraph -->\n\u003Cp>All the items listed above are just the beginning: you can organize your secure SDLC in any way that works for your organization and teams. You can use some of these or none of these; the key is finding activities and tooling that work for \u003Cem>your\u003C\u002Fem> organization.\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->\n\n\u003C!-- wp:paragraph -->\n\u003Cp>We can create a \u003Cem>secure\u003C\u002Fem> SDLC by adding security activities throughout out processes. That said, we have to follow the security steps every time, not just sometimes or when it’s convenient if we want to reliably produce secure software.\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->\n\n\u003C!-- wp:paragraph -->\n\u003Cp>If you add one single security step or verification to your SDLC, you will create more secure applications. If you add more than one step, you will create \u003Cem>even better\u003C\u002Fem> applications. \u003Ca href=\"https:\u002F\u002Fstackoverflow.blog\u002F2022\u002F01\u002F17\u002Fplan-for-tradeoffs-you-cant-optimize-all-software-quality-attributes\u002F\">Software is always a tradeoff\u003C\u002Fa>: we don’t want to spend a million dollars on security for an application that will only earn h a couple thousand dollars worth of value. We \u003Cem>do \u003C\u002Fem>want to ensure we are protecting our systems such that they meet the risk tolerance of our organization. In more plain language, we should work with the security team to decide exactly how much security is required, but generally it’s safe to assume that ‘more is more’ when it comes to security.\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->\n\n\u003C!-- wp:heading -->\n\u003Ch2 id=\"h-zero-trust-but-not-the-marketing-version\">Zero trust, but not the marketing version\u003C\u002Fh2>\n\u003C!-- \u002Fwp:heading -->\n\n\u003C!-- wp:paragraph -->\n\u003Cp>Quite often when designing systems, we create ‘implied trust’; that is, one or more parts of the system don’t verify something they should or could. When someone logs into a system, a security control verifies the user’s identity (via the username and password combination) and then grants them access to the parts they are allowed to access. In programming, we generally call the first part authentication (who are you?) and the second part authorization (should you be here?). If we skip this step, we are creating \u003Cem>implied trust\u003C\u002Fem>. We don’t care who the person is and are assuming that the person is allowed to be there.\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->\n\n\u003C!-- wp:paragraph -->\n\u003Cp>Zero trust means never, ever, having any implied trust. Every single possible part of a system is locked down and only opened if it must be. This means closing all ports except the ones you need. It means blocking all connections except the ones you know you need. It means always verifying everything before using it. No trust in anything at all, even the other systems you have as dependencies.\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->\n\n\u003C!-- wp:paragraph -->\n\u003Cp>Although zero trust is quite a lot of work to implement, it \u003Cem>works\u003C\u002Fem>. And it works \u003Cem>well\u003C\u002Fem>.\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->\n\n\u003C!-- wp:paragraph -->\n\u003Cp>Examples of zero trust that you could implement in programming:\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->\n\n\u003C!-- wp:list -->\n\u003Cul>\u003C!-- wp:list-item -->\n\u003Cli>Validating, sanitizing, and escaping all inputs (in that order)\u003C\u002Fli>\n\u003C!-- \u002Fwp:list-item -->\n\n\u003C!-- wp:list-item -->\n\u003Cli>Each API, serverless, container, and app is an island; treat them like that. They should not trust each other!\u003C\u002Fli>\n\u003C!-- \u002Fwp:list-item -->\n\n\u003C!-- wp:list-item -->\n\u003Cli>Authentication and authorization for everyone! Every single integration, even with systems built and maintained by your team, requires authentication and authorization, for every single connection.\u003C\u002Fli>\n\u003C!-- \u002Fwp:list-item -->\n\n\u003C!-- wp:list-item -->\n\u003Cli>Output encoding, because you never know if someone changed something. Do not trust your user’s input or input that may have been tampered with!\u003C\u002Fli>\n\u003C!-- \u002Fwp:list-item -->\u003C\u002Ful>\n\u003C!-- \u002Fwp:list -->\n\n\u003C!-- wp:paragraph -->\n\u003Cp>I have never seen an organization implement every single possible variation of zero trust, but that’s okay. Applying zero trust principles to as many systems as possible is good enough.&nbsp;\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->\n\n\u003C!-- wp:heading -->\n\u003Ch2 id=\"h-buy-borrow-then-build\">Buy, borrow, \u003Cem>then\u003C\u002Fem> build\u003C\u002Fh2>\n\u003C!-- \u002Fwp:heading -->\n\n\u003C!-- wp:paragraph -->\n\u003Cp>Building security controls is hard. They are complex in nature to build, they are tested far more often and more aggressively than any other feature (thanks to malicious actors), and there are few public examples to work from due to companies wanting to protect their intellectual property. This puts us in a situation where building our own custom security control ends up being expensive, time consuming, and potentially even dangerous.\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->\n\n\u003C!-- wp:paragraph -->\n\u003Cp>With this in mind, security professionals (and software architects, for that matter) often recommend we go in this order when we decide if we will use a pre-existing component or write our own:&nbsp;\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->\n\n\u003C!-- wp:list -->\n\u003Cul>\u003C!-- wp:list-item -->\n\u003Cli>\u003Cstrong>Buy it \u003C\u002Fstrong>if we can afford it with the budget we have. The reason for this is that it’s available immediately, we don’t need to assign resources to create and thus they are free for other work, we don’t need to maintain it ourselves (which is almost always the reason custom software costs more than buying it), and it is very likely to have had significantly more security testing performed against it (big customers demand intensive testing and high security assurance). Although the price tag may seem steep, when you calculate the risk, the wait, and the long-term cost of maintaining the system, it is almost always cheaper to buy than build.\u003C\u002Fli>\n\u003C!-- \u002Fwp:list-item -->\n\n\u003C!-- wp:list-item -->\n\u003Cli>\u003Cstrong>Borrow it.\u003C\u002Fstrong> This can mean open source software, online examples, code from other teams, using the features in your framework, or even having an entire system supplied (this happens in government and nonprofit organizations more often than for-profit\u002Fprivate). Borrowing it is more of an expression than a reality, we mean ‘use code that is open source or other code you can use for free, but that you did not write’. The advantages of this are similar to the ‘buy’ section: the borrowed code is available immediately, it’s free, and we don’t have to maintain it ourselves. That said, if it’s given for free, it might not have had any security testing on it, meaning you should verify that it’s secure before using it if at all possible.&nbsp;&nbsp;\u003C\u002Fli>\n\u003C!-- \u002Fwp:list-item -->\n\n\u003C!-- wp:list-item -->\n\u003Cli>If neither of those is an option, we \u003Cstrong>build it\u003C\u002Fstrong>.&nbsp;\u003C\u002Fli>\n\u003C!-- \u002Fwp:list-item -->\u003C\u002Ful>\n\u003C!-- \u002Fwp:list -->\n\n\u003C!-- wp:paragraph -->\n\u003Cp>This saves our organizations money, time and risk, despite the fact that building our own from scratch is usually way more fun.\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->\n\n\u003C!-- wp:paragraph -->\n\u003Cp>With this in mind, whenever possible, use the security features found within your programming framework, such as: encryption, authentication, and session management. They are tried, tested, and true!&nbsp;\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->\n\n\u003C!-- wp:paragraph -->\n\u003Cp>Next, use third-party components (libraries, packages, gems, etc.), as they have (usually) been tested quite thoroughly. Verify third-party code and components via a software composition analysis (SCA) tool and reverify often.&nbsp;\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->\n\n\u003C!-- wp:paragraph -->\n\u003Cp>To summarize the buy\u002Fborrow\u002Fbuild philosophy: don’t write your own security features unless you absolutely have to. It’s hard to get right!\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->\n\n\u003C!-- wp:paragraph -->\n\u003Cp>In closing, although we may not have been taught it in school, we can start with the steps above to begin creating more secure applications and code. By creating a secure system development lifecycle, avoiding implied trust within the systems we build, and only creating our own security controls when it is absolutely necessary, we will reduce the risk to our organizations in a consistently positive way. The organizations we work for are counting on us to be their first line of defense, and with these new strategies, you should be up to the task!\u003C\u002Fp>\n\u003C!-- \u002Fwp:paragraph -->","html","2023-02-09T15:00:00.000Z",{"current":548},"three-layers-to-secure-a-software-development-organization",[550,558],{"_createdAt":551,"_id":552,"_rev":553,"_type":554,"_updatedAt":551,"slug":555,"title":557},"2023-05-23T16:43:21Z","wp-tagcat-code-for-a-living","9HpbCsT2tq0xwozQfkc4ih","blogTag",{"current":556},"code-for-a-living","Code for a Living",{"_createdAt":551,"_id":559,"_rev":553,"_type":554,"_updatedAt":551,"slug":560,"title":561},"wp-tagcat-security",{"current":561},"security","Three layers to secure a software development organization",[564,570,576,582],{"_id":565,"publishedAt":566,"slug":567,"sponsored":12,"title":569},"76c9771b-34e6-4d98-8641-ecefc711f0ef","2026-07-06T15:23:34.559Z",{"_type":10,"current":568},"when-the-sensor-starts-thinking-snortml-agentic-ai-and-the-evolving-architecture-of-intrusion-detection","When the sensor starts thinking: SnortML, agentic AI, and the evolving architecture of intrusion detection",{"_id":571,"publishedAt":572,"slug":573,"sponsored":12,"title":575},"28e560af-f0aa-4d46-bd90-f435ad604aa7","2026-06-26T14:00:27.102Z",{"_type":10,"current":574},"paging-charity-how-can-engineering-leaders-avoid-becoming-bond-villains","Paging Charity! How can engineering leaders avoid becoming Bond villains?",{"_id":577,"publishedAt":578,"slug":579,"sponsored":12,"title":581},"4b22c2a3-3779-4966-93eb-5230391dbdce","2026-06-23T14:08:58.595Z",{"_type":10,"current":580},"your-ai-shipped-a-backend-that-boots-that-is-the-whole-problem","Your AI shipped a backend that boots. That is the whole problem.",{"_id":583,"publishedAt":584,"slug":585,"sponsored":12,"title":587},"5cf362e1-fe7b-45af-b69c-914731c6a052","2026-06-23T14:00:00.000Z",{"_type":10,"current":586},"the-2026-developer-survey-is-now-open-for-human-developers-only","The 2026 Developer Survey is now open (for human developers only)!",{"data":589,"sourceMap":-1},{"count":590,"lastTimestamp":591},4,"2023-05-25T09:48:04Z"]