Add server-side text safety features - user input will now be checked against a known list of profanities (such as toyo). Filter mode can be adjusted in global config file between four levels according to desired level of punishment;

0 - None
1 - Asterisks
2 - Random Characters
3 - Furry

Fixes #34
This commit is contained in:
Logan Lowe 2022-03-08 00:43:00 -07:00
commit 0d54c5ade1
9 changed files with 655 additions and 42 deletions

View file

@ -78,11 +78,15 @@ public class MessageController : ControllerBase
public async Task<IActionResult> Filter()
{
User? user = await this.database.UserFromGameRequest(this.Request);
if (user == null) return this.StatusCode(403, "");
string loggedText = await new StreamReader(this.Request.Body).ReadToEndAsync();
string response = await new StreamReader(this.Request.Body).ReadToEndAsync();
string scannedText = CensorHelper.ScanMessage(response);
Logger.Log($"{user.Username}: {loggedText}", LoggerLevelFilter.Instance);
return this.Ok(loggedText);
Logger.Log($"{user.Username}: {response} / {scannedText}", LoggerLevelFilter.Instance);
return this.Ok(scannedText);
}
}

View file

@ -0,0 +1,142 @@
using System.Text;
using LBPUnion.ProjectLighthouse.Types.Settings;
namespace LBPUnion.ProjectLighthouse.Helpers;
public enum FilterMode
{
None,
Asterisks,
Random,
Furry,
}
public static class CensorHelper
{
private static readonly char[] _randomCharacters =
{
'!',
'@',
'#',
'$',
'&',
'%',
'-',
'A',
'b',
'C',
'd',
'E',
'f',
'G',
'h',
'I',
'j',
'K',
'l',
'M',
'n',
'O',
'p',
'Q',
'r',
'S',
't',
'U',
'v',
'W',
'x',
'Y',
'z',
};
private static readonly string[] _randomFurry =
{
"UwU",
"OwO",
"uwu",
"owo",
"o3o",
">.>",
"*pounces on you*",
"*boops*",
"*baps*",
":P",
"x3",
"O_O",
"xD",
":3",
";3",
"^w^",
};
private static readonly string[] _censorList = ResourceHelper.readManifestFile("chatCensoredList.txt").Split("\n");
public static string ScanMessage(string message)
{
if (ServerSettings.Instance.UserInputFilterMode == FilterMode.None) return message;
int profaneIndex = -1;
foreach (string profanity in _censorList)
do
{
profaneIndex = message.ToLower().IndexOf(profanity);
if (profaneIndex != -1)
message = Censor(profaneIndex,
profanity.Length,
message);
}
while (profaneIndex != -1);
return message;
}
private static string Censor(int profanityIndex, int profanityLength, string message)
{
StringBuilder sb = new();
string randomWord;
char randomChar;
char prevRandomChar = '\0';
sb.Append(message.Substring(0,
profanityIndex));
switch (ServerSettings.Instance.UserInputFilterMode)
{
case FilterMode.Random:
for (int i = 0; i < profanityLength; i++)
lock (RandomHelper.random)
{
randomChar = _randomCharacters[RandomHelper.random.Next(0,
_randomCharacters.Length - 1)];
if (randomChar == prevRandomChar)
randomChar = _randomCharacters[RandomHelper.random.Next(0,
_randomCharacters.Length - 1)];
prevRandomChar = randomChar;
sb.Append(randomChar);
}
break;
case FilterMode.Asterisks:
for (int i = 0; i < profanityLength; i++) sb.Append('*');
break;
case FilterMode.Furry:
lock (RandomHelper.random)
{
randomWord = _randomFurry[RandomHelper.random.Next(0,
_randomFurry.Length - 1)];
sb.Append(randomWord);
}
break;
}
sb.Append(message.Substring(profanityIndex + profanityLength));
return sb.ToString();
}
}

View file

@ -14,7 +14,6 @@ public static class HashHelper
{
// private static readonly SHA1 sha1 = SHA1.Create();
private static readonly SHA256 sha256 = SHA256.Create();
private static readonly Random random = new();
/// <summary>
/// Generates a specified amount of random bytes in an array.
@ -24,8 +23,12 @@ public static class HashHelper
public static IEnumerable<byte> GenerateRandomBytes(int count)
{
byte[] b = new byte[count];
random.NextBytes(b);
lock (RandomHelper.random)
{
RandomHelper.random.NextBytes(b);
}
return b;
}

View file

@ -0,0 +1,8 @@
using System;
namespace LBPUnion.ProjectLighthouse.Helpers;
public static class RandomHelper
{
public static readonly Random random = new();
}

View file

@ -0,0 +1,20 @@
using System;
using System.IO;
using System.Linq;
using Kettu;
using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Types.Settings;
namespace LBPUnion.ProjectLighthouse.Helpers;
public static class ResourceHelper
{
public static string readManifestFile(string fileName)
{
using Stream stream =
typeof(Program).Assembly.GetManifestResourceStream($"{typeof(Program).Namespace}.{fileName}");
using StreamReader reader = new(stream ?? throw new Exception("The assembly or manifest resource is null."));
return reader.ReadToEnd().Trim();
}
}

View file

@ -13,10 +13,10 @@ public static class VersionHelper
{
try
{
CommitHash = readManifestFile("gitVersion.txt");
Branch = readManifestFile("gitBranch.txt");
CommitHash = ResourceHelper.readManifestFile("gitVersion.txt");
Branch = ResourceHelper.readManifestFile("gitBranch.txt");
string remotesFile = readManifestFile("gitRemotes.txt");
string remotesFile = ResourceHelper.readManifestFile("gitRemotes.txt");
string[] lines = remotesFile.Split('\n');
@ -26,7 +26,7 @@ public static class VersionHelper
// linq is a serious and painful catastrophe but its useful so i'm gonna keep using it
Remotes = lines.Select(line => line.Split("\t")[1]).ToArray();
CommitsOutOfDate = readManifestFile("gitUnpushed.txt").Split('\n').Length;
CommitsOutOfDate = ResourceHelper.readManifestFile("gitUnpushed.txt").Split('\n').Length;
CanCheckForUpdates = true;
}
@ -55,14 +55,6 @@ public static class VersionHelper
}
}
private static string readManifestFile(string fileName)
{
using Stream stream = typeof(Program).Assembly.GetManifestResourceStream($"{typeof(Program).Namespace}.{fileName}");
using StreamReader reader = new(stream ?? throw new Exception("The assembly or manifest resource is null."));
return reader.ReadToEnd().Trim();
}
public static string CommitHash { get; set; }
public static string Branch { get; set; }
public static string FullVersion => $"{ServerStatics.ServerName} {Branch}@{CommitHash} {Build}";

View file

@ -12,53 +12,57 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3"/>
<PackageReference Include="DDSReader" Version="1.0.8-pre"/>
<PackageReference Include="Discord.Net.Webhook" Version="3.4.0"/>
<PackageReference Include="InfluxDB.Client" Version="3.3.0"/>
<PackageReference Include="JetBrains.Annotations" Version="2021.3.0"/>
<PackageReference Include="Kettu" Version="1.2.2"/>
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="6.0.2"/>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.2"/>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.2"/>
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
<PackageReference Include="DDSReader" Version="1.0.8-pre" />
<PackageReference Include="Discord.Net.Webhook" Version="3.4.0" />
<PackageReference Include="InfluxDB.Client" Version="3.3.0" />
<PackageReference Include="JetBrains.Annotations" Version="2021.3.0" />
<PackageReference Include="Kettu" Version="1.2.2" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="6.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.1"/>
<PackageReference Include="SharpZipLib" Version="1.3.3"/>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3"/>
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.1" />
<PackageReference Include="SharpZipLib" Version="1.3.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>
<ItemGroup>
<None Remove="gitVersion.txt"/>
<None Remove="gitVersion.txt" />
<EmbeddedResource Include="gitVersion.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<None Remove="gitBranch.txt"/>
<None Remove="gitBranch.txt" />
<EmbeddedResource Include="gitBranch.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<None Remove="gitRemotes.txt"/>
<None Remove="gitRemotes.txt" />
<EmbeddedResource Include="gitRemotes.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<None Remove="gitUnpushed.txt"/>
<None Remove="gitUnpushed.txt" />
<EmbeddedResource Include="gitUnpushed.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<None Remove="recent-activity.xml"/>
<None Remove="r.tar.gz"/>
<None Remove="chatCensoredList.txt" />
<EmbeddedResource Include="chatCensoredList.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<None Remove="recent-activity.xml" />
<None Remove="r.tar.gz" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Migrations\20220301204930_AddEmailVerificationTokens.Designer.cs"/>
<Compile Remove="Migrations\20220301204930_AddEmailVerificationTokens.Designer.cs" />
</ItemGroup>
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command="git describe --long --always --dirty --exclude=\* --abbrev=8 &gt; &quot;$(ProjectDir)/gitVersion.txt&quot;"/>
<Exec Command="git branch --show-current &gt; &quot;$(ProjectDir)/gitBranch.txt&quot;"/>
<Exec Command="git remote -v &gt; &quot;$(ProjectDir)/gitRemotes.txt&quot;"/>
<Exec Command="git log --branches --not --remotes --oneline &gt; &quot;$(ProjectDir)/gitUnpushed.txt&quot;"/>
<Exec Command="git describe --long --always --dirty --exclude=\* --abbrev=8 &gt; &quot;$(ProjectDir)/gitVersion.txt&quot;" />
<Exec Command="git branch --show-current &gt; &quot;$(ProjectDir)/gitBranch.txt&quot;" />
<Exec Command="git remote -v &gt; &quot;$(ProjectDir)/gitRemotes.txt&quot;" />
<Exec Command="git log --branches --not --remotes --oneline &gt; &quot;$(ProjectDir)/gitUnpushed.txt&quot;" />
</Target>
</Project>

View file

@ -5,6 +5,7 @@ using System.Text.Json;
using System.Text.Json.Serialization;
using JetBrains.Annotations;
using Kettu;
using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Logging;
namespace LBPUnion.ProjectLighthouse.Types.Settings;
@ -12,7 +13,7 @@ namespace LBPUnion.ProjectLighthouse.Types.Settings;
[Serializable]
public class ServerSettings
{
public const int CurrentConfigVersion = 24; // MUST BE INCREMENTED FOR EVERY CONFIG CHANGE!
public const int CurrentConfigVersion = 25; // MUST BE INCREMENTED FOR EVERY CONFIG CHANGE!
private static FileSystemWatcher fileWatcher;
static ServerSettings()
{
@ -144,6 +145,8 @@ public class ServerSettings
public bool BooingEnabled { get; set; } = true;
public FilterMode UserInputFilterMode { get; set; } = FilterMode.None;
public bool DiscordWebhookEnabled { get; set; }
public string DiscordWebhookUrl { get; set; } = "";

View file

@ -0,0 +1,437 @@
4r5e
5h1t
5hit
a55
anal
anus
ar5e
arrse
ass-fucker
asses
assfucker
assfukka
assholes
asswhole
a_s_s
b!tch
b00bs
b17ch
b1tch
ballbag
ballsack
bastard
beastial
beastiality
bellend
bestial
bestiality
bi+ch
biatch
bitch
bitcher
bitchers
bitches
bitching
bloody
blow job
blowjob
blowjobs
boiolas
bollock
bollok
boner
boob
boobs
booobs
boooobs
booooobs
booooooobs
breasts
buceta
bugger
bum
bunny fucker
butt
butthole
buttmunch
buttplug
c0ck
c0cksucker
carpet muncher
cawk
chink
cipa
cl1t
clit
clitoris
clits
cnut
cock
cock-sucker
cockface
cockhead
cockmunch
cockmuncher
cocks
cocksuck
cocksucked
cocksucker
cocksucking
cocksucks
cocksuka
cocksukka
cok
cokmuncher
coksucka
coon
cox
crap
cum
cummer
cumming
cums
cumshot
cunilingus
cunillingus
cunnilingus
cunt
cuntlick
cuntlicker
cuntlicking
cunts
cyalis
cyberfuc
cyberfuck
cyberfucked
cyberfucker
cyberfuckers
cyberfucking
d1ck
dick
dickhead
dildo
dildos
dink
dinks
dirsa
dlck
dog-fucker
doggin
dogging
donkeyribber
doosh
duche
dyke
ejaculate
ejaculated
ejaculates
ejaculating
ejaculatings
ejaculation
ejakulate
f u c k
f u c k e r
f4nny
fridinator
fag
fagging
faggitt
faggot
faggs
fagot
fagots
fags
fanny
fannyflaps
fannyfucker
fanyy
fatass
fcuk
fcuker
fcuking
fecker
felching
fellate
fellatio
fingerfuck
fingerfucked
fingerfucker
fingerfuckers
fingerfucking
fingerfucks
fistfuck
fistfucked
fistfucker
fistfuckers
fistfucking
fistfuckings
fistfucks
flange
fook
fooker
fucka
fucked
fucker
fuckers
fuckhead
fuckheads
fuckin
fucking
fuckings
fuckingshitmotherfucker
fuckme
fucks
fuckwhit
fuckwit
fudge packer
fudgepacker
fuk
fuker
fukker
fukkin
fuks
fukwhit
fukwit
fux
fux0r
f_u_c_k
gangbang
gangbanged
gangbangs
gaylord
gaysex
goatse
hardcoresex
heshe
hoar
hoare
hoer
hore
horniest
horny
hotsex
jack-off
jackoff
jap
jerk-off
jism
jiz
jizm
jizz
kawk
knob
knobead
knobed
knobend
knobhead
knobjocky
knobjokey
kock
kondum
kondums
kum
kummer
kumming
kums
kunilingus
kiunt
l3i+ch
l3itch
labia
lmfao
lust
lusting
m0f0
m0fo
m45terbate
ma5terb8
ma5terbate
masochist
master-bate
masterb8
masterbat*
masterbat3
masterbate
masterbation
masterbations
masturbate
mo-fo
mof0
mofo
mothafuck
mothafucka
mothafuckas
mothafuckaz
mothafucked
mothafucker
mothafuckers
mothafuckin
mothafucking
mothafuckings
mothafucks
mother fucker
motherfuck
motherfucked
motherfucker
motherfuckers
motherfuckin
motherfucking
motherfuckings
motherfuckka
motherfucks
muff
mutha
muthafecker
muthafuckker
muther
mutherfucker
n1gga
n1gger
nazi
nft
nigg3r
nigg4h
nigga
niggah
niggas
niggaz
nigger
niggers
nob
nob jokey
nobhead
nobjocky
nobjokey
numbnuts
nutsack
orgasim
orgasims
orgasm
orgasms
p0rn
pawn
pecker
penis
penisfucker
phonesex
phuck
phuk
phuked
phuking
phukked
phukking
phuks
phuq
pigfucker
pimpis
pissed
pisser
pissers
pisses
pissflaps
pissin
pissing
pissoff
porn
porno
pornography
pornos
prick
pricks
pron
pube
pusse
pussi
pussies
pussy
pussys
rectum
restitched
retard
rimjaw
rimming
s hit
s.o.b.
sadist
schlong
screwing
scroat
scrote
scrotum
semen
sex
sh!+
sh!t
sh1t
shag
shagger
shaggin
shagging
shemale
shi+
shitdick
shited
shitey
shitfuck
shitfull
shithead
shiting
shitings
shits
shitted
shitter
shitters
shitting
shittings
shitty
skank
slut
shiftos
sluts
smegma
smut
snatch
son-of-a-bitch
spac
spunk
s_h_i_t
t1tt1e5
t1tties
teets
teez
testical
testicle
tit
titfuck
tits
titt
tittie5
tittiefucker
titties
tittyfuck
tittywank
titwank
toyo
tosser
tw4t
twat
twathead
twatty
twunt
twunter
v14gra
v1gra
vagina
viagra
vulva
w00se
wang
wank
wanker
wanky
whoar
whore
willies
willy
xrated
xxx