Dolibarr/dolibarr · error

Bad link. Bad value for parameter hashp

Error message

Bad link. Bad value for parameter hashp

What it means

To prevent leaking files via guessed or forged public hashes, document.php rejects the literal value hashp='shared' with HTTP 400 via httponly_accessforbidden(). A real shared link hash is a long random string; 'shared' is a placeholder, not a valid hash.

Solutions

  1. Use the real share hash generated by Dolibarr (ECM share tab / share links), not the literal 'shared'
  2. Re-generate the public share link from the document's Share page
  3. Fix templates that print 'shared' as an unsubstituted placeholder
  4. Remove hashp and use modulepart+original_file for authenticated downloads

Example fix

// before
href="document.php?hashp=shared"
// after
href="document.php?hashp=<?php echo $ecmfile->share; ?>"
Defensive patterns

Strategy: validation

Validate before calling

if (isset($_GET['hashp']) && ($_GET['hashp'] === '' || $_GET['hashp'] === 'shared')) {
  http_response_code(400); exit('hashp must be the generated share hash');
}

Prevention

When it happens

Trigger: Accessing document.php with hashp=shared in the query string — the check `if ($hashp == 'shared')` fires and access is forbidden with HTTP 400.

Common situations: Copy-pasting incomplete share links where the real hash was replaced/lost; templates with a literal 'shared' placeholder not substituted; documentation examples used verbatim.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of Dolibarr/dolibarr@598aa4bdad (2026-09-14). Data as JSON: /api/errors/c6f42c3acd0d3e83. Report an issue: GitHub.

Appendix: source

Thrown at htdocs/document.php:159

require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';

$encoding = '';
$action = GETPOST('action', 'aZ09');
$original_file = GETPOST('file', 'alphanohtml');
$hashp = GETPOST('hashp', 'aZ09');
$modulepart = GETPOST('modulepart', 'alpha');
$urlsource = GETPOST('urlsource', 'alpha');
$entity = ($entity > 0 ? $entity : $conf->entity);

// Security check
if (empty($modulepart) && empty($hashp)) {
	httponly_accessforbidden('Bad link. Bad value for parameter modulepart', 400);
}
if (empty($original_file) && empty($hashp)) {
	httponly_accessforbidden('Bad link. Missing identification to find file (original_file or hashp)', 400);
}
if ($hashp == 'shared') {
	httponly_accessforbidden('Bad link. Bad value for parameter hashp', 400);
}
if ($modulepart == 'fckeditor') {
	$modulepart = 'medias'; // For backward compatibility
}

$socid = 0;
if ($user->socid > 0) {
	$socid = $user->socid;
}

// For some module part, dir may be privates
if (in_array($modulepart, array('facture_paiement', 'unpaid'))) {
	if (!$user->hasRight('societe', 'client', 'voir')) {
		$original_file = 'private/'.$user->id.'/'.$original_file; // If user has no permission to see all, output dir is specific to user
	}
}

View on GitHub (pinned to 598aa4bdad)