From be1961ed65c2262efcc47f19d5fb41a3eff8e381 Mon Sep 17 00:00:00 2001 From: Andrew Nesbitt Date: Sat, 11 Apr 2026 19:08:25 +0100 Subject: [PATCH] Tighten _threats.toml: add feature-flags mapping, LDAP libs, drop dead scraping mapping The function:scraping mapping fired on nothing since no tool def carries that tag. Removed rather than leaving dead code; re-add when scrapy/beautifulsoup/puppeteer defs land. Added function:feature-flags mapping to auth_bypass so Flipper/LaunchDarkly/Unleash contribute to threat-model. Feature gates protecting access checks are a real auth bypass surface. Added ldap3 (Python), ldapjs (Node), net-ldap (Ruby), PHP LDAP extension as detection-only defs with ldap_injection sinks so that threat is no longer Java-only. Each detected via dependencies. Closes #31 --- knowledge/_shared/_threats.toml | 10 +++++----- knowledge/node/ldapjs.toml | 28 +++++++++++++++++++++++++++ knowledge/php/ldap.toml | 34 +++++++++++++++++++++++++++++++++ knowledge/python/ldap3.toml | 27 ++++++++++++++++++++++++++ knowledge/ruby/net-ldap.toml | 27 ++++++++++++++++++++++++++ 5 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 knowledge/node/ldapjs.toml create mode 100644 knowledge/php/ldap.toml create mode 100644 knowledge/python/ldap3.toml create mode 100644 knowledge/ruby/net-ldap.toml diff --git a/knowledge/_shared/_threats.toml b/knowledge/_shared/_threats.toml index 4789259..81226ce 100644 --- a/knowledge/_shared/_threats.toml +++ b/knowledge/_shared/_threats.toml @@ -148,11 +148,6 @@ match = ["function:file-management"] threats = ["path_traversal"] note = "File operations with caller-controlled paths" -[[mappings]] -match = ["function:scraping"] -threats = ["ssrf"] -note = "Fetches caller-controlled URLs" - [[mappings]] match = ["function:http-client"] threats = ["ssrf"] @@ -183,6 +178,11 @@ match = ["role:framework", "layer:backend"] threats = ["xss", "csrf", "open_redirect", "ssrf", "path_traversal", "auth_bypass"] note = "Server-side framework handling user-controlled HTTP input" +[[mappings]] +match = ["function:feature-flags"] +threats = ["auth_bypass"] +note = "Feature gates protecting access checks; accidental exposure of flagged-off code paths" + [[mappings]] match = ["role:framework", "layer:frontend"] threats = ["xss", "open_redirect"] diff --git a/knowledge/node/ldapjs.toml b/knowledge/node/ldapjs.toml new file mode 100644 index 0000000..26e3051 --- /dev/null +++ b/knowledge/node/ldapjs.toml @@ -0,0 +1,28 @@ +[tool] +name = "ldapjs" +category = "build" +homepage = "http://ldapjs.org" +docs = "http://ldapjs.org" +repo = "https://github.com/ldapjs/node-ldapjs" +description = "LDAP client and server for Node.js" + +[detect] +dependencies = ["ldapjs"] +ecosystems = ["node"] + +[taxonomy] +role = ["library"] +function = ["authentication"] +layer = ["backend"] + +[[security.sinks]] +symbol = "client.search" +threat = "ldap_injection" +cwe = "CWE-90" +note = "When filter string built from caller input; use ldapjs filter objects" + +[[security.sinks]] +symbol = "client.bind" +threat = "ldap_injection" +cwe = "CWE-90" +note = "When DN built from caller input" diff --git a/knowledge/php/ldap.toml b/knowledge/php/ldap.toml new file mode 100644 index 0000000..183d34b --- /dev/null +++ b/knowledge/php/ldap.toml @@ -0,0 +1,34 @@ +[tool] +name = "PHP LDAP" +category = "build" +homepage = "https://www.php.net/manual/en/book.ldap.php" +docs = "https://www.php.net/manual/en/book.ldap.php" +description = "LDAP extension for PHP" + +[detect] +ecosystems = ["php"] + +[detect.file_contains] +"composer.json" = ["ext-ldap"] + +[taxonomy] +role = ["library"] +function = ["authentication"] +layer = ["backend"] + +[[security.sinks]] +symbol = "ldap_search" +threat = "ldap_injection" +cwe = "CWE-90" +note = "When filter built from user input without escaping; use ldap_escape" + +[[security.sinks]] +symbol = "ldap_bind" +threat = "ldap_injection" +cwe = "CWE-90" +note = "When DN built from user input" + +[[security.sinks]] +symbol = "ldap_read" +threat = "ldap_injection" +cwe = "CWE-90" diff --git a/knowledge/python/ldap3.toml b/knowledge/python/ldap3.toml new file mode 100644 index 0000000..e6caac9 --- /dev/null +++ b/knowledge/python/ldap3.toml @@ -0,0 +1,27 @@ +[tool] +name = "ldap3" +category = "build" +homepage = "https://ldap3.readthedocs.io" +docs = "https://ldap3.readthedocs.io" +repo = "https://github.com/cannatag/ldap3" +description = "LDAP client library for Python" + +[detect] +dependencies = ["ldap3"] +ecosystems = ["python"] + +[taxonomy] +role = ["library"] +function = ["authentication"] +layer = ["backend"] + +[[security.sinks]] +symbol = "Connection.search" +threat = "ldap_injection" +cwe = "CWE-90" +note = "When search_filter built via string formatting with caller input" + +[[security.sinks]] +symbol = "Connection.extend.standard.modify_password" +threat = "ldap_injection" +cwe = "CWE-90" diff --git a/knowledge/ruby/net-ldap.toml b/knowledge/ruby/net-ldap.toml new file mode 100644 index 0000000..778baed --- /dev/null +++ b/knowledge/ruby/net-ldap.toml @@ -0,0 +1,27 @@ +[tool] +name = "net-ldap" +category = "build" +homepage = "https://github.com/ruby-ldap/ruby-net-ldap" +docs = "https://www.rubydoc.info/gems/net-ldap" +repo = "https://github.com/ruby-ldap/ruby-net-ldap" +description = "LDAP client library for Ruby" + +[detect] +dependencies = ["net-ldap"] +ecosystems = ["ruby"] + +[taxonomy] +role = ["library"] +function = ["authentication"] +layer = ["backend"] + +[[security.sinks]] +symbol = "Net::LDAP#search" +threat = "ldap_injection" +cwe = "CWE-90" +note = "When filter built via string interpolation; use Net::LDAP::Filter" + +[[security.sinks]] +symbol = "Net::LDAP#bind_as" +threat = "ldap_injection" +cwe = "CWE-90"