From 65bc0f386db326f0b15722f9ad1bdabf22d12098 Mon Sep 17 00:00:00 2001 From: felix-20 Date: Tue, 30 May 2023 11:34:17 +0200 Subject: [PATCH] review PHP Patterns 6, 45, 47, 75, 83 --- ...stance_45_static_method_from_variable.bash | 72 ++-- ...stance_45_static_method_from_variable.json | 73 ++-- ...nstance_45_static_method_from_variable.php | 27 +- ...instance_45_static_method_from_variable.sc | 10 +- .../45_static_method_from_variable.json | 26 +- ...rn object Static method from a variable.md | 106 ----- PHP/45_static_method_from_variable/README.md | 120 ++++++ .../docs/description.md | 1 + .../1_instance_47_overriding.bash | 76 ++-- .../1_instance_47_overriding.json | 73 ++-- .../1_instance_47_overriding.php | 35 +- .../1_instance_47_overriding.py | 95 ----- .../2_instance_47_overriding.bash | 38 ++ .../2_instance_47_overriding.json | 38 ++ .../2_instance_47_overriding.php | 18 + PHP/47_overriding/47_methods.sc | 8 - PHP/47_overriding/47_overriding.json | 27 +- PHP/47_overriding/47_overriding.sc | 10 + PHP/47_overriding/Pattern Override.md | 104 ----- PHP/47_overriding/README.md | 272 +++++++++++++ PHP/47_overriding/docs/description.md | 1 + .../1_instance_6_coalesce.bash | 34 +- .../1_instance_6_coalesce.json | 73 ++-- .../1_instance_6_coalesce.php | 8 +- .../2_instance_6_coalesce.bash | 14 + .../2_instance_6_coalesce.json | 73 ++-- .../2_instance_6_coalesce.php | 6 +- .../2_instance_6_coalesce.sc | 6 - .../3_instance_6_coalesce.bash | 16 + .../3_instance_6_coalesce.json | 38 ++ .../3_instance_6_coalesce.php | 5 + PHP/6_coalesce/6_coalesce.json | 29 +- ...1_instance_6_coalesce.sc => 6_coalesce.sc} | 10 +- PHP/6_coalesce/README.md | 383 ++++++++++++++---- PHP/6_coalesce/docs/description.md | 1 + .../1_instance_75_buffer.bash | 19 + .../1_instance_75_buffer.json | 73 ++-- .../1_instance_75_buffer.php | 14 +- .../1_instance_75_buffer.sc | 5 - .../2_instance_75_buffer.bash | 17 + .../2_instance_75_buffer.json | 38 ++ .../2_instance_75_buffer.php | 6 + PHP/75_buffer/75_buffer.json | 27 +- PHP/75_buffer/75_buffer.sc | 6 + PHP/75_buffer/Pattern Buffer.md | 13 - PHP/75_buffer/README.md | 204 ++++++++++ PHP/75_buffer/docs/description.md | 4 + .../1_instance_83_array_variable_key.bash | 40 +- .../1_instance_83_array_variable_key.json | 73 ++-- .../1_instance_83_array_variable_key.php | 12 +- .../1_instance_83_array_variable_key.sc | 14 +- .../2_instance_83_array_variable_key.bash | 47 +-- .../2_instance_83_array_variable_key.json | 73 ++-- .../2_instance_83_array_variable_key.php | 12 +- .../2_instance_83_array_variable_key.sc | 16 +- .../3_instance_83_array_variable_key.bash | 46 +-- .../3_instance_83_array_variable_key.json | 73 ++-- .../3_instance_83_array_variable_key.php | 11 +- .../3_instance_83_array_variable_key.sc | 12 +- .../83_array_variable_key.json | 30 +- .../Pattern Array Variable Key.md | 292 ------------- PHP/83_array_variable_key/README.md | 299 ++++++++++++++ PHP/83_array_variable_key/docs/description.md | 1 + 63 files changed, 2079 insertions(+), 1324 deletions(-) mode change 100644 => 100755 PHP/45_static_method_from_variable/1_instance_45_static_method_from_variable/1_instance_45_static_method_from_variable.bash mode change 100644 => 100755 PHP/45_static_method_from_variable/1_instance_45_static_method_from_variable/1_instance_45_static_method_from_variable.json mode change 100644 => 100755 PHP/45_static_method_from_variable/1_instance_45_static_method_from_variable/1_instance_45_static_method_from_variable.php mode change 100644 => 100755 PHP/45_static_method_from_variable/1_instance_45_static_method_from_variable/1_instance_45_static_method_from_variable.sc mode change 100644 => 100755 PHP/45_static_method_from_variable/45_static_method_from_variable.json delete mode 100644 PHP/45_static_method_from_variable/Pattern object Static method from a variable.md create mode 100755 PHP/45_static_method_from_variable/README.md create mode 100755 PHP/45_static_method_from_variable/docs/description.md mode change 100644 => 100755 PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.bash mode change 100644 => 100755 PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.json mode change 100644 => 100755 PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.php delete mode 100644 PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.py create mode 100755 PHP/47_overriding/2_instance_47_overriding/2_instance_47_overriding.bash create mode 100755 PHP/47_overriding/2_instance_47_overriding/2_instance_47_overriding.json create mode 100755 PHP/47_overriding/2_instance_47_overriding/2_instance_47_overriding.php delete mode 100644 PHP/47_overriding/47_methods.sc mode change 100644 => 100755 PHP/47_overriding/47_overriding.json create mode 100755 PHP/47_overriding/47_overriding.sc delete mode 100644 PHP/47_overriding/Pattern Override.md create mode 100755 PHP/47_overriding/README.md create mode 100755 PHP/47_overriding/docs/description.md mode change 100644 => 100755 PHP/6_coalesce/1_instance_6_coalesce/1_instance_6_coalesce.bash mode change 100644 => 100755 PHP/6_coalesce/1_instance_6_coalesce/1_instance_6_coalesce.json mode change 100644 => 100755 PHP/6_coalesce/1_instance_6_coalesce/1_instance_6_coalesce.php create mode 100755 PHP/6_coalesce/2_instance_6_coalesce/2_instance_6_coalesce.bash mode change 100644 => 100755 PHP/6_coalesce/2_instance_6_coalesce/2_instance_6_coalesce.json mode change 100644 => 100755 PHP/6_coalesce/2_instance_6_coalesce/2_instance_6_coalesce.php delete mode 100644 PHP/6_coalesce/2_instance_6_coalesce/2_instance_6_coalesce.sc create mode 100755 PHP/6_coalesce/3_instance_6_coalesce/3_instance_6_coalesce.bash create mode 100755 PHP/6_coalesce/3_instance_6_coalesce/3_instance_6_coalesce.json create mode 100755 PHP/6_coalesce/3_instance_6_coalesce/3_instance_6_coalesce.php mode change 100644 => 100755 PHP/6_coalesce/6_coalesce.json rename PHP/6_coalesce/{1_instance_6_coalesce/1_instance_6_coalesce.sc => 6_coalesce.sc} (97%) mode change 100644 => 100755 mode change 100644 => 100755 PHP/6_coalesce/README.md create mode 100755 PHP/6_coalesce/docs/description.md create mode 100755 PHP/75_buffer/1_instance_75_buffer/1_instance_75_buffer.bash mode change 100644 => 100755 PHP/75_buffer/1_instance_75_buffer/1_instance_75_buffer.json mode change 100644 => 100755 PHP/75_buffer/1_instance_75_buffer/1_instance_75_buffer.php delete mode 100644 PHP/75_buffer/1_instance_75_buffer/1_instance_75_buffer.sc create mode 100755 PHP/75_buffer/2_instance_75_buffer/2_instance_75_buffer.bash create mode 100755 PHP/75_buffer/2_instance_75_buffer/2_instance_75_buffer.json create mode 100755 PHP/75_buffer/2_instance_75_buffer/2_instance_75_buffer.php mode change 100644 => 100755 PHP/75_buffer/75_buffer.json create mode 100755 PHP/75_buffer/75_buffer.sc delete mode 100644 PHP/75_buffer/Pattern Buffer.md create mode 100755 PHP/75_buffer/README.md create mode 100755 PHP/75_buffer/docs/description.md mode change 100644 => 100755 PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.bash mode change 100644 => 100755 PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.json mode change 100644 => 100755 PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.php mode change 100644 => 100755 PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.sc mode change 100644 => 100755 PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.bash mode change 100644 => 100755 PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.json mode change 100644 => 100755 PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.php mode change 100644 => 100755 PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.sc mode change 100644 => 100755 PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.bash mode change 100644 => 100755 PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.json mode change 100644 => 100755 PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.php mode change 100644 => 100755 PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.sc mode change 100644 => 100755 PHP/83_array_variable_key/83_array_variable_key.json delete mode 100644 PHP/83_array_variable_key/Pattern Array Variable Key.md create mode 100755 PHP/83_array_variable_key/README.md create mode 100755 PHP/83_array_variable_key/docs/description.md diff --git a/PHP/45_static_method_from_variable/1_instance_45_static_method_from_variable/1_instance_45_static_method_from_variable.bash b/PHP/45_static_method_from_variable/1_instance_45_static_method_from_variable/1_instance_45_static_method_from_variable.bash old mode 100644 new mode 100755 index 8b499cd..407e22a --- a/PHP/45_static_method_from_variable/1_instance_45_static_method_from_variable/1_instance_45_static_method_from_variable.bash +++ b/PHP/45_static_method_from_variable/1_instance_45_static_method_from_variable/1_instance_45_static_method_from_variable.bash @@ -1,42 +1,30 @@ - -$_main: ; (lines=15, args=0, vars=2, tmps=8) - ; (before optimizer) - ; /home/user/gitlab/static-tools---latex/paper_code/PHP/Testability_Patterns/48_static_method_from_variable/48_static_method_from_variable.php:1-16 -L0 (3): NOP -L1 (14): EXT_STMT -L2 (14): T2 = FETCH_R (global) string("_GET") -L3 (14): T3 = FETCH_DIM_R T2 string("p1") -L4 (14): ASSIGN CV0($b) T3 -L5 (15): EXT_STMT -L6 (15): V5 = NEW 1 string("A") -L7 (15): SEND_VAR_EX CV0($b) 1 -L8 (15): DO_FCALL -L9 (15): ASSIGN CV1($a) V5 -L10 (16): EXT_STMT -L11 (16): V8 = FETCH_CLASS (exception) CV1($a) -L12 (16): INIT_STATIC_METHOD_CALL 0 V8 string("show_one") -L13 (16): DO_FCALL -L14 (16): RETURN int(1) -LIVE RANGES: - 5: L7 - L9 (new) - -A::__construct: ; (lines=7, args=1, vars=1, tmps=1) - ; (before optimizer) - ; /home/user/gitlab/static-tools---latex/paper_code/PHP/Testability_Patterns/48_static_method_from_variable/48_static_method_from_variable.php:5-7 -L0 (5): EXT_NOP -L1 (5): CV0($b) = RECV 1 -L2 (6): EXT_STMT -L3 (6): ASSIGN_OBJ THIS string("one") -L4 (6): OP_DATA CV0($b) -L5 (7): EXT_STMT -L6 (7): RETURN null - -A::show_one: ; (lines=6, args=0, vars=0, tmps=1) - ; (before optimizer) - ; /home/user/gitlab/static-tools---latex/paper_code/PHP/Testability_Patterns/48_static_method_from_variable/48_static_method_from_variable.php:9-11 -L0 (9): EXT_NOP -L1 (10): EXT_STMT -L2 (10): T0 = FETCH_OBJ_R THIS string("one") -L3 (10): ECHO T0 -L4 (11): EXT_STMT -L5 (11): RETURN null + +$_main: + ; (lines=13, args=0, vars=3, tmps=9) + ; (before optimizer) + ; /.../PHP/45_static_method_from_variable/1_instance_45_static_method_from_variable/1_instance_45_static_method_from_variable.php:1-12 + ; return [] RANGE[0..0] +0000 T3 = FETCH_R (global) string("_GET") +0001 T4 = FETCH_DIM_R T3 string("p1") +0002 ASSIGN CV0($b) T4 +0003 V6 = NEW 0 string("A") +0004 DO_FCALL +0005 ASSIGN CV1($a) V6 +0006 V9 = FETCH_CLASS (exception) CV1($a) +0007 INIT_STATIC_METHOD_CALL 1 V9 string("show_one") +0008 SEND_VAR_EX CV0($b) 1 +0009 V10 = DO_FCALL +0010 ASSIGN CV2($c) V10 +0011 ECHO CV2($c) +0012 RETURN int(1) +LIVE RANGES: + 6: 0004 - 0005 (new) + +A::show_one: + ; (lines=3, args=1, vars=1, tmps=0) + ; (before optimizer) + ; /.../PHP/45_static_method_from_variable/1_instance_45_static_method_from_variable/1_instance_45_static_method_from_variable.php:3-5 + ; return [] RANGE[0..0] +0000 CV0($a) = RECV 1 +0001 RETURN CV0($a) +0002 RETURN null diff --git a/PHP/45_static_method_from_variable/1_instance_45_static_method_from_variable/1_instance_45_static_method_from_variable.json b/PHP/45_static_method_from_variable/1_instance_45_static_method_from_variable/1_instance_45_static_method_from_variable.json old mode 100644 new mode 100755 index 31571ee..877b999 --- a/PHP/45_static_method_from_variable/1_instance_45_static_method_from_variable/1_instance_45_static_method_from_variable.json +++ b/PHP/45_static_method_from_variable/1_instance_45_static_method_from_variable/1_instance_45_static_method_from_variable.json @@ -1,37 +1,38 @@ -{ - "code": { - "path": "./1_instance_45_static_method_from_variable.php", - "injection_skeleton_broken": false - }, - "discovery": { - "rule": "./1_instance_45_static_method_from_variable.sc", - "method": "joern", - "rule_accuracy": null, - "notes": null - }, - "compile": { - "binary": "./1_instance_45_static_method_from_variable.bash", - "instruction": null, - "dependencies": null - }, - "expectation": { - "type": "xss", - "sink_file": "./1_instance_45_static_method_from_variable.php", - "sink_line": 10, - "source_file": "./1_instance_45_static_method_from_variable.php", - "source_line": 14, - "expectation": true - }, - "properties": { - "category": "D2", - "feature_vs_internal_api": "FEATURE", - "input_sanitizer": false, - "source_and_sink": false, - "negative_test_case": false - }, - "remediation": { - "notes": "", - "transformation": null, - "modeling_rule": null - } +{ + "description": "This instance calls a static function on a variable. That variable contains an instance of a class.", + "code": { + "path": "./1_instance_45_static_method_from_variable.php", + "injection_skeleton_broken": false + }, + "discovery": { + "rule": "./1_instance_45_static_method_from_variable.sc", + "method": "joern", + "rule_accuracy": "FP", + "notes": "The rule searches for `INIT_STATIC_METHOD_CALL` where the first argument is a variable." + }, + "compile": { + "binary": "./1_instance_45_static_method_from_variable.bash", + "instruction": null, + "dependencies": null + }, + "expectation": { + "type": "xss", + "sink_file": "./1_instance_45_static_method_from_variable.php", + "sink_line": 11, + "source_file": "./1_instance_45_static_method_from_variable.php", + "source_line": 8, + "expectation": true + }, + "properties": { + "category": "D2", + "feature_vs_internal_api": "FEATURE", + "input_sanitizer": false, + "source_and_sink": false, + "negative_test_case": false + }, + "remediation": { + "notes": "", + "transformation": null, + "modeling_rule": null + } } \ No newline at end of file diff --git a/PHP/45_static_method_from_variable/1_instance_45_static_method_from_variable/1_instance_45_static_method_from_variable.php b/PHP/45_static_method_from_variable/1_instance_45_static_method_from_variable/1_instance_45_static_method_from_variable.php old mode 100644 new mode 100755 index 7aa6c7c..364c7de --- a/PHP/45_static_method_from_variable/1_instance_45_static_method_from_variable/1_instance_45_static_method_from_variable.php +++ b/PHP/45_static_method_from_variable/1_instance_45_static_method_from_variable/1_instance_45_static_method_from_variable.php @@ -1,16 +1,11 @@ -one = $b; - } - - static function show_one() { - echo $this->one; - } - } - -$b = $_GET["p1"]; -$a = new A($b); -$a::show_one(); \ No newline at end of file +one = $b; - } - - static function show_one() { - echo $this->one; - } - } - -$b = $_GET["p1"]; -$a = new A($b); -$a::show_one(); -``` - -- MEASUREMENT: - -| Tool | RIPS | phpSAFE | WAP | Progpilot | Comm_1 | Comm_2 | Correct | -| ------------- | ---- | ------- | ---- | --------- | ------- | --------- | ------- | -| Vulnerability | NO | NO |NO | YES | NO | YES | YES | -Measurements Date: 8 June 2021 - -- OPCODE: - -```bash -$_main: ; (lines=15, args=0, vars=2, tmps=8) - ; (before optimizer) - ; /home/user/gitlab/static-tools---latex/paper_code/PHP/Testability_Patterns/48_static_method_from_variable/48_static_method_from_variable.php:1-16 -L0 (3): NOP -L1 (14): EXT_STMT -L2 (14): T2 = FETCH_R (global) string("_GET") -L3 (14): T3 = FETCH_DIM_R T2 string("p1") -L4 (14): ASSIGN CV0($b) T3 -L5 (15): EXT_STMT -L6 (15): V5 = NEW 1 string("A") -L7 (15): SEND_VAR_EX CV0($b) 1 -L8 (15): DO_FCALL -L9 (15): ASSIGN CV1($a) V5 -L10 (16): EXT_STMT -L11 (16): V8 = FETCH_CLASS (exception) CV1($a) -L12 (16): INIT_STATIC_METHOD_CALL 0 V8 string("show_one") -L13 (16): DO_FCALL -L14 (16): RETURN int(1) -LIVE RANGES: - 5: L7 - L9 (new) - -A::__construct: ; (lines=7, args=1, vars=1, tmps=1) - ; (before optimizer) - ; /home/user/gitlab/static-tools---latex/paper_code/PHP/Testability_Patterns/48_static_method_from_variable/48_static_method_from_variable.php:5-7 -L0 (5): EXT_NOP -L1 (5): CV0($b) = RECV 1 -L2 (6): EXT_STMT -L3 (6): ASSIGN_OBJ THIS string("one") -L4 (6): OP_DATA CV0($b) -L5 (7): EXT_STMT -L6 (7): RETURN null - -A::show_one: ; (lines=6, args=0, vars=0, tmps=1) - ; (before optimizer) - ; /home/user/gitlab/static-tools---latex/paper_code/PHP/Testability_Patterns/48_static_method_from_variable/48_static_method_from_variable.php:9-11 -L0 (9): EXT_NOP -L1 (10): EXT_STMT -L2 (10): T0 = FETCH_OBJ_R THIS string("one") -L3 (10): ECHO T0 -L4 (11): EXT_STMT -L5 (11): RETURN null -``` - -- DISCOVERY: - -```bash -cpg.call.name(".*INIT_STATIC_METHOD_CALL.*").argument.order(1).code("CV.*|T.*|V.*").location.l -``` - -- PRECONDITIONS: - 1. - -- TRANSFORMATION: - -``` - -``` - diff --git a/PHP/45_static_method_from_variable/README.md b/PHP/45_static_method_from_variable/README.md new file mode 100755 index 0000000..8ceb8c7 --- /dev/null +++ b/PHP/45_static_method_from_variable/README.md @@ -0,0 +1,120 @@ +[//]: # (This file is automatically generated. If you wish to make any changes, please use the JSON files and regenerate this file using the tpframework.) + +# Static Method From Variable + +Tags: sast, php, php_v7.4.9 + +Version: v1.0 + +## Description + +In PHP it is possible to call a static method from the instance of a class using the Scope Resolution Operator (`::`). + +## Overview + +| Instances | has discovery rule | discovery method | rule successfull | +|---------------------------|----------------------|--------------------|--------------------| +| [1 Instance](#1-instance) | yes | joern | yes | + +## 1 Instance + +This instance calls a static function on a variable. That variable contains an instance of a class. + +### Code + +```PHP + + +More + +
+ + +### Compile + + +```bash +$_main: + ; (lines=13, args=0, vars=3, tmps=9) + ; (before optimizer) + ; /.../PHP/45_static_method_from_variable/1_instance_45_static_method_from_variable/1_instance_45_static_method_from_variable.php:1-12 + ; return [] RANGE[0..0] +0000 T3 = FETCH_R (global) string("_GET") +0001 T4 = FETCH_DIM_R T3 string("p1") +0002 ASSIGN CV0($b) T4 +0003 V6 = NEW 0 string("A") +0004 DO_FCALL +0005 ASSIGN CV1($a) V6 +0006 V9 = FETCH_CLASS (exception) CV1($a) +0007 INIT_STATIC_METHOD_CALL 1 V9 string("show_one") +0008 SEND_VAR_EX CV0($b) 1 +0009 V10 = DO_FCALL +0010 ASSIGN CV2($c) V10 +0011 ECHO CV2($c) +0012 RETURN int(1) +LIVE RANGES: + 6: 0004 - 0005 (new) + +A::show_one: + ; (lines=3, args=1, vars=1, tmps=0) + ; (before optimizer) + ; /.../PHP/45_static_method_from_variable/1_instance_45_static_method_from_variable/1_instance_45_static_method_from_variable.php:3-5 + ; return [] RANGE[0..0] +0000 CV0($a) = RECV 1 +0001 RETURN CV0($a) +0002 RETURN null +``` + +
+ +
+ + +### Discovery + + +The rule searches for `INIT_STATIC_METHOD_CALL` where the first argument is a variable. + +```scala +val x45 = (name, "45_static_method_from_variable_iall", cpg.call.name(".*INIT_STATIC_METHOD_CALL.*").argument.order(1).code("CV.*|T.*|V.*").location.toJson); +``` + +| discovery method | expected accuracy | +|--------------------|---------------------| +| joern | FP | + +
+ +
+ + +### Measurement + + +| Tool | Comm_1 | Comm_2 | phpSAFE | Progpilot | RIPS | WAP | Ground Truth | +|-------------|----------|----------|-----------|-------------|--------|-------|----------------| +| 08 Jun 2021 | no | yes | no | yes | no | no | yes | +| 22 May 2023 | no | no | | | | | yes | + +
+ + diff --git a/PHP/45_static_method_from_variable/docs/description.md b/PHP/45_static_method_from_variable/docs/description.md new file mode 100755 index 0000000..d17ec7f --- /dev/null +++ b/PHP/45_static_method_from_variable/docs/description.md @@ -0,0 +1 @@ +In PHP it is possible to call a static method from the instance of a class using the Scope Resolution Operator (`::`). \ No newline at end of file diff --git a/PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.bash b/PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.bash old mode 100644 new mode 100755 index 11d1cc4..64ded95 --- a/PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.bash +++ b/PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.bash @@ -1,38 +1,38 @@ - -$_main: ; (lines=12, args=0, vars=1, tmps=6) - ; (before optimizer) - ; /home/user/gitlab/static-tools---latex/paper_code/PHP/Testability_Patterns/89_override/first_ex/first_ex.php:1-18 -L0 (17): EXT_STMT -L1 (17): V1 = NEW 0 string("parent_class") -L2 (17): DO_FCALL -L3 (17): ASSIGN CV0($obj) V1 -L4 (18): EXT_STMT -L5 (18): INIT_METHOD_CALL 1 CV0($obj) string("F") -L6 (18): CHECK_FUNC_ARG 1 -L7 (18): V4 = FETCH_FUNC_ARG (global) string("_GET") -L8 (18): V5 = FETCH_DIM_FUNC_ARG V4 string("p1") -L9 (18): SEND_FUNC_ARG V5 1 -L10 (18): DO_FCALL -L11 (18): RETURN int(1) -LIVE RANGES: - 1: L2 - L3 (new) - -parent_class::F: ; (lines=6, args=1, vars=1, tmps=0) - ; (before optimizer) - ; /home/user/gitlab/static-tools---latex/paper_code/PHP/Testability_Patterns/89_override/first_ex/first_ex.php:5-7 -L0 (5): EXT_NOP -L1 (5): CV0($b) = RECV 1 -L2 (6): EXT_STMT -L3 (6): ECHO CV0($b) -L4 (7): EXT_STMT -L5 (7): RETURN null - -child_class::F: ; (lines=6, args=1, vars=1, tmps=0) - ; (before optimizer) - ; /home/user/gitlab/static-tools---latex/paper_code/PHP/Testability_Patterns/89_override/first_ex/first_ex.php:11-13 -L0 (11): EXT_NOP -L1 (11): CV0($b) = RECV 1 -L2 (12): EXT_STMT -L3 (12): ECHO string("safe") -L4 (13): EXT_STMT -L5 (13): RETURN null + +$_main: + ; (lines=12, args=0, vars=3, tmps=8) + ; (before optimizer) + ; /.../PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.php:1-18 + ; return [] RANGE[0..0] +0000 T3 = FETCH_R (global) string("_GET") +0001 T4 = FETCH_DIM_R T3 string("p1") +0002 ASSIGN CV0($b) T4 +0003 V6 = NEW 0 string("parent_class") +0004 DO_FCALL +0005 ASSIGN CV1($obj) V6 +0006 INIT_METHOD_CALL 1 CV1($obj) string("F") +0007 SEND_VAR_EX CV0($b) 1 +0008 V9 = DO_FCALL +0009 ASSIGN CV2($a) V9 +0010 ECHO CV2($a) +0011 RETURN int(1) +LIVE RANGES: + 6: 0004 - 0005 (new) + +parent_class::F: + ; (lines=3, args=1, vars=1, tmps=0) + ; (before optimizer) + ; /.../PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.php:3-5 + ; return [] RANGE[0..0] +0000 CV0($b) = RECV 1 +0001 RETURN CV0($b) +0002 RETURN null + +child_class::F: + ; (lines=3, args=1, vars=1, tmps=0) + ; (before optimizer) + ; /.../PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.php:9-11 + ; return [] RANGE[0..0] +0000 CV0($b) = RECV 1 +0001 RETURN string("safe") +0002 RETURN null diff --git a/PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.json b/PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.json old mode 100644 new mode 100755 index 2573ece..105dec7 --- a/PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.json +++ b/PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.json @@ -1,37 +1,38 @@ -{ - "code": { - "path": "./1_instance_47_overriding.php", - "injection_skeleton_broken": false - }, - "discovery": { - "rule": "./1_instance_47_overriding.sc", - "method": "joern", - "rule_accuracy": null, - "notes": null - }, - "compile": { - "binary": "./1_instance_47_overriding.bash", - "instruction": null, - "dependencies": null - }, - "expectation": { - "type": "xss", - "sink_file": "./1_instance_47_overriding.php", - "sink_line": 6, - "source_file": "./1_instance_47_overriding.php", - "source_line": 18, - "expectation": true - }, - "properties": { - "category": "S0", - "feature_vs_internal_api": "FEATURE", - "input_sanitizer": false, - "source_and_sink": false, - "negative_test_case": false - }, - "remediation": { - "notes": "", - "transformation": null, - "modeling_rule": null - } +{ + "description": "This instance shows an inheritance construct, where both parent and child class implement the same function. An object of the parent class is instantiated and the function is called on that object. As it is an object of the parent class this instance is vulnerable.", + "code": { + "path": "./1_instance_47_overriding.php", + "injection_skeleton_broken": false + }, + "discovery": { + "rule": "../47_overriding.sc", + "method": "joern", + "rule_accuracy": "FP", + "notes": "The rule would be perfect, if we could check for inheritance. This instance might profid from source code discovery." + }, + "compile": { + "binary": "./1_instance_47_overriding.bash", + "instruction": null, + "dependencies": null + }, + "expectation": { + "type": "xss", + "sink_file": "./1_instance_47_overriding.php", + "sink_line": 17, + "source_file": "./1_instance_47_overriding.php", + "source_line": 14, + "expectation": true + }, + "properties": { + "category": "S0", + "feature_vs_internal_api": "FEATURE", + "input_sanitizer": false, + "source_and_sink": false, + "negative_test_case": false + }, + "remediation": { + "notes": "", + "transformation": null, + "modeling_rule": null + } } \ No newline at end of file diff --git a/PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.php b/PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.php old mode 100644 new mode 100755 index 2be311e..32cdc96 --- a/PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.php +++ b/PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.php @@ -1,18 +1,17 @@ -F($_GET['p1']); \ No newline at end of file +F($b); +echo $a; // sink diff --git a/PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.py b/PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.py deleted file mode 100644 index b3e4e06..0000000 --- a/PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.py +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/bin/env python3 -import shutil -import subprocess -import sys -import os -from pathlib import Path - -def run_scala_query(project_folder): - ROOT_DIR = os.path.abspath('/TP_Automatic_Framework') #TODO: to fix. On docker is ok, but not for Linux - my_dir = Path(ROOT_DIR) / Path('testability_patterns/PHP/47_overriding') - cpg_php = os.path.abspath(Path(ROOT_DIR) / Path('joern/querydb-php')) - scala_query = my_dir / Path('./47_methods.sc') - - # 1) Generate binary for each file of the project - # 2) Scala query launch - binary_folder = os.path.abspath(project_folder / Path('binary_for_cpg_overr')) - if not os.path.exists(binary_folder): - os.mkdir(binary_folder) - # NOTE: to properly run, we need to be in the joern directory - os.chdir(cpg_php) - binary_file = binary_folder / Path("binary.bin") - cmd1 = 'bash php2cpg ' + str(project_folder) + " --interactive false -o " + str(binary_file) - os.system(cmd1) - cmd2 = 'bash joern --script ' + str(scala_query) + " --params name=" + str(binary_file) - result = subprocess.check_output(cmd2, shell=True) - # result retrieved and parsed to have all the information to create a Discovery object - results = result.decode('utf-8-sig') - os.chdir(my_dir) - shutil.rmtree(binary_folder) - return results - -if __name__ == "__main__": - project_folder = Path(sys.argv[1]) - cmd = "grep -Hn -r 'class.*extends' " + str(project_folder) - try: - result = subprocess.check_output(cmd, shell=True) - results = result.decode('utf-8-sig') - co = 0 - data = results - methods_list = run_scala_query(project_folder) #obtained from scala query - methods_list = methods_list[5:][:-2] - methods = methods_list.replace("), (", ")AAAAA(").split("AAAAA") - res = 0 - resin = 0 - for line in data.split("\n"): - if line == "" or ".php:" not in line: - continue - dir = line.split(".php:")[0] + ".php" - line = line.split(".php:")[1].lower() - if "class" not in line: - continue - parent = line.replace("{", " ").split("extends")[1] - ls = parent.split(" ") - cls = line.split("class")[1].split("extends")[0].replace(" ", "") - par = "" - for l in ls: - if l != "": - par = l - break - # print("Class: "+cls+" Parent: "+par) - ls_cls = [] # list of classes - ls_par = [] # list of parents - dt = {} - for m in methods: - m = m[1:][:-1] - if m == "": - continue - cs = m.split(",") - if par in cs[1]: - ls_par.append(cs[0]) - if cls in cs[1]: - ls_cls.append(cs[0]) - for f in ls_par: - if f in ls_cls and f not in dt: - # res = res + 1 - # print(dir) - if f[0] == "_" and f[1] == "_": - continue - try: - with open(dir, 'r', encoding='utf8') as fl3: - conts = fl3.read() - conts = conts.lower() - if "function " + f in conts: - print(dir + '%' + line.split(":")[0]) - dt[f] = 1 - except: - continue - except: - print('') - - - - - - diff --git a/PHP/47_overriding/2_instance_47_overriding/2_instance_47_overriding.bash b/PHP/47_overriding/2_instance_47_overriding/2_instance_47_overriding.bash new file mode 100755 index 0000000..6f3321c --- /dev/null +++ b/PHP/47_overriding/2_instance_47_overriding/2_instance_47_overriding.bash @@ -0,0 +1,38 @@ + +$_main: + ; (lines=12, args=0, vars=3, tmps=8) + ; (before optimizer) + ; /.../PHP/47_overriding/2_instance_47_overriding/2_instance_47_overriding.php:1-19 + ; return [] RANGE[0..0] +0000 T3 = FETCH_R (global) string("_GET") +0001 T4 = FETCH_DIM_R T3 string("p1") +0002 ASSIGN CV0($b) T4 +0003 V6 = NEW 0 string("child_class") +0004 DO_FCALL +0005 ASSIGN CV1($obj) V6 +0006 INIT_METHOD_CALL 1 CV1($obj) string("F") +0007 SEND_VAR_EX CV0($b) 1 +0008 V9 = DO_FCALL +0009 ASSIGN CV2($a) V9 +0010 ECHO CV2($a) +0011 RETURN int(1) +LIVE RANGES: + 6: 0004 - 0005 (new) + +parent_class::F: + ; (lines=3, args=1, vars=1, tmps=0) + ; (before optimizer) + ; /.../PHP/47_overriding/2_instance_47_overriding/2_instance_47_overriding.php:3-5 + ; return [] RANGE[0..0] +0000 CV0($b) = RECV 1 +0001 RETURN CV0($b) +0002 RETURN null + +child_class::F: + ; (lines=3, args=1, vars=1, tmps=0) + ; (before optimizer) + ; /.../PHP/47_overriding/2_instance_47_overriding/2_instance_47_overriding.php:9-11 + ; return [] RANGE[0..0] +0000 CV0($b) = RECV 1 +0001 RETURN string("safe") +0002 RETURN null diff --git a/PHP/47_overriding/2_instance_47_overriding/2_instance_47_overriding.json b/PHP/47_overriding/2_instance_47_overriding/2_instance_47_overriding.json new file mode 100755 index 0000000..ac44e46 --- /dev/null +++ b/PHP/47_overriding/2_instance_47_overriding/2_instance_47_overriding.json @@ -0,0 +1,38 @@ +{ + "description": "This instance is similar to the previous instance. The difference is, that this time the object is instantiated from the child class and the function in the child class is not vulnerable.", + "code": { + "path": "./2_instance_47_overriding.php", + "injection_skeleton_broken": false + }, + "expectation": { + "type": "xss", + "sink_file": "./2_instance_47_overriding.php", + "sink_line": 18, + "source_file": "./2_instance_47_overriding.php", + "source_line": 14, + "expectation": false + }, + "compile": { + "binary": "./2_instance_47_overriding.bash", + "instruction": null, + "dependencies": null + }, + "discovery": { + "rule": "../47_overriding.sc", + "method": "joern", + "rule_accuracy": "FP", + "notes": "The rule would be perfect, if we could check for inheritance" + }, + "properties": { + "category": "S0", + "feature_vs_internal_api": "FEATURE", + "input_sanitizer": false, + "source_and_sink": false, + "negative_test_case": false + }, + "remediation": { + "notes": "", + "transformation": null, + "modeling_rule": null + } +} \ No newline at end of file diff --git a/PHP/47_overriding/2_instance_47_overriding/2_instance_47_overriding.php b/PHP/47_overriding/2_instance_47_overriding/2_instance_47_overriding.php new file mode 100755 index 0000000..b87257e --- /dev/null +++ b/PHP/47_overriding/2_instance_47_overriding/2_instance_47_overriding.php @@ -0,0 +1,18 @@ +F($b); +echo $a; // sink diff --git a/PHP/47_overriding/47_methods.sc b/PHP/47_overriding/47_methods.sc deleted file mode 100644 index 5970073..0000000 --- a/PHP/47_overriding/47_methods.sc +++ /dev/null @@ -1,8 +0,0 @@ -@main def main(name : String): Unit = { - importCpg(name) - println("*********************************************") - val x = cpg.method.astParentType("TYPE_DECL").map{x => (x.name,x.astParentFullName)}.l; - println(x) - println("*********************************************") - delete; -} \ No newline at end of file diff --git a/PHP/47_overriding/47_overriding.json b/PHP/47_overriding/47_overriding.json old mode 100644 new mode 100755 index 1718ff9..a903b49 --- a/PHP/47_overriding/47_overriding.json +++ b/PHP/47_overriding/47_overriding.json @@ -1,14 +1,15 @@ -{ - "name": "Overriding", - "description": "", - "family": "code_pattern_php", - "tags": [ - "sast", - "php", - "php_v7.4.9" - ], - "instances": [ - "./1_instance_47_overriding/1_instance_47_overriding.json" - ], - "version": "v0.draft" +{ + "name": "Overriding", + "description": "./docs/description.md", + "family": "code_pattern_php", + "tags": [ + "sast", + "php", + "php_v7.4.9" + ], + "instances": [ + "./1_instance_47_overriding/1_instance_47_overriding.json", + "./2_instance_47_overriding/2_instance_47_overriding.json" + ], + "version": "v1.0" } \ No newline at end of file diff --git a/PHP/47_overriding/47_overriding.sc b/PHP/47_overriding/47_overriding.sc new file mode 100755 index 0000000..1adc8e6 --- /dev/null +++ b/PHP/47_overriding/47_overriding.sc @@ -0,0 +1,10 @@ +@main def main(name : String): Unit = { + importCpg(name) + // Get all classes and all the methods within this classes as a list of arrays with two elements [[, ], [, ]] + val allClassesAndMethods = cpg.method.astParentType("TYPE_DECL").fullName.l.map(x => x.split("::")).filter(x => x.length > 1) + // Get all classnames, that implement the same method as any other class + val classNames = allClassesAndMethods.flatMap(a => allClassesAndMethods.filter(b => b(1) == a(1) && b(0) != a(0)).map(b => (a(0), b(1)))).toSet + val x47 = (name, "47_overriding_iall", cpg.method.filter(node => classNames.contains((node.astParentFullName, node.name))).location.toJson); + println(x47) + delete; +} \ No newline at end of file diff --git a/PHP/47_overriding/Pattern Override.md b/PHP/47_overriding/Pattern Override.md deleted file mode 100644 index 9f6cca3..0000000 --- a/PHP/47_overriding/Pattern Override.md +++ /dev/null @@ -1,104 +0,0 @@ -# Pattern: Overriding - -## Category - -Objects - -## Definition - -## Instances - -### Instance 1 - -- CATEGORY: S0 -- FEATURE vs INTERNAL API: FEATURE -- INPUT SANITIZERS: NO -- SOURCES AND SINKS: NO -- NEGATIVE TEST CASES: NO -- CODE: - -```php -F($_GET['p1']); -``` - -- MEASUREMENT: - -| Tool | RIPS | phpSAFE | WAP | Progpilot | Comm_1 | Comm_2 | Correct | -| ------------- | ---- | ------- | ---- | --------- | ------- | --------- | ------- | -| Vulnerability | NO | NO | NO | YES | YES | YES | YES | -Measurements Date: 8 June 2021 - -- OPCODE: - -```bash -$_main: ; (lines=12, args=0, vars=1, tmps=6) - ; (before optimizer) - ; /home/user/gitlab/static-tools---latex/paper_code/PHP/Testability_Patterns/89_override/first_ex/first_ex.php:1-18 -L0 (17): EXT_STMT -L1 (17): V1 = NEW 0 string("parent_class") -L2 (17): DO_FCALL -L3 (17): ASSIGN CV0($obj) V1 -L4 (18): EXT_STMT -L5 (18): INIT_METHOD_CALL 1 CV0($obj) string("F") -L6 (18): CHECK_FUNC_ARG 1 -L7 (18): V4 = FETCH_FUNC_ARG (global) string("_GET") -L8 (18): V5 = FETCH_DIM_FUNC_ARG V4 string("p1") -L9 (18): SEND_FUNC_ARG V5 1 -L10 (18): DO_FCALL -L11 (18): RETURN int(1) -LIVE RANGES: - 1: L2 - L3 (new) - -parent_class::F: ; (lines=6, args=1, vars=1, tmps=0) - ; (before optimizer) - ; /home/user/gitlab/static-tools---latex/paper_code/PHP/Testability_Patterns/89_override/first_ex/first_ex.php:5-7 -L0 (5): EXT_NOP -L1 (5): CV0($b) = RECV 1 -L2 (6): EXT_STMT -L3 (6): ECHO CV0($b) -L4 (7): EXT_STMT -L5 (7): RETURN null - -child_class::F: ; (lines=6, args=1, vars=1, tmps=0) - ; (before optimizer) - ; /home/user/gitlab/static-tools---latex/paper_code/PHP/Testability_Patterns/89_override/first_ex/first_ex.php:11-13 -L0 (11): EXT_NOP -L1 (11): CV0($b) = RECV 1 -L2 (12): EXT_STMT -L3 (12): ECHO string("safe") -L4 (13): EXT_STMT -L5 (13): RETURN null -``` - -- DISCOVERY: - -```bash -SCRIPTING -``` - -- PRECONDITIONS: - 1. - -- TRANSFORMATION: T1 - -``` - -``` - diff --git a/PHP/47_overriding/README.md b/PHP/47_overriding/README.md new file mode 100755 index 0000000..72d35f7 --- /dev/null +++ b/PHP/47_overriding/README.md @@ -0,0 +1,272 @@ +[//]: # (This file is automatically generated. If you wish to make any changes, please use the JSON files and regenerate this file using the tpframework.) + +# Overriding + +Tags: sast, php, php_v7.4.9 + +Version: v1.0 + +## Description + +A child class can override a method from a parent class by implementing this function with the same parameters and the same return type. + +## Overview + +| Instances | has discovery rule | discovery method | rule successfull | +|---------------------------|----------------------|--------------------|--------------------| +| [1 Instance](#1-instance) | yes | joern | no | +| [2 Instance](#2-instance) | yes | joern | no | + +
+ + +## 1 Instance + + +This instance shows an inheritance construct, where both parent and child class implement the same function. An object of the parent class is instantiated and the function is called on that object. As it is an object of the parent class this instance is vulnerable. + +### Code + +```PHP +F($b); +echo $a; // sink +``` + +### Instance Properties + +| category | feature_vs_internal_api | input_sanitizer | negative_test_case | source_and_sink | +|------------|---------------------------|-------------------|----------------------|-------------------| +| S0 | FEATURE | no | no | no | + +
+ +More + +
+ + +### Compile + + +```bash +$_main: + ; (lines=12, args=0, vars=3, tmps=8) + ; (before optimizer) + ; /.../PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.php:1-18 + ; return [] RANGE[0..0] +0000 T3 = FETCH_R (global) string("_GET") +0001 T4 = FETCH_DIM_R T3 string("p1") +0002 ASSIGN CV0($b) T4 +0003 V6 = NEW 0 string("parent_class") +0004 DO_FCALL +0005 ASSIGN CV1($obj) V6 +0006 INIT_METHOD_CALL 1 CV1($obj) string("F") +0007 SEND_VAR_EX CV0($b) 1 +0008 V9 = DO_FCALL +0009 ASSIGN CV2($a) V9 +0010 ECHO CV2($a) +0011 RETURN int(1) +LIVE RANGES: + 6: 0004 - 0005 (new) + +parent_class::F: + ; (lines=3, args=1, vars=1, tmps=0) + ; (before optimizer) + ; /.../PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.php:3-5 + ; return [] RANGE[0..0] +0000 CV0($b) = RECV 1 +0001 RETURN CV0($b) +0002 RETURN null + +child_class::F: + ; (lines=3, args=1, vars=1, tmps=0) + ; (before optimizer) + ; /.../PHP/47_overriding/1_instance_47_overriding/1_instance_47_overriding.php:9-11 + ; return [] RANGE[0..0] +0000 CV0($b) = RECV 1 +0001 RETURN string("safe") +0002 RETURN null +``` + +
+ +
+ + +### Discovery + + +The rule would be perfect, if we could check for inheritance. This instance might profid from source code discovery. + +```scala +// Get all classes and all the methods within this classes as a list of arrays with two elements [[, ], [, ]] +val allClassesAndMethods = cpg.method.astParentType("TYPE_DECL").fullName.l.map(x => x.split("::")).filter(x => x.length > 1) +// Get all classnames, that implement the same method as any other class +val classNames = allClassesAndMethods.flatMap(a => allClassesAndMethods.filter(b => b(1) == a(1) && b(0) != a(0)).map(b => (a(0), b(1)))).toSet +val x47 = (name, "47_overriding_iall", cpg.method.filter(node => classNames.contains((node.astParentFullName, node.name))).location.toJson); +``` + +| discovery method | expected accuracy | +|--------------------|---------------------| +| joern | FP | + +
+ +
+ + +### Measurement + + +| Tool | Comm_1 | Comm_2 | phpSAFE | Progpilot | RIPS | WAP | Ground Truth | +|-------------|----------|----------|-----------|-------------|--------|-------|----------------| +| 08 Jun 2021 | yes | yes | no | yes | no | no | yes | +| 22 May 2023 | yes | yes | | | | | yes | + +
+ +
+ +
+ +
+ + +## 2 Instance + + +This instance is similar to the previous instance. The difference is, that this time the object is instantiated from the child class and the function in the child class is not vulnerable. + +### Code + +```PHP +F($b); +echo $a; // sink +``` + +### Instance Properties + +| category | feature_vs_internal_api | input_sanitizer | negative_test_case | source_and_sink | +|------------|---------------------------|-------------------|----------------------|-------------------| +| S0 | FEATURE | no | no | no | + +
+ +More + +
+ + +### Compile + + +```bash +$_main: + ; (lines=12, args=0, vars=3, tmps=8) + ; (before optimizer) + ; /.../PHP/47_overriding/2_instance_47_overriding/2_instance_47_overriding.php:1-19 + ; return [] RANGE[0..0] +0000 T3 = FETCH_R (global) string("_GET") +0001 T4 = FETCH_DIM_R T3 string("p1") +0002 ASSIGN CV0($b) T4 +0003 V6 = NEW 0 string("child_class") +0004 DO_FCALL +0005 ASSIGN CV1($obj) V6 +0006 INIT_METHOD_CALL 1 CV1($obj) string("F") +0007 SEND_VAR_EX CV0($b) 1 +0008 V9 = DO_FCALL +0009 ASSIGN CV2($a) V9 +0010 ECHO CV2($a) +0011 RETURN int(1) +LIVE RANGES: + 6: 0004 - 0005 (new) + +parent_class::F: + ; (lines=3, args=1, vars=1, tmps=0) + ; (before optimizer) + ; /.../PHP/47_overriding/2_instance_47_overriding/2_instance_47_overriding.php:3-5 + ; return [] RANGE[0..0] +0000 CV0($b) = RECV 1 +0001 RETURN CV0($b) +0002 RETURN null + +child_class::F: + ; (lines=3, args=1, vars=1, tmps=0) + ; (before optimizer) + ; /.../PHP/47_overriding/2_instance_47_overriding/2_instance_47_overriding.php:9-11 + ; return [] RANGE[0..0] +0000 CV0($b) = RECV 1 +0001 RETURN string("safe") +0002 RETURN null +``` + +
+ +
+ + +### Discovery + + +The rule would be perfect, if we could check for inheritance + +```scala +// Get all classes and all the methods within this classes as a list of arrays with two elements [[, ], [, ]] +val allClassesAndMethods = cpg.method.astParentType("TYPE_DECL").fullName.l.map(x => x.split("::")).filter(x => x.length > 1) +// Get all classnames, that implement the same method as any other class +val classNames = allClassesAndMethods.flatMap(a => allClassesAndMethods.filter(b => b(1) == a(1) && b(0) != a(0)).map(b => (a(0), b(1)))).toSet +val x47 = (name, "47_overriding_iall", cpg.method.filter(node => classNames.contains((node.astParentFullName, node.name))).location.toJson); +``` + +| discovery method | expected accuracy | +|--------------------|---------------------| +| joern | FP | + +
+ +
+ + +### Measurement + + +| Tool | Comm_1 | Ground Truth | +|-------------|----------|----------------| +| 22 May 2023 | no | no | + +
+ +
+ +
diff --git a/PHP/47_overriding/docs/description.md b/PHP/47_overriding/docs/description.md new file mode 100755 index 0000000..73ca60c --- /dev/null +++ b/PHP/47_overriding/docs/description.md @@ -0,0 +1 @@ +A child class can override a method from a parent class by implementing this function with the same parameters and the same return type. \ No newline at end of file diff --git a/PHP/6_coalesce/1_instance_6_coalesce/1_instance_6_coalesce.bash b/PHP/6_coalesce/1_instance_6_coalesce/1_instance_6_coalesce.bash old mode 100644 new mode 100755 index babdd96..42c3d5b --- a/PHP/6_coalesce/1_instance_6_coalesce/1_instance_6_coalesce.bash +++ b/PHP/6_coalesce/1_instance_6_coalesce/1_instance_6_coalesce.bash @@ -1,18 +1,16 @@ - -$_main: ; (lines=14, args=0, vars=3, tmps=7) - ; (before optimizer) - ; /home/user/gitlab/static-tools---latex/paper_code/PHP/Testability_Patterns/116_coalesce/116_coalesce.php:1-8 -L0 (2): EXT_STMT -L1 (2): T3 = FETCH_R (global) string("_GET") -L2 (2): T4 = FETCH_DIM_R T3 string("p1") -L3 (2): ASSIGN CV0($b) T4 -L4 (4): EXT_STMT -L5 (4): ASSIGN CV1($arr) array(...) -L6 (5): EXT_STMT -L7 (5): T7 = FETCH_DIM_IS CV1($arr) int(4) -L8 (5): T8 = COALESCE T7 L10 -L9 (5): T8 = QM_ASSIGN CV0($b) -L10 (5): ASSIGN CV2($x) T8 -L11 (6): EXT_STMT -L12 (6): ECHO CV2($x) -L13 (8): RETURN int(1) + +$_main: + ; (lines=10, args=0, vars=3, tmps=7) + ; (before optimizer) + ; /.../PHP/6_coalesce/1_instance_6_coalesce/1_instance_6_coalesce.php:1-5 + ; return [] RANGE[0..0] +0000 T3 = FETCH_R (global) string("_GET") +0001 T4 = FETCH_DIM_R T3 string("p1") +0002 ASSIGN CV0($a) T4 +0003 ASSIGN CV1($arr) array(...) +0004 T7 = FETCH_DIM_IS CV1($arr) int(4) +0005 T8 = COALESCE T7 0007 +0006 T8 = QM_ASSIGN CV0($a) +0007 ASSIGN CV2($b) T8 +0008 ECHO CV2($b) +0009 RETURN int(1) diff --git a/PHP/6_coalesce/1_instance_6_coalesce/1_instance_6_coalesce.json b/PHP/6_coalesce/1_instance_6_coalesce/1_instance_6_coalesce.json old mode 100644 new mode 100755 index 5bd47c1..e59fbdc --- a/PHP/6_coalesce/1_instance_6_coalesce/1_instance_6_coalesce.json +++ b/PHP/6_coalesce/1_instance_6_coalesce/1_instance_6_coalesce.json @@ -1,37 +1,38 @@ -{ - "code": { - "path": "./1_instance_6_coalesce.php", - "injection_skeleton_broken": false - }, - "discovery": { - "rule": "./1_instance_6_coalesce.sc", - "method": "joern", - "rule_accuracy": "Perfect", - "notes": "This rule should discover all usages of the null coalescing operator" - }, - "compile": { - "binary": "./1_instance_6_coalesce.bash", - "instruction": null, - "dependencies": null - }, - "expectation": { - "type": "xss", - "sink_file": "./1_instance_6_coalesce.php", - "sink_line": 6, - "source_file": "./1_instance_6_coalesce.php", - "source_line": 2, - "expectation": true - }, - "properties": { - "category": "S0", - "feature_vs_internal_api": "FEATURE", - "input_sanitizer": false, - "source_and_sink": false, - "negative_test_case": false - }, - "remediation": { - "notes": "", - "transformation": null, - "modeling_rule": null - } +{ + "description": "This instance targets the use of the coalescing operator when we try to access an array element, that does not exist.", + "code": { + "path": "./1_instance_6_coalesce.php", + "injection_skeleton_broken": false + }, + "discovery": { + "rule": "../6_coalesce.sc", + "method": "joern", + "rule_accuracy": "Perfect", + "notes": "This rule should discover all usages of the null coalescing operator" + }, + "compile": { + "binary": "./1_instance_6_coalesce.bash", + "instruction": null, + "dependencies": null + }, + "expectation": { + "type": "xss", + "sink_file": "./1_instance_6_coalesce.php", + "sink_line": 5, + "source_file": "./1_instance_6_coalesce.php", + "source_line": 2, + "expectation": true + }, + "properties": { + "category": "S0", + "feature_vs_internal_api": "FEATURE", + "input_sanitizer": false, + "source_and_sink": false, + "negative_test_case": false + }, + "remediation": { + "notes": "One could transform that case by inserting an if-statement, that checks for the length of the array before accessing certain indices. That might not work in all the cases though.", + "transformation": null, + "modeling_rule": null + } } \ No newline at end of file diff --git a/PHP/6_coalesce/1_instance_6_coalesce/1_instance_6_coalesce.php b/PHP/6_coalesce/1_instance_6_coalesce/1_instance_6_coalesce.php old mode 100644 new mode 100755 index e4d7964..c20ac5d --- a/PHP/6_coalesce/1_instance_6_coalesce/1_instance_6_coalesce.php +++ b/PHP/6_coalesce/1_instance_6_coalesce/1_instance_6_coalesce.php @@ -1,5 +1,5 @@ - + + +## 1 Instance + + +This instance targets the use of the coalescing operator when we try to access an array element, that does not exist. + +### Code + +```PHP + + +More + +
+ + +### Compile + + +```bash +$_main: + ; (lines=10, args=0, vars=3, tmps=7) + ; (before optimizer) + ; /.../PHP/6_coalesce/1_instance_6_coalesce/1_instance_6_coalesce.php:1-5 + ; return [] RANGE[0..0] +0000 T3 = FETCH_R (global) string("_GET") +0001 T4 = FETCH_DIM_R T3 string("p1") +0002 ASSIGN CV0($a) T4 +0003 ASSIGN CV1($arr) array(...) +0004 T7 = FETCH_DIM_IS CV1($arr) int(4) +0005 T8 = COALESCE T7 0007 +0006 T8 = QM_ASSIGN CV0($a) +0007 ASSIGN CV2($b) T8 +0008 ECHO CV2($b) +0009 RETURN int(1) +``` + +
+ +
+ + +### Discovery + + +This rule should discover all usages of the null coalescing operator + +```scala +val x6 = (name, "6_coalesce_iall", cpg.call(".*COALESCE.*").location.toJson); +``` + +| discovery method | expected accuracy | +|--------------------|---------------------| +| joern | Perfect | + +
+ +
+ + +### Measurement + + +| Tool | Comm_1 | Comm_2 | phpSAFE | Progpilot | RIPS | WAP | Ground Truth | +|-------------|----------|----------|-----------|-------------|--------|-------|----------------| +| 08 Jun 2021 | yes | yes | yes | no | yes | no | yes | +| 17 May 2023 | yes | yes | | | | | yes | + +
+ +
+ + +### Remediation + + +One could transform that case by inserting an if-statement, that checks for the length of the array before accessing certain indices. That might not work in all the cases though. + +
+ + + + + +
+ + +## 2 Instance + + +This instance should show, that `null` triggers the alternative value to be inserted. + +### Code + +```PHP + + +More + +
+ + +### Compile + + +```bash +$_main: + ; (lines=8, args=0, vars=2, tmps=5) + ; (before optimizer) + ; /.../PHP/6_coalesce/2_instance_6_coalesce/2_instance_6_coalesce.php:1-4 + ; return [] RANGE[0..0] +0000 T2 = FETCH_R (global) string("_GET") +0001 T3 = FETCH_DIM_R T2 string("p1") +0002 ASSIGN CV0($a) T3 +0003 T5 = COALESCE null 0005 +0004 T5 = QM_ASSIGN CV0($a) +0005 ASSIGN CV1($b) T5 +0006 ECHO CV1($b) +0007 RETURN int(1) +``` + +
+ +
+ + +### Discovery + + +This rule should discover all usages of the null coalescing operator + +```scala +val x6 = (name, "6_coalesce_iall", cpg.call(".*COALESCE.*").location.toJson); +``` + +| discovery method | expected accuracy | +|--------------------|---------------------| +| joern | Perfect | + +
+ +
+ + +### Measurement + + +| Tool | Comm_1 | Comm_2 | Ground Truth | +|-------------|----------|----------|----------------| +| 17 May 2023 | yes | yes | yes | + +
+ +
+ + +### Remediation + + +One could rewrite this with an if-else statement, and check if something is `null` before assigning. + +
+ +
+ + + +
+ + +## 3 Instance + + +This instance should show, that the coalescing operator works with a short version as well. + +### Code + +```PHP + + +More + +
+ + +### Compile + + +```bash +$_main: + ; (lines=10, args=0, vars=2, tmps=6) + ; (before optimizer) + ; /.../PHP/6_coalesce/3_instance_6_coalesce/3_instance_6_coalesce.php:1-5 + ; return [] RANGE[0..0] +0000 T2 = FETCH_R (global) string("_GET") +0001 T3 = FETCH_DIM_R T2 string("p1") +0002 ASSIGN CV0($a) T3 +0003 ASSIGN CV1($b) null +0004 T6 = COALESCE CV1($b) 0007 +0005 T7 = ASSIGN CV1($b) CV0($a) +0006 T6 = QM_ASSIGN T7 +0007 FREE T6 +0008 ECHO CV1($b) +0009 RETURN int(1) +``` + +
+ +
+ + +### Discovery + + +This rule should discover all usages of the null coalescing operator + +```scala +val x6 = (name, "6_coalesce_iall", cpg.call(".*COALESCE.*").location.toJson); +``` + +| discovery method | expected accuracy | +|--------------------|---------------------| +| joern | Perfect | + +
+ +
+ + +### Measurement + + +| Tool | Comm_1 | Ground Truth | +|-------------|----------|----------------| +| 17 May 2023 | no | yes | + +
+ +
+ + +### Remediation + + +This could be transformed in an if-statement. + +
+ +
+ + diff --git a/PHP/6_coalesce/docs/description.md b/PHP/6_coalesce/docs/description.md new file mode 100755 index 0000000..0d5a65e --- /dev/null +++ b/PHP/6_coalesce/docs/description.md @@ -0,0 +1 @@ +The coalescence operator (also known as the null coalescing operator) in PHP is used to check if a variable is set and not null, and if it is not, it returns a default value. \ No newline at end of file diff --git a/PHP/75_buffer/1_instance_75_buffer/1_instance_75_buffer.bash b/PHP/75_buffer/1_instance_75_buffer/1_instance_75_buffer.bash new file mode 100755 index 0000000..9aea1e1 --- /dev/null +++ b/PHP/75_buffer/1_instance_75_buffer/1_instance_75_buffer.bash @@ -0,0 +1,19 @@ + +$_main: + ; (lines=13, args=0, vars=2, tmps=7) + ; (before optimizer) + ; /.../PHP/75_buffer/1_instance_75_buffer/1_instance_75_buffer.php:1-7 + ; return [] RANGE[0..0] +0000 T2 = FETCH_R (global) string("_GET") +0001 T3 = FETCH_DIM_R T2 string("p1") +0002 ASSIGN CV0($a) T3 +0003 INIT_FCALL 0 80 string("ob_start") +0004 DO_ICALL +0005 ECHO CV0($a) +0006 INIT_FCALL 0 80 string("ob_get_contents") +0007 V6 = DO_ICALL +0008 ASSIGN CV1($x) V6 +0009 INIT_FCALL 0 80 string("ob_end_clean") +0010 DO_ICALL +0011 ECHO CV1($x) +0012 RETURN int(1) diff --git a/PHP/75_buffer/1_instance_75_buffer/1_instance_75_buffer.json b/PHP/75_buffer/1_instance_75_buffer/1_instance_75_buffer.json old mode 100644 new mode 100755 index 23a575f..f13fb1c --- a/PHP/75_buffer/1_instance_75_buffer/1_instance_75_buffer.json +++ b/PHP/75_buffer/1_instance_75_buffer/1_instance_75_buffer.json @@ -1,37 +1,38 @@ -{ - "code": { - "path": "./1_instance_75_buffer.php", - "injection_skeleton_broken": false - }, - "discovery": { - "rule": "./1_instance_75_buffer.sc", - "method": "joern", - "rule_accuracy": "Perfect", - "notes": null - }, - "compile": { - "binary": "./1_instance_75_buffer.bash", - "instruction": null, - "dependencies": null - }, - "expectation": { - "type": "xss", - "sink_file": "./1_instance_75_buffer.php", - "sink_line": 7, - "source_file": "./1_instance_75_buffer.php", - "source_line": 2, - "expectation": true - }, - "properties": { - "category": "S0", - "feature_vs_internal_api": "INTERNAL_API", - "input_sanitizer": false, - "source_and_sink": false, - "negative_test_case": false - }, - "remediation": { - "notes": "", - "transformation": null, - "modeling_rule": null - } +{ + "description": "The instance shows an example of buffering in PHP. The variable `x` contains everything that should have been written to the output.", + "code": { + "path": "./1_instance_75_buffer.php", + "injection_skeleton_broken": false + }, + "discovery": { + "rule": "../75_buffer.sc", + "method": "joern", + "rule_accuracy": "Perfect", + "notes": "The rule searches for function calls to `ob_start` on opcode level." + }, + "compile": { + "binary": "./1_instance_75_buffer.bash", + "instruction": null, + "dependencies": null + }, + "expectation": { + "type": "xss", + "sink_file": "./1_instance_75_buffer.php", + "sink_line": 7, + "source_file": "./1_instance_75_buffer.php", + "source_line": 2, + "expectation": true + }, + "properties": { + "category": "S0", + "feature_vs_internal_api": "INTERNAL_API", + "input_sanitizer": false, + "source_and_sink": false, + "negative_test_case": false + }, + "remediation": { + "notes": "", + "transformation": null, + "modeling_rule": null + } } \ No newline at end of file diff --git a/PHP/75_buffer/1_instance_75_buffer/1_instance_75_buffer.php b/PHP/75_buffer/1_instance_75_buffer/1_instance_75_buffer.php old mode 100644 new mode 100755 index 7acb175..4864ed8 --- a/PHP/75_buffer/1_instance_75_buffer/1_instance_75_buffer.php +++ b/PHP/75_buffer/1_instance_75_buffer/1_instance_75_buffer.php @@ -1,7 +1,7 @@ - + + +## 1 Instance + + +The instance shows an example of buffering in PHP. The variable `x` contains everything that should have been written to the output. + +### Code + +```PHP + + +More + +
+ + +### Compile + + +```bash +$_main: + ; (lines=13, args=0, vars=2, tmps=7) + ; (before optimizer) + ; /.../PHP/75_buffer/1_instance_75_buffer/1_instance_75_buffer.php:1-7 + ; return [] RANGE[0..0] +0000 T2 = FETCH_R (global) string("_GET") +0001 T3 = FETCH_DIM_R T2 string("p1") +0002 ASSIGN CV0($a) T3 +0003 INIT_FCALL 0 80 string("ob_start") +0004 DO_ICALL +0005 ECHO CV0($a) +0006 INIT_FCALL 0 80 string("ob_get_contents") +0007 V6 = DO_ICALL +0008 ASSIGN CV1($x) V6 +0009 INIT_FCALL 0 80 string("ob_end_clean") +0010 DO_ICALL +0011 ECHO CV1($x) +0012 RETURN int(1) +``` + +
+ +
+ + +### Discovery + + +The rule searches for function calls to `ob_start` on opcode level. + +```scala +val x75 = (name, "75_buffer_iall", cpg.call.name(".*INIT_FCALL.*").argument.code("ob_start").astParent.location.toJson); +``` + +| discovery method | expected accuracy | +|--------------------|---------------------| +| joern | Perfect | + +
+ +
+ + +### Measurement + + +| Tool | Comm_1 | Comm_2 | Ground Truth | +|-------------|----------|----------|----------------| +| 22 May 2023 | yes | yes | yes | + +
+ + + + + +
+ + +## 2 Instance + + +This instance shows, that instead of `ob_get_contents` and `ob_end_clean`, you can use `ob_get_clean` which does the same. It returns the buffered output and ends the buffering. + +### Code + +```PHP + + +More + +
+ + +### Compile + + +```bash +$_main: + ; (lines=11, args=0, vars=2, tmps=6) + ; (before optimizer) + ; /.../PHP/75_buffer/2_instance_75_buffer/2_instance_75_buffer.php:1-6 + ; return [] RANGE[0..0] +0000 T2 = FETCH_R (global) string("_GET") +0001 T3 = FETCH_DIM_R T2 string("p1") +0002 ASSIGN CV0($a) T3 +0003 INIT_FCALL 0 80 string("ob_start") +0004 DO_ICALL +0005 ECHO CV0($a) +0006 INIT_FCALL 0 80 string("ob_get_clean") +0007 V6 = DO_ICALL +0008 ASSIGN CV1($x) V6 +0009 ECHO CV1($x) +0010 RETURN int(1) +``` + +
+ +
+ + +### Discovery + + +The rule searches for function calls to `ob_start` on opcode level. + +```scala +val x75 = (name, "75_buffer_iall", cpg.call.name(".*INIT_FCALL.*").argument.code("ob_start").astParent.location.toJson); +``` + +| discovery method | expected accuracy | +|--------------------|---------------------| +| joern | Perfect | + +
+ +
+ + +### Measurement + + +| Tool | Comm_1 | Comm_2 | Ground Truth | +|-------------|----------|----------|----------------| +| 22 May 2023 | yes | yes | yes | + +
+ +
+ + diff --git a/PHP/75_buffer/docs/description.md b/PHP/75_buffer/docs/description.md new file mode 100755 index 0000000..15f8dd8 --- /dev/null +++ b/PHP/75_buffer/docs/description.md @@ -0,0 +1,4 @@ +In PHP, [`obj_start()`](https://www.php.net/manual/en/function.ob-start.php) is a function used to start output buffering. This means that any output generated by PHP after the `ob_start()` call will not be sent to the browser or client immediately, but instead will be stored in an internal buffer. +To retrieve the contents of the buffer, you can use the [`ob_get_contents()`](https://www.php.net/manual/en/function.ob-get-contents.php) function. This function returns the contents of the buffer as a string, without clearing the buffer itself. +Once you're done with the output buffering, you can use the [`ob_end_clean()`](https://www.php.net/manual/en/function.ob-end-clean.php) function to discard the contents of the buffer and turn off output buffering. This function removes all data from the output buffer and disables buffering. +Alternatively, you can use the [`ob_get_clean()`](https://www.php.net/manual/en/function.ob-get-clean.php) function, which returns the contents of the output buffer as a string and turns off output buffering in one step. This function is equivalent to calling `ob_get_contents()` followed by `ob_end_clean()`. \ No newline at end of file diff --git a/PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.bash b/PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.bash old mode 100644 new mode 100755 index 0e0fb91..34af5ff --- a/PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.bash +++ b/PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.bash @@ -1,21 +1,19 @@ - -$_main: ; (lines=15, args=0, vars=3, tmps=7) - ; (before optimizer) - ; /home/user/gitlab/static-tools---latex/paper_code/PHP/Testability_Patterns/84_array_variable_key/first_ex/first_ex.php:1-7 -L0 (4): EXT_STMT -L1 (4): ASSIGN CV0($a) string("abc") -L2 (5): EXT_STMT -L3 (5): T4 = FETCH_R (global) string("_GET") -L4 (5): T5 = FETCH_DIM_R T4 string("p1") -L5 (5): ASSIGN CV1($b) T5 -L6 (6): EXT_STMT -L7 (6): T7 = INIT_ARRAY 3 (packed) int(1) NEXT -L8 (6): T7 = ADD_ARRAY_ELEMENT int(2) NEXT -L9 (6): T7 = ADD_ARRAY_ELEMENT CV1($b) CV0($a) -L10 (6): ASSIGN CV2($x) T7 -L11 (7): EXT_STMT -L12 (7): T9 = FETCH_DIM_R CV2($x) string("abc") -L13 (7): ECHO T9 -L14 (7): RETURN int(1) -LIVE RANGES: - 7: L8 - L10 (tmp/var) + +$_main: + ; (lines=11, args=0, vars=3, tmps=7) + ; (before optimizer) + ; /.../PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.php:1-5 + ; return [] RANGE[0..0] +0000 ASSIGN CV0($a) string("abc") +0001 T4 = FETCH_R (global) string("_GET") +0002 T5 = FETCH_DIM_R T4 string("p1") +0003 ASSIGN CV1($b) T5 +0004 T7 = INIT_ARRAY 3 (packed) int(1) NEXT +0005 T7 = ADD_ARRAY_ELEMENT int(2) NEXT +0006 T7 = ADD_ARRAY_ELEMENT CV1($b) CV0($a) +0007 ASSIGN CV2($x) T7 +0008 T9 = FETCH_DIM_R CV2($x) string("abc") +0009 ECHO T9 +0010 RETURN int(1) +LIVE RANGES: + 7: 0005 - 0007 (tmp/var) diff --git a/PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.json b/PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.json old mode 100644 new mode 100755 index 20a84b3..871e371 --- a/PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.json +++ b/PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.json @@ -1,37 +1,38 @@ -{ - "code": { - "path": "./1_instance_83_array_variable_key.php", - "injection_skeleton_broken": false - }, - "discovery": { - "rule": "./1_instance_83_array_variable_key.sc", - "method": "joern", - "rule_accuracy": null, - "notes": null - }, - "compile": { - "binary": "./1_instance_83_array_variable_key.bash", - "instruction": null, - "dependencies": null - }, - "expectation": { - "type": "xss", - "sink_file": "./1_instance_83_array_variable_key.php", - "sink_line": 7, - "source_file": "./1_instance_83_array_variable_key.php", - "source_line": 5, - "expectation": true - }, - "properties": { - "category": "D2", - "feature_vs_internal_api": "FEATURE", - "input_sanitizer": false, - "source_and_sink": false, - "negative_test_case": false - }, - "remediation": { - "notes": "", - "transformation": null, - "modeling_rule": null - } +{ + "description": "The instance creates an array, where a user defined value is assigned to 'abc'.", + "code": { + "path": "./1_instance_83_array_variable_key.php", + "injection_skeleton_broken": false + }, + "discovery": { + "rule": "./1_instance_83_array_variable_key.sc", + "method": "joern", + "rule_accuracy": "FP", + "notes": null + }, + "compile": { + "binary": "./1_instance_83_array_variable_key.bash", + "instruction": null, + "dependencies": null + }, + "expectation": { + "type": "xss", + "sink_file": "./1_instance_83_array_variable_key.php", + "sink_line": 5, + "source_file": "./1_instance_83_array_variable_key.php", + "source_line": 3, + "expectation": true + }, + "properties": { + "category": "D2", + "feature_vs_internal_api": "FEATURE", + "input_sanitizer": false, + "source_and_sink": false, + "negative_test_case": false + }, + "remediation": { + "notes": "", + "transformation": null, + "modeling_rule": null + } } \ No newline at end of file diff --git a/PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.php b/PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.php old mode 100644 new mode 100755 index 8d9d5de..9771544 --- a/PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.php +++ b/PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.php @@ -1,7 +1,5 @@ -$b); -echo $x["abc"]; \ No newline at end of file +$b); +echo $x["abc"]; // sink \ No newline at end of file diff --git a/PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.sc b/PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.sc old mode 100644 new mode 100755 index afe3c95..35299f5 --- a/PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.sc +++ b/PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.sc @@ -1,8 +1,8 @@ -@main def main(name : String): Unit = { - importCpg(name) - def G5 = cpg.call("ASSIGN").code(".*string.*").argument.order(0).isIdentifier.name.l.distinct - def R6 = cpg.call("ASSIGN_DIM|FETCH_DIM_R|FETCH_DIM_W|FETCH_DIM_RW|ADD_ARRAY_ELEMENT").l - val x94 = (name, "83_array_variable_key_D2", R6.filter{ call => G5.exists{ h => call.argument.order(1).code.l.contains("CV($" + h + ")")} }.location.toJson); - println(x94) - delete; +@main def main(name : String): Unit = { + importCpg(name) + def G5 = cpg.call("ASSIGN").code(".*string.*").argument.order(0).isIdentifier.name.l.distinct + def R6 = cpg.call("ASSIGN_DIM|FETCH_DIM_R|FETCH_DIM_W|FETCH_DIM_RW|ADD_ARRAY_ELEMENT").l + val x83 = (name, "83_array_variable_key_i1", R6.filter{ call => G5.exists{ h => call.argument.order(1).code.l.contains("CV($" + h + ")")} }.location.toJson); + println(x83) + delete; } \ No newline at end of file diff --git a/PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.bash b/PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.bash old mode 100644 new mode 100755 index 666e0ca..3594dfa --- a/PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.bash +++ b/PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.bash @@ -1,25 +1,22 @@ - -$_main: ; (lines=19, args=0, vars=4, tmps=10) - ; (before optimizer) - ; /home/user/gitlab/static-tools---latex/paper_code/PHP/Testability_Patterns/84_array_variable_key/second_ex/second_ex.php:1-6 -L0 (2): EXT_STMT -L1 (2): ASSIGN CV0($a) string("ttt") -L2 (3): EXT_STMT -L3 (3): T5 = FETCH_R (global) string("_GET") -L4 (3): T6 = FETCH_DIM_R T5 string("p1") -L5 (3): ASSIGN CV1($b) T6 -L6 (4): EXT_STMT -L7 (4): T8 = FETCH_R (global) string("_GET") -L8 (4): T9 = FETCH_DIM_R T8 string("p2") -L9 (4): ASSIGN CV2($c) T9 -L10 (5): EXT_STMT -L11 (5): T11 = INIT_ARRAY 3 (packed) int(1) NEXT -L12 (5): T11 = ADD_ARRAY_ELEMENT int(2) NEXT -L13 (5): T11 = ADD_ARRAY_ELEMENT CV1($b) CV0($a) -L14 (5): ASSIGN CV3($x) T11 -L15 (6): EXT_STMT -L16 (6): T13 = FETCH_DIM_R CV3($x) CV2($c) -L17 (6): ECHO T13 -L18 (6): RETURN int(1) -LIVE RANGES: - 11: L12 - L14 (tmp/var) + +$_main: + ; (lines=14, args=0, vars=4, tmps=10) + ; (before optimizer) + ; /.../PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.php:1-6 + ; return [] RANGE[0..0] +0000 ASSIGN CV0($a) string("ttt") +0001 T5 = FETCH_R (global) string("_GET") +0002 T6 = FETCH_DIM_R T5 string("p1") +0003 ASSIGN CV1($b) T6 +0004 T8 = FETCH_R (global) string("_GET") +0005 T9 = FETCH_DIM_R T8 string("p2") +0006 ASSIGN CV2($c) T9 +0007 T11 = INIT_ARRAY 3 (packed) int(1) NEXT +0008 T11 = ADD_ARRAY_ELEMENT int(2) NEXT +0009 T11 = ADD_ARRAY_ELEMENT CV1($b) CV0($a) +0010 ASSIGN CV3($x) T11 +0011 T13 = FETCH_DIM_R CV3($x) CV2($c) +0012 ECHO T13 +0013 RETURN int(1) +LIVE RANGES: + 11: 0008 - 0010 (tmp/var) diff --git a/PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.json b/PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.json old mode 100644 new mode 100755 index 667b94f..0b167fd --- a/PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.json +++ b/PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.json @@ -1,37 +1,38 @@ -{ - "code": { - "path": "./2_instance_83_array_variable_key.php", - "injection_skeleton_broken": false - }, - "discovery": { - "rule": "./2_instance_83_array_variable_key.sc", - "method": "joern", - "rule_accuracy": null, - "notes": null - }, - "compile": { - "binary": "./2_instance_83_array_variable_key.bash", - "instruction": null, - "dependencies": null - }, - "expectation": { - "type": "xss", - "sink_file": "./2_instance_83_array_variable_key.php", - "sink_line": 6, - "source_file": "./2_instance_83_array_variable_key.php", - "source_line": 3, - "expectation": false - }, - "properties": { - "category": "D2", - "feature_vs_internal_api": "FEATURE", - "input_sanitizer": false, - "source_and_sink": false, - "negative_test_case": true - }, - "remediation": { - "notes": "", - "transformation": null, - "modeling_rule": null - } +{ + "description": "The instance creates an array, where a user defined value is assigned to 'ttt'. The output value is determined by `$_GET['p2']`. So if that is set to 'ttt', this code is vulnerable.", + "code": { + "path": "./2_instance_83_array_variable_key.php", + "injection_skeleton_broken": false + }, + "discovery": { + "rule": "./2_instance_83_array_variable_key.sc", + "method": "joern", + "rule_accuracy": "FP", + "notes": null + }, + "compile": { + "binary": "./2_instance_83_array_variable_key.bash", + "instruction": null, + "dependencies": null + }, + "expectation": { + "type": "xss", + "sink_file": "./2_instance_83_array_variable_key.php", + "sink_line": 6, + "source_file": "./2_instance_83_array_variable_key.php", + "source_line": 5, + "expectation": false + }, + "properties": { + "category": "D2", + "feature_vs_internal_api": "FEATURE", + "input_sanitizer": false, + "source_and_sink": false, + "negative_test_case": true + }, + "remediation": { + "notes": "", + "transformation": null, + "modeling_rule": null + } } \ No newline at end of file diff --git a/PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.php b/PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.php old mode 100644 new mode 100755 index 4b2c4d1..8a40867 --- a/PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.php +++ b/PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.php @@ -1,6 +1,6 @@ -$b); -echo $x[$c]; \ No newline at end of file +$b); // source +echo $x[$c]; // sink \ No newline at end of file diff --git a/PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.sc b/PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.sc old mode 100644 new mode 100755 index afe3c95..9f73d4f --- a/PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.sc +++ b/PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.sc @@ -1,8 +1,8 @@ -@main def main(name : String): Unit = { - importCpg(name) - def G5 = cpg.call("ASSIGN").code(".*string.*").argument.order(0).isIdentifier.name.l.distinct - def R6 = cpg.call("ASSIGN_DIM|FETCH_DIM_R|FETCH_DIM_W|FETCH_DIM_RW|ADD_ARRAY_ELEMENT").l - val x94 = (name, "83_array_variable_key_D2", R6.filter{ call => G5.exists{ h => call.argument.order(1).code.l.contains("CV($" + h + ")")} }.location.toJson); - println(x94) - delete; -} \ No newline at end of file +@main def main(name : String): Unit = { + importCpg(name) + def G5 = cpg.call("ASSIGN").code(".*string.*").argument.order(0).isIdentifier.name.l.distinct + def R6 = cpg.call("ASSIGN_DIM|FETCH_DIM_R|FETCH_DIM_W|FETCH_DIM_RW|ADD_ARRAY_ELEMENT").l + val x83 = (name, "83_array_variable_key_i2", R6.filter{ call => G5.exists{ h => call.argument.order(1).code.l.contains("CV($" + h + ")")} }.location.toJson); + println(x83) + delete; +} \ No newline at end of file diff --git a/PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.bash b/PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.bash old mode 100644 new mode 100755 index 36559d5..58bfd0b --- a/PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.bash +++ b/PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.bash @@ -1,25 +1,21 @@ - -$_main: ; (lines=19, args=0, vars=4, tmps=10) - ; (before optimizer) - ; /home/user/gitlab/static-tools---latex/paper_code/PHP/Testability_Patterns/84_array_variable_key/third_ex/third_ex.php:1-6 -L0 (2): EXT_STMT -L1 (2): ASSIGN CV0($a) string("ttt") -L2 (3): EXT_STMT -L3 (3): T5 = FETCH_R (global) string("_GET") -L4 (3): T6 = FETCH_DIM_R T5 string("p1") -L5 (3): ASSIGN CV1($b) T6 -L6 (4): EXT_STMT -L7 (4): T8 = FETCH_R (global) string("_GET") -L8 (4): T9 = FETCH_DIM_R T8 string("p2") -L9 (4): ASSIGN CV2($c) T9 -L10 (5): EXT_STMT -L11 (5): T11 = INIT_ARRAY 3 (packed) int(1) NEXT -L12 (5): T11 = ADD_ARRAY_ELEMENT int(2) NEXT -L13 (5): T11 = ADD_ARRAY_ELEMENT CV1($b) CV0($a) -L14 (5): ASSIGN CV3($x) T11 -L15 (6): EXT_STMT -L16 (6): T13 = FETCH_DIM_R CV3($x) CV2($c) -L17 (6): ECHO T13 -L18 (6): RETURN int(1) -LIVE RANGES: - 11: L12 - L14 (tmp/var) + +$_main: + ; (lines=13, args=0, vars=3, tmps=9) + ; (before optimizer) + ; /.../PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.php:1-5 + ; return [] RANGE[0..0] +0000 T3 = FETCH_R (global) string("_GET") +0001 T4 = FETCH_DIM_R T3 string("p1") +0002 ASSIGN CV0($b) T4 +0003 T6 = FETCH_R (global) string("_GET") +0004 T7 = FETCH_DIM_R T6 string("p2") +0005 ASSIGN CV1($c) T7 +0006 T9 = INIT_ARRAY 3 (packed) int(1) NEXT +0007 T9 = ADD_ARRAY_ELEMENT int(2) NEXT +0008 T9 = ADD_ARRAY_ELEMENT CV1($c) CV0($b) +0009 ASSIGN CV2($x) T9 +0010 T11 = FETCH_DIM_R CV2($x) CV0($b) +0011 ECHO T11 +0012 RETURN int(1) +LIVE RANGES: + 9: 0007 - 0009 (tmp/var) diff --git a/PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.json b/PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.json old mode 100644 new mode 100755 index b8429c3..99e301f --- a/PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.json +++ b/PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.json @@ -1,37 +1,38 @@ -{ - "code": { - "path": "./3_instance_83_array_variable_key.php", - "injection_skeleton_broken": false - }, - "discovery": { - "rule": "./3_instance_83_array_variable_key.sc", - "method": "joern", - "rule_accuracy": null, - "notes": null - }, - "compile": { - "binary": "./3_instance_83_array_variable_key.bash", - "instruction": null, - "dependencies": null - }, - "expectation": { - "type": "xss", - "sink_file": "./3_instance_83_array_variable_key.php", - "sink_line": 6, - "source_file": "./3_instance_83_array_variable_key.php", - "source_line": 4, - "expectation": false - }, - "properties": { - "category": "D4", - "feature_vs_internal_api": "FEATURE", - "input_sanitizer": false, - "source_and_sink": false, - "negative_test_case": false - }, - "remediation": { - "notes": "", - "transformation": null, - "modeling_rule": null - } +{ + "description": "The instance creates an array, where a user defined value is assigned to a value defined by `$_GET['p1']`.", + "code": { + "path": "./3_instance_83_array_variable_key.php", + "injection_skeleton_broken": false + }, + "discovery": { + "rule": "./3_instance_83_array_variable_key.sc", + "method": "joern", + "rule_accuracy": "FP", + "notes": null + }, + "compile": { + "binary": "./3_instance_83_array_variable_key.bash", + "instruction": null, + "dependencies": null + }, + "expectation": { + "type": "xss", + "sink_file": "./3_instance_83_array_variable_key.php", + "sink_line": 5, + "source_file": "./3_instance_83_array_variable_key.php", + "source_line": 3, + "expectation": true + }, + "properties": { + "category": "D4", + "feature_vs_internal_api": "FEATURE", + "input_sanitizer": false, + "source_and_sink": false, + "negative_test_case": false + }, + "remediation": { + "notes": "", + "transformation": null, + "modeling_rule": null + } } \ No newline at end of file diff --git a/PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.php b/PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.php old mode 100644 new mode 100755 index 4b2c4d1..59fa0c6 --- a/PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.php +++ b/PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.php @@ -1,6 +1,5 @@ -$b); -echo $x[$c]; \ No newline at end of file +$c); +echo $x[$b]; // sink \ No newline at end of file diff --git a/PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.sc b/PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.sc old mode 100644 new mode 100755 index 9bf095c..c2143c6 --- a/PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.sc +++ b/PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.sc @@ -1,6 +1,6 @@ -@main def main(name : String): Unit = { - importCpg(name) - val x93 = (name, "83_array_variable_key_D4", cpg.call(".*FETCH_DIM_.*|.*ADD_ARRAY_ELEMENT.*|.*ASSIGN_DIM.*").argument.order(1).code("CV.*").location.toJson ::: cpg.call(".*INIT_ARRAY.*").argument.order(3).code("CV.*|T.*|V.*").location.toJson); - println(x93) - delete; -} \ No newline at end of file +@main def main(name : String): Unit = { + importCpg(name) + val x83 = (name, "83_array_variable_key_i3", cpg.call("ADD_ARRAY_ELEMENT.*").code(".*CV.*CV.*").location.toJson); + println(x83) + delete; +} \ No newline at end of file diff --git a/PHP/83_array_variable_key/83_array_variable_key.json b/PHP/83_array_variable_key/83_array_variable_key.json old mode 100644 new mode 100755 index c14755e..2674552 --- a/PHP/83_array_variable_key/83_array_variable_key.json +++ b/PHP/83_array_variable_key/83_array_variable_key.json @@ -1,16 +1,16 @@ -{ - "name": "Array Variable Key", - "description": "", - "family": "code_pattern_php", - "tags": [ - "sast", - "php", - "php_v7.4.9" - ], - "instances": [ - "./1_instance_83_array_variable_key/1_instance_83_array_variable_key.json", - "./2_instance_83_array_variable_key/2_instance_83_array_variable_key.json", - "./3_instance_83_array_variable_key/3_instance_83_array_variable_key.json" - ], - "version": "v0.draft" +{ + "name": "Array Variable Key", + "description": "./docs/description.md", + "family": "code_pattern_php", + "tags": [ + "sast", + "php", + "php_v7.4.9" + ], + "instances": [ + "./1_instance_83_array_variable_key/1_instance_83_array_variable_key.json", + "./2_instance_83_array_variable_key/2_instance_83_array_variable_key.json", + "./3_instance_83_array_variable_key/3_instance_83_array_variable_key.json" + ], + "version": "v1.0" } \ No newline at end of file diff --git a/PHP/83_array_variable_key/Pattern Array Variable Key.md b/PHP/83_array_variable_key/Pattern Array Variable Key.md deleted file mode 100644 index a236c26..0000000 --- a/PHP/83_array_variable_key/Pattern Array Variable Key.md +++ /dev/null @@ -1,292 +0,0 @@ -# Pattern: Array Variable Key - -## Category - -Array - -## Definition - -## Instances - -### Instance 1 - -- CATEGORY: D2 -- FEATURE vs INTERNAL API: FEATURE -- INPUT SANITIZERS: NO -- SOURCES AND SINKS: NO -- NEGATIVE TEST CASES: NO -- CODE: - -```php -$b); -echo $x["abc"]; -``` - -- MEASUREMENT: - -| Tool | RIPS | phpSAFE | WAP | Progpilot | Comm_1 | Comm_2 | Correct | -| ------------- | ---- | ------- | ---- | --------- | ------- | --------- | ------- | -| Vulnerability | YES | NO | NO | NO | YES | YES | YES | - -Measurements Date: 8 June 2021 - -- OPCODE: - -```bash -$_main: ; (lines=15, args=0, vars=3, tmps=7) - ; (before optimizer) - ; /home/user/gitlab/static-tools---latex/paper_code/PHP/Testability_Patterns/84_array_variable_key/first_ex/first_ex.php:1-7 -L0 (4): EXT_STMT -L1 (4): ASSIGN CV0($a) string("abc") -L2 (5): EXT_STMT -L3 (5): T4 = FETCH_R (global) string("_GET") -L4 (5): T5 = FETCH_DIM_R T4 string("p1") -L5 (5): ASSIGN CV1($b) T5 -L6 (6): EXT_STMT -L7 (6): T7 = INIT_ARRAY 3 (packed) int(1) NEXT -L8 (6): T7 = ADD_ARRAY_ELEMENT int(2) NEXT -L9 (6): T7 = ADD_ARRAY_ELEMENT CV1($b) CV0($a) -L10 (6): ASSIGN CV2($x) T7 -L11 (7): EXT_STMT -L12 (7): T9 = FETCH_DIM_R CV2($x) string("abc") -L13 (7): ECHO T9 -L14 (7): RETURN int(1) -LIVE RANGES: - 7: L8 - L10 (tmp/var) -``` - -- DISCOVERY: - -```bash -def G5 = cpg.call("ASSIGN").code(".*string.*").argument.order(0).isIdentifier.name.l.distinct -def R6 = cpg.call("ASSIGN_DIM|FETCH_DIM_R|FETCH_DIM_W|FETCH_DIM_RW|ADD_ARRAY_ELEMENT").l -R6.filter{ call => G5.exists{ h => call.argument.order(1).code.l.contains("CV($" + h + ")")} }.size - -``` - -- PRECONDITIONS: - 1. - -- TRANSFORMATION: - -``` - -``` - -### Instance 2 - -- CATEGORY: D2 -- FEATURE vs INTERNAL API: FEATURE -- INPUT SANITIZERS: NO -- SOURCES AND SINKS: NO -- NEGATIVE TEST CASES: YES -- CODE: - -```php -$b); -echo $x["ttt"]; -``` - -- MEASUREMENT: - -| Tool | RIPS | phpSAFE | WAP | Progpilot | Comm_1 | Comm_2 | Correct | -| ------------- | ---- | ------- | ---- | --------- | ------- | --------- | ------- | -| Vulnerability | NO | - | - | - | YES | YES | NO | - -Measurements Date: 8 June 2021 - -- OPCODE: - -```bash -$_main: ; (lines=19, args=0, vars=4, tmps=10) - ; (before optimizer) - ; /home/user/gitlab/static-tools---latex/paper_code/PHP/Testability_Patterns/84_array_variable_key/second_ex/second_ex.php:1-6 -L0 (2): EXT_STMT -L1 (2): ASSIGN CV0($a) string("ttt") -L2 (3): EXT_STMT -L3 (3): T5 = FETCH_R (global) string("_GET") -L4 (3): T6 = FETCH_DIM_R T5 string("p1") -L5 (3): ASSIGN CV1($b) T6 -L6 (4): EXT_STMT -L7 (4): T8 = FETCH_R (global) string("_GET") -L8 (4): T9 = FETCH_DIM_R T8 string("p2") -L9 (4): ASSIGN CV2($c) T9 -L10 (5): EXT_STMT -L11 (5): T11 = INIT_ARRAY 3 (packed) int(1) NEXT -L12 (5): T11 = ADD_ARRAY_ELEMENT int(2) NEXT -L13 (5): T11 = ADD_ARRAY_ELEMENT CV1($b) CV0($a) -L14 (5): ASSIGN CV3($x) T11 -L15 (6): EXT_STMT -L16 (6): T13 = FETCH_DIM_R CV3($x) CV2($c) -L17 (6): ECHO T13 -L18 (6): RETURN int(1) -LIVE RANGES: - 11: L12 - L14 (tmp/var) -``` - -- DISCOVERY: - -```bash - -``` - -- PRECONDITIONS: - 1. - -- TRANSFORMATION: - -``` - -``` - -### Instance 3 - -- CATEGORY: D4 -- FEATURE vs INTERNAL API: FEATURE -- INPUT SANITIZERS: NO -- SOURCES AND SINKS: NO -- NEGATIVE TEST CASES: NO -- CODE: - -```php -$b); -echo $x[$c]; -``` - -- MEASUREMENT: - -| Tool | RIPS | phpSAFE | WAP | Progpilot | Comm_1 | Comm_2 | Correct | -| ------------- | ---- | ------- | ---- | --------- | ------- | --------- | ------- | -| Vulnerability | NO | NO | NO | NO | YES | YES | YES | - -Measurements Date: 8 June 2021 - -- OPCODE: - -```bash -$_main: ; (lines=19, args=0, vars=4, tmps=10) - ; (before optimizer) - ; /home/user/gitlab/static-tools---latex/paper_code/PHP/Testability_Patterns/84_array_variable_key/third_ex/third_ex.php:1-6 -L0 (2): EXT_STMT -L1 (2): ASSIGN CV0($a) string("ttt") -L2 (3): EXT_STMT -L3 (3): T5 = FETCH_R (global) string("_GET") -L4 (3): T6 = FETCH_DIM_R T5 string("p1") -L5 (3): ASSIGN CV1($b) T6 -L6 (4): EXT_STMT -L7 (4): T8 = FETCH_R (global) string("_GET") -L8 (4): T9 = FETCH_DIM_R T8 string("p2") -L9 (4): ASSIGN CV2($c) T9 -L10 (5): EXT_STMT -L11 (5): T11 = INIT_ARRAY 3 (packed) int(1) NEXT -L12 (5): T11 = ADD_ARRAY_ELEMENT int(2) NEXT -L13 (5): T11 = ADD_ARRAY_ELEMENT CV1($b) CV0($a) -L14 (5): ASSIGN CV3($x) T11 -L15 (6): EXT_STMT -L16 (6): T13 = FETCH_DIM_R CV3($x) CV2($c) -L17 (6): ECHO T13 -L18 (6): RETURN int(1) -LIVE RANGES: - 11: L12 - L14 (tmp/var) -``` - -- DISCOVERY: - -```bash -cpg.call(".*FETCH_DIM_.*|.*ADD_ARRAY_ELEMENT.*|.*ASSIGN_DIM.*").argument.order(1).code("CV.*").location.l+cpg.call(".*INIT_ARRAY.*").argument.order(3).code("CV.*|T.*|V.*").location.l -``` - -- PRECONDITIONS: - 1. - -- TRANSFORMATION: - -``` - -``` - -### Instance 4 - -- CATEGORY: D4 -- FEATURE vs INTERNAL API: FEATURE -- INPUT SANITIZERS: NO -- SOURCES AND SINKS: NO -- NEGATIVE TEST CASES: YES -- CODE: - -```php -$b); -echo $x[$c]; -``` - -- MEASUREMENT: - -| Tool | RIPS | phpSAFE | WAP | Progpilot | Comm_1 | Comm_2 | Correct | -| ------------- | ---- | ------- | ---- | --------- | ------- | --------- | ------- | -| Vulnerability | - | - | - | - | YES | YES | NO | - -Measurements Date: 8 June 2021 - -- OPCODE: - -```bash -$_main: ; (lines=19, args=0, vars=4, tmps=10) - ; (before optimizer) - ; /home/user/gitlab/static-tools---latex/paper_code/PHP/Testability_Patterns/84_array_variable_key/third_ex/third_ex.php:1-6 -L0 (2): EXT_STMT -L1 (2): ASSIGN CV0($a) string("ttt") -L2 (3): EXT_STMT -L3 (3): T5 = FETCH_R (global) string("_GET") -L4 (3): T6 = FETCH_DIM_R T5 string("p1") -L5 (3): ASSIGN CV1($b) T6 -L6 (4): EXT_STMT -L7 (4): T8 = FETCH_R (global) string("_GET") -L8 (4): T9 = FETCH_DIM_R T8 string("p2") -L9 (4): ASSIGN CV2($c) T9 -L10 (5): EXT_STMT -L11 (5): T11 = INIT_ARRAY 3 (packed) int(1) NEXT -L12 (5): T11 = ADD_ARRAY_ELEMENT int(2) NEXT -L13 (5): T11 = ADD_ARRAY_ELEMENT CV1($b) CV0($a) -L14 (5): ASSIGN CV3($x) T11 -L15 (6): EXT_STMT -L16 (6): T13 = FETCH_DIM_R CV3($x) CV2($c) -L17 (6): ECHO T13 -L18 (6): RETURN int(1) -LIVE RANGES: - 11: L12 - L14 (tmp/var) - -``` - -- DISCOVERY: - -```bash - -``` - -- PRECONDITIONS: - 1. - -- TRANSFORMATION: - -``` - -``` - diff --git a/PHP/83_array_variable_key/README.md b/PHP/83_array_variable_key/README.md new file mode 100755 index 0000000..7e46bb7 --- /dev/null +++ b/PHP/83_array_variable_key/README.md @@ -0,0 +1,299 @@ +[//]: # (This file is automatically generated. If you wish to make any changes, please use the JSON files and regenerate this file using the tpframework.) + +# Array Variable Key + +Tags: sast, php, php_v7.4.9 + +Version: v1.0 + +## Description + +This pattern targets the usage of variables as keys for arrays in PHP. + +## Overview + +| Instances | has discovery rule | discovery method | rule successfull | +|---------------------------|----------------------|--------------------|--------------------| +| [1 Instance](#1-instance) | yes | joern | yes | +| [2 Instance](#2-instance) | yes | joern | yes | +| [3 Instance](#3-instance) | yes | joern | yes | + +
+ + +## 1 Instance + + +The instance creates an array, where a user defined value is assigned to 'abc'. + +### Code + +```PHP +$b); +echo $x["abc"]; // sink +``` + +### Instance Properties + +| category | feature_vs_internal_api | input_sanitizer | negative_test_case | source_and_sink | +|------------|---------------------------|-------------------|----------------------|-------------------| +| D2 | FEATURE | no | no | no | + +
+ +More + +
+ + +### Compile + + +```bash +$_main: + ; (lines=11, args=0, vars=3, tmps=7) + ; (before optimizer) + ; /.../PHP/83_array_variable_key/1_instance_83_array_variable_key/1_instance_83_array_variable_key.php:1-5 + ; return [] RANGE[0..0] +0000 ASSIGN CV0($a) string("abc") +0001 T4 = FETCH_R (global) string("_GET") +0002 T5 = FETCH_DIM_R T4 string("p1") +0003 ASSIGN CV1($b) T5 +0004 T7 = INIT_ARRAY 3 (packed) int(1) NEXT +0005 T7 = ADD_ARRAY_ELEMENT int(2) NEXT +0006 T7 = ADD_ARRAY_ELEMENT CV1($b) CV0($a) +0007 ASSIGN CV2($x) T7 +0008 T9 = FETCH_DIM_R CV2($x) string("abc") +0009 ECHO T9 +0010 RETURN int(1) +LIVE RANGES: + 7: 0005 - 0007 (tmp/var) +``` + +
+ +
+ + +### Discovery + + +```scala +def G5 = cpg.call("ASSIGN").code(".*string.*").argument.order(0).isIdentifier.name.l.distinct +def R6 = cpg.call("ASSIGN_DIM|FETCH_DIM_R|FETCH_DIM_W|FETCH_DIM_RW|ADD_ARRAY_ELEMENT").l +val x83 = (name, "83_array_variable_key_i1", R6.filter{ call => G5.exists{ h => call.argument.order(1).code.l.contains("CV($" + h + ")")} }.location.toJson); +``` + +| discovery method | expected accuracy | +|--------------------|---------------------| +| joern | FP | + +
+ +
+ + +### Measurement + + +| Tool | Comm_1 | Comm_2 | phpSAFE | Progpilot | RIPS | WAP | Ground Truth | +|-------------|----------|----------|-----------|-------------|--------|-------|----------------| +| 08 Jun 2021 | yes | yes | no | no | yes | no | yes | +| 22 May 2023 | yes | yes | | | | | yes | + +
+ +
+ +
+ +
+ + +## 2 Instance + + +The instance creates an array, where a user defined value is assigned to 'ttt'. The output value is determined by `$_GET['p2']`. So if that is set to 'ttt', this code is vulnerable. + +### Code + +```PHP +$b); // source +echo $x[$c]; // sink +``` + +### Instance Properties + +| category | feature_vs_internal_api | input_sanitizer | negative_test_case | source_and_sink | +|------------|---------------------------|-------------------|----------------------|-------------------| +| D2 | FEATURE | no | yes | no | + +
+ +More + +
+ + +### Compile + + +```bash +$_main: + ; (lines=14, args=0, vars=4, tmps=10) + ; (before optimizer) + ; /.../PHP/83_array_variable_key/2_instance_83_array_variable_key/2_instance_83_array_variable_key.php:1-6 + ; return [] RANGE[0..0] +0000 ASSIGN CV0($a) string("ttt") +0001 T5 = FETCH_R (global) string("_GET") +0002 T6 = FETCH_DIM_R T5 string("p1") +0003 ASSIGN CV1($b) T6 +0004 T8 = FETCH_R (global) string("_GET") +0005 T9 = FETCH_DIM_R T8 string("p2") +0006 ASSIGN CV2($c) T9 +0007 T11 = INIT_ARRAY 3 (packed) int(1) NEXT +0008 T11 = ADD_ARRAY_ELEMENT int(2) NEXT +0009 T11 = ADD_ARRAY_ELEMENT CV1($b) CV0($a) +0010 ASSIGN CV3($x) T11 +0011 T13 = FETCH_DIM_R CV3($x) CV2($c) +0012 ECHO T13 +0013 RETURN int(1) +LIVE RANGES: + 11: 0008 - 0010 (tmp/var) +``` + +
+ +
+ + +### Discovery + + +```scala +def G5 = cpg.call("ASSIGN").code(".*string.*").argument.order(0).isIdentifier.name.l.distinct +def R6 = cpg.call("ASSIGN_DIM|FETCH_DIM_R|FETCH_DIM_W|FETCH_DIM_RW|ADD_ARRAY_ELEMENT").l +val x83 = (name, "83_array_variable_key_i2", R6.filter{ call => G5.exists{ h => call.argument.order(1).code.l.contains("CV($" + h + ")")} }.location.toJson); +``` + +| discovery method | expected accuracy | +|--------------------|---------------------| +| joern | FP | + +
+ +
+ + +### Measurement + + +| Tool | Comm_1 | Comm_2 | RIPS | Ground Truth | +|-------------|----------|----------|--------|----------------| +| 08 Jun 2021 | yes | yes | no | no | +| 22 May 2023 | yes | yes | | no | + +
+ +
+ +
+ +
+ + +## 3 Instance + + +The instance creates an array, where a user defined value is assigned to a value defined by `$_GET['p1']`. + +### Code + +```PHP +$c); +echo $x[$b]; // sink +``` + +### Instance Properties + +| category | feature_vs_internal_api | input_sanitizer | negative_test_case | source_and_sink | +|------------|---------------------------|-------------------|----------------------|-------------------| +| D4 | FEATURE | no | no | no | + +
+ +More + +
+ + +### Compile + + +```bash +$_main: + ; (lines=13, args=0, vars=3, tmps=9) + ; (before optimizer) + ; /.../PHP/83_array_variable_key/3_instance_83_array_variable_key/3_instance_83_array_variable_key.php:1-5 + ; return [] RANGE[0..0] +0000 T3 = FETCH_R (global) string("_GET") +0001 T4 = FETCH_DIM_R T3 string("p1") +0002 ASSIGN CV0($b) T4 +0003 T6 = FETCH_R (global) string("_GET") +0004 T7 = FETCH_DIM_R T6 string("p2") +0005 ASSIGN CV1($c) T7 +0006 T9 = INIT_ARRAY 3 (packed) int(1) NEXT +0007 T9 = ADD_ARRAY_ELEMENT int(2) NEXT +0008 T9 = ADD_ARRAY_ELEMENT CV1($c) CV0($b) +0009 ASSIGN CV2($x) T9 +0010 T11 = FETCH_DIM_R CV2($x) CV0($b) +0011 ECHO T11 +0012 RETURN int(1) +LIVE RANGES: + 9: 0007 - 0009 (tmp/var) +``` + +
+ +
+ + +### Discovery + + +```scala +val x83 = (name, "83_array_variable_key_i3", cpg.call("ADD_ARRAY_ELEMENT.*").code(".*CV.*CV.*").location.toJson); +``` + +| discovery method | expected accuracy | +|--------------------|---------------------| +| joern | FP | + +
+ +
+ + +### Measurement + + +| Tool | Comm_1 | Comm_2 | phpSAFE | Progpilot | RIPS | WAP | Ground Truth | +|-------------|----------|----------|-----------|-------------|--------|-------|----------------| +| 08 Jun 2021 | yes | yes | no | no | no | no | yes | +| 22 May 2023 | no | no | | | | | yes | + +
+ +
+ +
diff --git a/PHP/83_array_variable_key/docs/description.md b/PHP/83_array_variable_key/docs/description.md new file mode 100755 index 0000000..a38ab41 --- /dev/null +++ b/PHP/83_array_variable_key/docs/description.md @@ -0,0 +1 @@ +This pattern targets the usage of variables as keys for arrays in PHP. \ No newline at end of file