[{"data":1,"prerenderedAt":1522},["ShallowReactive",2],{"blog-file-attack-ics":3,"blog-all-for-related":1025},{"id":4,"title":5,"author":6,"body":7,"cardAlt":1006,"categories":1007,"description":1010,"draft":1011,"extension":1012,"headerImage":1013,"keywords":1014,"meta":1015,"name":1016,"navigation":1017,"path":1018,"seo":1019,"series":1020,"stem":1022,"updated":6,"year":1023,"__hash__":1024},"blog\u002Fblog\u002Ffile-attack-ics.md","File Attack Deep Dives: ICS Calendar Invites",null,{"type":8,"value":9,"toc":998},"minimark",[10,22,31,155,158,192,197,233,265,284,288,291,316,324,328,331,385,388,572,575,737,741,744,785,789,792,917,921,935,938,959,962,994],[11,12,13],"key-takeaway",{"dataCallout":11},[14,15,16,17,21],"p",{},"A calendar invite is a phishing page that renders inside your own calendar. It\narrives as a schedule event, not a message, so it skips the \"is this email\nlegit\" reflex — and the danger is never the ",[18,19,20],"code",{},".ics"," file itself, it is the URL\nhidden in the description that your calendar turns into a clickable \"join\".",[14,23,24,25,30],{},"Part 3, ",[26,27,29],"a",{"href":28},"\u002Fblog\u002Ffile-attack-document-macros","Document macros",", showed code hiding\ninside an Office package and firing on an entry-point name. This part covers the\ncalendar family, which goes one step further: the lure renders on a surface the user\nalready trusts, their own calendar app, and the click is dressed as an\ninvitation rather than an attachment. Same goal as every part before it, a\nclick that becomes a credential or a consent grant. Different wrapper, and the\nwrapper is the whole trick.",[32,33,38,151],"figure",{"className":34,"role":36,"ariaLabel":37},[35],"article-figure","img","ICS calendar chain: a calendar invite is delivered, renders as a native calendar alert, shows a join link, and the click lands on a fake login or an OAuth consent grant.",[39,40,44,61],"svg",{"viewBox":41,"xmlns":42,"style":43},"0 0 640 452","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","display:block;width:100%;max-width:640px;height:auto;margin:0 auto",[45,46,47],"defs",{},[48,49,56],"marker",{"id":50,"viewBox":51,"refX":52,"refY":53,"markerWidth":54,"markerHeight":54,"orient":55},"ics-arrow","0 0 10 10","10","5","7","auto",[57,58],"path",{"d":59,"style":60},"M0,0 L10,5 L0,10 z","fill:var(--muted)",[62,63,65,74,81,86,94,98,102,106,110,113,117,121,125,128,132,136,140,143,147],"g",{"style":64},"font-family:var(--mono);fill:var(--ink)",[66,67],"rect",{"x":68,"y":69,"width":70,"height":71,"rx":72,"style":73},"36","18","568","62","8","fill:var(--paper);stroke:var(--line)",[75,76,80],"text",{"x":77,"y":78,"style":79},"60","45","font-size:14px","Invoice_review_0316.ics",[75,82,85],{"x":77,"y":83,"style":84},"64","font-size:11.5px;fill:var(--muted)","plain text, no attachment to scan",[87,88],"line",{"x1":89,"y1":90,"x2":89,"y2":91,"style":92,"markerEnd":93},"320","82","102","stroke:var(--muted)","url(#ics-arrow)",[66,95],{"x":68,"y":96,"width":70,"height":71,"rx":72,"style":97},"106","fill:var(--paper);stroke:var(--accent)",[75,99,101],{"x":77,"y":100,"style":79},"133","Native calendar alert",[75,103,105],{"x":77,"y":104,"style":84},"152","renders even if the email is never opened",[87,107],{"x1":89,"y1":108,"x2":89,"y2":109,"style":92,"markerEnd":93},"170","190",[66,111],{"x":68,"y":112,"width":70,"height":71,"rx":72,"style":97},"194",[75,114,116],{"x":77,"y":115,"style":79},"221","\"Join meeting\" link",[75,118,120],{"x":77,"y":119,"style":84},"240","a URL inside X-ALT-DESC, rendered as clickable text",[87,122],{"x1":89,"y1":123,"x2":89,"y2":124,"style":92,"markerEnd":93},"258","278",[66,126],{"x":68,"y":127,"width":70,"height":71,"rx":72,"style":97},"282",[75,129,131],{"x":77,"y":130,"style":79},"309","Credential prompt or OAuth consent",[75,133,135],{"x":77,"y":134,"style":84},"328","a fake login, an AiTM proxy, or a consent grant",[87,137],{"x1":89,"y1":138,"x2":89,"y2":139,"style":92,"markerEnd":93},"346","366",[66,141],{"x":68,"y":142,"width":70,"height":71,"rx":72,"style":97},"370",[75,144,146],{"x":77,"y":145,"style":79},"397","Account or mailbox taken over",[75,148,150],{"x":77,"y":149,"style":84},"416","session token, consent grant, or recurring persistence",[152,153,154],"figcaption",{},"The invite is the delivery: the calendar renders the link the attacker planted, and the user does the clicking.",[14,156,157],{},"Here is what the victim actually sees, a normal-looking Google Calendar event\nwhose only anomaly is the link in the \"Join meeting\" line and the description:",[32,159,162,184,189],{"className":160},[161],"browser-frame",[163,164,167,179],"div",{"className":165},[166],"chrome",[168,169,172,175,177],"span",{"className":170},[171],"dots",[173,174],"i",{},[173,176],{},[173,178],{},[168,180,183],{"className":181},[182],"url","calendar.google.com · Invoice review",[36,185],{"src":186,"alt":187,"loading":188},"\u002Fimages\u002Fblog\u002Ffile-attack-ics\u002Fexamples\u002Fgcal-invite.webp","A Google Calendar event titled Invoice review from billing@acme-partner[.]example, with a Join meeting link and a description both pointing to acme-verify[.]example\u002Fjoin.","lazy",[152,190,191],{},"It reads like a meeting, so the brain skips the URL. The link is the whole attack.",[193,194,196],"h2",{"id":195},"how-a-calendar-invite-becomes-a-phishing-page","How a calendar invite becomes a phishing page",[14,198,199,200,202,203,206,207,210,211,214,215,214,218,221,222,225,226,232],{},"An ",[18,201,20],{}," file is a ",[18,204,205],{},"VCALENDAR"," wrapper holding one or more ",[18,208,209],{},"VEVENT"," blocks in\nplain text. The fields that matter are ",[18,212,213],{},"ORGANIZER",", ",[18,216,217],{},"DESCRIPTION",[18,219,220],{},"URL",", and\n",[18,223,224],{},"X-ALT-DESC"," (an HTML alternative body many clients render). Everything is\ntext, nothing is executable, which is exactly why gateways treat it as benign\n(",[26,227,231],{"href":228,"rel":229},"https:\u002F\u002Fdatatracker.ietf.org\u002Fdoc\u002Fhtml\u002Frfc5545",[230],"nofollow","RFC 5545","). Walk the chain:",[234,235,236,244,250,262],"ol",{},[237,238,239,240,243],"li",{},"The invite arrives as an attachment or a ",[18,241,242],{},"text\u002Fcalendar"," MIME part. The\nlures are the same as every other part of this series — invoices, payroll,\nshared documents — but the calendar flavor adds urgency: a meeting already\n\"on your calendar\".",[237,245,246,247,249],{},"The calendar client parses the ",[18,248,209],{}," and renders it as a native alert.\nCrucially, the alert fires even if the victim never opens the email, because\nthe event is already provisionally added to the calendar.",[237,251,252,253,255,256,258,259,261],{},"The attacker's URL sits in ",[18,254,217],{}," or ",[18,257,224],{},", rendered as a\n\"Join meeting\" or \"Review document\" link. The ",[18,260,20],{}," carries it as plain\ntext, so there is no attachment sandbox and no Mark of the Web.",[237,263,264],{},"The click lands on a credential harvester, an adversary-in-the-middle proxy\nthat relays the session and steals the token, or an OAuth consent screen\nthat grants the attacker read\u002Fwrite to the mailbox and calendar.",[14,266,267,268,271,272,277,278,283],{},"The surge is measurable. Over the past year calendar-based phishing became the\nthird most common email social-engineering vector, and campaigns now combine\nconsent phishing (",[18,269,270],{},"CalPhishing",") with post-delivery persistence\n(",[26,273,276],{"href":274,"rel":275},"https:\u002F\u002Fcybersecuritynews.com\u002Fcalendar-files-weaponized-as-attack-vector\u002F",[230],"calendar files weaponized",",\n",[26,279,282],{"href":280,"rel":281},"https:\u002F\u002Fwww.fortra.com\u002Fblog\u002Fnew-calendar-invite-phishing-campaign-ics-abuse-and-post-delivery-persistence",[230],"Fortra on ConsentFix + CalPhishing",").",[193,285,287],{"id":286},"why-gateways-miss-it","Why gateways miss it",[14,289,290],{},"The bypass rests on three mismatches.",[292,293,294,304,310],"ul",{},[237,295,296,300,301,303],{},[297,298,299],"strong",{},"Plain text, no payload."," Security scanners are built to look for\nexecutables, macros, and scripts. An ",[18,302,20],{}," is a scheduling format, so it\npasses the attachment filter the way a calendar invite should.",[237,305,306,309],{},[297,307,308],{},"A trusted surface."," The event renders inside the calendar app, a UI the\nuser has no reason to distrust, rather than inside the email client they have\nlearned to read carefully. The \"meeting\" appears without the usual envelope\ncues.",[237,311,312,315],{},[297,313,314],{},"No attachment warning."," Unlike Office documents in Protected View or\nexecutables behind SmartScreen, a calendar event has no Mark of the Web and\nno open-in-sandbox step. The link is a link, and links are everywhere.",[14,317,318,319,283],{},"A QR code often carries the same URL instead of a clickable link, so the victim\npulls out a phone and visits the page outside every corporate control\n(",[26,320,323],{"href":321,"rel":322},"https:\u002F\u002Fwww.proarch.com\u002Fblog\u002Fthreats-vulnerabilities\u002Fcalendar-invite-phishing-ics-qr-aitm-attack",[230],"ICS and QR AiTM",[193,325,327],{"id":326},"detection-tells","Detection tells",[14,329,330],{},"Work these in order of signal quality.",[292,332,333,345,359,365,376],{},[237,334,335,344],{},[297,336,337,339,340,343],{},[18,338,213],{}," versus ",[18,341,342],{},"From","."," The invite's organizer address and the email\nenvelope sender rarely match in a forged invite. Compare the two; a mismatch\nis the first tell.",[237,346,347,350,351,214,353,355,356,358],{},[297,348,349],{},"The URL fields."," Read ",[18,352,217],{},[18,354,224],{},", and ",[18,357,220],{}," for hidden\nor encoded links before accepting. A \"meeting\" whose only content is an\nexternal link is not a meeting.",[237,360,361,364],{},[297,362,363],{},"Unsolicited + urgency."," An invite you did not ask for, with a deadline,\na \"join now\", or a recurring series, is the same social shape as every other\nphish — it just wears a calendar costume.",[237,366,367,370,371,283],{},[297,368,369],{},"Consent grant auditing."," CalPhishing ends in an OAuth grant. Audit\nEnterprise Applications and tenant consent for apps requesting Mail.Read or\nCalendars.Read, and revoke anything unexplained\n(",[26,372,375],{"href":373,"rel":374},"https:\u002F\u002Fblog.barracuda.com\u002F2026\u002F08\u002F06\u002Fcalendar-invite-phishing-ics-files",[230],"calendar invite phishing",[237,377,378,381,382,384],{},[297,379,380],{},"Gateway .ics scanning."," Block or quarantine calendar attachments from\nuntrusted senders, and strip or re-write ",[18,383,224],{}," URLs at the mail\ngateway.",[14,386,387],{},"Step through the chain and watch a calendar alert become a takeover:",[389,390,395],"pre",{"className":391,"code":392,"language":393,"meta":394,"style":394},"language-walkthrough shiki shiki-themes github-light github-dark","{\n  \"title\": \"An ICS invite chain, end to end\",\n  \"carrier\": \"Invoice_review_0316.ics\",\n  \"stages\": [\n    {\n      \"title\": \"Delivered\",\n      \"sees\": \"a meeting invitation from a known-looking name\",\n      \"actually\": \"a plain-text VCALENDAR whose description holds a phishing URL\",\n      \"artifact\": { \"kind\": \"code\", \"lang\": \"text\", \"content\": \"BEGIN:VCALENDAR\\nBEGIN:VEVENT\\nSUMMARY:Invoice review\\nORGANIZER:MAILTO:billing@acme-partner[.]example\\nDESCRIPTION:Review before the call:\\n  https:\u002F\u002Facme-verify[.]example\u002Fjoin\\nEND:VEVENT\\nEND:VCALENDAR\" }\n    },\n    {\n      \"title\": \"Rendered\",\n      \"sees\": \"a native calendar alert for a meeting that is already on the calendar\",\n      \"actually\": \"the alert fires without the email ever being opened, on a surface the user trusts\",\n      \"artifact\": { \"kind\": \"code\", \"lang\": \"text\", \"content\": \"BEGIN:VEVENT\\nORGANIZER:MAILTO:notifications@acme-partner[.]example\\nDESCRIPTION:Review your invoice before the call:\\n  https:\u002F\u002Facme-verify[.]example\u002Fjoin\\nEND:VEVENT\" }\n    },\n    {\n      \"title\": \"Clicked\",\n      \"sees\": \"a familiar-looking login or consent screen\",\n      \"actually\": \"a credential harvester, an AiTM proxy, or an OAuth consent grant\",\n      \"artifact\": { \"kind\": \"code\", \"lang\": \"text\", \"content\": \"https:\u002F\u002Facme-verify[.]example\u002Fjoin\\n  └─ Sign in with Microsoft (AiTM proxy)\\n  └─ or Acme wants to: Read mail, Read calendar (consent)\" }\n    },\n    {\n      \"title\": \"Taken over\",\n      \"sees\": \"nothing obvious; the meeting just disappears\",\n      \"actually\": \"a stolen session token, a granted consent, or a recurring event that resurfaces the link\",\n      \"artifact\": { \"kind\": \"code\", \"lang\": \"text\", \"content\": \"POST \u002Ftoken (attacker relays)\\n  session cookie → mailbox access\\n  consent grant  → Mail.Read + Calendars.Read\" }\n    }\n  ]\n}\n","walkthrough","",[18,396,397,403,409,415,421,427,433,439,445,451,457,462,468,474,480,486,491,496,502,508,514,520,525,530,536,542,548,554,560,566],{"__ignoreMap":394},[168,398,400],{"class":87,"line":399},1,[168,401,402],{},"{\n",[168,404,406],{"class":87,"line":405},2,[168,407,408],{},"  \"title\": \"An ICS invite chain, end to end\",\n",[168,410,412],{"class":87,"line":411},3,[168,413,414],{},"  \"carrier\": \"Invoice_review_0316.ics\",\n",[168,416,418],{"class":87,"line":417},4,[168,419,420],{},"  \"stages\": [\n",[168,422,424],{"class":87,"line":423},5,[168,425,426],{},"    {\n",[168,428,430],{"class":87,"line":429},6,[168,431,432],{},"      \"title\": \"Delivered\",\n",[168,434,436],{"class":87,"line":435},7,[168,437,438],{},"      \"sees\": \"a meeting invitation from a known-looking name\",\n",[168,440,442],{"class":87,"line":441},8,[168,443,444],{},"      \"actually\": \"a plain-text VCALENDAR whose description holds a phishing URL\",\n",[168,446,448],{"class":87,"line":447},9,[168,449,450],{},"      \"artifact\": { \"kind\": \"code\", \"lang\": \"text\", \"content\": \"BEGIN:VCALENDAR\\nBEGIN:VEVENT\\nSUMMARY:Invoice review\\nORGANIZER:MAILTO:billing@acme-partner[.]example\\nDESCRIPTION:Review before the call:\\n  https:\u002F\u002Facme-verify[.]example\u002Fjoin\\nEND:VEVENT\\nEND:VCALENDAR\" }\n",[168,452,454],{"class":87,"line":453},10,[168,455,456],{},"    },\n",[168,458,460],{"class":87,"line":459},11,[168,461,426],{},[168,463,465],{"class":87,"line":464},12,[168,466,467],{},"      \"title\": \"Rendered\",\n",[168,469,471],{"class":87,"line":470},13,[168,472,473],{},"      \"sees\": \"a native calendar alert for a meeting that is already on the calendar\",\n",[168,475,477],{"class":87,"line":476},14,[168,478,479],{},"      \"actually\": \"the alert fires without the email ever being opened, on a surface the user trusts\",\n",[168,481,483],{"class":87,"line":482},15,[168,484,485],{},"      \"artifact\": { \"kind\": \"code\", \"lang\": \"text\", \"content\": \"BEGIN:VEVENT\\nORGANIZER:MAILTO:notifications@acme-partner[.]example\\nDESCRIPTION:Review your invoice before the call:\\n  https:\u002F\u002Facme-verify[.]example\u002Fjoin\\nEND:VEVENT\" }\n",[168,487,489],{"class":87,"line":488},16,[168,490,456],{},[168,492,494],{"class":87,"line":493},17,[168,495,426],{},[168,497,499],{"class":87,"line":498},18,[168,500,501],{},"      \"title\": \"Clicked\",\n",[168,503,505],{"class":87,"line":504},19,[168,506,507],{},"      \"sees\": \"a familiar-looking login or consent screen\",\n",[168,509,511],{"class":87,"line":510},20,[168,512,513],{},"      \"actually\": \"a credential harvester, an AiTM proxy, or an OAuth consent grant\",\n",[168,515,517],{"class":87,"line":516},21,[168,518,519],{},"      \"artifact\": { \"kind\": \"code\", \"lang\": \"text\", \"content\": \"https:\u002F\u002Facme-verify[.]example\u002Fjoin\\n  └─ Sign in with Microsoft (AiTM proxy)\\n  └─ or Acme wants to: Read mail, Read calendar (consent)\" }\n",[168,521,523],{"class":87,"line":522},22,[168,524,456],{},[168,526,528],{"class":87,"line":527},23,[168,529,426],{},[168,531,533],{"class":87,"line":532},24,[168,534,535],{},"      \"title\": \"Taken over\",\n",[168,537,539],{"class":87,"line":538},25,[168,540,541],{},"      \"sees\": \"nothing obvious; the meeting just disappears\",\n",[168,543,545],{"class":87,"line":544},26,[168,546,547],{},"      \"actually\": \"a stolen session token, a granted consent, or a recurring event that resurfaces the link\",\n",[168,549,551],{"class":87,"line":550},27,[168,552,553],{},"      \"artifact\": { \"kind\": \"code\", \"lang\": \"text\", \"content\": \"POST \u002Ftoken (attacker relays)\\n  session cookie → mailbox access\\n  consent grant  → Mail.Read + Calendars.Read\" }\n",[168,555,557],{"class":87,"line":556},28,[168,558,559],{},"    }\n",[168,561,563],{"class":87,"line":562},29,[168,564,565],{},"  ]\n",[168,567,569],{"class":87,"line":568},30,[168,570,571],{},"}\n",[14,573,574],{},"Pick a pattern below, see how it lands, then reveal the tell and the detection.",[389,576,580],{"className":577,"code":578,"language":579,"meta":394,"style":394},"language-files shiki shiki-themes github-light github-dark","[\n  {\n    \"name\": \"Credential phishing in the description\",\n    \"how\": \"The URL in DESCRIPTION or X-ALT-DESC points at a fake login. The victim accepts the invite and clicks, then types credentials into a page the calendar just vouched for.\",\n    \"tell\": \"A single external link in the invite body, a mismatched ORGANIZER, and a sense of urgency.\",\n    \"detect\": \"Compare ORGANIZER to the envelope sender, and strip or inspect URL fields at the gateway.\"\n  },\n  {\n    \"name\": \"MFA bypass with AiTM and QR\",\n    \"how\": \"The link lands on an adversary-in-the-middle proxy that relays the victim to the real login, captures the session cookie, and defeats MFA by riding the authenticated session. A QR code often replaces the link to move the victim off-device.\",\n    \"tell\": \"A QR code in the invite, or a login that completes but lands on a new device in the audit log.\",\n    \"detect\": \"Alert on logins from new devices or locations immediately after a calendar invite is accepted; hunt for known AiTM proxy infrastructure.\"\n  },\n  {\n    \"name\": \"OAuth consent phishing (CalPhishing)\",\n    \"how\": \"The link opens a legitimate consent screen where the attacker's app asks for Mail.Read and Calendars.Read. The victim approves, and the attacker gets standing API access without a password.\",\n    \"tell\": \"An unsolicited invite that leads to a consent prompt, especially one asking for mail or calendar scope.\",\n    \"detect\": \"Audit Enterprise Applications for consented apps requesting mail\u002Fcalendar scopes, and block or alert on unsolicited consent grants.\"\n  },\n  {\n    \"name\": \"Recurring-event persistence\",\n    \"how\": \"The attacker plants the invite as a recurring series, so the phishing link resurfaces every week on the victim's calendar and keeps the campaign alive.\",\n    \"tell\": \"A series invite with a URL in every occurrence, from an organizer the victim never met.\",\n    \"detect\": \"Delete the whole series, not one occurrence; flag recurring invites from untrusted senders at the gateway.\"\n  },\n  {\n    \"name\": \"Malware via the invite attachment\",\n    \"how\": \"The .ics carries an ATTACH payload or a URL that fetches a file, trading the calendar's trust for a download.\",\n    \"tell\": \"An ATTACH field or a file-fetching URL in an unsolicited invite.\",\n    \"detect\": \"Strip calendar ATTACH fields at the gateway and treat invite-downloaded files as internet-born.\"\n  }\n]\n","files",[18,581,582,587,592,597,602,607,612,617,621,626,631,636,641,645,649,654,659,664,669,673,677,682,687,692,697,701,705,710,715,720,725,731],{"__ignoreMap":394},[168,583,584],{"class":87,"line":399},[168,585,586],{},"[\n",[168,588,589],{"class":87,"line":405},[168,590,591],{},"  {\n",[168,593,594],{"class":87,"line":411},[168,595,596],{},"    \"name\": \"Credential phishing in the description\",\n",[168,598,599],{"class":87,"line":417},[168,600,601],{},"    \"how\": \"The URL in DESCRIPTION or X-ALT-DESC points at a fake login. The victim accepts the invite and clicks, then types credentials into a page the calendar just vouched for.\",\n",[168,603,604],{"class":87,"line":423},[168,605,606],{},"    \"tell\": \"A single external link in the invite body, a mismatched ORGANIZER, and a sense of urgency.\",\n",[168,608,609],{"class":87,"line":429},[168,610,611],{},"    \"detect\": \"Compare ORGANIZER to the envelope sender, and strip or inspect URL fields at the gateway.\"\n",[168,613,614],{"class":87,"line":435},[168,615,616],{},"  },\n",[168,618,619],{"class":87,"line":441},[168,620,591],{},[168,622,623],{"class":87,"line":447},[168,624,625],{},"    \"name\": \"MFA bypass with AiTM and QR\",\n",[168,627,628],{"class":87,"line":453},[168,629,630],{},"    \"how\": \"The link lands on an adversary-in-the-middle proxy that relays the victim to the real login, captures the session cookie, and defeats MFA by riding the authenticated session. A QR code often replaces the link to move the victim off-device.\",\n",[168,632,633],{"class":87,"line":459},[168,634,635],{},"    \"tell\": \"A QR code in the invite, or a login that completes but lands on a new device in the audit log.\",\n",[168,637,638],{"class":87,"line":464},[168,639,640],{},"    \"detect\": \"Alert on logins from new devices or locations immediately after a calendar invite is accepted; hunt for known AiTM proxy infrastructure.\"\n",[168,642,643],{"class":87,"line":470},[168,644,616],{},[168,646,647],{"class":87,"line":476},[168,648,591],{},[168,650,651],{"class":87,"line":482},[168,652,653],{},"    \"name\": \"OAuth consent phishing (CalPhishing)\",\n",[168,655,656],{"class":87,"line":488},[168,657,658],{},"    \"how\": \"The link opens a legitimate consent screen where the attacker's app asks for Mail.Read and Calendars.Read. The victim approves, and the attacker gets standing API access without a password.\",\n",[168,660,661],{"class":87,"line":493},[168,662,663],{},"    \"tell\": \"An unsolicited invite that leads to a consent prompt, especially one asking for mail or calendar scope.\",\n",[168,665,666],{"class":87,"line":498},[168,667,668],{},"    \"detect\": \"Audit Enterprise Applications for consented apps requesting mail\u002Fcalendar scopes, and block or alert on unsolicited consent grants.\"\n",[168,670,671],{"class":87,"line":504},[168,672,616],{},[168,674,675],{"class":87,"line":510},[168,676,591],{},[168,678,679],{"class":87,"line":516},[168,680,681],{},"    \"name\": \"Recurring-event persistence\",\n",[168,683,684],{"class":87,"line":522},[168,685,686],{},"    \"how\": \"The attacker plants the invite as a recurring series, so the phishing link resurfaces every week on the victim's calendar and keeps the campaign alive.\",\n",[168,688,689],{"class":87,"line":527},[168,690,691],{},"    \"tell\": \"A series invite with a URL in every occurrence, from an organizer the victim never met.\",\n",[168,693,694],{"class":87,"line":532},[168,695,696],{},"    \"detect\": \"Delete the whole series, not one occurrence; flag recurring invites from untrusted senders at the gateway.\"\n",[168,698,699],{"class":87,"line":538},[168,700,616],{},[168,702,703],{"class":87,"line":544},[168,704,591],{},[168,706,707],{"class":87,"line":550},[168,708,709],{},"    \"name\": \"Malware via the invite attachment\",\n",[168,711,712],{"class":87,"line":556},[168,713,714],{},"    \"how\": \"The .ics carries an ATTACH payload or a URL that fetches a file, trading the calendar's trust for a download.\",\n",[168,716,717],{"class":87,"line":562},[168,718,719],{},"    \"tell\": \"An ATTACH field or a file-fetching URL in an unsolicited invite.\",\n",[168,721,722],{"class":87,"line":568},[168,723,724],{},"    \"detect\": \"Strip calendar ATTACH fields at the gateway and treat invite-downloaded files as internet-born.\"\n",[168,726,728],{"class":87,"line":727},31,[168,729,730],{},"  }\n",[168,732,734],{"class":87,"line":733},32,[168,735,736],{},"]\n",[193,738,740],{"id":739},"what-to-do-about-it","What to do about it",[14,742,743],{},"Treat every unsolicited calendar invite as internet-born until its organizer\nchecks out. Verify the organizer against the sender, read the description for\nlinks before accepting, and never click a \"join\" link inside an invite you did\nnot ask for. Turn off auto-add invites where you can. At the tenant level,\naudit consent grants for mail and calendar scopes, and have the mail gateway\nstrip or rewrite calendar URL and ATTACH fields. The backstop is the same as\nevery other part of this series: the click is the weapon, and detection has to\nwatch what happens after the accept.",[745,746,747,752,758,763,769,774,777,782],"faq",{"dataFaq":394},[14,748,749],{},[297,750,751],{},"Is a calendar invite dangerous on its own?",[14,753,754,755,757],{},"No. The ",[18,756,20],{}," is inert plain text. The risk is the link the calendar renders\nfrom it, which turns the invite into a phishing page on a trusted surface.",[14,759,760],{},[297,761,762],{},"Does blocking all calendar attachments work?",[14,764,765,766,768],{},"Not always, because invites also arrive as ",[18,767,242],{}," MIME parts rather\nthan attachments. Where you can, block or quarantine invites from untrusted\nsenders; where you cannot, strip the URL and ATTACH fields before delivery.",[14,770,771],{},[297,772,773],{},"What is CalPhishing?",[14,775,776],{},"OAuth consent phishing via a calendar invite. The victim approves an app that\nasks for mail or calendar scope, and the attacker gets standing API access\nwithout a password. Audit consented apps and revoke unexplained grants.",[14,778,779],{},[297,780,781],{},"Why does MFA not stop this?",[14,783,784],{},"Because the attack rides the authenticated session. An adversary-in-the-middle\nproxy relays the victim to the real login and captures the session cookie after\nMFA succeeds. The credential is not the prize; the session token is.",[193,786,788],{"id":787},"test-yourself","Test yourself",[14,790,791],{},"A quick self-check on ICS and calendar invite phishing.",[389,793,797],{"className":794,"code":795,"language":796,"meta":394,"style":394},"language-quiz shiki shiki-themes github-light github-dark","[\n  {\n    \"q\": \"Why does a calendar invite bypass the email security reflex?\",\n    \"options\": [\"It renders as a native calendar alert on a surface the user trusts\", \"It is encrypted and unreadable\", \"It is always from an internal address\"],\n    \"answer\": 0,\n    \"explain\": \"The event is provisionally added to the calendar and renders as a trusted alert, often without the victim ever opening the email.\"\n  },\n  {\n    \"q\": \"Which .ics field most often carries the phishing link?\",\n    \"options\": [\"ORGANIZER\", \"DESCRIPTION or X-ALT-DESC\", \"UID\"],\n    \"answer\": 1,\n    \"explain\": \"The attacker plants the URL in the description or the HTML alternative body, and the calendar renders it as a clickable link.\"\n  },\n  {\n    \"q\": \"A consent screen asks for Mail.Read after you accept an invite. What is happening?\",\n    \"options\": [\"A normal calendar integration\", \"CalPhishing — an OAuth consent grant that hands over mailbox access\", \"A software update\"],\n    \"answer\": 1,\n    \"explain\": \"Consent phishing trades a click for standing API access, no password needed. Audit and revoke unexplained grants.\"\n  },\n  {\n    \"q\": \"Which detection survives every static evasion of this chain?\",\n    \"options\": [\"Blocking .ics attachments\", \"Comparing ORGANIZER to the sender and auditing post-accept logins and consent grants\", \"Deleting the calendar app\"],\n    \"answer\": 1,\n    \"explain\": \"The links and lures change, but the mismatch between organizer and sender, and the session\u002Fconsent that follows the accept, are the behavior that has to happen.\"\n  }\n]\n","quiz",[18,798,799,803,807,812,817,822,827,831,835,840,845,850,855,859,863,868,873,877,882,886,890,895,900,904,909,913],{"__ignoreMap":394},[168,800,801],{"class":87,"line":399},[168,802,586],{},[168,804,805],{"class":87,"line":405},[168,806,591],{},[168,808,809],{"class":87,"line":411},[168,810,811],{},"    \"q\": \"Why does a calendar invite bypass the email security reflex?\",\n",[168,813,814],{"class":87,"line":417},[168,815,816],{},"    \"options\": [\"It renders as a native calendar alert on a surface the user trusts\", \"It is encrypted and unreadable\", \"It is always from an internal address\"],\n",[168,818,819],{"class":87,"line":423},[168,820,821],{},"    \"answer\": 0,\n",[168,823,824],{"class":87,"line":429},[168,825,826],{},"    \"explain\": \"The event is provisionally added to the calendar and renders as a trusted alert, often without the victim ever opening the email.\"\n",[168,828,829],{"class":87,"line":435},[168,830,616],{},[168,832,833],{"class":87,"line":441},[168,834,591],{},[168,836,837],{"class":87,"line":447},[168,838,839],{},"    \"q\": \"Which .ics field most often carries the phishing link?\",\n",[168,841,842],{"class":87,"line":453},[168,843,844],{},"    \"options\": [\"ORGANIZER\", \"DESCRIPTION or X-ALT-DESC\", \"UID\"],\n",[168,846,847],{"class":87,"line":459},[168,848,849],{},"    \"answer\": 1,\n",[168,851,852],{"class":87,"line":464},[168,853,854],{},"    \"explain\": \"The attacker plants the URL in the description or the HTML alternative body, and the calendar renders it as a clickable link.\"\n",[168,856,857],{"class":87,"line":470},[168,858,616],{},[168,860,861],{"class":87,"line":476},[168,862,591],{},[168,864,865],{"class":87,"line":482},[168,866,867],{},"    \"q\": \"A consent screen asks for Mail.Read after you accept an invite. What is happening?\",\n",[168,869,870],{"class":87,"line":488},[168,871,872],{},"    \"options\": [\"A normal calendar integration\", \"CalPhishing — an OAuth consent grant that hands over mailbox access\", \"A software update\"],\n",[168,874,875],{"class":87,"line":493},[168,876,849],{},[168,878,879],{"class":87,"line":498},[168,880,881],{},"    \"explain\": \"Consent phishing trades a click for standing API access, no password needed. Audit and revoke unexplained grants.\"\n",[168,883,884],{"class":87,"line":504},[168,885,616],{},[168,887,888],{"class":87,"line":510},[168,889,591],{},[168,891,892],{"class":87,"line":516},[168,893,894],{},"    \"q\": \"Which detection survives every static evasion of this chain?\",\n",[168,896,897],{"class":87,"line":522},[168,898,899],{},"    \"options\": [\"Blocking .ics attachments\", \"Comparing ORGANIZER to the sender and auditing post-accept logins and consent grants\", \"Deleting the calendar app\"],\n",[168,901,902],{"class":87,"line":527},[168,903,849],{},[168,905,906],{"class":87,"line":532},[168,907,908],{},"    \"explain\": \"The links and lures change, but the mismatch between organizer and sender, and the session\u002Fconsent that follows the accept, are the behavior that has to happen.\"\n",[168,910,911],{"class":87,"line":538},[168,912,730],{},[168,914,915],{"class":87,"line":544},[168,916,736],{},[193,918,920],{"id":919},"what-to-remember","What to remember",[292,922,923,929,932],{},[237,924,925,926,928],{},"The ",[18,927,20],{}," is inert; the link it renders is the weapon.",[237,930,931],{},"The invite lands on a trusted surface, so the user does the clicking.",[237,933,934],{},"The signals that survive are the organizer mismatch, the URL in the\ndescription, and the login or consent grant that follows the accept.",[14,936,937],{},"Explore next:",[292,939,940,945,952],{},[237,941,942,944],{},[26,943,29],{"href":28}," — the previous deep dive,\nwhere the code hides inside the file instead of pointing out of it.",[237,946,947,951],{},[26,948,950],{"href":949},"\u002Fblog\u002Ffile-attack-html-smuggling","HTML as an attack surface"," — the file type\nthat is also a program.",[237,953,954,958],{},[26,955,957],{"href":956},"\u002Fblog\u002Ffile-attack-field-guide","File attack field guide, part 1"," — the taxonomy\nthis series builds on.",[14,960,961],{},"Useful references:",[292,963,964,970,976,982,988],{},[237,965,966],{},[26,967,969],{"href":274,"rel":968},[230],"Hackers Weaponizing Calendar Files as a New Attack Vector",[237,971,972],{},[26,973,975],{"href":373,"rel":974},[230],"Calendar invite phishing: How attackers abuse .ics files (Barracuda)",[237,977,978],{},[26,979,981],{"href":280,"rel":980},[230],"ICS abuse and post-delivery persistence (Fortra)",[237,983,984],{},[26,985,987],{"href":321,"rel":986},[230],"Calendar invite phishing, ICS + QR AiTM (ProArch)",[237,989,990],{},[26,991,993],{"href":228,"rel":992},[230],"RFC 5545: Internet Calendaring and Scheduling Core Object Specification",[995,996,997],"style",{},"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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":394,"searchDepth":405,"depth":405,"links":999},[1000,1001,1002,1003,1004,1005],{"id":195,"depth":405,"text":196},{"id":286,"depth":405,"text":287},{"id":326,"depth":405,"text":327},{"id":739,"depth":405,"text":740},{"id":787,"depth":405,"text":788},{"id":919,"depth":405,"text":920},"A calendar invite notification whose description hides a phishing link",[1008,1009],"Security","Systems","How attackers weaponize .ics calendar invites to phish credentials, bypass MFA, and steal OAuth consent — and the fields that catch them.",false,"md","blog\u002Ffile-attack-ics\u002Ffile-attack-ics-card.webp","ics phishing, calendar invite phishing, calphishing, consent phishing, adversary in the middle, mfa bypass",{},"file-attack-ics",true,"\u002Fblog\u002Ffile-attack-ics",{"title":5,"description":1010},{"name":1021,"part":417},"File Attack Deep Dives","blog\u002Ffile-attack-ics","2026-10-21","7_ZjajLj3o_AtG19V_p2W9rGxqAzIPA626o8pL9_3Nw",[1026,1034,1041,1049,1058,1065,1072,1079,1085,1091,1097,1103,1109,1115,1120,1126,1129,1136,1143,1149,1156,1162,1168,1174,1180,1186,1192,1198,1204,1211,1218,1224,1230,1236,1242,1248,1254,1260,1266,1272,1278,1284,1290,1296,1303,1309,1315,1321,1328,1334,1340,1347,1354,1360,1367,1373,1380,1386,1393,1399,1405,1411,1417,1423,1429,1435,1441,1447,1453,1459,1465,1472,1478,1485,1491,1497,1503,1510,1516],{"path":1027,"title":1028,"description":1029,"categories":1030,"draft":1017,"year":1033,"series":6},"\u002Fblog\u002Fai-assisted-workstation","Building an AI-Assisted Personal Workstation","How I built a personal AI workstation: markdown knowledge base, portable agent skills, handoff-driven sessions. What worked, what broke, what I would change.",[1031,1032],"Productivity","Programming","2026-08-26",{"path":1035,"title":1036,"description":1037,"categories":1038,"draft":1011,"year":1040,"series":6},"\u002Fblog\u002Faws-s3-golang","Uploading images to AWS S3 in Golang","In this tutorial I cover how to upload, fetch and manage other operations for objects on AWS S3 in Golang",[1039,1032],"Golang","2020-01-12",{"path":1042,"title":1043,"description":1044,"categories":1045,"draft":1011,"year":1048,"series":6},"\u002Fblog\u002Fbooks-for-engineers","Best Books for Software Engineers","Best Books to help you build you software engineering career - ranging from fundamentats, interview prep to productivity.",[1046,1047],"Books","Life","2021-12-26",{"path":1050,"title":1051,"description":1052,"categories":1053,"draft":1011,"year":1057,"series":6},"\u002Fblog\u002Fbuilding-acrons","Building Acrons 🚀","Building Acrons, a one-stop tool to decode everyday acronyms like DIY, FOMO, and BRB without losing your flow.",[1054,1055,1056],"Side Projects","Web","Tools","2020-05-26",{"path":1059,"title":1060,"description":1061,"categories":1062,"draft":1011,"year":1064,"series":6},"\u002Fblog\u002Fcap-theorem","CAP Theorem Explained","Learn the concept and misconceptions around popular CAP theorem in system design.",[1063,1032],"System Design","2021-07-26",{"path":1066,"title":1067,"description":1068,"categories":1069,"draft":1011,"year":1071,"series":6},"\u002Fblog\u002Fcode-reviews","Code Review Checklist","Why code reviews matter, and best practices that catch bugs early and keep code quality high before merge.",[1070],"Engineering Principles","2020-07-20",{"path":1073,"title":1074,"description":1075,"categories":1076,"draft":1011,"year":1078,"series":6},"\u002Fblog\u002Fdark-mode","Add Dark mode to websites","Dark mode is ❤️️ Add it to your websites with little CSS and JS",[1077,1055],"Javascript","2020-07-04",{"path":1080,"title":1081,"description":1082,"categories":1083,"draft":1011,"year":1084,"series":6},"\u002Fblog\u002Fdate-time-golang","Working with Date and Time in Go","Learn how to use time in Golang - Multiple formats, locations and using date.",[1039,1032],"2020-10-09",{"path":1086,"title":1087,"description":1088,"categories":1089,"draft":1011,"year":1090,"series":6},"\u002Fblog\u002Fdefer-in-golang","Understanding Defer In Golang","Learn about defer keyword in golang and how it can help you avoid panics due to bugs.",[1039,1032],"2021-05-05",{"path":1092,"title":1093,"description":1094,"categories":1095,"draft":1011,"year":1096,"series":6},"\u002Fblog\u002Fenums-golang","Implementing Enums in Golang","Enums are a way to defined set of constant values. Learn how to implement enums in Go using iota with examples.",[1039,1032],"2021-12-18",{"path":1098,"title":1099,"description":1100,"categories":1101,"draft":1011,"year":1102,"series":6},"\u002Fblog\u002Fenvironment-variable-golang","Guide to Environment variables in Go","Learn what are environment variables and how to use them in Go",[1039,1032],"2020-08-14",{"path":1104,"title":1105,"description":1106,"categories":1107,"draft":1011,"year":1108,"series":6},"\u002Fblog\u002Ferror-handling-golang","Handle errors the right way — Golang","How to handle errors in golang to make your life easy",[1039,1032],"2020-01-30",{"path":28,"title":1110,"description":1111,"categories":1112,"draft":1011,"year":1113,"series":1114},"File Attack Deep Dives: Office Documents as an Attack Surface","Every way an Office document attacks: macros, remote templates, embedded objects, hyperlinks, QR handoffs and invoice fraud, plus the signals that catch each.",[1008,1009],"2026-10-17",{"name":1021,"part":411},{"path":956,"title":1116,"description":1117,"categories":1118,"draft":1011,"year":1033,"series":1119},"How File-Based Attacks Land: A Detection Engineer's Field Guide","A practical taxonomy of how malware and phishing arrive as files, why classic controls miss them, and how detection should think.",[1008,1009],{"name":1021,"part":399},{"path":949,"title":1121,"description":1122,"categories":1123,"draft":1011,"year":1124,"series":1125},"File Attack Deep Dives: HTML as an Attack Surface","Every way an HTML page attacks: smuggling, external fetches, QR handoffs, phone callbacks, credential phishing, job scams, and AI prompt injection.",[1008,1009],"2026-09-12",{"name":1021,"part":405},{"path":1018,"title":5,"description":1010,"categories":1127,"draft":1011,"year":1023,"series":1128},[1008,1009],{"name":1021,"part":417},{"path":1130,"title":1131,"description":1132,"categories":1133,"draft":1017,"year":1134,"series":1135},"\u002Fblog\u002Ffile-attack-lnk-iso","File Attack Deep Dives: LNK and ISO Smuggling","How ISO, IMG, and ZIP containers and weaponized shortcuts bypass Mark of the Web, and the forensic fields that catch them.",[1008,1009],"2026-10-31",{"name":1021,"part":423},{"path":1137,"title":1138,"description":1139,"categories":1140,"draft":1017,"year":1141,"series":1142},"\u002Fblog\u002Ffile-attack-pdf-url-actions","File Attack Deep Dives: PDF URL Actions","How PDF OpenAction, Launch, URI, JavaScript, and embedded-file actions turn a document into a click — and the action audit that catches them.",[1008,1009],"2026-10-24",{"name":1021,"part":423},{"path":1144,"title":1145,"description":1146,"categories":1147,"draft":1011,"year":1148,"series":6},"\u002Fblog\u002Ffile-upload-golang","Uploading Files in Golang with Multipart Request","Learn how to upload files from your client to server as a multipart request in Golang.",[1039,1032],"2021-03-13",{"path":1150,"title":1151,"description":1152,"categories":1153,"draft":1011,"year":1155,"series":6},"\u002Fblog\u002Fgit-branch","Git Branch 101","Branching is a new path of development that makes it a lot easier to build features. Learn why and how to use branching in git.",[1154,1032],"Git","2022-03-20",{"path":1157,"title":1158,"description":1159,"categories":1160,"draft":1011,"year":1161,"series":6},"\u002Fblog\u002Fgit-pull-request-template","Pull Request Templates (GitHub, Bitbucket)","A PR template that gets used: the sections worth keeping, plus where the file lives on GitHub, GitLab and Bitbucket.",[1154,1032],"2023-08-24",{"path":1163,"title":1164,"description":1165,"categories":1166,"draft":1011,"year":1167,"series":6},"\u002Fblog\u002Fgit-remove-sensitive-info","Securing Git: Remove Sensitive Information","Protect your code from security breaches by using BFG tool to remove sensitive information from Git history. Learn how to do it in this comprehensive guide.",[1154,1032],"2023-10-16",{"path":1169,"title":1170,"description":1171,"categories":1172,"draft":1011,"year":1173,"series":6},"\u002Fblog\u002Fgit-tags-explained","Git tags : Explained","What Git tags are, why and when to use them, and how to start tagging releases in your own projects.",[1154,1032],"2020-06-18",{"path":1175,"title":1176,"description":1177,"categories":1178,"draft":1011,"year":1179,"series":6},"\u002Fblog\u002Fgo-dependency-injection","Dependency Injection in Go using Wire","Learn about dependency injection, its benefits and how to implement it in Go services using wire",[1039,1032],"2022-11-26",{"path":1181,"title":1182,"description":1183,"categories":1184,"draft":1011,"year":1185,"series":6},"\u002Fblog\u002Fgo-generics","Introduction to Generics in Go","Learn about generics in Golang, it's benefits and how to implement it in applications.",[1039,1032],"2022-11-27",{"path":1187,"title":1188,"description":1189,"categories":1190,"draft":1011,"year":1191,"series":6},"\u002Fblog\u002Fgo-in-memory-cache","In-Memory Cache in Go with TTL","Build an in-memory cache in Go: map plus RWMutex, TTL expiry, and a generics version with a typed key and value.",[1039,1032],"2024-03-28",{"path":1193,"title":1194,"description":1195,"categories":1196,"draft":1011,"year":1197,"series":6},"\u002Fblog\u002Fgo-makefile","Ultimate Makefile for Golang","Boost your productivity and save time with ultimate Makefile for Golang projects.",[1039,1032],"2024-06-10",{"path":1199,"title":1200,"description":1201,"categories":1202,"draft":1011,"year":1203,"series":6},"\u002Fblog\u002Fgo-middleware","Mastering Middlewares in Golang","Learn about middlewares, their use cases and how to implement them in Golang applications",[1039,1032],"2022-03-13",{"path":1205,"title":1206,"description":1207,"categories":1208,"draft":1011,"year":1210,"series":6},"\u002Fblog\u002Fgo-naming-conventions","Go Naming Conventions: A Practical Guide","Package, interface, function and variable naming in Go, with the rules that matter and the habits worth dropping.",[1039,1032,1209],"Code Quality","2023-05-19",{"path":1212,"title":1213,"description":1214,"categories":1215,"draft":1011,"year":1217,"series":6},"\u002Fblog\u002Fgo-with-redis","Go with Redis","A practical introduction to using Redis with Golang to make your applications faster with in-memory data storage.",[1039,1216,1032],"Database","2020-05-03",{"path":1219,"title":1220,"description":1221,"categories":1222,"draft":1011,"year":1223,"series":6},"\u002Fblog\u002Fgolang-maps","Golang Maps: Create, Iterate, Delete","How maps work in Go: declaring and initialising, adding and deleting keys, checking existence, iterating, and map equality.",[1039,1032],"2020-09-10",{"path":1225,"title":1226,"description":1227,"categories":1228,"draft":1011,"year":1229,"series":6},"\u002Fblog\u002Fguide-to-cdn","Guide to Content Delivery Network","CDN is one of the backbone of modern world internet infrastructure. Learn about Content Delivery Network, it's working, types and benefits.",[1063,1032],"2022-01-23",{"path":1231,"title":1232,"description":1233,"categories":1234,"draft":1011,"year":1235,"series":6},"\u002Fblog\u002Fguide-to-rule-engines","Rule Engines in Go: How They Work","What a rule engine is, the match-resolve-execute cycle, and a working rule engine built with Grule in Go.",[1039,1032],"2022-09-12",{"path":1237,"title":1238,"description":1239,"categories":1240,"draft":1011,"year":1241,"series":6},"\u002Fblog\u002Fhexagonal-architecture","Guide to Hexagonal Architecture","Learn how to design efficient application with hexagonal architecture with practical example",[1063,1032],"2020-12-13",{"path":1243,"title":1244,"description":1245,"categories":1246,"draft":1011,"year":1247,"series":6},"\u002Fblog\u002Fhttp-status-codes","Learn HTTP Status Codes","A tour of HTTP response status codes, what each class means, and when to use which code in your applications.",[1055,1032],"2020-07-30",{"path":1249,"title":1250,"description":1251,"categories":1252,"draft":1011,"year":1253,"series":6},"\u002Fblog\u002Fintroduction-to-goroutines","Introduction to Goroutines","Understand the basics of concurrency and learn how to work with Goroutines in golang.",[1039,1032],"2021-04-10",{"path":1255,"title":1256,"description":1257,"categories":1258,"draft":1011,"year":1259,"series":6},"\u002Fblog\u002Fjson-in-postgres-with-golang","Storing JSON in Postgres with Golang","Learn how to store JSON objects in Postgres and how to implement it in Golang.",[1032,1216,1039],"2021-02-13",{"path":1261,"title":1262,"description":1263,"categories":1264,"draft":1011,"year":1265,"series":6},"\u002Fblog\u002Fjson-web-token","Complete Guide to JWT","JSON Web Tokens are a very compact way to carry information. Learn about JWTs in depth, from its structure to when to use it.",[1032,1055],"2021-11-20",{"path":1267,"title":1268,"description":1269,"categories":1270,"draft":1011,"year":1271,"series":6},"\u002Fblog\u002Flearn-to-say-no","Learning to say No","Learn why it's important to say 'NO'. How it helps in increasing productivity and explore strategies for saying No",[1047,1046],"2022-04-09",{"path":1273,"title":1274,"description":1275,"categories":1276,"draft":1011,"year":1277,"series":6},"\u002Fblog\u002Flearn-unlearn-relearn","Learn - Unlearn - Relearn","Unlearning things to learn new is the way to grow. Discover how to do that!",[1031,1047],"2020-09-25",{"path":1279,"title":1280,"description":1281,"categories":1282,"draft":1011,"year":1283,"series":6},"\u002Fblog\u002Flinting-in-golang","Introduction to Linting in Go","Introduction to improving code quality using linting. Learn how to add linting in your Go projects.",[1039,1032],"2021-07-07",{"path":1285,"title":1286,"description":1287,"categories":1288,"draft":1011,"year":1289,"series":6},"\u002Fblog\u002Fload-balancing","Load Balancing 101","Complete guide on load balancers explaining the internal working and how does it help in making applications efficient.",[1063,1032],"2021-05-29",{"path":1291,"title":1292,"description":1293,"categories":1294,"draft":1011,"year":1295,"series":6},"\u002Fblog\u002Fmaking-decisions-the-right-way","Making Decisions: The right way","Decisions are hard! Learn how to make the right decisions always",[1031,1047],"2020-06-07",{"path":1297,"title":1298,"description":1299,"categories":1300,"draft":1011,"year":1302,"series":6},"\u002Fblog\u002Fmanage-logs-with-logrotate","Logrotate: Manage Linux Logs with Examples","Configure logrotate to rotate, compress and prune logs, including a Postgres setup and how to force a rotation.",[1301,1032],"Linux","2020-09-08",{"path":1304,"title":1305,"description":1306,"categories":1307,"draft":1011,"year":1308,"series":6},"\u002Fblog\u002Fmarshal-structs-golang","Marshal structs the right way: Golang","Why Golang marshals empty structs into your JSON instead of null, and how to marshal structs the right way.",[1039,1032],"2020-03-31",{"path":1310,"title":1311,"description":1312,"categories":1313,"draft":1011,"year":1314,"series":6},"\u002Fblog\u002Fnotes-almanack-naval","Book Notes : Almanack of Naval Ravikant","My notes\u002Fhighlights from Almanack of Naval Ravikant book by Eric Jorgenson",[1046,1047],"2020-10-17",{"path":1316,"title":1317,"description":1318,"categories":1319,"draft":1011,"year":1320,"series":6},"\u002Fblog\u002Fnotes-anything-you-want","Book Notes : Anything you want","My notes\u002Fhighlights from Anything you want book by Derek Sivers",[1046,1047],"2021-09-25",{"path":1322,"title":1323,"description":1324,"categories":1325,"draft":1011,"year":1327,"series":6},"\u002Fblog\u002Fnotes-getting-real","Book Notes : Getting Real","My notes and highlights from Getting Real by Jason Fried and David Heinemeier Hansson on building web applications.",[1046,1326],"Startups","2020-11-03",{"path":1329,"title":1330,"description":1331,"categories":1332,"draft":1011,"year":1333,"series":6},"\u002Fblog\u002Fnotes-hell-yeah-or-no","Book Notes : Hell Yeah or No","My notes\u002Fhighlights from Hell Yeah or No book by Derek Sivers",[1046,1047],"2020-09-16",{"path":1335,"title":1336,"description":1337,"categories":1338,"draft":1011,"year":1339,"series":6},"\u002Fblog\u002Fnotes-how-to-be-a-capitalist","Book Notes : How to Be a Capitalist Without Any Capital","My notes\u002Fhighlights from How to Be a Capitalist Without Any Capital by Nathan Latka",[1046,1326],"2020-01-07",{"path":1341,"title":1342,"description":1343,"categories":1344,"draft":1011,"year":1346,"series":6},"\u002Fblog\u002Fnotes-lean-b2b","Book Notes : Lean B2B","My notes and highlights from Lean B2B by Étienne Garbugli on assessing markets, building MVPs, and selling to businesses.",[1046,1345],"Entrepreneurship","2022-07-02",{"path":1348,"title":1349,"description":1350,"categories":1351,"draft":1011,"year":1353,"series":6},"\u002Fblog\u002Fnotes-lets-talk-money","Book Notes : Let's Talk Money","My notes and highlights from Let's Talk Money by Monica Halan on managing personal finances and savings.",[1046,1352],"Personal Finance","2021-02-26",{"path":1355,"title":1356,"description":1357,"categories":1358,"draft":1011,"year":1359,"series":6},"\u002Fblog\u002Fnotes-obviously-awesome","Book Notes : Obviously Awesome","My notes and highlights from Obviously Awesome by April Dunford on product positioning and marketing strategy.",[1046,1326],"2020-04-26",{"path":1361,"title":1362,"description":1363,"categories":1364,"draft":1011,"year":1366,"series":6},"\u002Fblog\u002Fnotes-refactoring-ui","Book Notes: Refactoring UI","My notes and highlights from Refactoring UI by Adam Wathan and Steve Schoger, full of practical design tips for engineers.",[1046,1365],"Design","2020-05-09",{"path":1368,"title":1369,"description":1370,"categories":1371,"draft":1011,"year":1372,"series":6},"\u002Fblog\u002Fnotes-rework","Book Notes: Rework","My notes and highlights from Rework by Jason Fried and David Heinemeier Hansson on a better way to succeed in business.",[1046,1326],"2021-04-14",{"path":1374,"title":1375,"description":1376,"categories":1377,"draft":1011,"year":1379,"series":6},"\u002Fblog\u002Fone-on-one-meetings","Guide to Effective 1:1 Meetings","One on One meetings are important for your personal & professional growth. Learn how to master 1:1s with your manager and peers.",[1378,1031],"Career","2023-03-05",{"path":1381,"title":1382,"description":1383,"categories":1384,"draft":1011,"year":1385,"series":6},"\u002Fblog\u002Fpersonal-okrs","Personal OKRs for Success","Why one should set personal OKRs and how to achieve success with them",[1031,1047],"2020-06-27",{"path":1387,"title":1388,"description":1389,"categories":1390,"draft":1011,"year":1392,"series":6},"\u002Fblog\u002Fpoker-tips","Poker Tips: Johns Hopkins Poker Class","Notes from Johns Hopkins poker course. This guide will help you improve in Poker and win some large pots.",[1047,1391],"Poker","2020-06-13",{"path":1394,"title":1395,"description":1396,"categories":1397,"draft":1011,"year":1398,"series":6},"\u002Fblog\u002Fpomodoro","Get work done: The Pomo Way","Learn to focus and get productive by following the Pomodoro Technique",[1031],"2020-10-24",{"path":1400,"title":1401,"description":1402,"categories":1403,"draft":1011,"year":1404,"series":6},"\u002Fblog\u002Fpostgres-constraints","Postgres Constraints","Constraints are line of defense for database. Explore various types of constrainsts in postgres",[1216,1032],"2020-11-07",{"path":1406,"title":1407,"description":1408,"categories":1409,"draft":1011,"year":1410,"series":6},"\u002Fblog\u002Fppf-explained","PPF Explained","Learn basics about Public Provident Fund and why you should invest",[1047,1352],"2020-12-24",{"path":1412,"title":1413,"description":1414,"categories":1415,"draft":1011,"year":1416,"series":6},"\u002Fblog\u002Fproductivity-chrome-extensions","Boost Productivity with Chrome Extensions","Utitizing chrome extensions to boost your productivity!",[1031,1056,1055],"2020-04-24",{"path":1418,"title":1419,"description":1420,"categories":1421,"draft":1011,"year":1422,"series":6},"\u002Fblog\u002Fproductivity-in-vscode","Improve your productivity with VS Code","Key VS Code features like the integrated terminal, shortcuts, and extensions that improved my everyday productivity.",[1031,1032],"2020-03-12",{"path":1424,"title":1425,"description":1426,"categories":1427,"draft":1011,"year":1428,"series":6},"\u002Fblog\u002Freading-101","Improving Reading 101","Why reading matters, how to build a reading habit, and what to read next - from my own journey into books.",[1046,1047],"2020-04-04",{"path":1430,"title":1431,"description":1432,"categories":1433,"draft":1011,"year":1434,"series":6},"\u002Fblog\u002Freverse-proxy","What is a Reverse Proxy? How It Works","What a reverse proxy is, how it differs from a forward proxy and a load balancer, and the benefits it adds to a system design.",[1063,1032],"2021-10-03",{"path":1436,"title":1437,"description":1438,"categories":1439,"draft":1011,"year":1440,"series":6},"\u002Fblog\u002Frunning-periodic-background-task-golang","Running periodic background tasks in Golang","How to run periodic background tasks in Golang by combining cron-style scheduling with background execution.",[1039,1032],"2019-11-21",{"path":1442,"title":1443,"description":1444,"categories":1445,"draft":1011,"year":1446,"series":6},"\u002Fblog\u002Fsessions-in-golang","Sessions using Golang and Redis","How cookies and sessions work, and how to implement persistent login sessions in Golang using Redis.",[1039,1216,1032],"2020-02-25",{"path":1448,"title":1449,"description":1450,"categories":1451,"draft":1011,"year":1452,"series":6},"\u002Fblog\u002Fsolid-dry-kiss-yagni","Solid Dry Kiss Yagni","An introduction to the SOLID, DRY, KISS, and YAGNI principles and how they help you write cleaner, robust code.",[1070],"2020-07-17",{"path":1454,"title":1455,"description":1456,"categories":1457,"draft":1011,"year":1458,"series":6},"\u002Fblog\u002Fstack-in-golang","Implement Stack in Golang","Learn how to implement stack data structure in Golang (Full code)",[1039,1032],"2020-09-14",{"path":1460,"title":1461,"description":1462,"categories":1463,"draft":1011,"year":1464,"series":6},"\u002Fblog\u002Fstart-oss-today","Start your Open Source journey today","Start your OSS journey with intro to GIT. Participate in Hacktoberfest!",[1154,1032],"2020-09-19",{"path":1466,"title":1467,"description":1468,"categories":1469,"draft":1011,"year":1471,"series":6},"\u002Fblog\u002Fsticky-social-bar","Sticky social share component in HTML","Learn how to build a social media sharing component in HTML and add it to your website.",[1032,1470],"Frontend","2021-02-05",{"path":1473,"title":1474,"description":1475,"categories":1476,"draft":1011,"year":1477,"series":6},"\u002Fblog\u002Fterm-insurance","Term insurance Simplified","Everything you need to know before you buy a term insurance.",[1047,1352],"2020-11-29",{"path":1479,"title":1480,"description":1481,"categories":1482,"draft":1011,"year":1484,"series":6},"\u002Fblog\u002Fterminal-output-with-redirection","Handling terminal outputs with Redirection","Learn how to handle terminal outputs with Redirection and saving it to files",[1301,1483,1032],"Terminal","2020-09-06",{"path":1486,"title":1487,"description":1488,"categories":1489,"draft":1011,"year":1490,"series":6},"\u002Fblog\u002Fthink-and-grow-rich","Book Notes: Think and Grow Rich","My notes and highlights from Think and Grow Rich by Napoleon Hill, covering its process for building wealth.",[1046,1047],"2020-05-19",{"path":1492,"title":1493,"description":1494,"categories":1495,"draft":1011,"year":1496,"series":6},"\u002Fblog\u002Ftransactions-postgres-golang","Transactions on Postgres with Golang","Performing Postgres database operations in Golang with GORM, from basic queries to full transaction support.",[1039,1216,1032],"2020-03-18",{"path":1498,"title":1499,"description":1500,"categories":1501,"draft":1011,"year":1502,"series":6},"\u002Fblog\u002Fwaitgroups-in-golang","WaitGroups in Golang","Learn about WaitGroups in golang and how to use them to perform concurrent operations without blocking the main thread.",[1039,1032],"2022-05-31",{"path":1504,"title":1505,"description":1506,"categories":1507,"draft":1011,"year":1509,"series":6},"\u002Fblog\u002Fwhat-i-use","What I Use: Products and Softwares","List of what I use in my day to day life ranging from terminal, editors, softwares, devices to accessories",[1047,1508],"Tech","2024-06-01",{"path":1511,"title":1512,"description":1513,"categories":1514,"draft":1011,"year":1515,"series":6},"\u002Fblog\u002Fyear-in-review-2020","Year in Review: 2020","It's a wrap! 2020 was a crazy year, See how my year went!",[1047],"2020-12-31",{"path":1517,"title":1518,"description":1519,"categories":1520,"draft":1011,"year":1521,"series":6},"\u002Fblog\u002Fyear-in-review-2021","Year in Review: 2021","It's a wrap! 2021 was a mixed bag, full of ups and downs. Key Goal for 2022: Start now!",[1047],"2021-12-31",1793277594159]