mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-08-01 08:18:20 -04:00
* Whitelist System.Memory and System.ReadOnlyMemory (without pinning) * Be very explicit with System.Span and System.ReadOnlySpan whitelists, do not allow pinnables * Be completely explicit with Unsafe IL whitelist, allow Unsafe.SizeOf<T> * BlacklistCodeWalker can have an allow list * Compiler blacklist explicitly bans CreateSpan, allows Unsafe.SizeOf<T> * Whitelist System.IO.InvalidDataException * Better InlineArray whitelisting for compiler generated code * WhitelistGen: Creates explicit signatures from wildcard rules * Claude skill for whitelisting, uses the WhitelistGen tool to be very explicit and makes a good effort to security review
54 lines
1.3 KiB
C#
54 lines
1.3 KiB
C#
using System.Text.RegularExpressions;
|
|
|
|
namespace Sandbox;
|
|
|
|
static partial class CompilerRules
|
|
{
|
|
public static List<Regex> Blacklist = new();
|
|
|
|
// Carve-outs: a member matching one of these is allowed even if it matches a Blacklist pattern.
|
|
// Lets us keep a broad default-deny ban (e.g. "Unsafe.*") while permitting a known-safe member.
|
|
public static List<Regex> Allowlist = new();
|
|
|
|
static CompilerRules()
|
|
{
|
|
AddRules( Methods );
|
|
AddRules( Attributes );
|
|
AddRules( Types );
|
|
}
|
|
|
|
static void AddRules( IEnumerable<string> rules )
|
|
{
|
|
foreach ( var rule in rules )
|
|
{
|
|
var line = rule.Trim();
|
|
|
|
bool exception = line.StartsWith( '!' );
|
|
if ( exception )
|
|
line = line[1..];
|
|
|
|
var wildcard = Regex.Escape( line ).Replace( "\\*", ".*" );
|
|
wildcard = $"^{wildcard}$";
|
|
|
|
var regex = new Regex( wildcard, RegexOptions.Compiled );
|
|
|
|
if ( exception )
|
|
Allowlist.Add( regex );
|
|
else
|
|
Blacklist.Add( regex );
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// True if this fully-qualified symbol is prohibited - i.e. it matches a blacklist pattern and
|
|
/// isn't carved back out by an allowlist (!) exception.
|
|
/// </summary>
|
|
public static bool IsBlocked( string name )
|
|
{
|
|
if ( !Blacklist.Any( x => x.IsMatch( name ) ) )
|
|
return false;
|
|
|
|
return !Allowlist.Any( x => x.IsMatch( name ) );
|
|
}
|
|
}
|