[{"data":1,"prerenderedAt":1829},["ShallowReactive",2],{"announcement":3,"i-tabler:sun":11,"i-tabler:moon":16,"i-tabler:menu-2":18,"i-tabler:x":20,"i-simple-icons:youtube":22,"i-simple-icons:github":24,"i-simple-icons:x":26,"i-simple-icons:linkedin":28,"i-tabler:arrow-up-right":31,"post-client-side-01-postmessage-bugs":33,"post-nav-client-side-01-postmessage-bugs":1807,"video-client-side-01-postmessage-bugs":1819,"i-tabler:copy":1827},{"startsAt":4,"endsAt":5,"scramble":6,"cta":7,"message":10},"2026-10-13","2026-11-30","Cache Poisoning:",{"href":8,"label":9},"\u002Fcache-poisoning-the-cache-you-cant-purge","Read it","The cache you can't purge.",{"left":12,"top":12,"width":13,"height":13,"rotate":12,"vFlip":14,"hFlip":14,"body":15},0,24,false,"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 12a4 4 0 1 0 8 0a4 4 0 1 0-8 0m-5 0h1m8-9v1m8 8h1m-9 8v1M5.6 5.6l.7.7m12.1-.7l-.7.7m0 11.4l.7.7m-12.1-.7l-.7.7\"\u002F>",{"left":12,"top":12,"width":13,"height":13,"rotate":12,"vFlip":14,"hFlip":14,"body":17},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 3h.393a7.5 7.5 0 0 0 7.92 12.446A9 9 0 1 1 12 2.992z\"\u002F>",{"left":12,"top":12,"width":13,"height":13,"rotate":12,"vFlip":14,"hFlip":14,"body":19},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 6h16M4 12h16M4 18h16\"\u002F>",{"left":12,"top":12,"width":13,"height":13,"rotate":12,"vFlip":14,"hFlip":14,"body":21},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18 6L6 18M6 6l12 12\"\u002F>",{"left":12,"top":12,"width":13,"height":13,"rotate":12,"vFlip":14,"hFlip":14,"body":23},"\u003Cpath fill=\"currentColor\" d=\"M23.498 6.186a3.02 3.02 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.02 3.02 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.02 3.02 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.02 3.02 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814M9.545 15.568V8.432L15.818 12z\"\u002F>",{"left":12,"top":12,"width":13,"height":13,"rotate":12,"vFlip":14,"hFlip":14,"body":25},"\u003Cpath fill=\"currentColor\" d=\"M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"\u002F>",{"left":12,"top":12,"width":13,"height":13,"rotate":12,"vFlip":14,"hFlip":14,"body":27},"\u003Cpath fill=\"currentColor\" d=\"M14.234 10.162L22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299l-.929-1.329L3.076 1.56h3.182l5.965 8.532l.929 1.329l7.754 11.09h-3.182z\"\u002F>",{"left":12,"top":12,"width":13,"height":13,"rotate":12,"vFlip":14,"hFlip":14,"body":29,"hidden":30},"\u003Cpath fill=\"currentColor\" d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037c-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85c3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.06 2.06 0 0 1-2.063-2.065a2.064 2.064 0 1 1 2.063 2.065m1.782 13.019H3.555V9h3.564zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0z\"\u002F>",true,{"left":12,"top":12,"width":13,"height":13,"rotate":12,"vFlip":14,"hFlip":14,"body":32},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M17 7L7 17M8 7h9v9\"\u002F>",{"id":34,"title":35,"body":36,"categories":1793,"coverImage":1796,"date":1797,"description":1798,"draft":14,"extension":1799,"meta":1800,"navigation":30,"noindex":14,"path":1801,"readingTime":1802,"seo":1803,"slug":1804,"stem":1804,"updatedAt":1805,"youtubeId":42,"__hash__":1806},"blog\u002Fclient-side-01-postmessage-bugs.md","Client Side 01: postMessage Bugs",{"type":37,"value":38,"toc":1781},"minimark",[39,43,47,50,53,56,59,62,70,73,76,79,82,85,90,93,99,105,111,114,120,123,126,129,134,228,231,234,237,243,246,249,329,335,338,341,392,395,398,404,407,410,489,492,495,500,503,559,568,571,659,662,665,769,775,778,784,787,792,867,870,875,942,945,950,1002,1005,1010,1066,1073,1078,1173,1176,1179,1185,1188,1193,1290,1293,1298,1345,1348,1357,1362,1420,1423,1441,1446,1488,1502,1507,1561,1564,1567,1573,1576,1581,1584,1587,1590,1593,1598,1601,1604,1607,1612,1615,1621,1627,1630,1633,1639,1642,1648,1654,1660,1666,1672,1675,1694,1697,1703,1706,1711,1714,1717,1722,1725,1728,1733,1736,1739,1744,1747,1750,1756,1759,1762,1765,1768,1771,1774,1777],[40,41],"post-media",{"video":42},"9OWy-c_ycOI",[44,45,46],"p",{},"postMessage vulnerabilities are one of those bugs that everyone talks about but nobody actually hunts for. And that's exactly why they're valuable.",[44,48,49],{},"While most bug bounty hunters are busy running Burp scans and looking for SQL injection, postMessage bugs are sitting there in checkout pages, authentication flows, and customer support widgets. Completely ignored. These vulnerabilities lead to XSS, data leaks, and account takeovers, but most researchers don't even know where to start looking.",[44,51,52],{},"I was recently listening to Critical Thinking Bug Bounty Podcast episode 151, where Ryanator and Rezo broke down client-side vulnerabilities. Their discussion on postMessage reminded me that I hadn't properly tested for these in quite some time. So I went back down the rabbit hole.",[44,54,55],{},"What I found wasn't surprising. These bugs are everywhere. Major applications. Production systems. Exploitable vulnerabilities that nobody's reporting because they don't know how to identify them.",[44,57,58],{},"If you're completely new to this topic, the \"Introduction to postMessage Vulnerabilities\" article on YesWeHack is a solid starting point. It covers the basics you need to understand the fundamentals. But this guide goes deeper. We're talking about real exploitation techniques, the mistakes developers actually make, and practical hunting methods that work in live bug bounty programs.",[44,60,61],{},"By the time you finish reading this, you'll know how to find these vulnerabilities systematically, exploit them effectively, and understand why they represent such a good opportunity in modern bug bounty.",[63,64,66],"h2",{"id":65},"understanding-postmessage",[67,68,69],"strong",{},"Understanding postMessage",[44,71,72],{},"So what is postMessage, and why does it exist?",[44,74,75],{},"postMessage is a JavaScript API that lets different windows or iframes talk to each other, even when they're from completely different domains. Normally, the browser's same-origin policy blocks this kind of communication. You can't just reach into another domain and grab data. That would be a massive security hole.",[44,77,78],{},"But sometimes, legitimate applications need cross-origin communication. Payment processors need to talk to merchant sites. OAuth popups need to send tokens back to the parent window. Live chat widgets need to exchange messages with the main application.",[44,80,81],{},"That's where postMessage comes in. It's the official, sanctioned way to break the same-origin policy when you need to.",[44,83,84],{},"The problem? When developers implement it wrong, you get vulnerabilities. And they implement it wrong constantly.",[44,86,87],{},[67,88,89],{},"The postMessage Triangle",[44,91,92],{},"Every postMessage interaction has three critical pieces. I call this the postMessage triangle, and if you understand these three elements, you understand postMessage exploitation:",[44,94,95,98],{},[67,96,97],{},"Sender"," - Who's initiating the message?",[44,100,101,104],{},[67,102,103],{},"Receiver"," - Who's listening for messages?",[44,106,107,110],{},[67,108,109],{},"Sink"," - Where does the data actually go?",[44,112,113],{},"Find these three elements in any postMessage implementation, and you'll know exactly how to exploit it. Missing any one of them means you don't fully understand the attack surface.",[63,115,117],{"id":116},"understanding-origin",[67,118,119],{},"Understanding Origin",[44,121,122],{},"Before we dive deeper into exploitation, you need to understand what \"origin\" actually means. This is where most vulnerabilities happen, so getting this concept right is critical.",[44,124,125],{},"Origin is simple: it's protocol plus host. That's it. Two components.",[44,127,128],{},"But this simplicity has massive security implications.",[44,130,131],{},[67,132,133],{},"Origin Examples:",[135,136,137,153],"table",{},[138,139,140],"thead",{},[141,142,143,147,150],"tr",{},[144,145,146],"th",{},"Full URL",[144,148,149],{},"Origin",[144,151,152],{},"Why?",[154,155,156,172,186,200,214],"tbody",{},[141,157,158,165,169],{},[159,160,161],"td",{},[162,163,164],"code",{},"https:\u002F\u002Fexample.com",[159,166,167],{},[162,168,164],{},[159,170,171],{},"Standard origin",[141,173,174,179,183],{},[159,175,176],{},[162,177,178],{},"https:\u002F\u002Fsub.example.com",[159,180,181],{},[162,182,178],{},[159,184,185],{},"Different subdomain = different origin",[141,187,188,193,197],{},[159,189,190],{},[162,191,192],{},"http:\u002F\u002Fexample.com",[159,194,195],{},[162,196,192],{},[159,198,199],{},"Different protocol = different origin",[141,201,202,207,211],{},[159,203,204],{},[162,205,206],{},"https:\u002F\u002Fexample.com:8080",[159,208,209],{},[162,210,206],{},[159,212,213],{},"Different port = different origin",[141,215,216,221,225],{},[159,217,218],{},[162,219,220],{},"https:\u002F\u002Fexample.com\u002Fpath",[159,222,223],{},[162,224,164],{},[159,226,227],{},"Path doesn't matter, only protocol + host",[44,229,230],{},"The key insight: small changes matter. Different subdomain? Different origin. Different protocol? Different origin. Different port? Different origin.",[44,232,233],{},"This matters because postMessage security is built entirely on origin validation. The receiver is supposed to check: \"Is this message coming from someone I trust?\"",[44,235,236],{},"If that check is weak, missing, or bypassable, you've found your entry point.",[63,238,240],{"id":239},"the-sender",[67,241,242],{},"The Sender",[44,244,245],{},"The sender is whoever initiates the postMessage. It's the starting point of the communication.",[44,247,248],{},"Here's what a basic sender looks like:",[250,251,256],"pre",{"code":252,"language":253,"meta":254,"className":255,"style":254},"window.postMessage({\n  type: \"userAction\",\n  data: userInput\n}, \"https:\u002F\u002Ftarget.com\");\n","javascript","","shiki shiki-themes vitesse-dark vitesse-light",[162,257,258,278,302,313],{},[259,260,263,267,271,275],"span",{"class":261,"line":262},"line",1,[259,264,266],{"class":265},"snInM","window",[259,268,270],{"class":269},"somML",".",[259,272,274],{"class":273},"swzfi","postMessage",[259,276,277],{"class":269},"({\n",[259,279,281,285,288,292,296,299],{"class":261,"line":280},2,[259,282,284],{"class":283},"s6_DI","  type",[259,286,287],{"class":269},":",[259,289,291],{"class":290},"sy_C3"," \"",[259,293,295],{"class":294},"sRRDT","userAction",[259,297,298],{"class":290},"\"",[259,300,301],{"class":269},",\n",[259,303,305,308,310],{"class":261,"line":304},3,[259,306,307],{"class":283},"  data",[259,309,287],{"class":269},[259,311,312],{"class":265}," userInput\n",[259,314,316,319,321,324,326],{"class":261,"line":315},4,[259,317,318],{"class":269},"},",[259,320,291],{"class":290},[259,322,323],{"class":294},"https:\u002F\u002Ftarget.com",[259,325,298],{"class":290},[259,327,328],{"class":269},");\n",[44,330,331,332,334],{},"Two arguments here. First argument is the data. Can be a string, an object, whatever you want to send. Second argument is the target origin. In this case, only ",[162,333,323],{}," should receive this message.",[44,336,337],{},"That second argument provides some security. You're explicitly saying \"only send this to target.com, nobody else.\"",[44,339,340],{},"But developers get lazy. They do this:",[250,342,344],{"code":343,"language":253,"meta":254,"className":255,"style":254},"window.postMessage({\n  type: \"userAction\",\n  data: sensitiveData\n}, \"*\");\n",[162,345,346,356,370,379],{},[259,347,348,350,352,354],{"class":261,"line":262},[259,349,266],{"class":265},[259,351,270],{"class":269},[259,353,274],{"class":273},[259,355,277],{"class":269},[259,357,358,360,362,364,366,368],{"class":261,"line":280},[259,359,284],{"class":283},[259,361,287],{"class":269},[259,363,291],{"class":290},[259,365,295],{"class":294},[259,367,298],{"class":290},[259,369,301],{"class":269},[259,371,372,374,376],{"class":261,"line":304},[259,373,307],{"class":283},[259,375,287],{"class":269},[259,377,378],{"class":265}," sensitiveData\n",[259,380,381,383,385,388,390],{"class":261,"line":315},[259,382,318],{"class":269},[259,384,291],{"class":290},[259,386,387],{"class":294},"*",[259,389,298],{"class":290},[259,391,328],{"class":269},[44,393,394],{},"That asterisk is a wildcard. It means \"send this to everyone.\" If that data contains anything sensitive, you just broadcast it to any malicious site that's listening.",[44,396,397],{},"Now, wildcard senders can expose data, but they're usually not the main vulnerability. The real problems show up in the receiver.",[63,399,401],{"id":400},"the-receiver",[67,402,403],{},"The Receiver",[44,405,406],{},"The receiver is the listener. It's sitting there waiting for messages to arrive.",[44,408,409],{},"Simple receiver:",[250,411,413],{"code":412,"language":253,"meta":254,"className":255,"style":254},"window.addEventListener('message', function(event) {\n  console.log('Received:', event.data);\n});\n",[162,414,415,453,484],{},[259,416,417,419,421,424,427,430,433,435,438,442,444,447,450],{"class":261,"line":262},[259,418,266],{"class":265},[259,420,270],{"class":269},[259,422,423],{"class":273},"addEventListener",[259,425,426],{"class":269},"(",[259,428,429],{"class":290},"'",[259,431,432],{"class":294},"message",[259,434,429],{"class":290},[259,436,437],{"class":269},",",[259,439,441],{"class":440},"sfIIG"," function",[259,443,426],{"class":269},[259,445,446],{"class":265},"event",[259,448,449],{"class":269},")",[259,451,452],{"class":269}," {\n",[259,454,455,458,460,463,465,467,470,472,474,477,479,482],{"class":261,"line":280},[259,456,457],{"class":265},"  console",[259,459,270],{"class":269},[259,461,462],{"class":273},"log",[259,464,426],{"class":269},[259,466,429],{"class":290},[259,468,469],{"class":294},"Received:",[259,471,429],{"class":290},[259,473,437],{"class":269},[259,475,476],{"class":265}," event",[259,478,270],{"class":269},[259,480,481],{"class":265},"data",[259,483,328],{"class":269},[259,485,486],{"class":261,"line":304},[259,487,488],{"class":269},"});\n",[44,490,491],{},"This listens for any postMessage. When one arrives, it logs the data. Harmless, right?",[44,493,494],{},"Wrong. This listener accepts messages from anywhere. No validation. No checking. Any website can send a message to this page and it'll be processed.",[44,496,497],{},[67,498,499],{},"The Event Object",[44,501,502],{},"When a message arrives, the listener gets an event object with three properties:",[135,504,505,518],{},[138,506,507],{},[141,508,509,512,515],{},[144,510,511],{},"Property",[144,513,514],{},"Contains",[144,516,517],{},"Purpose",[154,519,520,533,546],{},[141,521,522,527,530],{},[159,523,524],{},[162,525,526],{},"event.data",[159,528,529],{},"The actual message content",[159,531,532],{},"What was sent",[141,534,535,540,543],{},[159,536,537],{},[162,538,539],{},"event.origin",[159,541,542],{},"Sender's origin",[159,544,545],{},"Where it came from",[141,547,548,553,556],{},[159,549,550],{},[162,551,552],{},"event.source",[159,554,555],{},"Window reference",[159,557,558],{},"Who sent it",[44,560,561,562,564,565,567],{},"The receiver should always check ",[162,563,539],{}," before doing anything with ",[162,566,526],{},". That's the security control.",[44,569,570],{},"Here's what vulnerable code looks like:",[250,572,574],{"code":573,"language":253,"meta":254,"className":255,"style":254},"window.addEventListener('message', function(event) {\n  var data = event.data;\n  document.getElementById('output').innerHTML = data;\n});\n",[162,575,576,604,624,655],{},[259,577,578,580,582,584,586,588,590,592,594,596,598,600,602],{"class":261,"line":262},[259,579,266],{"class":265},[259,581,270],{"class":269},[259,583,423],{"class":273},[259,585,426],{"class":269},[259,587,429],{"class":290},[259,589,432],{"class":294},[259,591,429],{"class":290},[259,593,437],{"class":269},[259,595,441],{"class":440},[259,597,426],{"class":269},[259,599,446],{"class":265},[259,601,449],{"class":269},[259,603,452],{"class":269},[259,605,606,609,612,615,617,619,621],{"class":261,"line":280},[259,607,608],{"class":440},"  var",[259,610,611],{"class":265}," data",[259,613,614],{"class":269}," =",[259,616,476],{"class":265},[259,618,270],{"class":269},[259,620,481],{"class":265},[259,622,623],{"class":269},";\n",[259,625,626,629,631,634,636,638,641,643,646,649,651,653],{"class":261,"line":304},[259,627,628],{"class":265},"  document",[259,630,270],{"class":269},[259,632,633],{"class":273},"getElementById",[259,635,426],{"class":269},[259,637,429],{"class":290},[259,639,640],{"class":294},"output",[259,642,429],{"class":290},[259,644,645],{"class":269},").",[259,647,648],{"class":265},"innerHTML",[259,650,614],{"class":269},[259,652,611],{"class":265},[259,654,623],{"class":269},[259,656,657],{"class":261,"line":315},[259,658,488],{"class":269},[44,660,661],{},"No origin check. Any website sends a message, this code processes it. That's your exploitation entry point.",[44,663,664],{},"And here's what secure code should look like:",[250,666,668],{"code":667,"language":253,"meta":254,"className":255,"style":254},"window.addEventListener('message', function(event) {\n  if (event.origin === \"https:\u002F\u002Ftrusted.com\") {\n    document.getElementById('output').innerHTML = event.data;\n  }\n});\n",[162,669,670,698,728,759,764],{},[259,671,672,674,676,678,680,682,684,686,688,690,692,694,696],{"class":261,"line":262},[259,673,266],{"class":265},[259,675,270],{"class":269},[259,677,423],{"class":273},[259,679,426],{"class":269},[259,681,429],{"class":290},[259,683,432],{"class":294},[259,685,429],{"class":290},[259,687,437],{"class":269},[259,689,441],{"class":440},[259,691,426],{"class":269},[259,693,446],{"class":265},[259,695,449],{"class":269},[259,697,452],{"class":269},[259,699,700,704,707,709,711,714,717,719,722,724,726],{"class":261,"line":280},[259,701,703],{"class":702},"sR8n-","  if",[259,705,706],{"class":269}," (",[259,708,446],{"class":265},[259,710,270],{"class":269},[259,712,713],{"class":265},"origin",[259,715,716],{"class":440}," ===",[259,718,291],{"class":290},[259,720,721],{"class":294},"https:\u002F\u002Ftrusted.com",[259,723,298],{"class":290},[259,725,449],{"class":269},[259,727,452],{"class":269},[259,729,730,733,735,737,739,741,743,745,747,749,751,753,755,757],{"class":261,"line":304},[259,731,732],{"class":265},"    document",[259,734,270],{"class":269},[259,736,633],{"class":273},[259,738,426],{"class":269},[259,740,429],{"class":290},[259,742,640],{"class":294},[259,744,429],{"class":290},[259,746,645],{"class":269},[259,748,648],{"class":265},[259,750,614],{"class":269},[259,752,476],{"class":265},[259,754,270],{"class":269},[259,756,481],{"class":265},[259,758,623],{"class":269},[259,760,761],{"class":261,"line":315},[259,762,763],{"class":269},"  }\n",[259,765,767],{"class":261,"line":766},5,[259,768,488],{"class":269},[44,770,771,772,774],{},"This checks the origin first. Only messages from ",[162,773,721],{}," get processed. Everything else gets silently ignored.",[44,776,777],{},"That's how it should work. But developers mess this up constantly.",[63,779,781],{"id":780},"the-sink",[67,782,783],{},"The Sink",[44,785,786],{},"The sink is where the received data actually goes. This determines what you can do with the vulnerability.",[44,788,789],{},[67,790,791],{},"Common Sinks:",[135,793,794,806],{},[138,795,796],{},[141,797,798,800,803],{},[144,799,109],{},[144,801,802],{},"Code Example",[144,804,805],{},"Impact",[154,807,808,822,837,852],{},[141,809,810,814,819],{},[159,811,812],{},[162,813,648],{},[159,815,816],{},[162,817,818],{},"element.innerHTML = event.data",[159,820,821],{},"XSS",[141,823,824,829,834],{},[159,825,826],{},[162,827,828],{},"eval()",[159,830,831],{},[162,832,833],{},"eval(event.data)",[159,835,836],{},"JavaScript execution",[141,838,839,844,849],{},[159,840,841],{},[162,842,843],{},"location",[159,845,846],{},[162,847,848],{},"window.location = event.data",[159,850,851],{},"Open redirect \u002F XSS",[141,853,854,859,864],{},[159,855,856,858],{},[162,857,274],{}," response",[159,860,861],{},[162,862,863],{},"event.source.postMessage(userData, '*')",[159,865,866],{},"Data leak",[44,868,869],{},"Let's break down each one.",[44,871,872],{},[67,873,874],{},"innerHTML Sink:",[250,876,878],{"code":877,"language":253,"meta":254,"className":255,"style":254},"window.addEventListener('message', function(event) {\n  document.getElementById('output').innerHTML = event.data;\n});\n",[162,879,880,908,938],{},[259,881,882,884,886,888,890,892,894,896,898,900,902,904,906],{"class":261,"line":262},[259,883,266],{"class":265},[259,885,270],{"class":269},[259,887,423],{"class":273},[259,889,426],{"class":269},[259,891,429],{"class":290},[259,893,432],{"class":294},[259,895,429],{"class":290},[259,897,437],{"class":269},[259,899,441],{"class":440},[259,901,426],{"class":269},[259,903,446],{"class":265},[259,905,449],{"class":269},[259,907,452],{"class":269},[259,909,910,912,914,916,918,920,922,924,926,928,930,932,934,936],{"class":261,"line":280},[259,911,628],{"class":265},[259,913,270],{"class":269},[259,915,633],{"class":273},[259,917,426],{"class":269},[259,919,429],{"class":290},[259,921,640],{"class":294},[259,923,429],{"class":290},[259,925,645],{"class":269},[259,927,648],{"class":265},[259,929,614],{"class":269},[259,931,476],{"class":265},[259,933,270],{"class":269},[259,935,481],{"class":265},[259,937,623],{"class":269},[259,939,940],{"class":261,"line":304},[259,941,488],{"class":269},[44,943,944],{},"Message data goes straight into innerHTML. No sanitization. Send an XSS payload and it executes.",[44,946,947],{},[67,948,949],{},"eval Sink:",[250,951,953],{"code":952,"language":253,"meta":254,"className":255,"style":254},"window.addEventListener('message', function(event) {\n  eval(event.data);\n});\n",[162,954,955,983,998],{},[259,956,957,959,961,963,965,967,969,971,973,975,977,979,981],{"class":261,"line":262},[259,958,266],{"class":265},[259,960,270],{"class":269},[259,962,423],{"class":273},[259,964,426],{"class":269},[259,966,429],{"class":290},[259,968,432],{"class":294},[259,970,429],{"class":290},[259,972,437],{"class":269},[259,974,441],{"class":440},[259,976,426],{"class":269},[259,978,446],{"class":265},[259,980,449],{"class":269},[259,982,452],{"class":269},[259,984,985,988,990,992,994,996],{"class":261,"line":280},[259,986,987],{"class":273},"  eval",[259,989,426],{"class":269},[259,991,446],{"class":265},[259,993,270],{"class":269},[259,995,481],{"class":265},[259,997,328],{"class":269},[259,999,1000],{"class":261,"line":304},[259,1001,488],{"class":269},[44,1003,1004],{},"Even worse. The message goes to eval, which executes arbitrary JavaScript. You have complete code execution in the page context.",[44,1006,1007],{},[67,1008,1009],{},"location Sink:",[250,1011,1013],{"code":1012,"language":253,"meta":254,"className":255,"style":254},"window.addEventListener('message', function(event) {\n  window.location = event.data;\n});\n",[162,1014,1015,1043,1062],{},[259,1016,1017,1019,1021,1023,1025,1027,1029,1031,1033,1035,1037,1039,1041],{"class":261,"line":262},[259,1018,266],{"class":265},[259,1020,270],{"class":269},[259,1022,423],{"class":273},[259,1024,426],{"class":269},[259,1026,429],{"class":290},[259,1028,432],{"class":294},[259,1030,429],{"class":290},[259,1032,437],{"class":269},[259,1034,441],{"class":440},[259,1036,426],{"class":269},[259,1038,446],{"class":265},[259,1040,449],{"class":269},[259,1042,452],{"class":269},[259,1044,1045,1048,1050,1052,1054,1056,1058,1060],{"class":261,"line":280},[259,1046,1047],{"class":265},"  window",[259,1049,270],{"class":269},[259,1051,843],{"class":265},[259,1053,614],{"class":269},[259,1055,476],{"class":265},[259,1057,270],{"class":269},[259,1059,481],{"class":265},[259,1061,623],{"class":269},[259,1063,1064],{"class":261,"line":304},[259,1065,488],{"class":269},[44,1067,1068,1069,1072],{},"The message controls where the page navigates. Send a ",[162,1070,1071],{},"javascript:"," URL and you get XSS. Send a phishing domain and you get an open redirect.",[44,1074,1075],{},[67,1076,1077],{},"Data Response Sink:",[250,1079,1081],{"code":1080,"language":253,"meta":254,"className":255,"style":254},"window.addEventListener('message', function(event) {\n  if (event.data === \"getUserData\") {\n    event.source.postMessage(userData, event.origin);\n  }\n});\n",[162,1082,1083,1111,1136,1165,1169],{},[259,1084,1085,1087,1089,1091,1093,1095,1097,1099,1101,1103,1105,1107,1109],{"class":261,"line":262},[259,1086,266],{"class":265},[259,1088,270],{"class":269},[259,1090,423],{"class":273},[259,1092,426],{"class":269},[259,1094,429],{"class":290},[259,1096,432],{"class":294},[259,1098,429],{"class":290},[259,1100,437],{"class":269},[259,1102,441],{"class":440},[259,1104,426],{"class":269},[259,1106,446],{"class":265},[259,1108,449],{"class":269},[259,1110,452],{"class":269},[259,1112,1113,1115,1117,1119,1121,1123,1125,1127,1130,1132,1134],{"class":261,"line":280},[259,1114,703],{"class":702},[259,1116,706],{"class":269},[259,1118,446],{"class":265},[259,1120,270],{"class":269},[259,1122,481],{"class":265},[259,1124,716],{"class":440},[259,1126,291],{"class":290},[259,1128,1129],{"class":294},"getUserData",[259,1131,298],{"class":290},[259,1133,449],{"class":269},[259,1135,452],{"class":269},[259,1137,1138,1141,1143,1146,1148,1150,1152,1155,1157,1159,1161,1163],{"class":261,"line":304},[259,1139,1140],{"class":265},"    event",[259,1142,270],{"class":269},[259,1144,1145],{"class":265},"source",[259,1147,270],{"class":269},[259,1149,274],{"class":273},[259,1151,426],{"class":269},[259,1153,1154],{"class":265},"userData",[259,1156,437],{"class":269},[259,1158,476],{"class":265},[259,1160,270],{"class":269},[259,1162,713],{"class":265},[259,1164,328],{"class":269},[259,1166,1167],{"class":261,"line":315},[259,1168,763],{"class":269},[259,1170,1171],{"class":261,"line":766},[259,1172,488],{"class":269},[44,1174,1175],{},"This responds to messages by sending back data. Without origin validation, you can request sensitive user information from your own malicious page and the application just hands it over.",[44,1177,1178],{},"The sink determines impact. innerHTML gives XSS. eval gives code execution. location gives redirects. Data handlers give information leakage.",[63,1180,1182],{"id":1181},"common-developer-mistakes",[67,1183,1184],{},"Common Developer Mistakes",[44,1186,1187],{},"Now you understand the three elements. Here's where exploitation actually starts. Developers implement weak origin checks that you can bypass.",[44,1189,1190],{},[67,1191,1192],{},"Mistake Comparison:",[135,1194,1195,1211],{},[138,1196,1197],{},[141,1198,1199,1202,1205,1208],{},[144,1200,1201],{},"Validation Method",[144,1203,1204],{},"Code",[144,1206,1207],{},"Bypass",[144,1209,1210],{},"Why It Fails",[154,1212,1213,1233,1251,1271],{},[141,1214,1215,1220,1225,1230],{},[159,1216,1217],{},[162,1218,1219],{},"startsWith()",[159,1221,1222],{},[162,1223,1224],{},"event.origin.startsWith(\"https:\u002F\u002Ftarget.com\")",[159,1226,1227],{},[162,1228,1229],{},"https:\u002F\u002Ftarget.com.evil.com",[159,1231,1232],{},"Checks only the beginning",[141,1234,1235,1238,1243,1248],{},[159,1236,1237],{},"Unescaped dot regex",[159,1239,1240],{},[162,1241,1242],{},"event.origin.match(\u002Fhttps:\\\u002F\\\u002Ftarget.com\u002F)",[159,1244,1245],{},[162,1246,1247],{},"https:\u002F\u002FtargetXcom",[159,1249,1250],{},"Dot matches any character",[141,1252,1253,1258,1263,1268],{},[159,1254,1255],{},[162,1256,1257],{},"includes()",[159,1259,1260],{},[162,1261,1262],{},"event.origin.includes(\"target.com\")",[159,1264,1265],{},[162,1266,1267],{},"https:\u002F\u002Feviltarget.com",[159,1269,1270],{},"Checks if string appears anywhere",[141,1272,1273,1278,1283,1287],{},[159,1274,1275],{},[162,1276,1277],{},"indexOf()",[159,1279,1280],{},[162,1281,1282],{},"event.origin.indexOf(\"target.com\") > -1",[159,1284,1285],{},[162,1286,1229],{},[159,1288,1289],{},"Same as includes",[44,1291,1292],{},"Let's look at each mistake in detail.",[44,1294,1295],{},[67,1296,1297],{},"startsWith Bypass:",[250,1299,1301],{"code":1300,"language":253,"meta":254,"className":255,"style":254},"if (event.origin.startsWith(\"https:\u002F\u002Ftarget.com\")) {\n  \u002F\u002F Process message\n}\n",[162,1302,1303,1334,1340],{},[259,1304,1305,1308,1310,1312,1314,1316,1318,1321,1323,1325,1327,1329,1332],{"class":261,"line":262},[259,1306,1307],{"class":702},"if",[259,1309,706],{"class":269},[259,1311,446],{"class":265},[259,1313,270],{"class":269},[259,1315,713],{"class":265},[259,1317,270],{"class":269},[259,1319,1320],{"class":273},"startsWith",[259,1322,426],{"class":269},[259,1324,298],{"class":290},[259,1326,323],{"class":294},[259,1328,298],{"class":290},[259,1330,1331],{"class":269},"))",[259,1333,452],{"class":269},[259,1335,1336],{"class":261,"line":280},[259,1337,1339],{"class":1338},"sy60D","  \u002F\u002F Process message\n",[259,1341,1342],{"class":261,"line":304},[259,1343,1344],{"class":269},"}\n",[44,1346,1347],{},"Developer logic: \"If the origin starts with target.com, it must be trusted.\"",[44,1349,1350,1351,1353,1354,1356],{},"Reality: Register ",[162,1352,1229],{},". That origin starts with ",[162,1355,323],{},". Check passes. You're in.",[44,1358,1359],{},[67,1360,1361],{},"Regex Bypass:",[250,1363,1365],{"code":1364,"language":253,"meta":254,"className":255,"style":254},"if (event.origin.match(\u002Fhttps:\\\u002F\\\u002Ftarget.com\u002F)) {\n  \u002F\u002F Process message\n}\n",[162,1366,1367,1412,1416],{},[259,1368,1369,1371,1373,1375,1377,1379,1381,1384,1386,1389,1393,1397,1400,1403,1406,1408,1410],{"class":261,"line":262},[259,1370,1307],{"class":702},[259,1372,706],{"class":269},[259,1374,446],{"class":265},[259,1376,270],{"class":269},[259,1378,713],{"class":265},[259,1380,270],{"class":269},[259,1382,1383],{"class":273},"match",[259,1385,426],{"class":269},[259,1387,1388],{"class":290},"\u002F",[259,1390,1392],{"class":1391},"sH-WV","https:",[259,1394,1396],{"class":1395},"sbDyW","\\\u002F\\\u002F",[259,1398,1399],{"class":1391},"target",[259,1401,270],{"class":1402},"svjqz",[259,1404,1405],{"class":1391},"com",[259,1407,1388],{"class":290},[259,1409,1331],{"class":269},[259,1411,452],{"class":269},[259,1413,1414],{"class":261,"line":280},[259,1415,1339],{"class":1338},[259,1417,1418],{"class":261,"line":304},[259,1419,1344],{"class":269},[44,1421,1422],{},"The developer forgot to escape the dot. In regex, an unescaped dot means \"any single character.\"",[44,1424,1425,1426,1429,1430,1433,1434,1437,1438,1440],{},"So ",[162,1427,1428],{},"target.com"," matches ",[162,1431,1432],{},"targetXcom",", ",[162,1435,1436],{},"target-com",", anything where X is a single character. Register ",[162,1439,1432],{}," and you bypass the check.",[44,1442,1443],{},[67,1444,1445],{},"includes Bypass:",[250,1447,1449],{"code":1448,"language":253,"meta":254,"className":255,"style":254},"if (event.origin.includes(\"target.com\")) {\n  \u002F\u002F Process message\n}\n",[162,1450,1451,1480,1484],{},[259,1452,1453,1455,1457,1459,1461,1463,1465,1468,1470,1472,1474,1476,1478],{"class":261,"line":262},[259,1454,1307],{"class":702},[259,1456,706],{"class":269},[259,1458,446],{"class":265},[259,1460,270],{"class":269},[259,1462,713],{"class":265},[259,1464,270],{"class":269},[259,1466,1467],{"class":273},"includes",[259,1469,426],{"class":269},[259,1471,298],{"class":290},[259,1473,1428],{"class":294},[259,1475,298],{"class":290},[259,1477,1331],{"class":269},[259,1479,452],{"class":269},[259,1481,1482],{"class":261,"line":280},[259,1483,1339],{"class":1338},[259,1485,1486],{"class":261,"line":304},[259,1487,1344],{"class":269},[44,1489,1490,1491,1493,1494,1497,1498,1501],{},"This checks if ",[162,1492,1428],{}," appears anywhere in the origin. Register ",[162,1495,1496],{},"eviltarget.com"," or ",[162,1499,1500],{},"target.com.evil.com",". Both contain the substring. Both pass the check.",[44,1503,1504],{},[67,1505,1506],{},"indexOf Bypass:",[250,1508,1510],{"code":1509,"language":253,"meta":254,"className":255,"style":254},"if (event.origin.indexOf(\"target.com\") > -1) {\n  \u002F\u002F Process message\n}\n",[162,1511,1512,1553,1557],{},[259,1513,1514,1516,1518,1520,1522,1524,1526,1529,1531,1533,1535,1537,1539,1542,1545,1549,1551],{"class":261,"line":262},[259,1515,1307],{"class":702},[259,1517,706],{"class":269},[259,1519,446],{"class":265},[259,1521,270],{"class":269},[259,1523,713],{"class":265},[259,1525,270],{"class":269},[259,1527,1528],{"class":273},"indexOf",[259,1530,426],{"class":269},[259,1532,298],{"class":290},[259,1534,1428],{"class":294},[259,1536,298],{"class":290},[259,1538,449],{"class":269},[259,1540,1541],{"class":269}," >",[259,1543,1544],{"class":440}," -",[259,1546,1548],{"class":1547},"sUQhE","1",[259,1550,449],{"class":269},[259,1552,452],{"class":269},[259,1554,1555],{"class":261,"line":280},[259,1556,1339],{"class":1338},[259,1558,1559],{"class":261,"line":304},[259,1560,1344],{"class":269},[44,1562,1563],{},"Same exact problem as includes. As long as the substring appears somewhere, you're good.",[44,1565,1566],{},"These mistakes show up everywhere. And they're your consistent way in.",[63,1568,1570],{"id":1569},"hunting-for-postmessage-vulnerabilities",[67,1571,1572],{},"Hunting for postMessage Vulnerabilities",[44,1574,1575],{},"Theory is great, but finding these in real applications requires methodology.",[44,1577,1578],{},[67,1579,1580],{},"Method 1: Chrome DevTools",[44,1582,1583],{},"Chrome DevTools has built-in postMessage debugging.",[44,1585,1586],{},"Open DevTools. Go to Sources tab. On the right side, expand Event Listener Breakpoints. Check the box for \"message\" under Control.",[44,1588,1589],{},"Now interact with the page. If any postMessage fires, the debugger pauses. You can inspect the full event object: origin, data, source. Step through the code and see exactly where the data flows.",[44,1591,1592],{},"This is manual but powerful. You see everything in real-time with full context.",[44,1594,1595],{},[67,1596,1597],{},"Method 2: FancyTracker Extension",[44,1599,1600],{},"FancyTracker is a Chrome extension that automatically detects postMessage usage.",[44,1602,1603],{},"Install it. Visit any page. It highlights postMessage senders, listeners, and the data being passed. Quick reconnaissance without manual breakpoints.",[44,1605,1606],{},"Great for initial discovery before you dive into manual analysis.",[44,1608,1609],{},[67,1610,1611],{},"Method 3: Manual Code Review",[44,1613,1614],{},"Search the JavaScript source for these patterns:",[44,1616,1617,1618],{},"Looking for receivers: ",[162,1619,1620],{},"addEventListener('message'",[44,1622,1623,1624],{},"Looking for senders: ",[162,1625,1626],{},"postMessage(",[44,1628,1629],{},"Find a listener, then analyze the code. Does it validate origin? Can you bypass it? Where does the data go?",[44,1631,1632],{},"Manual review is the most thorough method because you understand the complete context, including business logic and edge cases.",[63,1634,1636],{"id":1635},"real-world-context",[67,1637,1638],{},"Real-World Context",[44,1640,1641],{},"postMessage vulnerabilities don't exist in random places. They show up in specific application contexts where cross-origin communication is necessary.",[44,1643,1644,1647],{},[67,1645,1646],{},"Checkout Pages"," - Payment processors run in iframes. The merchant site and payment gateway communicate via postMessage to handle transaction data.",[44,1649,1650,1653],{},[67,1651,1652],{},"Authentication Flows"," - OAuth popups send tokens back to the parent window via postMessage after the user authenticates.",[44,1655,1656,1659],{},[67,1657,1658],{},"Customer Support Widgets"," - Live chat runs in an iframe or popup. It exchanges messages with the main application through postMessage.",[44,1661,1662,1665],{},[67,1663,1664],{},"Hidden iframes"," - Invisible iframes handle cross-domain storage, analytics, or third-party integrations. They all communicate through postMessage.",[44,1667,1668,1671],{},[67,1669,1670],{},"Multi-Domain Workflows"," - Any feature spanning multiple domains or subdomains likely uses postMessage for coordination.",[44,1673,1674],{},"When you're testing applications, look specifically for:",[1676,1677,1678,1682,1685,1688,1691],"ul",{},[1679,1680,1681],"li",{},"Pages with iframes (visible or hidden)",[1679,1683,1684],{},"Login and authentication flows",[1679,1686,1687],{},"Checkout and payment processes",[1679,1689,1690],{},"Support or help desk features",[1679,1692,1693],{},"Third-party widgets and integrations",[44,1695,1696],{},"These are your hunting grounds.",[63,1698,1700],{"id":1699},"why-this-matters",[67,1701,1702],{},"Why This Matters",[44,1704,1705],{},"postMessage vulnerabilities represent a real opportunity in bug bounty, but most hunters miss them entirely. Understanding why reveals their value.",[44,1707,1708],{},[67,1709,1710],{},"Automated Scanners Can't Find These",[44,1712,1713],{},"Unlike SQL injection or reflected XSS, automated tools don't detect postMessage vulnerabilities. Finding them requires manual code review, understanding JavaScript execution context, knowledge of the postMessage API, creative bypass techniques, and contextual understanding of the application.",[44,1715,1716],{},"Most hunters rely heavily on automated tools. They run scans, submit findings, move on. This approach completely misses postMessage bugs.",[44,1718,1719],{},[67,1720,1721],{},"Skill Differentiator",[44,1723,1724],{},"postMessage exploitation requires actual security knowledge. You have to read JavaScript code, understand how applications work, think like developers to spot their mistakes, and craft custom exploits for specific implementations.",[44,1726,1727],{},"This creates a barrier to entry, which benefits skilled hunters. Programs need researchers who can find vulnerabilities that automated tools miss.",[44,1729,1730],{},[67,1731,1732],{},"Serious Impact",[44,1734,1735],{},"The impact is significant: XSS with full client-side code execution, data leaks exposing sensitive user information, account takeovers through stolen tokens, and open redirects for phishing attacks.",[44,1737,1738],{},"These qualify as Critical or High severity findings with substantial bounty payouts.",[44,1740,1741],{},[67,1742,1743],{},"Consistent Presence",[44,1745,1746],{},"postMessage is everywhere in modern web applications. As long as developers need cross-origin communication, these vulnerabilities will exist. The API itself isn't broken. The security issues come from incorrect implementation, which is ubiquitous.",[44,1748,1749],{},"If you want to stand out in bug bounty hunting, focus on vulnerability classes requiring manual analysis and deep understanding. Client-side vulnerabilities, especially postMessage exploitation, represent exactly this opportunity.",[63,1751,1753],{"id":1752},"conclusion",[67,1754,1755],{},"Conclusion",[44,1757,1758],{},"postMessage vulnerabilities offer a powerful attack vector that most bug bounty hunters completely overlook. Understanding the postMessage triangle (sender, receiver, and sink) lets you systematically identify and exploit these vulnerabilities across different applications.",[44,1760,1761],{},"The critical concepts: origin validation determines security, and understanding that origin equals protocol plus host lets you identify weak validation logic. Common mistakes like startsWith, includes, weak regex, and unescaped dots provide consistent exploitation paths.",[44,1763,1764],{},"Your methodology matters. Combine Chrome DevTools message breakpoints, FancyTracker for quick reconnaissance, and manual code review for complete analysis. Each method provides different perspectives.",[44,1766,1767],{},"Context is everything. postMessage appears in checkout pages, authentication flows, support widgets, and hidden iframes. Focus your testing on these high-probability locations.",[44,1769,1770],{},"Manual skills win. Automated scanners can't find these vulnerabilities. Developing the skills to identify and exploit postMessage bugs differentiates you from the majority of hunters relying solely on automated tools.",[44,1772,1773],{},"This guide covers the fundamentals, but significant depth remains. Advanced bypass techniques, chaining with other vulnerabilities, and framework-specific implementations all offer additional learning opportunities.",[44,1775,1776],{},"postMessage vulnerabilities are everywhere. Now you know how to find them.",[1778,1779,1780],"style",{},"html pre.shiki code .snInM, html code.shiki .snInM{--shiki-default:#BD976A;--shiki-light:#B07D48}html pre.shiki code .somML, html code.shiki .somML{--shiki-default:#666666;--shiki-light:#999999}html pre.shiki code .swzfi, html code.shiki .swzfi{--shiki-default:#80A665;--shiki-light:#59873A}html pre.shiki code .s6_DI, html code.shiki .s6_DI{--shiki-default:#B8A965;--shiki-light:#998418}html pre.shiki code .sy_C3, html code.shiki .sy_C3{--shiki-default:#C98A7D77;--shiki-light:#B5695977}html pre.shiki code .sRRDT, html code.shiki .sRRDT{--shiki-default:#C98A7D;--shiki-light:#B56959}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html pre.shiki code .sfIIG, html code.shiki .sfIIG{--shiki-default:#CB7676;--shiki-light:#AB5959}html pre.shiki code .sR8n-, html code.shiki .sR8n-{--shiki-default:#4D9375;--shiki-light:#1E754F}html pre.shiki code .sy60D, html code.shiki .sy60D{--shiki-default:#758575DD;--shiki-light:#A0ADA0}html pre.shiki code .sH-WV, html code.shiki .sH-WV{--shiki-default:#C4704F;--shiki-light:#AB5E3F}html pre.shiki code .sbDyW, html code.shiki .sbDyW{--shiki-default:#E6CC77;--shiki-light:#BDA437}html pre.shiki code .svjqz, html code.shiki .svjqz{--shiki-default:#6872AB;--shiki-light:#5A6AA6}html pre.shiki code .sUQhE, html code.shiki .sUQhE{--shiki-default:#4C9A91;--shiki-light:#2F798A}",{"title":254,"searchDepth":304,"depth":304,"links":1782},[1783,1784,1785,1786,1787,1788,1789,1790,1791,1792],{"id":65,"depth":280,"text":69},{"id":116,"depth":280,"text":119},{"id":239,"depth":280,"text":242},{"id":400,"depth":280,"text":403},{"id":780,"depth":280,"text":783},{"id":1181,"depth":280,"text":1184},{"id":1569,"depth":280,"text":1572},{"id":1635,"depth":280,"text":1638},{"id":1699,"depth":280,"text":1702},{"id":1752,"depth":280,"text":1755},[1794,1795],"Bug Bounty","Penetration Testing","\u002Fimages\u002Fblog\u002Fclient-side-01-postmessage-bugs\u002Fclient-side-01-postmessage-exploits-copy.webp","2025-12-14","postMessage bugs sit unnoticed in checkout pages, auth flows and chat widgets. Origins, senders, receivers, sinks, and the mistakes that expose them.","md",{},"\u002Fclient-side-01-postmessage-bugs",null,{"title":35,"description":1798},"client-side-01-postmessage-bugs","2026-01-04","xeJhp1bHZRaGQwO0J0D1rRnOgpDpBdYw-JNSgowYyos",{"older":1808,"newer":1813,"total":1818},{"slug":1809,"title":1810,"date":1811,"position":1812},"ssti-from-input-to-rce","SSTI From Input To RCE","2025-12-04",12,{"slug":1814,"title":1815,"date":1816,"position":1817},"ai-just-made-bug-bounty-way-easier","AI Just Made Bug Bounty Way Easier","2026-01-26",10,68,{"id":42,"title":35,"published":1820,"url":1821,"description":1822,"durationSeconds":1823,"viewCount":1824,"thumbnail":1825,"thumbnailSrcset":1826},"2026-01-04T16:00:15Z","https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=9OWy-c_ycOI","In this episode, we dive into one of the most ignored client-side vulnerability classes: postMessage bugs. These issues hide in checkout flows, authentication popups, embedded widgets, and cross-domain iframes, and when exploited correctly, they lead to XSS, sensitive data exposure, and account takeovers.",1190,5483,"\u002Fimages\u002Fvideos\u002F9OWy-c_ycOI-800.webp","\u002Fimages\u002Fvideos\u002F9OWy-c_ycOI-800.webp 800w, \u002Fimages\u002Fvideos\u002F9OWy-c_ycOI-1280.webp 1280w",{"left":12,"top":12,"width":13,"height":13,"rotate":12,"vFlip":14,"hFlip":14,"body":1828},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M7 9.667A2.667 2.667 0 0 1 9.667 7h8.666A2.667 2.667 0 0 1 21 9.667v8.666A2.667 2.667 0 0 1 18.333 21H9.667A2.667 2.667 0 0 1 7 18.333z\"\u002F>\u003Cpath d=\"M4.012 16.737A2 2 0 0 1 3 15V5c0-1.1.9-2 2-2h10c.75 0 1.158.385 1.5 1\"\u002F>\u003C\u002Fg>",1791942281073]