Skip to content

Instantly share code, notes, and snippets.

@DocGreenRob
Last active December 24, 2025 04:19
Show Gist options
  • Select an option

  • Save DocGreenRob/a7f08d56bae684f7f00583f446c27e8a to your computer and use it in GitHub Desktop.

Select an option

Save DocGreenRob/a7f08d56bae684f7f00583f446c27e8a to your computer and use it in GitHub Desktop.
.Net Engineer Pro Tools
Windows Pro Tips
-----------------
powertoys - https://apps.microsoft.com/store/detail/microsoft-powertoys/XP89DCGQ3K6VLD
devtoys - https://apps.microsoft.com/store/detail/devtoys/9PGCV4V3BK4W
Visual Studio 2022 Pro Tips
---------------------------
vscoloroutput - https://marketplace.visualstudio.com/items?itemName=MikeWard-AnnArbor.VSColorOutput
solutionColor - https://marketplace.visualstudio.com/items?itemName=Wumpf.SolutionColor
save vs settings to apply to other computer - https://learn.microsoft.com/en-us/visualstudio/install/import-export-installation-configurations?view=vs-2022
Podcasts
--------
Dev interrupted
Hacking Humans
Cyber Security Headlines
Click Here
Malicious Life
The Stack Overflow Podcast
The Backend Engineering (with Hussein Nasser)
The Changelog: Software Development, Open Source
Tech Stuff
Cyberwire Daily
Techmeme Ride Home
Soft Skills Engineering
Syntax - Tasty Web Development Treats
Cyber Security Today
Software Engineering Daily
Developer Tea
Coding Blocks .NET
The Cloud Cast
JS Party: Javascript, CSS, Web Development
Go Time: Golang, Software Engineering
Cyber
Dev Questions with Tim Corey
Thoughtworks Technology Podcast
.NET Rocks!
Smashing Security
Hanselminutes with Scott Hanselman
Software Engineering
Talk Python To Me
Security Now
Darknet Diaries
Hacked
The .NET Core Podcast
The .NET MAUI Podcast
Kubernetes Podcast from Google
Adventures in .NET
Coding After Work
Base.cs Podcast
The Static Void Podcast
Tools
------
couchbase
honeycomb.io/changelog
firehydrant
logrocket
playwright
openmct
thundra.io
raygun
fly.io
appwrite
sentry.io
https://sourcegraph.com/
https://www.kolide.com/
https://entity.services/
WeekPlan
Docker Extensions
------------------
Ddosify - High-performance load testing tool
- https://github.com/ddosify/ddosify
BurpSuite
- https://portswigger.net/burp
- https://danaepp.com/
VS Tips
--------
Extract method from selected code
- Ctrl + R + M
Ctrl + K + D
Ctrl + R + G
Ctrl + M + Z (Code Maid)
Important
----------
ApplicationInsights SamplingSettings for AzFn
- https://learn.microsoft.com/en-us/azure/azure-functions/functions-host-json
Design Patterns in C#
- https://www.dofactory.com/net/factory-method-design-pattern
- https://github.com/DovAmir/awesome-design-patterns?utm_source=programmingdigest&utm_medium&utm_campaign=1493
Shopify Query
- https://shopify.engineering/reducing-bigquery-costs?utm_source=programmingdigest&utm_medium&utm_campaign=1403
Building Own Operating System
- https://o-oconnell.github.io/2023/01/12/p1os.html?utm_source=programmingdigest&utm_medium&utm_campaign=1493
Debugging Linq
- https://www.red-gate.com/simple-talk/development/dotnet-development/linq-secrets-revealed-chaining-and-debugging/
--> https://michaelscodingspot.com/debug-linq-in-csharp/
Bleeping Computer
- https://www.bleepingcomputer.com/
Utilities
---------
Handle v5.0
- https://learn.microsoft.com/en-us/sysinternals/downloads/handle?WT.mc_id=DT-MVP-5003978
Auto Increment Build #
- https://stackoverflow.com/questions/826777/how-to-have-an-auto-incrementing-version-number-visual-studio
Phylosophy
----------
1. Do I have to have a "purpose" to have an address in the USA?
- if yes, then as a Human being I must have a purpose? Seriously? Ok, a purpose to whom? To whom must I state my pupose or execute or report to about...???
2. System Failure - Zero Day Exploit
3. Good PR example - https://github.com/dotnet/aspnetcore/pull/45587/files
App Insights Log Queries
------------------------
availabilityResults
| where timestamp > datetime("2022-12-19T04:07:00.000Z") and timestamp < datetime("2022-12-20T04:07:00.000Z")
| where customDimensions["WebtestArmResourceName"] == "availability-test-1-app-notepad-physical-activity-dev-eastus"
| where true and true
| extend percentage = toint(success) * 100
| summarize avg(percentage) by bin(timestamp, 1h)
| render timechart
******************************************************************
@DocGreenRob
Copy link
Author

@DocGreenRob
Copy link
Author

import { AfterViewInit, Component, Input, OnInit } from '@angular/core';
import { CommunicationService } from '../../../services/_internal/communication/communication.service';
import { SessionDataService } from '../../../services/_internal/session-data/session-data.service';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-global-spinner',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './global-spinner.component.html',
  styleUrl: './global-spinner.component.scss'
})
export class GlobalSpinnerComponent implements OnInit, AfterViewInit {
  // *********************
  // variables declaration
  // *********************

  // private
  // ********

  // public
  // ******
  @Input() spinnerText: string = "Searching...";

  constructor(private sessionDataService: SessionDataService,
    private communicationService: CommunicationService) {
  }

  // ***************
  // lifecycle hooks
  // ***************
  ngOnInit(): void {
    this.housekeeping();
  }

  ngAfterViewInit(): void {
  }

  // *******
  // methods
  // *******

  // public
  // ******

  // private
  // *******
  private housekeeping() {
  }

}

@DocGreenRob
Copy link
Author

RxProcessManagerLocalTest

Set WshShell = CreateObject("WScript.Shell")
Do
WshShell.SendKeys "{SCROLLLOCK}"
WScript.Sleep 60000 ' 60 seconds
Loop

cscript //nologo RxProcessManagerLocalTest.vbs

@DocGreenRob
Copy link
Author

image

@DocGreenRob
Copy link
Author

DocGreenRob commented Nov 2, 2025

🧩 Overview

You’ll:

  1. List secrets from the source Key Vault
  2. Loop through each secret name
  3. Retrieve the latest value
  4. Write it into the destination Key Vault

This approach preserves names and values, but not version history (you almost never want to duplicate every historical version).


⚙️ Prerequisites

Make sure:

az login
az account set --subscription "<YourSubscriptionID>"

You’ll also need read access to the source Key Vault and set access to the destination Key Vault (via RBAC or access policy).


🧠 Script (Bash for Azure Cloud Shell)

# Replace with your vault names
SOURCE_VAULT="source-keyvault-name"
DEST_VAULT="destination-keyvault-name"

# Get all secret names (not versions)
for secret in $(az keyvault secret list --vault-name $SOURCE_VAULT --query "[].name" -o tsv)
do
  echo "Copying secret: $secret"
  
  # Get the latest secret value
  value=$(az keyvault secret show --vault-name $SOURCE_VAULT --name $secret --query "value" -o tsv)

  # Recreate the secret in the destination vault
  az keyvault secret set --vault-name $DEST_VAULT --name $secret --value "$value" >/dev/null
  
done

echo "✅ All secrets copied from $SOURCE_VAULT to $DEST_VAULT"

🧰 Notes

  • If you have disabled secrets in the source vault and want to skip them:

    az keyvault secret list --vault-name $SOURCE_VAULT --query "[?attributes.enabled==\`true\`].name" -o tsv
  • To handle secrets with special characters or newlines safely, consider using --query "value" -o json and proper quoting, e.g.:

    value=$(az keyvault secret show --vault-name $SOURCE_VAULT --name $secret --query "value" -o json | jq -r)
  • The script does not copy tags or contentType. To include those, you’d extend it:

    metadata=$(az keyvault secret show --vault-name $SOURCE_VAULT --name $secret)
    value=$(echo $metadata | jq -r '.value')
    contentType=$(echo $metadata | jq -r '.contentType')
    az keyvault secret set --vault-name $DEST_VAULT --name $secret --value "$value" --content-type "$contentType"

🔐 Alternative (PowerShell in Cloud Shell)

If you prefer PowerShell syntax:

$sourceVault = "source-keyvault-name"
$destVault   = "destination-keyvault-name"

$secrets = az keyvault secret list --vault-name $sourceVault | ConvertFrom-Json
foreach ($secret in $secrets) {
    $name = $secret.name
    $value = az keyvault secret show --vault-name $sourceVault --name $name --query value -o tsv
    az keyvault secret set --vault-name $destVault --name $name --value $value | Out-Null
    Write-Host "Copied secret: $name"
}

Would you like me to include copying certificates and keys as well (not just secrets)? It’s a slightly different process involving az keyvault certificate and az keyvault key commands.

@DocGreenRob
Copy link
Author

What you’re seeing is normal internet “background radiation”: bots trawling every public site for WordPress/PHP holes (/wp-admin/*, random *.php, xmlrpc.php, etc.). Since your app isn’t PHP, they’re just probing. 46 requests in 24 hours is not a DDoS—a real DoS is usually thousands+ per minute—but you’re right to stop it from ever touching your app.

Here’s the clean playbook (Azure-native), in the order that actually reduces load.

1) Stop it at the edge (best ROI): Azure Front Door Premium + WAF

Front Door (Std/Premium) + WAF is what you want if your goal is “don’t let garbage reach my App Service.”

WAF rules to add (immediately)

Custom “Block PHP/WordPress scans” rule:

  • Block if URL path ends with .php

  • Block if URL path contains:

    • /wp-admin
    • /wp-content
    • /wp-includes
    • /xmlrpc.php

Rate limit rule (basic bot throttling):

  • If a single IP hits you more than (example) 100 requests in 1 minute, block for 5–10 minutes.

This removes noise before your app even sees it.

2) Prevent bypass: lock down the App Service origin

Once Front Door is in place, make sure attackers cannot hit your App Service URL directly.

In App Service → Networking → Access Restrictions:

  • Allow the AzureFrontDoor.Backend service tag (Front Door to origin)
  • Deny all else

That forces all traffic through WAF.

3) Don’t use APIM just to block bots

API Management is not the right tool for random internet scans.

  • Use APIM when you want: API products, subscriptions, quotas for real clients, versioning, developer portal, etc.
  • For bot junk and path probing: WAF is the tool.

(You can rate-limit in APIM, but you’ll pay more and the junk still has a chance to reach the gateway.)

4) Quick app-side safety net (so even without WAF you’re fine)

Add a tiny middleware early in the pipeline to short-circuit obvious garbage fast (no auth, no DB, no logging spam):

app.Use(async (ctx, next) =>
{
    var p = ctx.Request.Path.Value ?? "";

    if (p.EndsWith(".php", StringComparison.OrdinalIgnoreCase) ||
        p.StartsWith("/wp-", StringComparison.OrdinalIgnoreCase) ||
        p.Contains("/wp-admin", StringComparison.OrdinalIgnoreCase) ||
        p.Contains("/wp-content", StringComparison.OrdinalIgnoreCase) ||
        p.Contains("/wp-includes", StringComparison.OrdinalIgnoreCase) ||
        p.EndsWith("/xmlrpc.php", StringComparison.OrdinalIgnoreCase))
    {
        ctx.Response.StatusCode = StatusCodes.Status404NotFound;
        return;
    }

    await next();
});

Even if you later add Front Door/WAF, this keeps your origin resilient.

5) Fix robots.txt returning 400

A 400 for /robots.txt is unnecessary noise. Just serve a static robots.txt and return 200:

wwwroot/robots.txt

User-agent: *
Disallow:

Or if you want to discourage crawling:

User-agent: *
Disallow: /

6) Prove whether it’s actually “load” (App Insights check)

Run a quick KQL to see if these are cheap 404s or expensive requests:

requests
| where timestamp > ago(24h)
| where url has ".php" or url has "/wp-"
| summarize count(), avg(duration), max(duration) by resultCode, client_CountryOrRegion, client_IP
| order by count_ desc

If duration is tiny and counts are low, it’s noise. If duration is high, your app pipeline is doing too much before rejecting—then the middleware above matters a lot.


Bottom line

  • This is bot scanning, not a real DoS.
  • The “adult” solution is Front Door Premium + WAF + lock down origin.
  • APIM is optional and usually not the fix for this problem.

If you tell me what you’re hosting on (Azure App Service? Container Apps? AKS?) and whether you already have Front Door/Cloudflare, I’ll give you the exact click-path + the exact WAF rule patterns to paste in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment