Skip to content

Commit bd824af

Browse files
committed
Merge branch 'master' of github.com:designsecurity/progpilot
2 parents 499e634 + 1736e55 commit bd824af

File tree

723 files changed

+100795
-9734
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

723 files changed

+100795
-9734
lines changed

.devcontainer/Dockerfile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
FROM php:8.1.13-cli
2+
3+
RUN apt-get update && apt-get install -y vim git sudo
4+
5+
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
6+
&& php -r "if (hash_file('sha384', 'composer-setup.php') === '55ce33d7678c5a611085589f1f3ddf8b3c52d662cd01d4ba75c0ee0459970c2200a51f492d557530c71c15d8dba01eae') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
7+
&& php composer-setup.php \
8+
&& php -r "unlink('composer-setup.php');" \
9+
&& sudo mv composer.phar /usr/local/bin/composer
10+
11+
ARG USERNAME=developer
12+
ARG USER_UID=1000
13+
ARG USER_GID=$USER_UID
14+
15+
RUN groupadd --gid $USER_GID $USERNAME \
16+
&& useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME

.devcontainer/devcontainer.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "progpilot-linux",
3+
"build": {
4+
"dockerfile": "Dockerfile"
5+
},
6+
"remoteUser": "developer"
7+
}

.github/workflows/main.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ jobs:
1010
strategy:
1111
matrix:
1212
php-version:
13-
- "7.3"
1413
- "7.4"
14+
- "8.0"
15+
- "8.1"
1516
steps:
1617
- name: "Checkout"
1718
uses: "actions/checkout@v2"

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ articles/
22
builds/*.phar
33
projects/tests/vendor
44
projects/tests/composer.lock
5+
projects/tests/.phpunit.result.cache
56
projects/example/vendor
67
projects/example/composer.lock
78
projects/example_config/vendor

composer.json

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,26 @@
99
}
1010
],
1111
"require": {
12-
"php": ">=7.2.5",
13-
"ircmaxell/php-cfg": "1.0.x-dev",
12+
"php": ">=7.4",
13+
"ircmaxell/php-cfg": "^0.6.0",
1414
"symfony/yaml": ">=3.3.6",
15-
"symfony/console": ">=3.3.5"
15+
"symfony/console": ">=3.3.5",
16+
"myclabs/deep-copy": "^1.10.2"
1617
},
1718
"require-dev": {
18-
"phpunit/phpunit": "^6.0",
19-
"phpro/grumphp": "^1.3"
19+
"phpunit/phpunit": "^8.0 || ^9.0",
20+
"phpro/grumphp": "^1.3",
21+
"squizlabs/php_codesniffer": "^3.5"
2022
},
2123
"bin": ["projects/phar/progpilot"],
2224
"autoload": {
2325
"psr-0": {
2426
"progpilot": "package/src"
2527
}
28+
},
29+
"config": {
30+
"allow-plugins": {
31+
"phpro/grumphp": true
32+
}
2633
}
2734
}

docs/API.md

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,20 @@ To retrieve the value of $file, $code and $folder use these methods:
2020
***
2121
- $obj_context->inputs->setLanguages($array);
2222
Languages you want to analyze (["php", "js"] but js is in development), default is *["php"]*
23-
- $obj_context->inputs->setFrameworks($array);
24-
Frameworks you want to analyze (default is *["suitecrm", "codeigniter"]*)
2523
- $obj_context->inputs->setDev($bool);
2624
If you want to use security data relative to development of progpilot (default is *false*)
2725
***
2826

2927
***
28+
- $obj_context->inputs->addSources($files_sources);
3029
- $obj_context->inputs->setSources($files_sources);
30+
- $obj_context->inputs->addSinks($files_sinks);
3131
- $obj_context->inputs->setSinks($files_sinks);
32+
- $obj_context->inputs->addSanitizers($files_sanitizers);
3233
- $obj_context->inputs->setSanitizers($files_sanitizers);
34+
- $obj_context->inputs->addValidators($files_validators);
3335
- $obj_context->inputs->setValidators($files_validators);
36+
- $obj_context->inputs->addCustomRules($files_custom);
3437
- $obj_context->inputs->setCustomRules($files_custom);
3538
- $obj_context->inputs->getCustomRules();
3639
- $obj_context->inputs->getSources();
@@ -49,15 +52,15 @@ These functions are explained in the chapter about [**handling false positives**
4952
***
5053

5154
***
52-
- $obj_context->inputs->setIncludes($mixed);
53-
- $obj_context->inputs->setExcludes($mixed);
55+
- $obj_context->inputs->setInclusions($mixed);
56+
- $obj_context->inputs->setExclusions($mixed);
5457
For include or exclude files and folders during the analysis, see an [**example here**](./../projects/tests/exclude_files.json) with a json file configuration and an [**example here**](./../projects/tests/run_exclude_files.php) with a php array.
5558
***
5659

5760
## Outputs
5861
***
59-
- $obj_context->outputs->resolveIncludes($bool);
60-
- $obj_context->outputs->resolveIncludesFile($file);
62+
- $obj_context->outputs->setWriteIncludeFailures($bool);
63+
- $obj_context->outputs->setIncludeFailuresFile($file);
6164
These functions are explained in the chapter about [**included files**](./INCLUDES.md)
6265
- $obj_context->outputs->getAst();
6366
- $obj_context->outputs->getCfg();
@@ -72,25 +75,19 @@ print the number of files analyzed (it does not count the included files (with *
7275

7376
## Options
7477
***
75-
- $obj_context->setLimitDefs($nb);
78+
- $obj_context->setMaxDefinitions($nb);
7679
to prevent memory exhaustion you could limit the number of definitions by file during the analysis (default is *3000*)
77-
- $obj_context->setLimitTime($time_sec);
80+
- $obj_context->setMaxFileAnalysisDuration($time_sec);
7881
max execution time by file for some steps of the analysis (default is *10 seconds*)
79-
- $obj_context->setLimitSize($size_bytes);
82+
- $obj_context->setMaxFileSize($size_bytes);
8083
do not analyze file that are larger than this defined size (default is 500 000 bytes)
81-
- $obj_context->setPrintFile($bool);
82-
*true* if you want to print the name of files analyzed by progpilot, default is *false*
83-
- $obj_context->setPrintWarning($bool);
84-
*true* if you want to print warnings during the analysis, default is *false*
84+
- $obj_context->setDebugMode($bool);
85+
*true* if you want to output warnings during the analysis, default is *false*
8586
- $obj_context->setPrettyPrint($bool);
8687
*true* if you want to pretty print the JSON output of standalone progpilot application, default is *true*
87-
- $obj_context->setAnalyzeFunctions($bool);
88-
*true* if you want to analyze all functions (*false* only *main function* is analyzed), default is *true*
8988
- $obj_context->setAnalyzeIncludes($bool);
9089
*true* or *false* if you want to analyze included files, default is *true*
9190
- $obj_context->setConfiguration($config);
9291
you can use an yaml file to specify the configuration of analysis, see an [**example here**](./../projects/example_config/configuration.yml).
93-
- $obj_context->setAnalyzeHardRules($bool);
94-
If you want to check custom rules that can take a lot a time (default is false)
9592
These rules are explained in the chapter [**customize an analyze**](./CUSTOM_ANALYSIS.md)
9693
***

docs/CONTRIBUTING.md

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,7 @@ That will allow the ability of contributors to reproduce the bug.
1616
All php code must adhere to [PSR-2 standard](https://www.php-fig.org/psr/psr-2/) (except for tests).
1717

1818
### GrumPHP
19-
Developers can use [GrumPHP](https://github.com/phpro/grumphp/) to ensure each progpilot commit reaches code style (phpcs) and security (progpilot itself) requirements.
20-
Install GrumPHP globally or in the progpilot repository:
21-
```shell
22-
composer require --dev phpro/grumphp
23-
```
24-
Install the [required tasks](../grumphp.yml) for Progpilot:
25-
```shell
26-
composer config minimum-stability dev
27-
composer require --dev squizlabs/php_codesniffer
28-
composer require --dev designsecurity/progpilot
29-
```
30-
Configure the following env variable to instruct GrumPHP to locate tasks executables:
31-
```shell
32-
export GRUMPHP_BIN_DIR="/path/to/vendor/bin"
33-
```
19+
Developers can use [GrumPHP](https://github.com/phpro/grumphp/) to ensure each progpilot commit reaches code style (phpcs) requirements.
3420

3521
### Frameworks support
3622
Most of the time the analysis of progpilot can be extended simply with adding the corresponding [sources, sinks, validators and sanitizers](./SPECIFY_ANALYSIS.md): look at how it was done for [current frameworks](https://github.com/designsecurity/progpilot/tree/master/package/src/uptodate_data/php/frameworks).

docs/FAQ.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# FAQ
22

33
#### Which version of PHP do I need?
4-
The minimum version of PHP needed to run Progpilot is 7.2.5
4+
The minimum version of PHP needed to run Progpilot is 7.4
55

66
#### Where can I find the updated security files configuration (sinks, sources, validators, sanitizers and rules) of Progpilot?
77
You can find the updated security files configuration of Progpilot in [package/src/uptodate_data](../package/src/uptodate_data) folder.
@@ -11,13 +11,12 @@ Example of control flow graph and call graph of source code transformed to dot f
1111

1212
#### When I use progpilot I often run out of memory?
1313
Static analyzers use a lot of memory but you could try to handle this with [these functions](./API.md):
14-
- *$obj_context->setLimitDefs($nb);*
15-
- *$obj_context->setLimitSize($size_bytes);*
14+
- *$obj_context->setMaxDefinitions($nb);*
15+
- *$obj_context->setMaxFileSize($size_bytes);*
1616

1717
And by increasing the maximum memory amount for a script (*memory_limit*) in the configuration of PHP (*php.ini*).
1818

1919
#### What frameworks are supported by progpilot?
2020
At this moment, these frameworks are supported:
2121
- suiteCRM
2222
- codeIgniter
23-
- wordpress

docs/INCLUDES.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ include($dir."myfile$suf.php");
1313
```
1414

1515
To bypass this limitation use these functions:
16-
- $obj_context->outputs->resolveIncludes($bool);
17-
- $obj_context->outputs->resolveIncludesFile($file);
16+
- $obj_context->outputs->setWriteIncludeFailures($bool);
17+
- $obj_context->outputs->setIncludeFailuresFile($file);
1818
When *$bool* set to *true* and *$file* set to *resolve_includes.json* for example
1919

2020
For each include not resolved an entry will be printed in the *$file* with the location of the include function (file, line, column):
2121
```javascript
22-
{"includes_not_resolved":[["/home/dev/projects/tests/includes/simple5.php",11,11]]}
22+
{"include_failures":[["/home/dev/projects/tests/includes/simple5.php",11,11]]}
2323
```
2424
Next create a *resolved_includes.json* file with the good value for each include function call:
2525
```javascript

docs/SPECIFY_ANALYSIS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ To specify the way vulnerabilities are detected, customize the sources, sinks, s
99

1010
## Configure sources
1111
- $obj_context->inputs->setSources($files_sources);
12+
- $obj_context->inputs->addSources($files_sources);
1213
- $obj_context->inputs->getSources();
1314

1415
Where *$file_sources* is a json file (or an array of json files) like below:
@@ -32,6 +33,7 @@ Optional properties:
3233

3334
## Configure sanitizers
3435
- $obj_context->inputs->setSanitizers($file_sanitizers);
36+
- $obj_context->inputs->addSanitizers($file_sanitizers);
3537
- $obj_context->inputs->getSanitizers();
3638

3739
Where *$file_sanitizers* is a json file (or an array of json files) like below:
@@ -63,6 +65,7 @@ Optional properties:
6365

6466
## Configure sinks
6567
- $obj_context->inputs->setSinks($file_sinks);
68+
- $obj_context->inputs->addSinks($file_sinks);
6669
- $obj_context->inputs->getSinks();
6770

6871
Where *$file_sinks* is a json file (or an array of json files) like below:
@@ -88,6 +91,7 @@ Optional properties:
8891
- [instanceof](#instanceof-property), [prevent](#prevent-property), [parameters](#parameters-property)
8992

9093
## Configure validators
94+
- $obj_context->inputs->addValidators($file_validators);
9195
- $obj_context->inputs->setValidators($file_validators);
9296
- $obj_context->inputs->getValidators();
9397

docs/dev/STATES.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# definition states API
2+
3+
Each definition has at least one state holding attributes like isTainted. The goal is to handle properties and array dataflow.
4+
5+
For simple variable, the defaultState is enough, as dataflow is correctly performed by visitorDataFlow:
6+
```
7+
// block 1
8+
// foo defined in blockid 1 (defaultState = 1)
9+
// state 1 of foo tainted
10+
$foo = $_GET["p"];
11+
12+
if(rand()) {
13+
// block 2
14+
// bar defined in blockid 2 (defaultState = 2)
15+
// state 2 of foo bar (get value of foo->currentState()) tainted
16+
$bar = $foo;
17+
}
18+
else {
19+
// block 3
20+
// bar defined in blockid 3 (defaultState = 3)
21+
// state 3 of foo bar empty
22+
$bar = null;
23+
}
24+
25+
// block 4
26+
// bar search def:
27+
// * block2 $bar->getCurrentState()
28+
// * block3 $bar->getCurrentState()
29+
// merge states on block 4 of echo_arg0
30+
echo $bar;
31+
```
32+
33+
For instances/properties variable, we need different states:
34+
```
35+
// block 1
36+
// instance defined in blockid 1 (defaultState = 1)
37+
$instance = new Object;
38+
39+
if(rand()) {
40+
// block 2
41+
// instance defined in blockid 1 (defaultState = 1)
42+
// state 2 of instance prop tainted
43+
$instance->prop = $_GET["p"];
44+
echo $instance->prop;
45+
}
46+
else {
47+
// block 3
48+
// instance defined in blockid 1 (defaultState = 1)
49+
// state 3 of instance prop "null"
50+
$instance->prop = "null";
51+
echo $instance->prop;
52+
}
53+
54+
// block 4
55+
// we launch dataflow analysis for properties
56+
// parent of 4 = block 2, 3
57+
// state 4 = merge(state 2,3)
58+
echo $instance->prop;
59+
```
60+
61+
62+
Chained calls:
63+
```
64+
// block 1
65+
// instance1 defined in blockid 1 (defaultState = 1)
66+
$instance1 = new Object1;
67+
68+
/*
69+
function func1() {
70+
// block 2
71+
// instance2 defined in blockid 2 (defaultState = 2)
72+
$instance2 = new Object2;
73+
return $instance2;
74+
}
75+
76+
function func2() {
77+
// block 3
78+
// instance3 defined in blockid 3 (defaultState = 3)
79+
$instance3 = new Object3;
80+
return $instance3;
81+
}
82+
83+
function func3() {
84+
echo $this->prop;
85+
}
86+
*/
87+
88+
$instance1->func1()->func2()->func3();
89+
```

grumphp.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,3 @@ grumphp:
66
metadata:
77
priority: 300
88
ignore_patterns: ["*/projects/tests/*"]
9-
10-
progpilot:
11-
config_file: progpilot.yml
12-
triggered_by: [php]

package/composer.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99
}
1010
],
1111
"require": {
12-
"php": "^7.0",
13-
"ircmaxell/php-cfg": "1.0.x-dev",
12+
"php": ">=7.4",
13+
"ircmaxell/php-cfg": "^0.6.0",
1414
"symfony/yaml": ">=3.3.6",
1515
"symfony/console": ">=3.3.5"
1616
},
1717
"require-dev": {
18-
"phpunit/phpunit": "^6.0"
18+
"phpunit/phpunit": "^8.0 || ^9.0"
1919
},
2020
"autoload": {
2121
"psr-0": {

0 commit comments

Comments
 (0)