From 2e0465517784a545fce62ca20057412534475ac3 Mon Sep 17 00:00:00 2001 From: Yunus AYDIN Date: Wed, 20 Dec 2023 23:56:46 +0300 Subject: [PATCH 1/6] add rule and example code for express --- .../Security/CWE-525/WebCacheDeception.ql | 19 +++++++++++++++++++ .../Security/CWE-525/WebCacheDeceptionBad.js | 12 ++++++++++++ .../Security/CWE-525/WebCacheDeceptionGood.js | 12 ++++++++++++ .../Security/CWE-525/WebCacheDeceptionLib.qll | 16 ++++++++++++++++ 4 files changed, 59 insertions(+) create mode 100644 javascript/ql/src/experimental/Security/CWE-525/WebCacheDeception.ql create mode 100644 javascript/ql/src/experimental/Security/CWE-525/WebCacheDeceptionBad.js create mode 100644 javascript/ql/src/experimental/Security/CWE-525/WebCacheDeceptionGood.js create mode 100644 javascript/ql/src/experimental/Security/CWE-525/WebCacheDeceptionLib.qll diff --git a/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeception.ql b/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeception.ql new file mode 100644 index 000000000000..3ad50e061033 --- /dev/null +++ b/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeception.ql @@ -0,0 +1,19 @@ +/** + * @name Web Cache Deception in Express + * @description A caching system has been detected on the application and is vulnerable to web cache deception. By manipulating the URL it is possible to force the application to cache pages that are only accessible by an authenticated user. Once cached, these pages can be accessed by an unauthenticated user. + * @kind problem + * @problem.severity error + * @security-severity 9 + * @precision medium + * @id js/web-cache-deception-express + * @tags javascript + * cwe-525 + * bug + */ + + import javascript + import WebCacheDeceptionLib + + from WebCacheDeception::Sink httpHandleFuncCall + where httpHandleFuncCall.toString().matches("%*%") + select httpHandleFuncCall, httpHandleFuncCall + " is used as wildcard endpoint." \ No newline at end of file diff --git a/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeceptionBad.js b/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeceptionBad.js new file mode 100644 index 000000000000..544f80d76cb1 --- /dev/null +++ b/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeceptionBad.js @@ -0,0 +1,12 @@ +const express = require('express') +const app = express() +port = 3000 + +app.get('/test*', (req, res) => { + res.send('Company: Trendyol, Birth Date: 1997, Country: Turkey, Phone: 5554443322') +}) + + +app.listen(port, () => { + console.log(`Example app listening on port ${port}`) +}) \ No newline at end of file diff --git a/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeceptionGood.js b/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeceptionGood.js new file mode 100644 index 000000000000..cb10d8966cbb --- /dev/null +++ b/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeceptionGood.js @@ -0,0 +1,12 @@ +const express = require('express') +const app = express() +port = 3000 + +app.get('/test', (req, res) => { + res.send('Company: Trendyol, Birth Date: 1997, Country: Turkey, Phone: 5554443322') +}) + + +app.listen(port, () => { + console.log(`Example app listening on port ${port}`) +}) \ No newline at end of file diff --git a/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeceptionLib.qll b/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeceptionLib.qll new file mode 100644 index 000000000000..e9b612be1ecb --- /dev/null +++ b/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeceptionLib.qll @@ -0,0 +1,16 @@ +import javascript +import StringOps + +module WebCacheDeception { + abstract class Sink extends DataFlow::Node { } + + private class Express extends Sink { + Express() { + exists(Import is | is.getImportedModuleNode().getASuccessor().toString() = "express") and + exists(DataFlow::CallNode m | + m.getAMethodCall().getArgument(0).getStringValue().matches("%*") and + this = m.getAMethodCall().getArgument(0) + ) + } + } +} From 8a3018ecc5f0a509d9cd25f474bed79c190b357c Mon Sep 17 00:00:00 2001 From: Yunus AYDIN Date: Wed, 20 Dec 2023 23:57:34 +0300 Subject: [PATCH 2/6] add rule and example code for express --- .../CWE-525/WebCacheDeception.expected | 1 + .../Security/CWE-525/WebCacheDeception.qhelp | 35 +++++++++++++++++++ .../Security/CWE-525/WebCacheDeception.qlref | 1 + .../Security/CWE-525/WebCacheDeceptionBad.js | 11 ++++++ .../Security/CWE-525/WebCacheDeceptionGood.js | 12 +++++++ 5 files changed, 60 insertions(+) create mode 100644 javascript/ql/test/experimental/Security/CWE-525/WebCacheDeception.expected create mode 100644 javascript/ql/test/experimental/Security/CWE-525/WebCacheDeception.qhelp create mode 100644 javascript/ql/test/experimental/Security/CWE-525/WebCacheDeception.qlref create mode 100644 javascript/ql/test/experimental/Security/CWE-525/WebCacheDeceptionBad.js create mode 100644 javascript/ql/test/experimental/Security/CWE-525/WebCacheDeceptionGood.js diff --git a/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeception.expected b/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeception.expected new file mode 100644 index 000000000000..f37ea991c303 --- /dev/null +++ b/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeception.expected @@ -0,0 +1 @@ +| WebCacheDeceptionBad.js:5:9:5:16 | '/test*' | '/test*' is used as wildcard endpoint. | diff --git a/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeception.qhelp b/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeception.qhelp new file mode 100644 index 000000000000..f60fea4ec8bb --- /dev/null +++ b/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeception.qhelp @@ -0,0 +1,35 @@ + + + +

+ Web Cache Deception is a security vulnerability where an attacker tricks a web server into caching sensitive information and then accesses that cached data. +

+

+ This attack exploits certain behaviors in caching mechanisms by requesting URLs that trick the server into thinking that a non-cachable page is cachable. If a user then accesses sensitive information on these pages, it could be cached and later retrieved by the attacker. +

+
+ +

+ To prevent Web Cache Deception attacks, web applications should clearly define cacheable and non-cacheable resources. Implementing strict cache controls and validating requested URLs can mitigate the risk of sensitive data being cached. +

+
+ +

+ Vulnerable code example: A web server is configured to cache all responses ending in '.css'. An attacker requests 'profile.css', and the server processes 'profile', a sensitive page, and caches it. +

+ +
+ +

+ Secure code example: The server is configured with strict cache controls and URL validation, preventing caching of dynamic or sensitive pages regardless of their URL pattern. +

+ +
+ +
  • + OWASP Web Cache Deception Attack: + Understanding Web Cache Deception Attacks +
  • + +
    +
    \ No newline at end of file diff --git a/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeception.qlref b/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeception.qlref new file mode 100644 index 000000000000..92bb095ef462 --- /dev/null +++ b/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeception.qlref @@ -0,0 +1 @@ +experimental/Security/CWE-525/WebCacheDeception.ql \ No newline at end of file diff --git a/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeceptionBad.js b/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeceptionBad.js new file mode 100644 index 000000000000..2a19dc9f7314 --- /dev/null +++ b/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeceptionBad.js @@ -0,0 +1,11 @@ +const express = require('express') +const app = express() +port = 3000 + +app.get('/test*', (req, res) => { + res.send('Company: Trendyol, Birth Date: 1997, Country: Turkey, Phone: 5554443322') +}) + +app.listen(port, () => { + console.log(`Example app listening on port ${port}`) +}) \ No newline at end of file diff --git a/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeceptionGood.js b/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeceptionGood.js new file mode 100644 index 000000000000..cb10d8966cbb --- /dev/null +++ b/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeceptionGood.js @@ -0,0 +1,12 @@ +const express = require('express') +const app = express() +port = 3000 + +app.get('/test', (req, res) => { + res.send('Company: Trendyol, Birth Date: 1997, Country: Turkey, Phone: 5554443322') +}) + + +app.listen(port, () => { + console.log(`Example app listening on port ${port}`) +}) \ No newline at end of file From bacde7f9503b314fcee64f0a2ba467b7ba02fe1d Mon Sep 17 00:00:00 2001 From: Yunus AYDIN Date: Wed, 20 Dec 2023 23:58:56 +0300 Subject: [PATCH 3/6] update example code --- .../test/experimental/Security/CWE-525/WebCacheDeceptionBad.js | 2 +- .../test/experimental/Security/CWE-525/WebCacheDeceptionGood.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeceptionBad.js b/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeceptionBad.js index 2a19dc9f7314..5310a59f2caf 100644 --- a/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeceptionBad.js +++ b/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeceptionBad.js @@ -3,7 +3,7 @@ const app = express() port = 3000 app.get('/test*', (req, res) => { - res.send('Company: Trendyol, Birth Date: 1997, Country: Turkey, Phone: 5554443322') + res.send('test') }) app.listen(port, () => { diff --git a/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeceptionGood.js b/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeceptionGood.js index cb10d8966cbb..0b643703f74a 100644 --- a/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeceptionGood.js +++ b/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeceptionGood.js @@ -3,7 +3,7 @@ const app = express() port = 3000 app.get('/test', (req, res) => { - res.send('Company: Trendyol, Birth Date: 1997, Country: Turkey, Phone: 5554443322') + res.send('test') }) From 3ec7ac55faed36904d6e030734def15fd8de569b Mon Sep 17 00:00:00 2001 From: Yunus AYDIN Date: Wed, 20 Dec 2023 23:59:12 +0300 Subject: [PATCH 4/6] update example code --- .../Security/CWE-525/WebCacheDeception.ql | 12 ++++++------ .../Security/CWE-525/WebCacheDeceptionBad.js | 2 +- .../Security/CWE-525/WebCacheDeceptionGood.js | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeception.ql b/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeception.ql index 3ad50e061033..6c4b7c029bdc 100644 --- a/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeception.ql +++ b/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeception.ql @@ -11,9 +11,9 @@ * bug */ - import javascript - import WebCacheDeceptionLib - - from WebCacheDeception::Sink httpHandleFuncCall - where httpHandleFuncCall.toString().matches("%*%") - select httpHandleFuncCall, httpHandleFuncCall + " is used as wildcard endpoint." \ No newline at end of file +import javascript +import WebCacheDeceptionLib + +from WebCacheDeception::Sink httpHandleFuncCall +where httpHandleFuncCall.toString().matches("%*%") +select httpHandleFuncCall, httpHandleFuncCall + " is used as wildcard endpoint." diff --git a/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeceptionBad.js b/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeceptionBad.js index 544f80d76cb1..13b5099cd665 100644 --- a/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeceptionBad.js +++ b/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeceptionBad.js @@ -3,7 +3,7 @@ const app = express() port = 3000 app.get('/test*', (req, res) => { - res.send('Company: Trendyol, Birth Date: 1997, Country: Turkey, Phone: 5554443322') + res.send('test') }) diff --git a/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeceptionGood.js b/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeceptionGood.js index cb10d8966cbb..0b643703f74a 100644 --- a/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeceptionGood.js +++ b/javascript/ql/src/experimental/Security/CWE-525/WebCacheDeceptionGood.js @@ -3,7 +3,7 @@ const app = express() port = 3000 app.get('/test', (req, res) => { - res.send('Company: Trendyol, Birth Date: 1997, Country: Turkey, Phone: 5554443322') + res.send('test') }) From c830a0475b77ae202a19b188de88adba739bfa9e Mon Sep 17 00:00:00 2001 From: Yunus AYDIN Date: Thu, 21 Dec 2023 00:17:47 +0300 Subject: [PATCH 5/6] add missing files --- .../Security/CWE-525/WebCacheDeception.ql | 20 +++++++++++++++++++ .../Security/CWE-525/WebCacheDeceptionLib.qll | 16 +++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 javascript/ql/test/experimental/Security/CWE-525/WebCacheDeception.ql create mode 100644 javascript/ql/test/experimental/Security/CWE-525/WebCacheDeceptionLib.qll diff --git a/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeception.ql b/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeception.ql new file mode 100644 index 000000000000..f81701420e83 --- /dev/null +++ b/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeception.ql @@ -0,0 +1,20 @@ +/** + * @name Web Cache Deception in Express + * @description A caching system has been detected on the application and is vulnerable to web cache deception. By manipulating the URL it is possible to force the application to cache pages that are only accessible by an authenticated user. Once cached, these pages can be accessed by an unauthenticated user. + * @kind problem + * @problem.severity error + * @security-severity 9 + * @precision medium + * @id js/web-cache-deception-express + * @tags javascript + * cwe-525 + * bug + */ + + import javascript + import WebCacheDeceptionLib + + from WebCacheDeception::Sink httpHandleFuncCall + where httpHandleFuncCall.toString().matches("%*%") + select httpHandleFuncCall, httpHandleFuncCall + " is used as wildcard endpoint." + \ No newline at end of file diff --git a/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeceptionLib.qll b/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeceptionLib.qll new file mode 100644 index 000000000000..e9b612be1ecb --- /dev/null +++ b/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeceptionLib.qll @@ -0,0 +1,16 @@ +import javascript +import StringOps + +module WebCacheDeception { + abstract class Sink extends DataFlow::Node { } + + private class Express extends Sink { + Express() { + exists(Import is | is.getImportedModuleNode().getASuccessor().toString() = "express") and + exists(DataFlow::CallNode m | + m.getAMethodCall().getArgument(0).getStringValue().matches("%*") and + this = m.getAMethodCall().getArgument(0) + ) + } + } +} From f8ad4941501473b9ed887a0e58aaac6d8b548bb7 Mon Sep 17 00:00:00 2001 From: Yunus AYDIN Date: Thu, 21 Dec 2023 00:29:01 +0300 Subject: [PATCH 6/6] fix formatting --- .../Security/CWE-525/WebCacheDeception.ql | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeception.ql b/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeception.ql index f81701420e83..6c4b7c029bdc 100644 --- a/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeception.ql +++ b/javascript/ql/test/experimental/Security/CWE-525/WebCacheDeception.ql @@ -11,10 +11,9 @@ * bug */ - import javascript - import WebCacheDeceptionLib - - from WebCacheDeception::Sink httpHandleFuncCall - where httpHandleFuncCall.toString().matches("%*%") - select httpHandleFuncCall, httpHandleFuncCall + " is used as wildcard endpoint." - \ No newline at end of file +import javascript +import WebCacheDeceptionLib + +from WebCacheDeception::Sink httpHandleFuncCall +where httpHandleFuncCall.toString().matches("%*%") +select httpHandleFuncCall, httpHandleFuncCall + " is used as wildcard endpoint."