<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Ankit Saini(@d3afh3av3n) on Medium]]></title>
        <description><![CDATA[Stories by Ankit Saini(@d3afh3av3n) on Medium]]></description>
        <link>https://medium.com/@ankitsaini2609?source=rss-4f95bcfb6faf------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*0EbJ5Sl_uOBQAlEPs1iCpw.jpeg</url>
            <title>Stories by Ankit Saini(@d3afh3av3n) on Medium</title>
            <link>https://medium.com/@ankitsaini2609?source=rss-4f95bcfb6faf------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 16:09:38 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@ankitsaini2609/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[[Flash Blogs] Cybersecurity Meets AI: Automating STRIDE-Based Threat Modeling]]></title>
            <link>https://medium.com/@ankitsaini2609/flash-blogs-cybersecurity-meets-ai-automating-stride-based-threat-modeling-108a0c35a1a8?source=rss-4f95bcfb6faf------2</link>
            <guid isPermaLink="false">https://medium.com/p/108a0c35a1a8</guid>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[jira]]></category>
            <category><![CDATA[threat-modeling]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[automation]]></category>
            <dc:creator><![CDATA[Ankit Saini(@d3afh3av3n)]]></dc:creator>
            <pubDate>Fri, 18 Jul 2025 18:53:52 GMT</pubDate>
            <atom:updated>2025-07-18T18:53:52.867Z</atom:updated>
            <content:encoded><![CDATA[<p>In <strong>2017</strong>, <strong>Equifax</strong>, one of the largest credit bureaus in the U.S., suffered a catastrophic <strong>data breach</strong> that exposed the personal information of <strong>147 million </strong>people. The cause? A known vulnerability in Apache Struts, a web application framework, left unpatched for months. The result: $1.4 billion in recovery costs, plummeting stock prices, and irreversible reputational damage. This wasn’t a sophisticated attack — it was a failure to identify and prioritize risks during development systematically.</p><p>In <strong>2013</strong>, Target’s massive <strong>data breach</strong> exposed <strong>40 million credit card </strong>details and <strong>cost</strong> the company <strong>$292 million</strong> in settlements. Attackers infiltrated the network through a third-party HVAC vendor — a risk overlooked during manual threat assessments</p><h3><strong>Why Threat Modeling Matters (And Why It’s Broken)</strong></h3><p>The Equifax and Target breaches weren’t anomalies — they were preventable. Both catastrophes stemmed from failures to systematically identify risks during development. Threat modeling, using frameworks like STRIDE, could have flagged these oversights before attackers struck. For example:</p><ul><li>Equifax’s unpatched Apache Struts vulnerability represented a classic Information Disclosure risk.</li><li>Target’s third-party HVAC vendor access was an Elevation of Privilege loophole.</li></ul><p>Yet, most organizations still rely on manual processes, overburdened experts, and outdated checklists — a recipe for disaster. Here’s why traditional methods fail:</p><blockquote><strong>Human Bottlenecks:</strong> <a href="https://www.isc2.org/Insights/2023/11/ISC2-Cybersecurity-Workforce-Study-Looking-Deeper-into-the-Workforce-Gap">A global shortage of 3.4 million cybersecurity professionals (ISC² 2022) leaves teams drowning in alerts</a>. Equifax’s engineers knew about the Apache Struts flaw but lacked bandwidth to prioritize it amid competing tasks.</blockquote><blockquote><strong>Inconsistency:</strong> Manual reviews miss critical patterns. Target’s threat model likely focused on internal systems, ignoring third-party attack surfaces like HVAC vendors — a fatal oversight.</blockquote><blockquote><strong>Speed: </strong>Equifax left the vulnerability unpatched for 78 days — plenty of time for attackers to exploit it. Manual threat modeling cycles can’t keep pace with DevOps pipelines deploying code every 11 seconds (GitLab 2023).</blockquote><p>AI-driven automation fixes this. By applying STRIDE systematically, AI scans PRDs for risks like:</p><ul><li><strong>Tampering:</strong> Unpatched dependencies (e.g., Equifax’s Apache Struts).</li><li><strong>Spoofing/Elevation of Privilege:</strong> Weak third-party access controls (e.g., Target’s HVAC vendor).</li></ul><p>It generates actionable reports in minutes, not months.</p><h3>The AI-Driven Solution: A Technical Deep Dive</h3><p>A practical implementation of AI-powered threat modeling. Let’s dissect its workflow:</p><h4>1. Inputs: PRD and Threat Modeling Template</h4><ul><li><strong>sample_prd</strong>: A Product Requirements Document (PRD) outlining system functionality. It can be a list of documents, flow diagrams etc.</li><li><strong>threat_modeling_template [prompt]</strong>: A markdown template/prompt defining the structure for the threat report (e.g., risk categories, mitigation steps).</li></ul><h4>2. Crafting the AI Prompt</h4><p>You can create a get_prompt() function. The get_prompt function constructs a detailed instruction set for GPT-4, combining:</p><ul><li><strong>Role Definition:</strong> “You are a cybersecurity expert with 10+ years of experience.”</li><li><strong>Task:</strong> Analyze the PRD using the STRIDE model and populate the template.</li><li><strong>Formatting Rules:</strong> Use ** bold ** key terms and adhere strictly to Markdown.</li></ul><h4>3. Querying AI models and Generating the Final Report</h4><p>Your Tool sends the prompt to GPT-4 via OpenAI’s API or Claude Sonnet 4, DeepSeek (R1), or any other AI tool, with a low temperature of 0.2 to prioritize accuracy over creativity. The model returns a structured markdown report based on your template.</p><p><strong><em>Note: A better prompt will give you a better response.</em></strong></p><p><strong>Sample PRD — — — — — — — — — — — -</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kdw6hM3zpJpsR1g79Fal4g.png" /><figcaption>Sample PRD</figcaption></figure><p>For a full PRD document, please refer <a href="https://github.com/ankitsaini2609/ThreatModellingSampleFileAndReport/blob/master/Sample%20PRD%20for%20login%20feature.pdf">here</a>.</p><p><strong>Sample Threat Modeling Report — — — — —</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oh9lIEa6dECewYiYJnCVPQ.png" /><figcaption>Sample Report.</figcaption></figure><p>For a Full report, please refer to <a href="https://github.com/ankitsaini2609/ThreatModellingSampleFileAndReport/blob/master/Sample%20PRD%20for%20login%20feature%20Threat%20Modelling%20Report_63008bdd.pdf">this link</a>.</p><p><strong>Possible Implementation:</strong> A User will create a JIRA ticket and will attach the PRD; the automation will pick this PRD and will do the threat modelling and attach it back to the JIRA ticket. It can provide the checklist as well to the developers so they can check what they have implemented and what’s left.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GG5otS5hXeAJwTebgyqc5A.png" /><figcaption>Sample Checklist</figcaption></figure><p>Thank you for reading.</p><p>If you liked the blog, follow me on <a href="https://twitter.com/d3afh3av3n">Twitter</a>/<a href="https://linkedin.com/in/d3afh3av3n">LinkedIn</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=108a0c35a1a8" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Solving the ‘Nobody Reads the Docs’ Problem with LLMs]]></title>
            <link>https://medium.com/@ankitsaini2609/solving-the-nobody-reads-the-docs-problem-with-llms-e382ef679b79?source=rss-4f95bcfb6faf------2</link>
            <guid isPermaLink="false">https://medium.com/p/e382ef679b79</guid>
            <category><![CDATA[bots]]></category>
            <category><![CDATA[rags]]></category>
            <category><![CDATA[llm]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[confluence]]></category>
            <dc:creator><![CDATA[Ankit Saini(@d3afh3av3n)]]></dc:creator>
            <pubDate>Tue, 27 May 2025 12:29:16 GMT</pubDate>
            <atom:updated>2025-05-27T12:29:16.178Z</atom:updated>
            <content:encoded><![CDATA[<h3>What If Your Documentation Could Talk Back?</h3><p>We’ve all been there.<br>The team has spent countless hours documenting everything—onboarding guides, deployment steps, architectural decisions, and troubleshooting steps. It’s all in Confluence, searchable, and yet… the same questions keep landing in Slack.</p><blockquote>“Hey, where’s the link to that dashboard again?”<br>“What’s the process for production deployments?”<br>“Who owns the XYZ microservice?”</blockquote><p>At some point, it stops being a documentation problem. The information exists, but no one is reading it.</p><p><strong>This got us thinking:</strong><br>What if we could make documentation more accessible? Not just as static pages, but as something you could talk to.</p><h3>The Challenge</h3><p>Most teams aren’t short on documentation. The real problem is retrieval and friction.</p><ul><li>Searching Confluence manually isn’t always intuitive.</li><li>Context-switching to find the right page disrupts flow.</li><li>And often, it’s just easier to ask a teammate.</li></ul><p>The result? High-context, repetitive questions that interrupt everyone’s time.</p><p>We wanted to explore whether we could build a lightweight assistant that understands your internal documentation and answers questions based on it.</p><h3>The Idea</h3><p>What we’re exploring is this:</p><blockquote><strong>Can we build an internal chatbot that reads Confluence and answers your team’s questions — instantly, privately, and accurately?</strong></blockquote><p>The idea is simple:</p><ul><li><strong>Ingest content</strong> from Confluence pages.</li><li><strong>Generate embeddings</strong> to represent meaning, not just keywords.</li><li><strong>Store these </strong>using a vector database.</li><li><strong>Query</strong> this store with natural language.</li><li><strong>Respond</strong> using an LLM based on the most relevant documents.</li></ul><p>Imagine asking:</p><blockquote>“How do I request an AWS role?”<br>“What’s the incident response process?”</blockquote><p>And getting a clear, context-aware answer — within seconds — based on your docs.</p><h3>💡 Here Comes the ConfluenceGPT</h3><p>We built a proof-of-concept project: <a href="https://github.com/ankitsaini2609/confluence-gpt"><strong>ConfluenceGPT</strong></a> — a simple, local-first chatbot that can read your Confluence pages and answer your team’s questions using LLMs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Pd-356Xnd4BqSv3HKSO4_Q.png" /></figure><p>Let’s break down how it works and what it includes.</p><h4>🔧 How It Works — Architecture Overview</h4><p><strong>Document Ingestion: </strong>We use the Confluence API to extract the raw text content from specified Confluence pages and sections. This is handled by the script: <strong>ingest_confluence_to_chroma.py</strong></p><ul><li>Pulls data from Confluence using basic auth or token.</li><li>Cleans and chunks the documents using LangChain’s TextSplitter</li><li>Converts text into vector embeddings using a Hugging Face model.</li><li>Stores these vectors locally in a Chroma DB.</li></ul><p><strong>Model Caching (Offline Ready): </strong>Since Hugging Face models are used, we’ve included: <strong><em>cacheHuggingFaceModel.py</em></strong></p><ul><li>Downloads and caches the BAAI/bge-base-en-v1.5 model locally.</li><li>Ensures the system doesn’t rely on internet access to use the model later.</li></ul><p><strong>Question Answering with LLM + Embeddings</strong></p><p>This is the heart of the project — querying your Confluence documents using natural language: <strong>query_chroma_with_llm.py</strong></p><ul><li>Takes a user’s question as input.</li><li>Uses <strong><em>BAAI/bge-base-en-v1.5</em></strong> to generate embedding for the question.</li><li>Searches Chroma DB for the most relevant chunks.</li><li>Sends the context to an LLM (like GPT, Mistral, or OpenChat) via LangChain. (<strong>Refer to Note</strong>)(*You can host an in-house model as well, to use it.)</li><li>Returns an answer based on both the question and the most relevant documentation chunk, along with the source URL so that hallucinations can be avoided.</li></ul><p><strong>Note: </strong>We are utilizing the GPT-4 model, as per <a href="https://openai.com/enterprise-privacy/">OpenAI’s official documentation</a>:</p><ul><li>OpenAI does not use data submitted via the API to train or improve its models.</li><li>All data is retained for a limited period and is automatically deleted after 30 days.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JklWATLVuYVyRzEUCIe_iA.png" /><figcaption>Query — 1</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*W8xKZqiiNj4XKQnHGlAlRQ.png" /><figcaption>Query — 2</figcaption></figure><h3>Future Plans &amp; Improvements</h3><p>While ConfluenceGPT is currently a lightweight, local-first assistant, there’s a clear roadmap to evolve it into a more robust, production-grade internal knowledge bot.</p><ul><li>If you think downloading and managing the model is too much, you can use the online model as well.</li><li>You can integrate it with <strong>Slack slash command</strong> and use it directly from Slack. You can refer to my<a href="https://medium.com/@ankitsaini2609/slack-aws-secure-one-click-role-access-with-zero-standing-privileges-edb51424ad8d"> Slack + AWS: Secure, One-Click Role Access (With Zero Standing Privileges)</a> blog, where I have talked about implementing automations using Slack slash commands.</li><li>You can consider using <strong>scalable vector stores </strong>like: Pinecone, Weaviate, Qdrant, Milvus, etc.</li><li>Improved Embeddings and LLMs like <strong>mxbai-embed-large</strong>, <strong>OpenAI’s ada-002.</strong></li><li>Web dashboard for people who are not using Slack.</li><li>It can be extended not just to Confluence but to anything or everything as far as they exist in the doc.</li></ul><p><strong>Github Repo:</strong> <a href="https://github.com/ankitsaini2609/confluence-gpt">https://github.com/ankitsaini2609/confluence-gpt</a></p><p>Thank you for reading.</p><p>If you liked it, you can follow me on <a href="https://twitter.com/d3afh3av3n">Twitter</a>/<a href="https://linkedin.com/in/d3afh3av3n">LinkedIn</a> for more.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e382ef679b79" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Slack + AWS: Secure, One-Click Role Access (With Zero Standing Privileges)]]></title>
            <link>https://medium.com/devsecops-ai/slack-aws-secure-one-click-role-access-with-zero-standing-privileges-edb51424ad8d?source=rss-4f95bcfb6faf------2</link>
            <guid isPermaLink="false">https://medium.com/p/edb51424ad8d</guid>
            <category><![CDATA[devsecops]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[slack]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[automation]]></category>
            <dc:creator><![CDATA[Ankit Saini(@d3afh3av3n)]]></dc:creator>
            <pubDate>Sun, 02 Mar 2025 07:58:30 GMT</pubDate>
            <atom:updated>2025-07-28T17:53:31.522Z</atom:updated>
            <content:encoded><![CDATA[<h3>The Problem: Standing Privileges Are Undermining Your Cloud Security</h3><p>Imagine this: Developers maintain permanent AWS role access “just in case,” while DevOps drown in frantic Slack requests for ProdDB access, and credentials are casually shared in public channels. When auditors ask, “Who approved this role?” the answer is met with a shrug.</p><p>This isn’t fiction — it’s the reality that led to catastrophic breaches. In 2019, <strong>Capital One’s </strong>misconfigured IAM roles <strong>allowed an attacker to access over 100 million customer records</strong>. In 2016, <strong>Uber’s exposed AWS credentials</strong> contributed to a major <strong>data compromise</strong> affecting millions of users. And in 2018, <strong>misconfigured Kubernetes clusters</strong> in a high-profile case involving <strong>Tesla</strong> enabled <strong>unauthorized AWS access</strong>.</p><p>This isn’t hypothetical — it’s the reality for teams using manual IAM role management. The risks?</p><ul><li>Permanent roles amplify breaches by serving as an irresistible treat for attackers.</li><li><strong>Human Error:</strong> When users have excessive privileges and policies are misconfigured, it paves the way for security breaches.</li><li><strong>Compliance Gaps:</strong> The lack of an audit trail for role assumptions hinders accountability.</li></ul><p>To eliminate permanent access risks, I architected a solution that ties AWS roles to Slack approvals and time-bound credentials.</p><h3>The solution: Slack-driven, approval-based role access by sharing temporary credentials</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RGcXnLAio3Is8gXdFm2REA.png" /><figcaption>Architecture digram</figcaption></figure><p>I automated the entire workflow into a Slack app that:</p><ul><li><strong>Lists Assumable Roles:</strong> Users type <strong><em>/aws-assign-role list-roles</em> </strong>to see what they’re allowed to request.</li><li><strong>Requests Approval:</strong> <strong><em>/aws-assign-role &lt;role name&gt; </em></strong>triggers an API Gateway → Lambda workflow.</li><li><strong>Securely Delivers Credentials:</strong> Approved? Temporary credentials land in the user’s Slack DMs — ephemeral, and never in public channels.</li></ul><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F9u84sGy7epA%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D9u84sGy7epA&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F9u84sGy7epA%2Fhqdefault.jpg&amp;type=text%2Fhtml&amp;schema=youtube" width="640" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/3fa9435bbed73bd0205cddcf94d86d1a/href">https://medium.com/media/3fa9435bbed73bd0205cddcf94d86d1a/href</a></iframe><h3>How It Works</h3><p>Let us break down the whole setup step by step:</p><h4><strong>Part- 1: The manifest: your Slack app’s security blueprint</strong></h4><pre>display_information:<br>  name: AWS_JIT_ACCESS_MANAGEMENT<br>features:<br>  bot_user:<br>    display_name: AWS_JIT_ACCESS_MANAGEMENT<br>    always_online: false<br>  slash_commands:<br>    - command: /aws_assign_role<br>      url: &lt;AWS_API_GATEWAY_URL&gt;/roleassignment<br>      description: This function will assign IAM role to the user.<br>      should_escape: false<br>oauth_config:<br>  scopes:<br>    user:<br>      - channels:write<br>      - groups:write<br>      - im:write<br>      - mpim:write<br>      - chat:write<br>    bot:<br>      - chat:write<br>      - commands<br>      - groups:write<br>      - im:write<br>      - mpim:write<br>settings:<br>  interactivity:<br>    is_enabled: true<br>    request_url: &lt;AWS_API_GATEWAY_URL&gt;/approvalCheck<br>  org_deploy_enabled: false<br>  socket_mode_enabled: false<br>  token_rotation_enabled: false</pre><p><strong>1- App Identity &amp; Core Features</strong></p><pre>display_information:<br>  name: AWS_JIT_ACCESS_MANAGEMENT  # Name visible to users<br>features:<br>  bot_user:<br>    display_name: AWS_JIT_ACCESS_MANAGEMENT  # Bot’s display name<br>    always_online: false  # No need for 24/7 uptime (security-first!)  </pre><blockquote><strong>Why It Matters:</strong> Clear naming avoids confusion (e.g., “AWS_JIT” signals its purpose).</blockquote><blockquote><strong>always_online: false</strong> reduces attack surface when idle.</blockquote><p><strong>2- Slash Command — The User’s Gateway</strong></p><pre>slash_commands:<br>  - command: /aws_assign_role<br>    url: &lt;API_GATEWAY_URL&gt;/roleassignment  # Endpoint for role assignment logic<br>    description: This function will assign IAM role to the user.<br>    should_escape: false  # Allows markdown formatting in responses  </pre><blockquote><strong>/aws_assign_role:</strong> The command triggers role assignment — ensure it is only accessible to authorized users.</blockquote><blockquote><strong>url:</strong> Points to your secured API Gateway endpoint (validate Slack signatures here).</blockquote><blockquote><strong>should_escape: false:</strong> Lets you format error messages (e.g., code blocks for clarity).</blockquote><p><strong>3- OAuth Scopes — Least Privilege in Action</strong></p><pre>oauth_config:<br>  scopes:<br>    user:<br>      - channels:write  # Post to public channels (for audit logs)<br>      - groups:write    # Post to private channels<br>      - im:write        # Send DMs to users<br>      - mpim:write      # Post to multiparty DMs<br>      - chat:write      # General message posting  <br>    bot:<br>      - chat:write      # Post messages as the bot<br>      - commands        # Enable slash commands<br>      - groups:write    # Join private channels<br>      - im:write        # Initiate DMs  <br>      - mpim:write      # Post to multiparty DMs</pre><p><strong>4- Interactivity — Secure Approval Workflows</strong></p><pre>settings:<br>  interactivity:<br>    is_enabled: true<br>    request_url: &lt;API_GATEWAY_URL&gt;/approvalCheck  # Endpoint for button clicks (approve/deny)  </pre><blockquote><strong>Validate Requests:</strong> Use Slack’s signing secret to verify that interactions (e.g., approval button clicks) come from Slack — not attackers.</blockquote><blockquote><strong>Ephemeral Messages:</strong> Deliver credentials via DMs, not public channels.</blockquote><h4>Part-2: Secure AWS JIT Role Access: From Slack Command to Tamper-Proof Approvals</h4><p>In Part 1, we configured the Slack app. Now, let’s dissect the secure flow from command invocation to approval — designed to <strong>eliminate</strong> <strong>standing privileges</strong> and <strong>prevent tampering</strong>.</p><p><strong>1- Slack Slash Command → API Gateway</strong></p><ul><li>When a user runs <strong>/aws_assign_role</strong>, Slack sends a <strong>POST</strong> request to your API Gateway endpoint (<strong>/roleassignment</strong>) with <strong>application/x-www-form-urlencoded</strong> data.</li><li><strong>Problem</strong>: Lambda expects JSON, but Slack sends URL-encoded payloads.<br><strong>Solution: </strong>Use API Gateway’s mapping template(Integration Request) to transform the payload:</li></ul><pre>{<br>  &quot;body&quot; : $input.json(&quot;$&quot;),<br>  &quot;headers&quot;: {<br>    #foreach($header in $input.params().header.keySet())<br>      &quot;$header&quot;: &quot;$util.escapeJavaScript($input.params().header.get($header))&quot; #if($foreach.hasNext),#end<br>    #end<br>  }<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*33X7PnY9cB48KXamVhajCA.png" /><figcaption>API Gateway Configuration for /roleassignment endpoint</figcaption></figure><p><strong>2- Request Verification — Guarding Against Spoofing</strong></p><p>The <strong>JIT_Role_assignment</strong> Lambda first verifies the request is from Slack using the <strong>X-Slack-Signature</strong> header:</p><ul><li><strong>Fetch Slack Signing Secret:</strong> Retrieve it from AWS Secrets Manager (never hardcode).</li><li><strong>Signature Verification: </strong>Whether the request came from the authorized Slack app or not.</li><li><strong>Reject Old Requests:</strong> If timestamp is &gt;5 minutes old, discard it (anti-replay).</li></ul><p><strong>3- Role Authorization Check — Least Privilege Enforcement</strong></p><p>The Lambda fetches a <strong>role assignment file</strong> from an <strong>S3 bucket</strong> (encrypted at rest):</p><pre>[{<br>    &quot;slack_userID&quot;: &quot;U12345&quot;,  // Slack user ID<br>    &quot;aws_username&quot;: &quot;dev-user-1&quot;,  // Corresponding AWS IAM user<br>    &quot;can_assume_role&quot;: [&quot;read-only-role&quot;, &quot;s3-admin&quot;],  // Allowed roles<br>    &quot;slack_approver_userid&quot;: &quot;U67890&quot;  // Approver’s Slack ID<br>}]  </pre><ul><li>Check if the requesting slack_userID is allowed to assume the role.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RXtLijfKX6k7sb4Xct-uRw.png" /><figcaption>User is trying to assume an unauthorized role</figcaption></figure><ul><li>Validate the role exists in AWS IAM.</li><li>Fetch the slack_approver_userid to send the approve request in the slack.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RtT17zDWxN8DgLB-onUrow.png" /><figcaption>approve and reject notification</figcaption></figure><p><strong>4- Approval Workflow — Tamper-Proof Design</strong></p><p>To prevent malicious approvals, the Lambda:</p><ul><li>Create a signature using HMAC-SHA256(timestamp + userID + role) and then encode it with a secret key.</li><li>Posts an ephemeral Slack message to the approver with ✅/❌ buttons and Embeds the signature and timestamp in the callback URL :</li></ul><blockquote>For example:<br><strong>https://&lt;APIGatewayURL&gt;/approvalCheck?user_id=&lt;userid&gt;&amp;action=approve&amp;role_name_to_assume=LambdaS3PolicySecuringRole&amp;timestamp=1740679860&amp;signature=f1e3d234672e2cdb88fe6c413844564e9c3da4eac8e1096c46f6c44294372649</strong></blockquote><ul><li><strong>Expires in 5 Minutes:</strong> Reject approvals if the timestamp is stale.</li></ul><p><strong>Why it matters:</strong></p><blockquote><strong>No Standing Access:</strong> Roles are inert until approved.</blockquote><blockquote><strong>Tamper-Proof Links: </strong>Signature ensures approval requests can’t be forged.</blockquote><blockquote><strong>Least Privilege:</strong> Users only see roles they’re explicitly allowed to request.</blockquote><blockquote><strong>Audit Trail:</strong> S3 access logs + CloudWatch track who requested/approved roles.</blockquote><h4>Part-3: The Approval Workflow — From Button Click to Secure Credentials</h4><p>In Part 2, we validated requests and triggered approvals. Now, let’s dissect the final steps: <strong>tamper-proof approval handling</strong>, <strong>STS credential generation</strong>, and <strong>automated cleanup</strong>.</p><p><strong>1- API Gateway Setup — Handling Approvals</strong></p><ul><li>When an approver clicks ✅/❌, Slack sends a GET request to <strong>/approvalCheck</strong> with query parameters:</li></ul><pre>/approvalCheck?user_id=U123&amp;action=approve&amp;timestamp=1700000000&amp;signature=abc123&amp;role_name_to_assume=read-only  </pre><ul><li><strong>API Gateway Configuration for GET Request:</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9gzGB8znDcgsl2srDh_UKw.png" /><figcaption>Method Request API Gateway Configuration</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*np5R-r15IXBhfRL435rmJw.png" /><figcaption>Integration request, API Gateway Configuration</figcaption></figure><p>This feeds clean JSON to Lambda.</p><p><strong>2- Tamper-Proof Validation</strong></p><p>Like the First lambda function, this lambda function will also do the following validations</p><ul><li>Recompute <strong><em>HMAC-SHA256(timestamp + user_id + role_name_to_assume)</em></strong> using a secret key, Match against the signature param. <strong>Mismatch</strong>? <strong>Reject</strong> instantly.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/874/1*D-QvxOwfPyEQk8E78vGYfg.png" /><figcaption>Invalid Signature</figcaption></figure><ul><li><strong>Timestamp Check: </strong>If (<strong>current_time — timestamp) &gt; 5 minutes</strong>, <strong>reject</strong>. Blocks replay attacks.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/884/1*VGXRjwFVlXxiz2yle-orEA.png" /><figcaption>Request Expired</figcaption></figure><ul><li>Whether a user is authorised to assume the role or not.</li><li><strong>Anti-Duplication via S3:</strong> Fetch database.json from S3, if signature exists: it will return <strong><em>“Request already processed”</em></strong> to Slack. If not, <strong>Add</strong> <strong>signature + timestamp </strong>to <strong>database.json</strong>, then proceed.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/908/1*kIqf7OU3GNEjwvuagrJNWw.png" /><figcaption>Request Already Processed</figcaption></figure><p><strong>3- Credential Generation &amp; Delivery</strong></p><ul><li>If approved: Lambda will assume role using STS and will share the credentials with the user.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*t6wE0yGsjCYSQrH-Kql0tw.png" /><figcaption>Shared Credentials</figcaption></figure><p><strong>Notes:</strong></p><ul><li>If you make a <strong>HEAD </strong>request in the <strong>/approvalCheck </strong>endpoint, it will do the s3 cleanup, meaning removing all the signatures that are not valid anymore.</li><li>Ensure the lambda role should have proper access to the S3 bucket and the trust policy is correctly set up in both the lambda role and the role lambda is going to assume.</li><li>The Lambda role can only assume specific roles — nothing else.</li><li>API Gateway throttles to block brute-force attacks.</li></ul><h3>Why This Stops Most of Cloud Security Incidents</h3><ul><li><strong>No Standing Privileges:</strong> Roles are inactive until approved.</li><li><strong>Slack = Audit Trail:</strong> Every request/approval is logged in Slack + CloudWatch.</li><li><strong>Least Privilege, By Default:</strong> Users only get what they need, when they need it.</li></ul><h3>Future Plans</h3><ul><li>This can be used to attach and remove the policies on a role or a user.</li><li>You can use the <a href="https://medium.com/@ankitsaini2609/safeguarding-credentials-in-slack-7890e2b0bb8f">privatebin to share the credentials</a> with the user rather than sending them in plaintext.</li><li>You can add the user to the group or remove it as well, after x hours, in case you don’t want to give temporary credentials using assume role by lambda.</li><li>You can play around with permission sets as well in IAM identity center.</li></ul><p>Thank you for reading.</p><p>If you liked the blog, you can follow me on <a href="https://twitter.com/d3afh3av3n">Twitter</a>/<a href="https://linkedin.com/in/d3afh3av3n">LinkedIn</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=edb51424ad8d" width="1" height="1" alt=""><hr><p><a href="https://medium.com/devsecops-ai/slack-aws-secure-one-click-role-access-with-zero-standing-privileges-edb51424ad8d">Slack + AWS: Secure, One-Click Role Access (With Zero Standing Privileges)</a> was originally published in <a href="https://medium.com/devsecops-ai">DevSecOps &amp; AI</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[Flash Blogs] Teamify Your AWS GuardDuty Alerts]]></title>
            <link>https://medium.com/@ankitsaini2609/flash-blogs-teamify-your-aws-guardduty-alerts-24e394c538b7?source=rss-4f95bcfb6faf------2</link>
            <guid isPermaLink="false">https://medium.com/p/24e394c538b7</guid>
            <category><![CDATA[microsoft-teams]]></category>
            <category><![CDATA[devsecops]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[aws-lambda]]></category>
            <dc:creator><![CDATA[Ankit Saini(@d3afh3av3n)]]></dc:creator>
            <pubDate>Tue, 17 Oct 2023 05:13:44 GMT</pubDate>
            <atom:updated>2023-10-17T05:13:44.041Z</atom:updated>
            <content:encoded><![CDATA[<p>Welcome to the Flash blogs, in these blogs I will be sharing brief insights on DevSecOps topics.</p><p><a href="https://docs.aws.amazon.com/guardduty/latest/ug/what-is-guardduty.html">Amazon GuardDuty</a>, a Security Monitoring Service, analyzes AWS data sources and uses threat intelligence and machine learning to identify malicious activity. It covers issues like unauthorized access, malware detection, unusual login patterns, etc.</p><p>Most organization uses Slack/Microsoft Teams for their day-to-day communications.</p><p>In this blog, we will try to get the Guard duty alerts in Microsoft Teams not only it will enhance security incident response but also fulfill one of the ISO27001 requirements. It can be achieved by SIEM tools as well. You can configure these alerts and take action on a real-time basis.</p><p><strong>Prerequisite</strong>: <em>Guard Duty should be enabled.</em></p><h3>Architecture Diagram</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/864/1*mMgZ-dJJnfpBn1wj9MkyUg.png" /></figure><p>As you can see, GuardDuty alerts will be triggering the EventBridge rule which will run the lambda function and will send the alerts in MS Teams.</p><h3>Creating a Lambda function</h3><ul><li>Login to your AWS account, Go to Lambda and create one function with basic permissions.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qUdz2CLk_Nw81ylc4SsU8g.png" /></figure><ul><li>Fill in the function name and select runtime as python 3.7 then click on create function.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vuiilkAOPYIoqYhqkXGoOg.png" /></figure><ul><li>Paste the code given in the <a href="https://github.com/ankitsaini2609/FlashBlogs/blob/main/teamify-your-guard-duty-alerts/lambda.py">link</a>.</li><li>Set up the Environment variable by navigating to Lambda -&gt; Configuration -&gt; Environment Variables -&gt; Edit and Set the TEAM_WEBHOOK_URL.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xVkDxPrFDy3HLBZSirGF7A.png" /></figure><ul><li>To create a Microsoft Teams incoming webhook refer to <a href="https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook?tabs=dotnet">this</a> article.</li></ul><h3>Setting Up EventBridge Rule</h3><ul><li>Search for EventBridge in the AWS console, open it, and click on Create Rule on the right side.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2XiMdBGEr38epef6-GKShw.png" /></figure><ul><li>Fill in the name and click on next.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_zFW8gz8zPYyNnSkbFZ6IA.png" /></figure><ul><li>In the next screen make the following changes:</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ymaTcRS7DGsI25ecIWRI9Q.png" /></figure><ul><li>Select the <strong>Target</strong> as a lambda function and choose its name from the drop-down.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qBuD4x63BtTNJWTwwhNszw.png" /></figure><ul><li>Add the relevant tag then click on review and create then click on create.</li></ul><p>That’s it.</p><h3>Output</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KyN_lYUEyZCEu7uzjT_fyg.png" /></figure><p>The same solution can be extended to Slack, Discord, etc.</p><h4>Future Plans</h4><p>You can make it automatically actionable based on the alert type using the same lambda function.</p><p>Thank you for reading.</p><p>You can follow me on <a href="https://twitter.com/d3afh3av3n">Twitter</a>/<a href="https://linkedin.com/in/d3afh3av3n">LinkedIn</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=24e394c538b7" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Safeguarding Credentials in Slack]]></title>
            <link>https://medium.com/@ankitsaini2609/safeguarding-credentials-in-slack-7890e2b0bb8f?source=rss-4f95bcfb6faf------2</link>
            <guid isPermaLink="false">https://medium.com/p/7890e2b0bb8f</guid>
            <category><![CDATA[slack]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[credentials]]></category>
            <category><![CDATA[hacking]]></category>
            <category><![CDATA[dlp-solution]]></category>
            <dc:creator><![CDATA[Ankit Saini(@d3afh3av3n)]]></dc:creator>
            <pubDate>Sat, 14 Jan 2023 15:49:19 GMT</pubDate>
            <atom:updated>2023-01-14T15:49:19.026Z</atom:updated>
            <content:encoded><![CDATA[<p>Many organizations are using chats application for communication within a company, let’s say S<strong>lack</strong>. These communications might be regular announcements, individuals requesting access, or sharing credentials with each other in a group or individually in plaintext. The problem arises when the slack token of an individual gets leaked which leads to data breaches like: <br><a href="https://mashable.com/article/slack-key-to-twitter-hack">https://mashable.com/article/slack-key-to-twitter-hack</a><br><a href="https://www.vice.com/en/article/7kvkqb/how-ea-games-was-hacked-slack">https://www.vice.com/en/article/7kvkqb/how-ea-games-was-hacked-slack</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BNjWgWfqWQOR9Ui8kw_HXw.png" /></figure><h4>The Core Problem?</h4><p>The sensitive data shared with human beings, ideally should not be accessible to human users also instead of storing them in a file, you should use password managers, for example, <a href="https://bitwarden.com/">Bitwarden</a>, <a href="https://www.lastpass.com/">Lastpass</a>, etc &amp; be available for systems from a creds store.</p><p>Sometimes we use a third party to share the credentials instead what if we can use in-house tools to share it? Like deploying in-house <a href="https://privatebin.info/">PrivateBin</a> behind the VPN and using it to share credentials.</p><h4>Why PrivateBin?</h4><ul><li>It gives you the flexibility to adjust the validity of the link as per the user’s need (Even a one-time link)</li><li>Links can be password protected</li><li>It’s free and open source</li><li>It’s easy to use</li></ul><h4>Why should PrivateBin be behind the VPN?</h4><p>It is because only people having access to the VPN can access the link. If it is not behind a VPN anyone having the slack token can get the link and access it over the internet.</p><h4><a href="https://github.com/ankitsaini2609/slackDLP">Automating the entire solution</a></h4><p>User opening the PrivateBin and generating the link will be a lot of work for the user, What if the user sends the message and it can get replaced by the PrivateBin link 😍.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F14O2gyXKiVc&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D14O2gyXKiVc&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=google" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/3727a7aefe7174ec9a1e46ff56d8b629/href">https://medium.com/media/3727a7aefe7174ec9a1e46ff56d8b629/href</a></iframe><p>Let’s create a slack app and with the help of AWS Lambda(Scalability) and AWS API Gateway, we will achieve our goal.</p><h4>Architecture Diagram</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*svFgcnnXESQTtMuLmsv3OQ.png" /></figure><h4>Implementation Steps — Configuring Slack app:</h4><ul><li>Open the <a href="https://api.slack.com/apps">slack apps</a> link.</li><li>Click on <strong>Create New App</strong> in the top right corner.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JNPp0Zzy72IXM2JvcayRCQ.png" /></figure><ul><li>Click on <strong>From Scratch</strong>.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1012/1*NM1bealmE4HmTMJCzDuVoQ.png" /></figure><ul><li>Give the Slack App name and choose the workspace and click on Create App.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1008/1*xaqTjCw-RafwVGkNbgUzdw.png" /></figure><ul><li>Click on <strong>Oauth &amp; Permissions </strong>and scroll down to the scopes and add the below-given scopes in <strong>Bot Token Scopes and User Token Scopes</strong>:</li></ul><pre>channels:read<br>files:read<br>groups:read<br>im:read<br>links:read<br>mpim:read<br>remote_files:read<br>search:read<br>team:read<br>users:read<br>users:read.email<br>chat:write</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TnjzNeUZGdMdxONrny_eAQ.png" /></figure><ul><li>Click on <strong>Events subscriptions</strong> on the left pane and click on the toggle button to enable it.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dsLxzVJAw7k7ZsAuY2sDZw.png" /></figure><ul><li>You can see the Request URL, It is the URL where slack is going to send all the events. So Let’s create a URL with the help of AWS API Gateway and AWS Lambda function.</li></ul><h4>Configuring AWS API Gateway and AWS Lambda function</h4><ul><li>We are going to configure AWS API Gateway and going to associate a lambda function which will get invoked every time that API endpoint gets a hit. Login to your AWS account, Go to Lambda, and create one function with basic permissions.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1_CZXZP3FdaHYt8qCtkpqw.png" /></figure><ul><li>Fill in the function name and select runtime as python 3.8 then click on create function.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*c7w8M44Tv4u45tO5npBM3g.png" /></figure><ul><li>Copy the code of the <a href="https://github.com/ankitsaini2609/slackDLP">lambda_function.py</a> and paste it into the lambda function and upload the remaining two zip(pbincli.zip and slack-sdk.zip) files as layers.</li><li>Remember to set environment variables in your lambda. These variables are Slack signing secret, server(URL of the private bin, for example, <a href="https://privatebin.net/),">https://privatebin.net/),</a> and user slack token( to post the link in the chat). You can get the Signing secret by going to the basic information of your slack app and App credentials, you can get the signing secret.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Q4Ac2eVNEiPLU2fWYk1w2Q.png" /></figure><ul><li>Now click on the install app, on the left pane of the slack app. After installing you will get a user OAuth token. The environment variable in your lambda will look like this:</li></ul><pre>server = &lt;Your Server URL&gt;<br>SLACK_USER_TOKEN = &lt;User Oauth Token&gt;<br>SLACK_SIGNING_SECRET = &lt;Slack Signing Secret&gt;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/746/1*bGteAON-On5sr4AdFn-ddA.png" /></figure><ul><li><strong>Do not forget to increase the timeout of the lambda to 5 min.</strong></li><li>We have completed the setup of lambda, Let&#39;s create an API gateway and associate it to the lambda function. Go to the API Gateway and click on build.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ujxmNadlmL2X1b2fN4hnMg.png" /></figure><ul><li>Choose the integration as lambda, give it a name and click on <strong>review and create</strong> and then click on create.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VYT1z7L878SPq58fngbFeg.png" /></figure><ul><li>Now copy the Invoke URL and append the API name which you have given in the previous stage. It will look something like this:</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/902/1*w_MMvNcVkImKuS1j_Anv6w.png" /></figure><h4>Final Configuration in Slack Bot</h4><ul><li>Copy above URL and open the slack app, go to the <strong>Event subscription</strong> on the left pane, Click on the <strong>toggle</strong> and paste the URL in the <strong>request URL</strong> and wait until it does not show verified.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vzz58yIwFLjQORlnhZ6iUw.png" /></figure><ul><li>Click on <strong>Subscribe to events on behalf of the users </strong>and <strong>Subscribe to bot events </strong>and add the following OAuth permissions.</li></ul><pre><a href="https://api.slack.com/events/message.groups">message.groups</a><br><a href="https://api.slack.com/events/message.channels">message.channels</a></pre><ul><li>Click on save and reinstall the app by going to the <strong>Install app</strong> on the left pane and clicking on <strong>reinstall to the workspace</strong>.</li><li>All Set !!!</li></ul><h4>Verifying the Solution</h4><ul><li>Open your slack, Add the bot to a channel and try to post a secret in it.</li></ul><h4>Future Plans</h4><ul><li>The same Solution can be expanded for Microsoft Teams, Confluence, etc.</li></ul><p>Thank you for reading.</p><p>Thanks to <a href="https://in.linkedin.com/in/abhinav-chourasia-b0642639">Abhinav</a>, <a href="https://in.linkedin.com/in/priyalviroja">Priyal</a>, and <a href="https://in.linkedin.com/in/jeyanthinath">Jeyanthi</a> for your ideas and suggestions.</p><p>You can follow me on <a href="https://twitter.com/d3afh3av3n">Twitter</a>/<a href="https://linkedin.com/in/d3afh3av3n">LinkedIn</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7890e2b0bb8f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Master the Container Security — Container Registry]]></title>
            <link>https://medium.com/@ankitsaini2609/master-the-container-security-container-registry-db9f0054e462?source=rss-4f95bcfb6faf------2</link>
            <guid isPermaLink="false">https://medium.com/p/db9f0054e462</guid>
            <category><![CDATA[information-security]]></category>
            <category><![CDATA[docker-image]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[containers]]></category>
            <category><![CDATA[devsecops]]></category>
            <dc:creator><![CDATA[Ankit Saini(@d3afh3av3n)]]></dc:creator>
            <pubDate>Wed, 13 Jul 2022 14:52:02 GMT</pubDate>
            <atom:updated>2022-07-13T14:52:02.511Z</atom:updated>
            <content:encoded><![CDATA[<h3>Master the Container Security — Container Registry</h3><p>In this series of containers, we have learned <a href="https://systemweakness.com/master-the-container-security-overview-b845f2a33162">what containers are</a> and <a href="https://medium.com/@ankitsaini2609/master-the-container-security-security-aspect-93b535e1befd">how to run them securely</a>. What if, the base image you are using in a container is not secure in itself, then no matter how securely you are running the container, it will have some side effects. This blog will talk about the container registry (The place where we store container images) and the security measures around container images.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0BvhR5wfN5p25C6BYL8H0Q.png" /><figcaption>Container Registries</figcaption></figure><p>While using docker, container images play a very crucial role, so it is important to establish trust that the container image you are using is secure. There are a few methods using which it can be achieved:</p><ul><li>Private registry</li><li>Docker official container images</li><li>Content trust in Docker</li></ul><h3>Private Registry</h3><p>The Registry is a stateless, highly scalable server-side application that stores and lets you distribute Docker images, some examples of registries are <a href="https://goharbor.io/">Harbor</a>, <a href="https://hub.docker.com/">Dockerhub</a>, <a href="https://aws.amazon.com/ecr/">Amazon ECR</a>, etc. You can either use a private or public registry, but they have their pros and cons. In a public registry, anyone can upload a malicious image and it is up to the user to decide whether he wants to use it or not, that’s why it is very hard to establish trust in the case of a public registry. Meanwhile, private registries provide the flexibility to control who can push images and pull images. In addition, Role-based access control can be enforced to have granular control over users by specifying which department or environment a specific user has access to. The private registry provides various other features like:</p><ul><li><strong>Tag Immutability</strong>: By default, if you are uploading an image, it will be tagged as the <strong>latest</strong>. It might be possible that the developer forgets to put the tag in the image and uploads it so that it will override the image having the latest tag. To prevent these situations there is a feature called Tag Immutability where you cannot alter the tag by pushing, retagging, or replication.<br>It also prevents the image from accidental deletion.</li><li><strong>Vulnerability Scanning</strong>: There is a static vulnerability scanner available in private registries for example Trivy, Clair, etc. On the basis of the results, you can even block all the deployments which are using the vulnerable image. You can scan the images at the time of upload or you can schedule the scanner to scan them at a particular time.</li></ul><h3>Docker official container images</h3><p>You can use the images stored in the docker registry as well but before using it make sure to check whether it is an official image or not. If the below-given tags are present it means, they are trusted:</p><ul><li><strong>DOCKER OFFICIAL IMAGE</strong></li><li><strong>VERIFIED PUBLISHER</strong></li><li><strong>OPEN SOURCE PROGRAM</strong></li></ul><p>To check the tag refer to the below-given image:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-q9TTVHgV9XSw3X0T79V4Q.png" /></figure><h3>Content trust in Docker</h3><p>When transferring data among networked systems, <em>trust</em> is a central concern. In particular, when communicating over an untrusted medium such as the internet, it is critical to ensure the integrity and the publisher of all the data a system operates on. You use the Docker Engine to push and pull images (data) to a public or private registry. Content trust allows you to verify both the integrity and the publisher of all the data received from a registry over any channel.</p><p>The content trust provides the ability to use digital signatures to verify the integrity and authenticity of the image. It is possible that an image having one tag is signed and the same image having another tag is not signed. Each image has a particular set of keys using which publishers sign an image tag.</p><blockquote>In order to use content trust user must have <a href="https://github.com/notaryproject/notary">notary</a> installed with the registry.<br>Notary is a tool for publishing and managing trusted collections of content. Publishers can digitally sign collections and consumers can verify integrity and origin of content.</blockquote><p>Let’s refer to the below image to understand it better:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1rTfCI_K_BV6gMpp5wzhGQ.png" /><figcaption>Content trust mechanism</figcaption></figure><p>Using an offline key, we can generate the tagging keys which can be used to sign the images. Similarly, a timestamp key is generated on the server-side which is associated with the image repository. To know more you can read <a href="https://docs.docker.com/engine/security/trust/">this</a>.</p><p>This is about container registry, feel free to reach out to me if you have any doubts/queries.</p><p>Thank you for reading. <br>If you liked it follow me on Twitter: <a href="https://twitter.com/d3afh3av3n">d3afh3av3n</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=db9f0054e462" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Master the Container Security — Security Aspect]]></title>
            <link>https://medium.com/@ankitsaini2609/master-the-container-security-security-aspect-93b535e1befd?source=rss-4f95bcfb6faf------2</link>
            <guid isPermaLink="false">https://medium.com/p/93b535e1befd</guid>
            <category><![CDATA[information-security]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[containers]]></category>
            <category><![CDATA[docker]]></category>
            <category><![CDATA[container-security]]></category>
            <dc:creator><![CDATA[Ankit Saini(@d3afh3av3n)]]></dc:creator>
            <pubDate>Wed, 22 Jun 2022 14:59:56 GMT</pubDate>
            <atom:updated>2022-06-22T21:28:59.054Z</atom:updated>
            <content:encoded><![CDATA[<h3>Master the Container Security — Security Aspect</h3><p>If you are new to the containers, you can read my <a href="https://systemweakness.com/master-the-container-security-overview-b845f2a33162">previous blog</a> to get a glimpse of the container’s basics.</p><p>Organizations are shifting from a monolithic architecture to microservices to containers. While deploying a microservice, it is very important to keep in mind that the architecture of the machine in production should be the same as where you are developing your application because of dependencies and architecture issues. To avoid these issues containers come into the picture. Hence many organizations are using containers to deploy their production application which are dealing with databases, AWS S3 buckets, etc. It is very important to keep containers secure, It can be achieved by using various techniques which are:</p><ul><li>Control Groups (CGroups)</li><li>Docker Rootless</li><li>Docker Namespace</li><li>Kernel Capabilities</li><li>AppArmor</li><li>Seccomp profiles</li></ul><p>Let&#39;s get started …</p><h3>Control Groups(CGroups)</h3><p>By default, a container has no resource constraints and can use as much of a given resource. CGroups implement resource accounting and limiting. They provide various helpful metrics and ensure that each container will get its fair share of the resources(CPU, Memory, I/O, etc) so that, a single container cannot bring down the whole system by exhausting all the resources.</p><p>They are the Linux capabilities so it is important for your kernel to support these capabilities. You can confirm whether the kernel supports it or not by running the following command:</p><pre>docker info</pre><p>If you see the output given below in the image it means it is disabled.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IxLxmhYIFx9NfgxDTnIhsQ.png" /></figure><p>You can use -m (or --memory) and --cpus to restrict the memory and number of cpus. To know more, read <a href="https://docs.docker.com/config/containers/resource_constraints/">this</a>.</p><h3>Docker Rootless</h3><h4>Running container as a non-root user</h4><p>You can create a group and a user and include a username in the dockerfile. It is important because even if an attacker gets hold of a container he won’t be able to run commands as root. Remember you are running container as non-root but there are chances that docker daemon might be running as root.</p><pre>RUN groupadd -g 1000 someUser &amp;&amp; useradd -u 1000 -g 1000\<br>-d /usr/share/someUser -M someUser<br>USER someUser</pre><h4>Running docker daemon as a non-root user (Rootless mode)</h4><p><strong>Rootless mode</strong> allows you to run <strong>docker daemon and container</strong> as a <strong>non-root</strong> user. It uses user namespace to run both docker daemon and docker container. The rootless mode does not use binaries with SETUID bits or file capabilities, except <em>newuidmap</em> and <em>newgidmap</em>, which are needed to allow multiple UIDs/GIDs to be used in the user namespace. To know more, read <a href="https://docs.docker.com/engine/security/rootless/">this</a>.</p><h3>Docker Namespace</h3><p>The concept of a namespace is the same here as it is used in other contexts. So here you can achieve more isolation since containers in one namespace won’t be able to access the containers in other namespaces. In case of a breach in one namespace, if configured properly attacker won’t be able to access the container in other namespaces. In the Docker namespace, the docker daemon is running as root and containers as non-root. The process running inside the containers assumes that is running as root within the container and it happens because of user remapping within a namespace.</p><p>The remapping itself is handled by two files: /etc/subuid and /etc/subgid. Each file works the same, but one is concerned with the user ID range, and the other with the group ID range. Consider the following entry in /etc/subuid:</p><pre>testuser:231072:65536</pre><p>This means that testuser is assigned a subordinate user ID range of 231072 and the next 65536 integers in sequence. UID 231072 is mapped within the namespace (within the container, in this case) as UID 0 (root). UID 231073 is mapped as UID 1, and so forth. If a process attempts to escalate privilege outside of the namespace, the process is running as an unprivileged high-number UID on the host, which does not even map to a real user. This means the process has no privileges on the host system at all. To know more, read <a href="https://docs.docker.com/engine/security/userns-remap/">this</a>.</p><h3>Kernel Capabilities</h3><p>By default, docker restricts a lot of kernel capabilities within a container. For example, processes(like web servers) that just need to bind on a port below 1024 do not need to run as root: they can just be granted the net_bind_service capability instead. And there are many other capabilities, for almost all the specific areas where root privileges are usually needed. We can deny these capabilities so even if an intruder manages to escalate to root within a container, it is much harder to do serious damage or to escalate to the host.</p><h3>AppArmor</h3><p>AppArmor is a Mandatory Access Control(MAC) system that confines a program to a limited set of resources. We can create a security profile that can be loaded in the kernel and AppArmor can be set to either enforce the profile or complain when profile rules are violated.</p><blockquote>Difference between DAC (Discretionary access control)(LINUX, UNIX etc) and MAC(Mandatory Access Control)(AppArmor, SELinux etc)</blockquote><blockquote>With DAC, files and processes have owners. You can have the user own a file, a group own a file, or other, which can be anyone else. Users have the ability to change permissions on their own files. The root user has full access control with a DAC system. If you have root access, then you can access any other user’s files or do whatever you want on the system.</blockquote><blockquote>But on MAC systems like SELinux, there is administratively set policy around access. Even if the DAC settings on your home directory are changed, an SELinux policy in place to prevent another user or process from accessing the directory will keep the system safe.</blockquote><p>AppArmor profiles are simple text files. <strong>AppArmor profiles</strong> are <strong>default-deny</strong> by <strong>default, which </strong>means if you have not defined something in the policy file it means it is denied you cannot execute it inside the container. I have attached a sample profile for Nginx. You can run the Nginx container and load this profile and when you will try commands like ping, touch, sh, dash, etc it will not work as deny is set in the profile. To know more, read <a href="https://docs.docker.com/engine/security/apparmor/">this</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UGE0nUdvDli7iKJKdlq0ZA.png" /><figcaption>AppArmor profile for Nginx</figcaption></figure><h3>Seccomp profiles</h3><p>Secure computing mode (seccomp) is a Linux kernel feature. Like AppArmor, it is also used to restrict the actions available within the container. We create seccomp profiles and pass them to the container using --security-opt option with docker run command. Seccomp is used to block syscall. This feature is available only if Docker has been built seccomp and the kernel is configured with CONFIG_SECCOMP enabled. To check if your kernel supports seccomp run the below-given command:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/820/1*Y8Bw8sZFdZTphbDqExI6ug.png" /></figure><p>Like AppArmor seccomp profile is an allowlist that denies access to system calls by default, then allowlists specific system calls. To know more, read <a href="https://docs.docker.com/engine/security/seccomp/">this</a>.</p><p>Few extra key points …</p><ul><li>Do not expose /var/run/docker.sock file to the container. This socket file is used for container management like collecting the logs, creating containers, stopping them, running commands on it, etc.</li><li>Volume mounts as read-only.</li><li>Ensure the host network interface is not shared with the containers.</li><li>Do not mount system volumes like /etc, /dev etc.</li></ul><p>Thank you for reading and Keep following for the next blog in the Container series.<br>You can always reach out to me if you have any questions/queries. <br>If you liked it follow me on Twitter: <a href="https://twitter.com/d3afh3av3n">@d3afh3av3n</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=93b535e1befd" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Master the Container Security — Overview]]></title>
            <link>https://systemweakness.com/master-the-container-security-overview-b845f2a33162?source=rss-4f95bcfb6faf------2</link>
            <guid isPermaLink="false">https://medium.com/p/b845f2a33162</guid>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[container-security]]></category>
            <category><![CDATA[containers]]></category>
            <category><![CDATA[information-security]]></category>
            <category><![CDATA[docker]]></category>
            <dc:creator><![CDATA[Ankit Saini(@d3afh3av3n)]]></dc:creator>
            <pubDate>Thu, 09 Jun 2022 13:39:40 GMT</pubDate>
            <atom:updated>2022-06-15T14:17:13.160Z</atom:updated>
            <content:encoded><![CDATA[<h3>Master the Container Security — Overview</h3><p>This blog is going to tell you about the fundamentals of the container. It is a pre-requisite for my upcoming blog on <strong>container security</strong>. You all must have heard of docker. If not, <a href="https://docs.docker.com/get-started/overview/">Docker</a> is one of the means of building and running containers.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JdQ2DpZDDRMP0bx4rBeIpA.png" /><figcaption>Docker Architecture</figcaption></figure><h3>What are containers and why do we need them?</h3><p>Before the Container era, developers used to write the code and try to deploy it in a different environment and because of dependencies and architecture issues sometimes it runs and sometimes it’s not. You all have heard about “<strong>It worked on my machine</strong>”. So basically containers resolve these issues and many others. In containers, you pack your application and deploy it in any environment you want.</p><h3>Difference between VMs and Containers</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*THDS2WeIzR5ycVmJo87qvA.png" /><figcaption>VMs v/s Containers</figcaption></figure><p>As you can see in the above diagram in VMs we share the hardware, we delicately assign a portion of the memory and CPU to the VMs while containers are just a process that shares the operating system. Containers are limited to what resources can be accessed and exit when the process running inside them stops.<br>When you start a VM, it takes a significant amount of time in booting up because they are having its own OS, also they are big in size. On the other side, containers have a relatively lower size and can quickly spin up and start running.</p><h3>Important Component of the Docker</h3><ul><li><strong>Dockerfile: </strong>It is a simple file where you write instructions that are being executed by the docker client.</li><li><strong>Docker Image: </strong>It is a collection of app binaries and dependencies. It is neither a complete OS nor a Kernel. It can be as small as golang binary and as big as ubuntu distro. You build dockerfile(executing the instructions written in the dockerfile) and it creates a docker image(read-only template containing instructions for building a container). Each instruction written in the dockerfile is called a layer.</li><li><strong>Docker Container: </strong>When you run a docker image we call it a docker container.</li><li><strong>Container Registry: </strong>It is a place where you store container images.</li><li><strong>Docker Host: </strong>Host machine where we have installed docker.</li><li><strong>Docker Daemon: </strong>It is a process that runs on the host machine and facilitates docker client commands.</li></ul><h3>How to use docker client</h3><p>You can install the docker engine by following <a href="https://docs.docker.com/engine/install/">this</a> link.</p><p>Let’s get started …</p><p><strong>docker --help <br></strong>Most useful command, whenever you are stuck with any command just append --help in front of it, It will be a great savior.</p><p>Example:</p><p><strong>docker container --help</strong>: You can see it will show you all the commands which you can run on the container.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TPG_9MPZUFxZeQh6Wg4mTA.png" /></figure><p>Few key points …</p><ul><li>What is the difference between docker container run, docker container start, and docker container exec?<br><strong>the run</strong> will always start a new container.<br><strong>the start</strong> will start the existing stopped container.<br><strong>exec </strong>will execute the command inside the existing running container.</li><li>What is the difference between docker container top, docker container stats, and docker container inspect?<br><strong>the top </strong>will list the process in a container.<br><strong>stats </strong>will give us the live performance stats of the container(s).<br><strong>inspect </strong>will give us details of one container config. (metadata like config, volumes, networking, etc)</li><li>By default <strong>docker container ls </strong>will list only the running container so in order to get all the containers(running + stopped) use the <strong>-a </strong>option with it.</li><li>A container is just a single read/write layer on top of the image.</li></ul><p><strong>docker image --help: </strong>It will show you all the commands you can run on an image.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*R8ruAJQ96Uivu07CDeJdPA.png" /></figure><p>Few key points …</p><ul><li><strong>docker image history </strong>will show layers of changes made in an image.</li><li>Each layer will be stored only once in the host machine and can be uniquely identified. This saves the space on the host machine and transfers time on push/pull.</li><li>Image tagging is used to manage different versions of an image. You can create a custom tag, and re-tag an existing image.</li></ul><p>There are several other commands which you can explore like docker network, docker volume, docker system, docker secret, etc.</p><p>Thank you for reading. <br>You can always reach out to me if you have any questions/queries. <br>If you liked it follow me on Twitter: <a href="https://twitter.com/d3afh3av3n">@d3afh3av3n</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b845f2a33162" width="1" height="1" alt=""><hr><p><a href="https://systemweakness.com/master-the-container-security-overview-b845f2a33162">Master the Container Security — Overview</a> was originally published in <a href="https://systemweakness.com/">System Weakness</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Secure provisioning of LoadBalancer Services on Kubernetes using Kyverno]]></title>
            <link>https://lambda.blinkit.com/secure-provisioning-of-loadbalancer-services-on-kubernetes-using-kyverno-2cdf5e30d296?source=rss-4f95bcfb6faf------2</link>
            <guid isPermaLink="false">https://medium.com/p/2cdf5e30d296</guid>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[infrastructure]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <dc:creator><![CDATA[Ankit Saini(@d3afh3av3n)]]></dc:creator>
            <pubDate>Thu, 08 Jul 2021 08:06:51 GMT</pubDate>
            <atom:updated>2021-12-14T04:13:27.247Z</atom:updated>
            <content:encoded><![CDATA[<p>There are <a href="https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0">many ways</a> by which Kubernetes allows you to expose applications (pods) to users. At Blinkit (formerly Grofers), we like to allow our developers to do this without needing intervention from the DevOps team. We find ourselves using LoadBalancer type services often. At the same time, we also want to ensure our developers don’t end up introducing any new security risks while provisioning LoadBalancer services. In this post, we’ll talk about how we augment the default provisioning process of Kubernetes LoadBalancers to suit those needs.</p><p>At Blinkit, we follow the “You build it, you run it” philosophy. This means that developers deploy applications and provision services independently. This philosophy has enabled us to move fast but it comes with its own set of challenges. Case in point — Kubernetes LoadBalancers. When Kubernetes LoadBalancer are provisioned, they are public by default. As a developer, you can choose to override this configuration and declare your LoadBalancers as private by adding the <a href="https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/service/annotations/#lb-internal">”service.beta.kubernetes.io/aws-load-balancer-internal” annotation</a>. However, this creates an inherent risk. The security of our setup hinges on whether a developer decides to add this annotation every time they create a new service. Should a developer forget to add this annotation, they would end up exposing internal applications to the public network. We don’t want that.</p><p>We needed better safety nets, better security controls in our service provisioning process in Kubernetes.</p><h3>Policy Enforcement and Governance using Kyverno</h3><p>Kubernetes has an interesting concept of <a href="https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/">admission controllers</a> that can be used to intercept requests to Kuberenetes’ API server and decide whether they should be allowed. This kind of control pattern can be leveraged to enforce policies and govern your Kubernetes cluster. We started looking for frameworks that had been built for this purpose and arrived at <a href="https://kyverno.io/">Kyverno</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/844/0*ESYWiq8rRGthSxE2" /></figure><h4>What is Kyverno and how is it useful?</h4><p><a href="https://kyverno.io/docs/introduction/">Kyverno</a> is a policy engine designed for Kubernetes. It can validate, mutate, and generate configurations using admission controls and background scans. Kyverno policies are Kubernetes resources and do not require learning a new language. You can write policies declaratively. The policies themselves are objects in Kubernetes. Another, more popular, alternative to Kyverno that deserves a mention is <a href="https://www.openpolicyagent.org/">Open Policy Agent</a> (which we use as well) but it requires you to learn Rego — an OPA specific language — to implement policy logic.</p><p><strong>How do we use Kyverno for secure provisioning of Services?</strong></p><p>Let us refer back to our problem statement. Kyverno allows us to write a policy that makes sure that developers are not able to provision any public facing LoadBalancers. The policy instructs Kyverno to inspect all the incoming requests for the creation of a new Service object. These requests are then rejected if they don’t contain the annotation required to declare them as private. Ofcourse, there are cases when we genuinely want to expose certain services to the public internet. For this purpose, we maintain a whitelist of service in a <a href="https://kubernetes.io/docs/concepts/configuration/configmap/">configmap</a><strong> </strong>that our Kyverno policy can refer to while considering if the request should be allowed.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b4d8dce19c381aa87cbfb46c8b23214b/href">https://medium.com/media/b4d8dce19c381aa87cbfb46c8b23214b/href</a></iframe><p><strong>Note: </strong>To whitelist your load balancer, add an entry like <em>namespace/service_name</em>.</p><p>Let’s look at our policy specification line-by-line:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/26d8eed8755b18fae2995983ececae34/href">https://medium.com/media/26d8eed8755b18fae2995983ececae34/href</a></iframe><ul><li><strong>Line 2</strong>: You can see that it is a cluster policy which means it is going to be applied cluster-wide irrespective of the namespace.</li><li><strong>Line 6–7:</strong> These lines represent that this policy is going to be of an “enforced” nature which means that it will block any incoming resources which will violate this policy.</li><li><strong>Line 10–14</strong>: These lines make the policy fetch the values from a configmap named <em>allowed-elbs</em> from the <em>security</em> namespace and become aware of whitelisted services.</li><li><strong>Line 15–18:</strong> These lines make sure that the policy only acts upon incoming requests of type Service.</li><li><strong>Line 19–31:</strong> These lines consist of the core logic of blocking any incoming service if it matches all of the following conditions:<br>- The service is not annotated with the annotation <strong><em>service.beta.kubernetes.io/aws-load-balancer-internal</em></strong><em>.<br></em>- The service is of the type load balancer.<br>- The <strong><em>namespace/service_name</em></strong> is not present in the configmap of whitelisted services.</li></ul><p>As Kubernetes is deployed in organizations to enable more and more developers to deploy applications, governance, and security of Kubernetes clusters are becoming an area of concern. Writing policies for security and governance with Kyverno is easy and the barrier to entry is extremely low. We are looking at adopting Kyverno for more governance-related use-cases.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-xO0dSUvZe8xxRwdMqCiaA.gif" /></figure><h4><a href="https://www.linkedin.com/in/d3afh3av3n/">Ankit Saini</a> used to work as a Security Engineer at Blinkit. Follow him on <a href="https://twitter.com/d3afh3av3n">Twitter</a>.</h4><h4>We are hiring across <a href="https://grofers.careers/">various roles</a>! If you are interested in exploring working at Blinkit, we’d love to hear from you.</h4><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2cdf5e30d296" width="1" height="1" alt=""><hr><p><a href="https://lambda.blinkit.com/secure-provisioning-of-loadbalancer-services-on-kubernetes-using-kyverno-2cdf5e30d296">Secure provisioning of LoadBalancer Services on Kubernetes using Kyverno</a> was originally published in <a href="https://lambda.blinkit.com/">Lambda by Blinkit</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Protect your data: S3]]></title>
            <link>https://medium.com/@ankitsaini2609/protect-your-data-s3-3c49f3a22887?source=rss-4f95bcfb6faf------2</link>
            <guid isPermaLink="false">https://medium.com/p/3c49f3a22887</guid>
            <category><![CDATA[aws-s3]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[hacking]]></category>
            <category><![CDATA[bug-bounty]]></category>
            <category><![CDATA[security]]></category>
            <dc:creator><![CDATA[Ankit Saini(@d3afh3av3n)]]></dc:creator>
            <pubDate>Sun, 02 Aug 2020 15:31:38 GMT</pubDate>
            <atom:updated>2020-08-02T15:38:02.336Z</atom:updated>
            <content:encoded><![CDATA[<h3>Protect your data in S3</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-cN8M5EY5rYW6AX5InbKJQ.jpeg" /><figcaption>Just a bucket thing.</figcaption></figure><p>BUG! BUG! BUG!<br>We have seen many bugs related to AWS S3, for example,<a href="http://www.exfiltrated.com/research-Instagram-RCE.php"> Instagram Million dollar bug</a>, <a href="https://www.upguard.com/breaches/facebook-user-data-leak">Facebook data breach</a>, <a href="https://www.upguard.com/breaches/public-domain-how-configuration-information-for-the-worlds-largest-domain-name-registrar-was-exposed-online">Leak of GoDaddy trade secrets</a>, <a href="https://www.upguard.com/breaches/cloud-leak-chicago-voters">Voters database</a> Leak. As people started using AWS, Simple Storage Service(S3) is one of the essential services used to store data, and most of the time some credentials get leaked or because of some misconfiguration in the bucket policy results to a data breach. so here are some preventive measures which can be implemented to avoid such kind of scenarios up to some extent.</p><blockquote><strong><em>AWS Simple Storage Service(S3)</em></strong><em> is used to store and retrieve any amount of data, it is a highly scalable, reliable, fast, inexpensive data storage service and because of all these features, it is highly used. Each item that we store inside the bucket is called an object. We can apply policies around the object, bucket, and account where account level policy will always have high priority.</em></blockquote><p>A few days back I wrote a<strong> </strong><a href="https://github.com/ankitsaini2609/Revoke-unused-AWS-access-key"><strong>scrip</strong>t</a>, which revokes the AWS access keys after certain days of inactivity. The assets lying around that are not used and maintained are often the biggest sources of incidents as nobody is watching over them also it enforces the key rotation.</p><p><strong>Versioning: </strong>It is like storing multiple versions of the object in the same bucket. You can use versioning to retrieve, preserve, and restore the object. Using versioning you can recover the object even if it was deleted intentionally or unintentionally. You can enable versioning by going to the properties of the bucket.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/992/1*liSDAGR8pJm1b28VD1udAQ.png" /><figcaption>Versioning.</figcaption></figure><p><strong>Multi-Factor Authentication (MFA): </strong>It will help you to prevent the accidental deletion of the bucket. For now, It can be only enabled from CLI.<br>Only the <strong>root</strong> account can enable MFA. Run the below command to enable it:<br>aws s3api put-bucket-versioning --bucket &lt;yourbucket&gt; --versioning-configuration Status=Enabled,MFADelete=Enabled --mfa &quot;arn:aws:iam::&lt;account number&gt;:mfa/root-account-mfa-device &lt;mfa code&gt;&quot;.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/472/1*EMCw5-kt1TQ3Uii2NHK-7A.png" /><figcaption>Enabling MFA on the bucket.</figcaption></figure><p><strong>Allow only your infrastructure IPs: </strong>A Simple bucket policy that can be applied to allow your IPs to access a particular s3 bucket in your infrastructure.</p><pre>{<br>  &quot;Version&quot;: &quot;2012-10-17&quot;,<br>  &quot;Id&quot;: &quot;S3PolicyId1&quot;,<br>  &quot;Statement&quot;: [<br>    {<br>      &quot;Sid&quot;: &quot;IPAllow&quot;,<br>      &quot;Effect&quot;: &quot;Allow&quot;,<br>      &quot;Principal&quot;: &quot;*&quot;,<br>      &quot;Action&quot;: &quot;s3:*&quot;,<br>      &quot;Resource&quot;: &quot;arn:aws:s3:::somebucketname/*&quot;,<br>      &quot;Condition&quot;: {<br>        &quot;IpAddress&quot;: {<br>          &quot;aws:SourceIp&quot;: [<br>            &quot;X.X.X.X/X&quot;<br>          ]<br>        }<br>      }<br>    }<br>  ]<br>}</pre><p>By <strong>default</strong>, all S3 bucket objects are <strong>private</strong>.</p><p>You can always set the <strong>IAM Policies for a user</strong> who can access the bucket, or <strong>control</strong> the permissions on <strong>bucket level, </strong>or<strong> </strong>set the <strong>permission</strong> for a <strong>specific object</strong> as well. Enabling encryption is just another option.</p><h3>Lets set some monitoring…</h3><p><strong>AWS Config: </strong>It is used<strong> </strong>to assess, audit, and evaluate the configuration of AWS resources, you can setup config rule against your bucket to check for the public access. It will help you to detect any public bucket as soon as possible.</p><p><strong>Trusted Advisor: </strong>It is a tool provided by AWS for real-time guidance to provision your resources. There is one section related to <strong>AWS S3 bucket permissions </strong>which will tell you about the open-access permissions.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*W0A081iiFxSKJYqUq7aXcQ.png" /><figcaption>S3 permission analysis by AWS trusted advisor.</figcaption></figure><p>There are several other ways, using which you can quickly track if your bucket gets public and once it is detected. You can set lambda function to again change its visibility to private.</p><p>Thanks for reading!!<br>You can follow me on twitter: <a href="https://twitter.com/d3afh3av3n">@d3afh3av3n</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3c49f3a22887" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>