<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: DANISH AHMAD</title>
    <description>The latest articles on DEV Community by DANISH AHMAD (@danish_ahmad_bd75f47f787f).</description>
    <link>https://dev.to/danish_ahmad_bd75f47f787f</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4104810%2F4e6ae478-1731-4574-965c-af8bced0989f.jpg</url>
      <title>DEV Community: DANISH AHMAD</title>
      <link>https://dev.to/danish_ahmad_bd75f47f787f</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/danish_ahmad_bd75f47f787f"/>
    <language>en</language>
    <item>
      <title>A Security Scanner Is Easy. Building One You Can Actually Trust Is Not.</title>
      <dc:creator>DANISH AHMAD</dc:creator>
      <pubDate>Wed, 02 Sep 2026 16:49:06 +0000</pubDate>
      <link>https://dev.to/danish_ahmad_bd75f47f787f/a-security-scanner-is-easy-building-one-you-can-actually-trust-is-not-2m</link>
      <guid>https://dev.to/danish_ahmad_bd75f47f787f/a-security-scanner-is-easy-building-one-you-can-actually-trust-is-not-2m</guid>
      <description>&lt;h1&gt;
  
  
  A Security Scanner Is Easy. Building One You Can Actually Trust Is Not.
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;I set out to build a repository security analyzer in C++17 without third-party runtime dependencies. The interesting part wasn't detecting &lt;code&gt;system()&lt;/code&gt; or a hardcoded secret. It was turning a collection of scanners into one tool that could understand a repository, explain its risk, recommend what to do next, produce machine-readable reports, and fail a CI pipeline when the security policy was violated.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For a hackathon, it would have been easy to stop at:&lt;/p&gt;

&lt;p&gt;Found a vulnerability.&lt;/p&gt;

&lt;p&gt;I didn't want that.&lt;/p&gt;

&lt;p&gt;I wanted the output to answer:&lt;/p&gt;

&lt;p&gt;What is in this repository?&lt;br&gt;&lt;br&gt;
What is risky?&lt;br&gt;&lt;br&gt;
Where is it?&lt;br&gt;&lt;br&gt;
How serious is it?&lt;br&gt;&lt;br&gt;
What does it depend on?&lt;br&gt;&lt;br&gt;
What should I do about it?&lt;br&gt;&lt;br&gt;
Can another tool consume the result?&lt;br&gt;&lt;br&gt;
Can CI automatically reject it?&lt;/p&gt;

&lt;p&gt;That became &lt;strong&gt;RepoShield&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And the zero-dependency constraint made the implementation much more interesting.&lt;/p&gt;




&lt;h2&gt;
  
  
  The constraint
&lt;/h2&gt;

&lt;p&gt;The project had one constraint that influenced almost every architectural decision:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Build the core tool using C++17 and the standard library rather than relying on third-party runtime libraries.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That sounds simple until you list what a developer security tool actually needs.&lt;/p&gt;

&lt;p&gt;A repository analyzer needs to deal with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;filesystem traversal&lt;/li&gt;
&lt;li&gt;source-file discovery&lt;/li&gt;
&lt;li&gt;code structure&lt;/li&gt;
&lt;li&gt;security rules&lt;/li&gt;
&lt;li&gt;dependency analysis&lt;/li&gt;
&lt;li&gt;risk scoring&lt;/li&gt;
&lt;li&gt;report generation&lt;/li&gt;
&lt;li&gt;Git information&lt;/li&gt;
&lt;li&gt;remediation&lt;/li&gt;
&lt;li&gt;configuration&lt;/li&gt;
&lt;li&gt;CI integration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Normally, several of those problems are solved by installing a package.&lt;/p&gt;

&lt;p&gt;For RepoShield, I kept asking a different question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Do I actually need a dependency here, or do I need a small, well-defined piece of functionality?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That distinction shaped the project.&lt;/p&gt;




&lt;h1&gt;
  
  
  What RepoShield actually does
&lt;/h1&gt;

&lt;p&gt;RepoShield is a standalone C++17 CLI for repository intelligence and security analysis.&lt;/p&gt;

&lt;p&gt;The pipeline looks like this:&lt;/p&gt;

&lt;p&gt;Repository&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
File Discovery&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Repository Statistics + Code Lens + Dependency Analysis&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Security Analysis&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Risk Scoring&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Remediation + Reporting&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Policy Enforcement&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Exit 0 / 1&lt;/p&gt;

&lt;p&gt;The important thing is that these aren't independent commands pretending to be one product.&lt;/p&gt;

&lt;p&gt;The results flow through the system.&lt;/p&gt;




&lt;h1&gt;
  
  
  First problem: understanding the repository
&lt;/h1&gt;

&lt;p&gt;Before detecting security issues, RepoShield has to understand what it is looking at.&lt;/p&gt;

&lt;p&gt;The file scanner recursively walks the target repository using the C++17 filesystem facilities.&lt;/p&gt;

&lt;p&gt;From there, repository statistics are calculated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Files&lt;/li&gt;
&lt;li&gt;Source files&lt;/li&gt;
&lt;li&gt;Header files&lt;/li&gt;
&lt;li&gt;Total size&lt;/li&gt;
&lt;li&gt;Total lines&lt;/li&gt;
&lt;li&gt;Languages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That might sound like basic information.&lt;/p&gt;

&lt;p&gt;It is.&lt;/p&gt;

&lt;p&gt;And that is intentional.&lt;/p&gt;

&lt;p&gt;A security analyzer should not need a separate tool just to answer how large the repository is.&lt;/p&gt;




&lt;h1&gt;
  
  
  Code Lens: security tools shouldn't be blind to code structure
&lt;/h1&gt;

&lt;p&gt;The next question was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can we understand a little more than files and line numbers without building a complete compiler?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I didn't try to build a C++ compiler frontend.&lt;/p&gt;

&lt;p&gt;Instead, RepoShield's &lt;strong&gt;Code Lens&lt;/strong&gt; extracts useful structural information from the source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Includes&lt;/li&gt;
&lt;li&gt;Functions&lt;/li&gt;
&lt;li&gt;Classes&lt;/li&gt;
&lt;li&gt;Structs&lt;/li&gt;
&lt;li&gt;Function locations&lt;/li&gt;
&lt;li&gt;Function sizes&lt;/li&gt;
&lt;li&gt;Class method counts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A scan can produce information such as:&lt;/p&gt;

&lt;p&gt;FUNCTIONS&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;process&lt;/li&gt;
&lt;li&gt;calculate&lt;/li&gt;
&lt;li&gt;unsafeCopy&lt;/li&gt;
&lt;li&gt;executeCommand&lt;/li&gt;
&lt;li&gt;main&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CLASSES&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DemoProcessor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;STRUCTS&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UserInfo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is deliberately smaller than a full language parser.&lt;/p&gt;

&lt;p&gt;The goal isn't to understand every semantic detail of C++.&lt;/p&gt;

&lt;p&gt;The goal is to provide useful repository intelligence while keeping the tool lightweight.&lt;/p&gt;




&lt;h1&gt;
  
  
  Then comes the security analyzer
&lt;/h1&gt;

&lt;p&gt;This is where RepoShield becomes a security tool rather than a repository statistics program.&lt;/p&gt;

&lt;p&gt;The analyzer currently contains rules for several common security-sensitive patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RS001&lt;/strong&gt; — Unsafe C string function&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RS002&lt;/strong&gt; — Command execution detected&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RS003&lt;/strong&gt; — Possible hardcoded secret&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RS004&lt;/strong&gt; — Weak cryptographic algorithm&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RS005&lt;/strong&gt; — Potentially dangerous file operation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RS006&lt;/strong&gt; — Potential SQL injection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RS007&lt;/strong&gt; — Insecure random number generation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each finding carries information such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rule ID&lt;/li&gt;
&lt;li&gt;Severity&lt;/li&gt;
&lt;li&gt;File&lt;/li&gt;
&lt;li&gt;Line&lt;/li&gt;
&lt;li&gt;Title&lt;/li&gt;
&lt;li&gt;Description&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[RS001] Unsafe C string function&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Severity: HIGH&lt;br&gt;&lt;br&gt;
File: demo-target/vulnerable.cpp&lt;/p&gt;

&lt;p&gt;Another example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[RS003] Possible hardcoded secret&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Severity: CRITICAL&lt;br&gt;&lt;br&gt;
File: demo-target/vulnerable.cpp&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;A scanner saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Secret found.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;forces the developer to do the rest of the investigation.&lt;/p&gt;

&lt;p&gt;RepoShield tries to provide the context immediately.&lt;/p&gt;




&lt;h1&gt;
  
  
  The seven security issues
&lt;/h1&gt;

&lt;p&gt;The vulnerable demonstration repository intentionally contains examples for all seven security rules.&lt;/p&gt;

&lt;h3&gt;
  
  
  RS001 — Unsafe C String Function
&lt;/h3&gt;

&lt;p&gt;Unsafe C string operations can introduce buffer overflows when used incorrectly.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;strcpy(buffer, input);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;RepoShield reports:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[RS001] Unsafe C string function&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Severity: HIGH&lt;/p&gt;

&lt;h3&gt;
  
  
  RS002 — Command Execution
&lt;/h3&gt;

&lt;p&gt;The analyzer also detects command execution:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;std::system(command);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;RepoShield reports:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[RS002] Command execution detected&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Severity: HIGH&lt;/p&gt;

&lt;h3&gt;
  
  
  RS003 — Possible Hardcoded Secret
&lt;/h3&gt;

&lt;p&gt;Hardcoded credentials and API keys are another common problem.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const char* api_key = "sk_test_123456789abcdef";&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;RepoShield reports:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[RS003] Possible hardcoded secret&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Severity: CRITICAL&lt;/p&gt;

&lt;h3&gt;
  
  
  RS004 — Weak Cryptographic Algorithm
&lt;/h3&gt;

&lt;p&gt;RepoShield identifies references to weak cryptographic algorithms and reports:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[RS004] Weak cryptographic algorithm&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Severity: HIGH&lt;/p&gt;

&lt;h3&gt;
  
  
  RS005 — Potentially Dangerous File Operation
&lt;/h3&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;std::remove("important_file.txt");&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;RepoShield reports:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[RS005] Potentially dangerous file operation&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Severity: MEDIUM&lt;/p&gt;

&lt;h3&gt;
  
  
  RS006 — Potential SQL Injection
&lt;/h3&gt;

&lt;p&gt;RepoShield also looks for suspicious SQL construction patterns.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;std::string query = "SELECT * FROM users WHERE username = '" + username + "'";&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The scanner reports:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[RS006] Potential SQL injection&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Severity: HIGH&lt;/p&gt;

&lt;h3&gt;
  
  
  RS007 — Insecure Random Number Generation
&lt;/h3&gt;

&lt;p&gt;Finally, RepoShield checks for insecure random number generation patterns.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;std::rand();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The result:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[RS007] Insecure random number generation&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Severity: MEDIUM&lt;/p&gt;

&lt;p&gt;The seven rules cover different types of security-sensitive code and give the analyzer a broader security surface than a single vulnerability check.&lt;/p&gt;




&lt;h1&gt;
  
  
  A finding count is not a risk model
&lt;/h1&gt;

&lt;p&gt;One of the first things I didn't want to do was treat every finding equally.&lt;/p&gt;

&lt;p&gt;Imagine two repositories:&lt;/p&gt;

&lt;p&gt;Repository A&lt;br&gt;&lt;br&gt;
10 LOW findings&lt;/p&gt;

&lt;p&gt;Repository B&lt;br&gt;&lt;br&gt;
1 CRITICAL finding&lt;/p&gt;

&lt;p&gt;A raw issue count makes Repository A look worse.&lt;/p&gt;

&lt;p&gt;That doesn't make much security sense.&lt;/p&gt;

&lt;p&gt;So RepoShield has a risk-scoring layer that considers finding severity.&lt;/p&gt;

&lt;p&gt;The vulnerable demonstration repository produces:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Risk Level: CRITICAL&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Risk Score: 100 / 100&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Critical: 1&lt;br&gt;&lt;br&gt;
High: 4&lt;br&gt;&lt;br&gt;
Medium: 2&lt;br&gt;&lt;br&gt;
Low: 0&lt;/p&gt;

&lt;p&gt;The point isn't that &lt;code&gt;100/100&lt;/code&gt; is some universal security standard.&lt;/p&gt;

&lt;p&gt;It is RepoShield's own normalized risk model.&lt;/p&gt;

&lt;p&gt;The important architectural decision is separating:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Detection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;from:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Risk interpretation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That means security rules can identify problems while another component decides how those problems contribute to repository-level risk.&lt;/p&gt;




&lt;h1&gt;
  
  
  One vulnerable repository, seven findings
&lt;/h1&gt;

&lt;p&gt;I wanted the demo to prove that the rules weren't just theoretical.&lt;/p&gt;

&lt;p&gt;So I created an intentionally vulnerable target containing examples for &lt;strong&gt;all seven rules&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Running:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./reposhield analyze demo-target&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;produces:&lt;/p&gt;

&lt;p&gt;Issues found: 7&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[RS001] Unsafe C string function&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Severity: HIGH&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[RS002] Command execution detected&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Severity: HIGH&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[RS003] Possible hardcoded secret&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Severity: CRITICAL&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[RS004] Weak cryptographic algorithm&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Severity: HIGH&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[RS005] Potentially dangerous file operation&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Severity: MEDIUM&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[RS006] Potential SQL injection&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Severity: HIGH&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[RS007] Insecure random number generation&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Severity: MEDIUM&lt;/p&gt;

&lt;p&gt;This was one of the most important parts of the project.&lt;/p&gt;

&lt;p&gt;The demo isn't simply printing seven predefined messages.&lt;/p&gt;

&lt;p&gt;The vulnerable source contains patterns that the &lt;strong&gt;actual analyzer detects&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That makes the demonstration reproducible.&lt;/p&gt;

&lt;p&gt;The analyzer detects all seven configured security rules from the source code and then passes those findings to the risk-scoring and policy layers.&lt;/p&gt;




&lt;h1&gt;
  
  
  The supply-chain view
&lt;/h1&gt;

&lt;p&gt;Security isn't only about the code you wrote.&lt;/p&gt;

&lt;p&gt;It is also about what the code depends on.&lt;/p&gt;

&lt;p&gt;RepoShield therefore analyzes source-level dependencies.&lt;/p&gt;

&lt;p&gt;For example, a repository can expose dependencies such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;[STANDARD] cstring&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[STANDARD] cstdlib&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[STANDARD] iostream&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[STANDARD] cstdio&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[STANDARD] string&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[EXTERNAL] openssl/sha.h&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This creates an important distinction.&lt;/p&gt;

&lt;p&gt;RepoShield itself can be built around the C++17 standard library while still analyzing repositories that use external dependencies.&lt;/p&gt;

&lt;p&gt;The dependency analyzer is describing the &lt;strong&gt;target repository's dependency surface&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It isn't importing those dependencies into RepoShield.&lt;/p&gt;




&lt;h1&gt;
  
  
  Turning dependencies into a graph
&lt;/h1&gt;

&lt;p&gt;Once dependency relationships existed as data, representing them as a graph became straightforward.&lt;/p&gt;

&lt;p&gt;The same repository can be represented as:&lt;/p&gt;

&lt;p&gt;demo-target/vulnerable.cpp&lt;br&gt;&lt;br&gt;
├── [STANDARD] cstring&lt;br&gt;&lt;br&gt;
├── [STANDARD] cstdlib&lt;br&gt;&lt;br&gt;
├── [STANDARD] iostream&lt;br&gt;&lt;br&gt;
├── [STANDARD] cstdio&lt;br&gt;&lt;br&gt;
├── [STANDARD] string&lt;br&gt;&lt;br&gt;
└── [EXTERNAL] openssl/sha.h&lt;/p&gt;

&lt;p&gt;The graph isn't there just to look impressive in a terminal.&lt;/p&gt;

&lt;p&gt;It gives the dependency analysis a structure that can later be consumed by other reporting or visualization layers.&lt;/p&gt;

&lt;p&gt;The underlying lesson was simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Design the data model before deciding which library should represent it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  Detection without remediation is only half a workflow
&lt;/h1&gt;

&lt;p&gt;At this point, RepoShield could tell me what was wrong.&lt;/p&gt;

&lt;p&gt;But the next question was obvious:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What should the developer do now?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So security findings can be mapped to remediation guidance.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[RS001] Unsafe C string function&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Recommendation:&lt;/p&gt;

&lt;p&gt;Prefer bounds-checked string handling or safer C++ string operations and validate input sizes.&lt;/p&gt;

&lt;p&gt;For command execution:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[RS002] Command execution detected&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Recommendation:&lt;/p&gt;

&lt;p&gt;Avoid executing untrusted input through &lt;code&gt;system()&lt;/code&gt;. Validate input and prefer a strictly controlled command interface or allowlist.&lt;/p&gt;

&lt;p&gt;For the hardcoded-secret rule:&lt;/p&gt;

&lt;p&gt;Remove credentials from source code. Store secrets in environment variables or a dedicated secret-management mechanism.&lt;/p&gt;

&lt;p&gt;The intended flow became:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Detect → Explain → Recommend&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;rather than simply:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Detect&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Automatic remediation
&lt;/h1&gt;

&lt;p&gt;RepoShield also contains a remediation engine for supported automatic fixes.&lt;/p&gt;

&lt;p&gt;The CLI exposes two modes.&lt;/p&gt;

&lt;p&gt;Apply supported fixes:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./reposhield fix ./demo-target&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Preview them first:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./reposhield fix ./demo-target --dry-run&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The second mode is important.&lt;/p&gt;

&lt;p&gt;Automatic source modification is powerful, but it should not mean:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Run the tool and hope."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Dry-run gives the developer a safety boundary:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Analyze → Identify fix → Preview → Developer decides → Apply&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For the current implementation, automatic remediation is intentionally limited to supported rules rather than pretending every security issue can safely be fixed automatically.&lt;/p&gt;

&lt;p&gt;That limitation is deliberate.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why JSON wasn't enough
&lt;/h1&gt;

&lt;p&gt;Terminal output is useful for a human.&lt;/p&gt;

&lt;p&gt;CI systems don't want to scrape terminal text.&lt;/p&gt;

&lt;p&gt;Other tools don't want to parse:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Risk Level: CRITICAL&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;from a console.&lt;/p&gt;

&lt;p&gt;So RepoShield supports machine-readable reports.&lt;/p&gt;

&lt;p&gt;JSON:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./reposhield analyze ./my-project --json report.json&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;SARIF:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./reposhield analyze ./my-project --sarif report.sarif&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The SARIF output is especially useful because security tooling needs a standardized way to communicate findings to other developer and code-scanning systems.&lt;/p&gt;

&lt;p&gt;The important part of the implementation was not building a general-purpose serialization framework.&lt;/p&gt;

&lt;p&gt;It was implementing the report structures RepoShield actually needs.&lt;/p&gt;




&lt;h1&gt;
  
  
  Git intelligence without turning Git into a hard dependency
&lt;/h1&gt;

&lt;p&gt;Repository analysis also becomes more useful when the tool understands the repository's Git state.&lt;/p&gt;

&lt;p&gt;RepoShield has a separate:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./reposhield git ./my-project&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;command.&lt;/p&gt;

&lt;p&gt;It can report:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Current branch&lt;/li&gt;
&lt;li&gt;Repository status&lt;/li&gt;
&lt;li&gt;Clean / dirty state&lt;/li&gt;
&lt;li&gt;Tracked files&lt;/li&gt;
&lt;li&gt;Modified files&lt;/li&gt;
&lt;li&gt;Staged files&lt;/li&gt;
&lt;li&gt;Untracked files&lt;/li&gt;
&lt;li&gt;Commit count&lt;/li&gt;
&lt;li&gt;Latest commit information&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Git is therefore an intelligence layer rather than a requirement for the core repository scanner.&lt;/p&gt;

&lt;p&gt;A non-Git directory can still be analyzed.&lt;/p&gt;

&lt;p&gt;If Git information exists, RepoShield can use it.&lt;/p&gt;

&lt;p&gt;That separation was important because I didn't want Git functionality to define the entire application architecture.&lt;/p&gt;




&lt;h1&gt;
  
  
  The feature that turns a scanner into a CI gate
&lt;/h1&gt;

&lt;p&gt;This was one of the most important pieces.&lt;/p&gt;

&lt;p&gt;Suppose a repository contains a critical security issue.&lt;/p&gt;

&lt;p&gt;Printing:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Risk Level: CRITICAL&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;doesn't automatically stop anything.&lt;/p&gt;

&lt;p&gt;A CI system needs a machine-readable result.&lt;/p&gt;

&lt;p&gt;RepoShield therefore uses meaningful exit codes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;0&lt;/strong&gt; → analysis completed successfully and policy passed&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1&lt;/strong&gt; → analysis error or configured security policy violation&lt;/p&gt;

&lt;p&gt;The resulting workflow is:&lt;/p&gt;

&lt;p&gt;Repository&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
RepoShield analyze&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Security Analysis&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Policy Evaluation&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
PASS → Exit 0 → Continue&lt;br&gt;&lt;br&gt;
or&lt;br&gt;&lt;br&gt;
FAIL → Exit 1 → Stop&lt;/p&gt;

&lt;p&gt;This changes RepoShield from:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"a command that prints security findings"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;into:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"a command that can participate in an automated security gate."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is a much more useful property for a developer tool.&lt;/p&gt;




&lt;h1&gt;
  
  
  Configuration makes the result enforceable
&lt;/h1&gt;

&lt;p&gt;The policy layer allows the project to decide which findings should cause the command to fail.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;security: fail_on: [CRITICAL, HIGH]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That means security analysis and policy enforcement remain separate concepts.&lt;/p&gt;

&lt;p&gt;A finding can exist.&lt;/p&gt;

&lt;p&gt;The risk engine can classify it.&lt;/p&gt;

&lt;p&gt;The policy engine can then decide whether it should block the workflow.&lt;/p&gt;

&lt;p&gt;The vulnerable demonstration repository therefore fails the configured policy:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security Policy: FAILED&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Exit Code: 1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A clean repository can pass:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security Policy: PASSED&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Exit Code: 0&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This makes the analyzer useful in automated workflows rather than only during local inspection.&lt;/p&gt;




&lt;h1&gt;
  
  
  The CLI became the integration point
&lt;/h1&gt;

&lt;p&gt;Instead of exposing a collection of unrelated executables, RepoShield uses one interface:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./reposhield analyze &amp;lt;path&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./reposhield fix &amp;lt;path&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./reposhield git &amp;lt;path&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With options such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--json &amp;lt;file&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--sarif &amp;lt;file&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--dry-run&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--help&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The help system is also command-aware:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./reposhield --help&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./reposhield analyze --help&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./reposhield fix --help&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./reposhield git --help&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This sounds like a small detail.&lt;/p&gt;

&lt;p&gt;It isn't.&lt;/p&gt;

&lt;p&gt;Developer tools live or die by how quickly someone can understand their interface.&lt;/p&gt;

&lt;p&gt;A technically powerful scanner with a confusing CLI is still a painful tool.&lt;/p&gt;




&lt;h1&gt;
  
  
  What the final architecture looks like
&lt;/h1&gt;

&lt;p&gt;The implementation is split into focused components:&lt;/p&gt;

&lt;p&gt;src/&lt;br&gt;&lt;br&gt;
├── core/&lt;br&gt;&lt;br&gt;
│   ├── FileScanner&lt;br&gt;&lt;br&gt;
│   └── RepositoryStats&lt;br&gt;&lt;br&gt;
│&lt;br&gt;&lt;br&gt;
├── codelens/&lt;br&gt;&lt;br&gt;
│   └── CodeLens&lt;br&gt;&lt;br&gt;
│&lt;br&gt;&lt;br&gt;
├── security/&lt;br&gt;&lt;br&gt;
│   └── SecurityAnalyzer&lt;br&gt;&lt;br&gt;
│&lt;br&gt;&lt;br&gt;
├── supplychain/&lt;br&gt;&lt;br&gt;
│   └── DependencyAnalyzer&lt;br&gt;&lt;br&gt;
│&lt;br&gt;&lt;br&gt;
├── graph/&lt;br&gt;&lt;br&gt;
│   └── DependencyGraph&lt;br&gt;&lt;br&gt;
│&lt;br&gt;&lt;br&gt;
├── risk/&lt;br&gt;&lt;br&gt;
│   └── RiskScorer&lt;br&gt;&lt;br&gt;
│&lt;br&gt;&lt;br&gt;
├── remediation/&lt;br&gt;&lt;br&gt;
│   └── RemediationEngine&lt;br&gt;&lt;br&gt;
│&lt;br&gt;&lt;br&gt;
├── reporting/&lt;br&gt;&lt;br&gt;
│   ├── HealthReport&lt;br&gt;&lt;br&gt;
│   ├── JsonReport&lt;br&gt;&lt;br&gt;
│   └── SarifReport&lt;br&gt;&lt;br&gt;
│&lt;br&gt;&lt;br&gt;
├── git/&lt;br&gt;&lt;br&gt;
│   └── GitAnalyzer&lt;br&gt;&lt;br&gt;
│&lt;br&gt;&lt;br&gt;
└── config/&lt;br&gt;&lt;br&gt;
    └── Config&lt;/p&gt;

&lt;p&gt;The architecture is intentionally modular.&lt;/p&gt;

&lt;p&gt;The file scanner doesn't need to know how security rules work.&lt;/p&gt;

&lt;p&gt;The security analyzer doesn't need to know how SARIF is written.&lt;/p&gt;

&lt;p&gt;The risk scorer doesn't need to know how files were discovered.&lt;/p&gt;

&lt;p&gt;The Git analyzer doesn't need to be involved in source scanning.&lt;/p&gt;

&lt;p&gt;That separation made it possible to keep adding capabilities without turning &lt;code&gt;main.cpp&lt;/code&gt; into the entire application.&lt;/p&gt;




&lt;h1&gt;
  
  
  What was actually difficult
&lt;/h1&gt;

&lt;p&gt;The most difficult part wasn't writing individual detection rules.&lt;/p&gt;

&lt;p&gt;A rule such as:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Find system()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;is relatively straightforward.&lt;/p&gt;

&lt;p&gt;The harder problem is everything around it.&lt;/p&gt;

&lt;p&gt;A useful security finding needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reliable location&lt;/li&gt;
&lt;li&gt;Correct rule ID&lt;/li&gt;
&lt;li&gt;Severity&lt;/li&gt;
&lt;li&gt;Description&lt;/li&gt;
&lt;li&gt;Remediation&lt;/li&gt;
&lt;li&gt;Risk contribution&lt;/li&gt;
&lt;li&gt;Report representation&lt;/li&gt;
&lt;li&gt;Policy behaviour&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And those representations have to remain consistent.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;SecurityAnalyzer&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
SecurityIssue&lt;br&gt;&lt;br&gt;
├── Risk&lt;br&gt;&lt;br&gt;
├── Remediation&lt;br&gt;&lt;br&gt;
└── Reports&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Policy&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Exit status&lt;/p&gt;

&lt;p&gt;That's where a collection of features becomes a system.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why pattern-based analysis needs honesty
&lt;/h1&gt;

&lt;p&gt;One of the biggest lessons was that detecting a pattern isn't the same as proving a vulnerability.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;std::system(...)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;is security-sensitive.&lt;/p&gt;

&lt;p&gt;But its presence alone doesn't prove exploitation.&lt;/p&gt;

&lt;p&gt;The same applies to:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;std::remove(...)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;or a string that looks like an API key.&lt;/p&gt;

&lt;p&gt;That's why RepoShield's findings use language such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Possible hardcoded secret&lt;/li&gt;
&lt;li&gt;Potential SQL injection&lt;/li&gt;
&lt;li&gt;Potentially dangerous file operation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;rather than pretending a lightweight pattern-based analyzer has the same certainty as a full semantic analysis engine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Useful warnings are better than false certainty.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Why I didn't try to make it an AI security scanner
&lt;/h1&gt;

&lt;p&gt;AI is everywhere in hackathon projects.&lt;/p&gt;

&lt;p&gt;That made one design decision relatively easy:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I didn't want RepoShield's core value proposition to be "ask an AI whether your repository is secure."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Security analysis needs deterministic behaviour that a developer can inspect.&lt;/p&gt;

&lt;p&gt;A rule such as:&lt;/p&gt;

&lt;p&gt;RS003&lt;br&gt;&lt;br&gt;
Possible hardcoded secret&lt;br&gt;&lt;br&gt;
File: vulnerable.cpp&lt;br&gt;&lt;br&gt;
Line: 42&lt;/p&gt;

&lt;p&gt;can be reproduced.&lt;/p&gt;

&lt;p&gt;The risk calculation can be inspected.&lt;/p&gt;

&lt;p&gt;The exit code can be tested.&lt;/p&gt;

&lt;p&gt;The SARIF output can be consumed by another tool.&lt;/p&gt;

&lt;p&gt;The remediation rule can be reviewed.&lt;/p&gt;

&lt;p&gt;AI can help during development, but the final security decision shouldn't depend on a model improvising an answer every time the repository changes.&lt;/p&gt;

&lt;p&gt;That was the direction I wanted for RepoShield:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;deterministic analysis first, automation around it second.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  What the zero-dependency constraint taught me
&lt;/h1&gt;

&lt;p&gt;The biggest lesson wasn't:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Third-party libraries are bad."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They aren't.&lt;/p&gt;

&lt;p&gt;Libraries exist because rebuilding mature functionality can be wasteful.&lt;/p&gt;

&lt;p&gt;The lesson was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Understand the abstraction before deciding you need the abstraction.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;C++17 already gives a lot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;std::filesystem&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;std::string&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;std::vector&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;std::map&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;std::fstream&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;std::algorithm&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;std::iostream&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those primitives are enough to build surprisingly capable developer tooling.&lt;/p&gt;

&lt;p&gt;The difficult part is designing the system around them.&lt;/p&gt;




&lt;h1&gt;
  
  
  What I would normally install
&lt;/h1&gt;

&lt;p&gt;If I weren't working under the zero-dependency constraint, I would likely reach for established libraries and frameworks for several pieces of this project.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON libraries for structured serialization&lt;/li&gt;
&lt;li&gt;YAML libraries for configuration&lt;/li&gt;
&lt;li&gt;CLI parsing libraries&lt;/li&gt;
&lt;li&gt;C++ parsing or AST libraries&lt;/li&gt;
&lt;li&gt;Existing security-analysis frameworks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But replacing those conveniences forced me to implement the integration myself.&lt;/p&gt;

&lt;p&gt;That meant dealing with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Parsing&lt;/li&gt;
&lt;li&gt;Escaping&lt;/li&gt;
&lt;li&gt;File traversal&lt;/li&gt;
&lt;li&gt;Structured output&lt;/li&gt;
&lt;li&gt;Configuration&lt;/li&gt;
&lt;li&gt;Command-line arguments&lt;/li&gt;
&lt;li&gt;Security rules&lt;/li&gt;
&lt;li&gt;Error handling&lt;/li&gt;
&lt;li&gt;CI integration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result isn't that standard-library-only is always better.&lt;/p&gt;

&lt;p&gt;The result is that I now understand much more clearly &lt;strong&gt;what those dependencies were actually doing for me&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  What I would improve next
&lt;/h1&gt;

&lt;p&gt;RepoShield is intentionally not pretending to be a replacement for every mature security platform.&lt;/p&gt;

&lt;p&gt;There are obvious areas for future work.&lt;/p&gt;

&lt;h3&gt;
  
  
  More precise language analysis
&lt;/h3&gt;

&lt;p&gt;The current Code Lens and security analysis are intentionally lightweight.&lt;/p&gt;

&lt;p&gt;A full AST-based analysis engine would provide much deeper semantic understanding.&lt;/p&gt;

&lt;h3&gt;
  
  
  More security rules
&lt;/h3&gt;

&lt;p&gt;The current rules cover several useful categories, but a production security analyzer would need a substantially broader rule set.&lt;/p&gt;

&lt;h3&gt;
  
  
  Better dependency resolution
&lt;/h3&gt;

&lt;p&gt;Source-level includes are useful, but package manifests and resolved dependency versions would provide a deeper software supply-chain picture.&lt;/p&gt;

&lt;h3&gt;
  
  
  More remediation rules
&lt;/h3&gt;

&lt;p&gt;Automatic fixes should remain conservative.&lt;/p&gt;

&lt;p&gt;The right direction is to add more fixes only where the transformation can be made predictable and reviewable.&lt;/p&gt;

&lt;h3&gt;
  
  
  More testing
&lt;/h3&gt;

&lt;p&gt;The next stage would be broader regression and adversarial testing across every analyzer and report format.&lt;/p&gt;

&lt;p&gt;These aren't hidden gaps.&lt;/p&gt;

&lt;p&gt;They're the next engineering milestones.&lt;/p&gt;




&lt;h1&gt;
  
  
  The thing I would not change
&lt;/h1&gt;

&lt;p&gt;I would keep the separation between:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Detection&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Risk&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Reporting&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Policy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;because that separation is what lets RepoShield behave like a toolchain instead of one giant scanner function.&lt;/p&gt;

&lt;p&gt;A security finding can be:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;detected&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;without automatically being:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;blocking&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A recommendation can exist without automatically modifying the source.&lt;/p&gt;

&lt;p&gt;A report can exist without being the same thing as terminal output.&lt;/p&gt;

&lt;p&gt;Those distinctions seem small.&lt;/p&gt;

&lt;p&gt;They are what make the system composable.&lt;/p&gt;




&lt;h1&gt;
  
  
  The final result
&lt;/h1&gt;

&lt;p&gt;RepoShield started with a fairly simple question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Can a standalone C++17 program provide useful repository security intelligence without depending on a third-party C++ runtime ecosystem?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The answer became:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Yes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But the more interesting result was everything around that answer.&lt;/p&gt;

&lt;p&gt;RepoShield can now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scan repository files&lt;/li&gt;
&lt;li&gt;calculate repository statistics&lt;/li&gt;
&lt;li&gt;identify code structure&lt;/li&gt;
&lt;li&gt;detect &lt;strong&gt;7 security issues&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;classify severity&lt;/li&gt;
&lt;li&gt;calculate repository risk&lt;/li&gt;
&lt;li&gt;analyze dependencies&lt;/li&gt;
&lt;li&gt;build dependency graphs&lt;/li&gt;
&lt;li&gt;generate remediation guidance&lt;/li&gt;
&lt;li&gt;apply supported automatic fixes&lt;/li&gt;
&lt;li&gt;preview fixes with dry-run mode&lt;/li&gt;
&lt;li&gt;inspect Git repositories&lt;/li&gt;
&lt;li&gt;generate JSON reports&lt;/li&gt;
&lt;li&gt;generate SARIF reports&lt;/li&gt;
&lt;li&gt;enforce configurable security policies&lt;/li&gt;
&lt;li&gt;return meaningful CI exit codes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All through one CLI.&lt;/p&gt;

&lt;p&gt;Discover&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Understand&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Detect&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Score&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Remediate&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Report&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Enforce&lt;/p&gt;

&lt;p&gt;That's the part I care about most.&lt;/p&gt;

&lt;p&gt;I didn't want to build another command that says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"You have 7 security issues."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I wanted to build something that could answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Here is what I found, here is why it matters, here is where it is, here is what you can do about it, here is the machine-readable result, and here is whether your security policy allows this repository to continue."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  One final lesson
&lt;/h1&gt;

&lt;p&gt;The zero-dependency constraint initially looked like a restriction.&lt;/p&gt;

&lt;p&gt;It turned out to be an architectural forcing function.&lt;/p&gt;

&lt;p&gt;Every time I wanted to reach for a library, I had to define the actual problem first.&lt;/p&gt;

&lt;p&gt;Sometimes the answer would have been:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Yes, use a library."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But sometimes it was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We only need 5% of what that library provides."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And that second answer is where RepoShield became interesting.&lt;/p&gt;

&lt;p&gt;The real challenge wasn't removing dependencies.&lt;/p&gt;

&lt;p&gt;It was &lt;strong&gt;owning the pieces of the security workflow that actually mattered.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And that is what I ended up building.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try RepoShield
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/Danish84295/reposhield-hackathon" rel="noopener noreferrer"&gt;https://github.com/Danish84295/reposhield-hackathon&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo:&lt;/strong&gt; &lt;a href="https://www.youtube.com/watch?v=Y0PwYIm7sYM&amp;amp;t=6s" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=Y0PwYIm7sYM&amp;amp;t=6s&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./reposhield analyze ./my-project&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Generate JSON:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./reposhield analyze ./my-project --json report.json&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Generate SARIF:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./reposhield analyze ./my-project --sarif report.sarif&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Preview remediation:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./reposhield fix ./my-project --dry-run&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Inspect Git intelligence:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./reposhield git ./my-project&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Built with
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;C++17&lt;/li&gt;
&lt;li&gt;Standard C++ library&lt;/li&gt;
&lt;li&gt;Filesystem analysis&lt;/li&gt;
&lt;li&gt;Static security rules&lt;/li&gt;
&lt;li&gt;Risk scoring&lt;/li&gt;
&lt;li&gt;Dependency analysis&lt;/li&gt;
&lt;li&gt;Git intelligence&lt;/li&gt;
&lt;li&gt;JSON reporting&lt;/li&gt;
&lt;li&gt;SARIF reporting&lt;/li&gt;
&lt;li&gt;Configurable security policies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No third-party C++ runtime dependency is required by RepoShield's core implementation.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;If you're building developer tooling, I'd love to hear what you would make if "just install a package" wasn't an option.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>programming</category>
      <category>security</category>
      <category>softwareengineering</category>
    </item>
  </channel>
</rss>
