Skip to content

Latest commit

 

History

History
146 lines (111 loc) · 5.37 KB

File metadata and controls

146 lines (111 loc) · 5.37 KB
ProtectedNumbers

ProtectedNumbers

Coverage GitHub Repo stars GitHub contributors GitHub last commit GitHub commit activity open issues .NET PRs Welcome

A .NET library for safe, opaque numeric identifiers you can pass through URLs, JSON, and model binding

What problem it solved

When working with a legacy database, most often primary keys are sequential numbers like this:

{
  "id": "4018378694012108869",
  "name": "some data row"
}

And if you expose the data as is on a public endpoint, an attacker can guess easily other identifiers:

{
  "id": "4018378694012108868",
  "name": "oops some other row"
}

There are ways to mitigate this problem. One of them is to make identifiers unguessable:

{
  "id": "CfDJ8K3W-Fa_koRAlAI935b9MJjgVrkgEMGZ5bvAPECdKZvgMpUPsvhVru9een2MVC0P8e4N4ehwgKgueAGjZlEP4s7gu3AsBLRoQrnUZr8hw4qZYAr-StAlQWCfx2FHTs1EGgEpB3T9YPSGxAxm0XVP7Mc",
  "name": "some data row"
}

What is ProtectedNumbers

  • ProtectedNumbers provides a lightweight struct, ProtectedNumber, that carries either a raw numeric value (long) or a protected string representation (for example for URLs or JSON), and can safely round-trip between the two with application-provided protection.
  • First-class ASP.NET Core integration is included:
    • Dependency injection helpers via services.AddProtectedNumbers().
    • MVC model binding for ProtectedNumber and ProtectedNumber? parameters.
    • System.Text.Json support.
  • Supported target frameworks: net6.0, net8.0, net9.0.

Key semantics of ProtectedNumber:

  • Dual representation: Value (long) and ProtectedValue (string). Either side can be present independently.
  • Empty sentinel: ProtectedNumber.Empty is initialized but HasValue == false and HasProtectedValue == false. Accessing Value or ProtectedValue on an empty instance throws InvalidOperationException.
  • Utility helpers: ProtectedNumber.IsNullOrEmpty(ProtectedNumber?) and initialization helpers to ensure safe usage.

Where can I get it?

First, install NuGet. Then, install ProtectedNumbers from the package manager console:

PM> Install-Package ProtectedNumbers

Or from the .NET CLI as:

dotnet add package ProtectedNumbers

How do I get started?

  • Add ProtectedNumbers services:
// ...
IServiceCollection services;
// ...

services.AddProtectedNumbers();
  • Replace the property type from int/long to ProtectedNumber:
// Before
public class SomeViewModel
{
  // ...
  public long? Id { get; set; }
  // ...
}

// After
public class SomeViewModel
{
  // ...
  public ProtectedNumbers? Id { get;set; }
  // ...
}
  • Example of json output from an api endpoint:

Before:

GET http://localhost:5000/minimal-api/samples-objects/4018378694012108869
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "id": "4018378694012108869",
  "name": "some data row"
}

After:

GET http://localhost:5000/minimal-api/samples-objects/CfDJ8K3W-Fa_koRAlAI935b9MJiwgpOlgJ5oj2hPOyJZZFqlHZB7JZKF5ccvazbH8_u4rtp1Ek-orXITi05_0MFOGj0Erm77rxFfpBQcfHVk04M-eaTiWkTNm54PwtmSdEZY5Iy9pGCCo_fYsFj2K54T89c
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "id": "CfDJ8K3W-Fa_koRAlAI935b9MJjgVrkgEMGZ5bvAPECdKZvgMpUPsvhVru9een2MVC0P8e4N4ehwgKgueAGjZlEP4s7gu3AsBLRoQrnUZr8hw4qZYAr-StAlQWCfx2FHTs1EGgEpB3T9YPSGxAxm0XVP7Mc",
  "name": "some data row"
}

Do you have an issue?

If you're still running into problems, file an issue above.

License, etc.

ProtectedNumbers is Copyright © 2025 Grégory Célet under the MIT license.