Skip to content

Latest commit

 

History

History
95 lines (74 loc) · 3.49 KB

CONTRIBUTING.md

File metadata and controls

95 lines (74 loc) · 3.49 KB

Contributing to GLPI Guard

Thanks for helping make GLPI installations safer! Issues, check ideas, translations and pull requests are welcome.

Ground rules

  • Read-only, always. A check may read files, file metadata and the database (SELECT/SHOW). It must never write, never send a request to a system other than the one given by its owner, never try a password or an exploit. Pull requests that add offensive features will be closed.
  • No secrets in output. Evidence lists names, settings and counts — not passwords, hashes, tokens or keys.
  • Every finding is actionable. Explain why it matters and how to fix it (menu path or command).
  • Both languages. All user-facing texts exist in English and Turkish (L::t('english', 'türkçe')). If you do not speak Turkish, write English and say so in the PR — we will translate.
  • PHP 7.4 compatible. Old installations need the tool most: no match, str_contains, enums, readonly, named arguments, union types…

Development setup

git clone https://github.com/CodeByPinar/glpi-guard.git && cd glpi-guard
php tests/run.php                       # must stay green
php bin/glpi-guard scan /path/to/a/test/glpi --lang en

To try the plugin, copy (or symlink) the repository to <glpi>/plugins/glpiguard and install it from Setup › Plugins. Please use a test GLPI.

Writing a check

  1. Create a class in src/Checks/, e.g. F07Example.php (letter = group: A versions, B accounts, C API, D files, F configuration, G rights; next free number):
<?php

declare(strict_types=1);

namespace GlpiGuard\Checks;

use GlpiGuard\Advisories;
use GlpiGuard\Check;
use GlpiGuard\Finding;
use GlpiGuard\Glpi;
use GlpiGuard\L;
use GlpiGuard\SkipException;

final class F07Example extends Check
{
    public function id(): string
    {
        return 'GG-F07';
    }

    public function name(): array
    {
        return L::t('Short name of the check', 'Kontrolün kısa adı');
    }

    public function run(Glpi $g, Advisories $adv): array
    {
        if (!$g->tableExists('glpi_something')) {
            throw new SkipException('not available in this GLPI version');
        }
        $rows = $g->rows('SELECT name FROM glpi_something WHERE risky = 1');
        if (!$rows) {
            return [];
        }
        return [$this->finding(
            Finding::MEDIUM,
            L::f(L::t('%d risky things', '%d riskli şey'), count($rows)),
            L::t('Why it matters.', 'Neden önemli.'),
            L::t('Setup > … : how to fix.', 'Kurulum > … : nasıl düzeltilir.'),
            [Checks\Util::names(array_column($rows, 'name'))]
        )];
    }
}
  1. Register it in Scanner::checks().
  2. Add tests in tests/run.php using FakeGlpi ($g->on('SQL fragment', $rows), $g->cfg = [...]).
  3. Add it to the checks table in README.md and to CHANGELOG.md.

Choosing a severity: critical = direct takeover or code execution likely; high = serious exposure an attacker can use; medium = weakens defences; low = hygiene; info = context, no penalty.

Advisory database

data/advisories.json is generated by tools/fetch-advisories.php from GitHub Security Advisories and refreshed daily by CI. To cover another plugin, add its directory name and repository to the PLUGINS list in that script.

Commit & PR

  • One topic per pull request, tests green, php -l clean.
  • Describe how you tested (GLPI version, database).
  • By contributing you agree that your work is licensed under GPL-3.0-or-later.