Skip to content

Commit 4a89092

Browse files
committed
Apply stopforumspam check on posts as well as topics, add heuristics based auto spam detection
1 parent 593ee39 commit 4a89092

File tree

1 file changed

+57
-13
lines changed

1 file changed

+57
-13
lines changed

src/forum.nim

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,49 @@ proc rateLimitCheck(c: TForumData): bool =
242242
if last300s > 6: return true
243243
return false
244244

245+
proc stopForumSpamCheck(c: TForumData): bool =
246+
if c.rank == Moderated:
247+
let
248+
client = newHttpClient()
249+
resp = client.get("https://api.stopforumspam.org/api?emailhash=" & c.email.getMd5 & "&json")
250+
if resp.code == Http200:
251+
let jresp = resp.body.parseJson
252+
if jresp["success"].num == 1 and jresp["emailhash"].hasKey("confidence") and jresp["emailhash"]["confidence"].str.parseFloat > 0.0:
253+
exec(
254+
db,
255+
sql"update person set status = ? where name = ?;",
256+
AutoSpammer, c.userName
257+
)
258+
return true
259+
260+
proc spamHeuristicsCheck(c: TForumData, content: string, topic = ""): bool =
261+
if c.rank == Moderated:
262+
var spamScore = 0.0
263+
if topic.len > 8 and topic.allCharsInSet(UppercaseLetters + Digits + Whitespace):
264+
spamScore += 1.0
265+
let dollar = content.find('$')
266+
if dollar != -1 and content.len > dollar + 1 and content[dollar + 1] in Digits:
267+
spamScore += 0.5
268+
269+
let
270+
lowerContent = content.toLowerAscii
271+
marker = "{{WORDLIST_HIT}}"
272+
wordlistHits = lowerContent.multiReplace([
273+
("bitcoin", marker), ("ethereum", marker), ("cryptocurrency", marker),
274+
("hacker", marker), ("recovery", marker), ("contact", marker),
275+
("hemp", marker), ("cbd", marker),("gummy", marker), ("thc", marker),
276+
("www.facebook.com", marker), ("whatsapp", marker)])
277+
wordlistHitCount = wordlistHits.count(marker)
278+
if wordlistHitCount >= 2:
279+
spamScore += wordlistHitCount.float * 0.3
280+
if spamScore > 1:
281+
echo "Post by user ", c.userid, " trigger AutoSpam with score ", spamScore
282+
exec(
283+
db,
284+
sql"update person set status = ? where name = ?;",
285+
AutoSpammer, c.userName
286+
)
287+
return true
245288

246289
proc verifyIdentHash(
247290
c: TForumData, name: string, epoch: int64, ident: string
@@ -478,6 +521,14 @@ proc executeReply(c: TForumData, threadId: int, content: string,
478521
if rateLimitCheck(c):
479522
raise newForumError("You're posting too fast!")
480523

524+
when not defined(skipStopForumSpamCheck):
525+
if stopForumSpamCheck(c):
526+
raise newForumError("Your account has been marked by https://www.stopforumspam.com/. If you believe this is a mistake please contact a moderator. " & supportUrl)
527+
528+
when not defined(skipSpamHeuristics):
529+
if spamHeuristicsCheck(c, content):
530+
raise newForumError("Your account has been automatically marked as spam. If you believe this is a mistake please contact a moderator. " & supportUrl)
531+
481532
if content.strip().len == 0:
482533
raise newForumError("Message cannot be empty")
483534

@@ -613,19 +664,12 @@ proc executeNewThread(c: TForumData, subject, msg, categoryID: string): (int64,
613664
raise newForumError("You're posting too fast!")
614665

615666
when not defined(skipStopForumSpamCheck):
616-
if c.rank == Moderated:
617-
let
618-
client = newHttpClient()
619-
resp = client.get("https://api.stopforumspam.org/api?emailhash=" & c.email.getMd5 & "&json")
620-
if resp.code == Http200:
621-
let jresp = resp.body.parseJson
622-
if jresp["success"].num == 1 and jresp["emailhash"].hasKey("confidence") and jresp["emailhash"]["confidence"].str.parseFloat > 0.0:
623-
exec(
624-
db,
625-
sql"update person set status = ? where name = ?;",
626-
AutoSpammer, c.userName
627-
)
628-
raise newForumError("Your account has been marked by https://www.stopforumspam.com/. If you believe this is a mistake please contact a moderator. " & supportUrl)
667+
if stopForumSpamCheck(c):
668+
raise newForumError("Your account has been marked by https://www.stopforumspam.com/. If you believe this is a mistake please contact a moderator. " & supportUrl)
669+
670+
when not defined(skipSpamHeuristics):
671+
if spamHeuristicsCheck(c, msg, subject):
672+
raise newForumError("Your account has been automatically marked as spam. If you believe this is a mistake please contact a moderator. " & supportUrl)
629673

630674
result[0] = tryInsertID(db, query, subject, categoryID).int
631675
if result[0] < 0:

0 commit comments

Comments
 (0)