Wikini

DocDeveloppeurSyntaxeDesLiens

PagePrincipale :: DerniersChangements :: DerniersCommentaires :: ParametresUtilisateur :: Vous êtes ec2-18-234-51-17.compute-1.amazonaws.com
La notion d'hyperlien est centrale dans un wiki :

Nous allons ici spécifier clairement la syntaxe des liens reconnus par WikiNi.
Il faut faire une distinction soigneuse entre :
  1. les chaines de caractères reconnues par WikiNi comme des liens :
    • ces chaines sont transformées par le code HTML <a href="/lien">lien</a>
    • ces chaines sont analysées dans /formatter/wakka.php
  2. ce que WikiNi accepte de créer comme nom de page dans sa base de données
    • ces chaines sont envoyées par le navigateur lorsque l'utilisateur clique sur un lien ou qu'il entre l'adresse dans le navigateur
    • ces chaines sont traitées dans /wakka.php
Un nom peut être reconnu comme un lien sans pour autant être une chaine valide pour être créé dans la base de données.

1. Liens internes au site


1.1. Motifs reconnus comme des liens


MotsWiki

Les MotsWiki ont été l'une des innovations qui ont accompagné la naissance des wikis. Il s'agit d'une manière simplifiée de créer un lien, sans connaissance technique, en collant deux ou plusieurs mots l'un à l'autre. Certains wikis, comme wikipédia, les ont abandonné mais ils jouissent encore d'un succès. WikiNi reconnait les MotsWikis? ; si nous pouvons envisager d'autres techniques de fabrication de liens, et d'autres noms de page que les mots wikis, nous les conserveront sans doute au moins au titre de la compatibilité ascendante.
Les MotsWiki sont actuellement reconnus dans WikiNi (0.4.1) par l'expression rationnelle suivante (/formatters/wakka.php) :
^[A-Z][a-z]+[A-Z,0-9][A-Z,a-z,0-9]*$
C'est à dire un ensemble de caractères :
Soit par exemple :
Ne fonctionnent pas :
Note : il y a, jusqu'à la version 0.4.1 inclue, un bug qui autorise d'utiliser des virgules dans les MotsWiki ; ceci sera corrigé dans les prochaines versions. -- ProgFou

Note 2 : il existe une limite de 50 caractères dans la base de données, mais pas dans le corps du script ! ce qui fait qu'un mot wiki de plus de 50 caractères est bien reconnu comme un MotWiki mais la page créée à partir de ce mot est elle limitée à 50 caractères (cf. TestsDeMotsWiki). Pour corriger ce problème, il faudrait :
  1. soit limiter la création de liens à des MotsWiki de 50 caractères maxi (ce qui n'empécherait pas les gens d'entrer à la main dans leur navigateur des URLs contenant un mot wiki de plus de 50 caractères)
  2. soit renvoyer une erreur explicite dans le cas d'une requête contenant un MotWiki de plus de 50 caractères (ce qui paraît être la meilleure solution)
-- CharlesNepote d'après ProgFou

Je propose d'appliquer la solution a) pour les raisons suivantes :

On verra les TestsDeMotsWiki.
[à compléter]


Liens forcés (internes)

Les liens forcés sont utilisés pour deux raisons :

Dans les versions 0.4.1 et inférieures, WikiNi :
Par exemple :
Note : le '\s' représente un caractère "blanc" et '\S' représente l'inverse (tous les autres caractères). -- ProgFou


1.2. Motifs acceptés pour la création d'une page


Dans les versions 0.4.1 et inférieures, WikiNi peut créer des pages de n'importe quel nom de moins de 50 caractères, créant ainsi des problèmes de sécurité ;
Note : la limite des 50 caractères est dans la base, mais pas dans le corps du script ! -- ProgFou
Ces fonctionnalités ont d'ailleurs donné lieu à la création de pages aux noms étranges qu'il conviendra peut-être de renommer :
(On peut voir toutes ces pages dans l'IndexDesPagesBis.)

Proposition 1 : reconnaitre les caractères alphanumériques + le signe "_"

Dans les versions 0.4.2 et 0.5.0 nous proposons de corriger ce problème. WikiNi :
Note : il n'est pas permis à un nom de page de commencer par un "_". -- CharlesNepote

Le code à modifier /wakka.php donne donc bien (j'ai testé) :
// Split into page/method
// (Note : it test if the wiki name doesn't contain some characters that should permit an XSS)
if (preg_match("#^([A-Za-z0-9][A-Za-z0-9_]{0,49})/([A-Za-z0-9_]*)$#", $wiki, $matches)) list(, $page, $method) = $matches;
else if (preg_match("#^([A-Za-z0-9][A-Za-z0-9_]{0,49})$#", $wiki, $matches)) list(, $page) = $matches;
else
{
	echo "Interdit !";
	exit;
}

-- CharlesNepote

Proposition 2 : reconnaitre tous les caractères

A la réflexion, d'un point de vue fonctionnel, tous les caractères devraient pouvoir être candidats à faire partie d'un nom de page. Chaque page d'un wiki représente un document ; à ce titre, une page titrée <script>alert(document.name)</script> doit être possible.
D'un point de vue technique, il ne faut pas que le HTML généré par WikiNi contienne du code non désirable interprétable par le navigateur : un nom de page doit rester un nom de page et non devenir un code exécutable. Il faut donc, à chaque affichage du nom d'une page, faire en sorte qu'il ne soit pas affiché de façon brute mais encodé à l'aide la fonction htmlentites().
Je propose donc de lister tous les endroits susceptibles d'afficher le nom d'une page pour voir tous les endroits à modifier et évaluer comment les modifier :
(Dans la partie "Split into page/method", il ne suffirait donc plus que de limiter le nombre de caractères à 50.)
Sur le principe, cette solution a ma préférence.
-- CharlesNepote


2. Liens interwikis

Actuellement (version <= 0.4.1) :
dans formatters/wakka.php : ^[A-Z][A-Z,a-z]+[:][A-Z,a-z,0-9]*$

Prochainement (version > 0.4.1) :
dans formatters/wakka.php : ^[A-Z][A-Za-z0-9]+[:][A-Za-z0-9-_]*$
Note de CharlesNepote : étant donné que les liens interwikis concernent aussi des sites qui ne sont pas des wikis (exemple : RFC) ou bien même des wikis qui gèrent des possibilités de caractères plus étendues (exemple PhpWiki qui gère les liens caractères accentués (cf. CraoWiki)), pourquoi se limiter à [A-Za-z0-9-_] ?
Note : attention, il ne faut pas que la partie après les deux points puisse commencer par //.
[à compléter]


3. Liens externes au site

[à réécrire]

Actuellement (version <= 0.4.3) :
dans formatters/wakka.php : ^([a-z]+:\/\/\S+?)([^[A-Za-z0-9]^\/])?$
[à compléter]

Attention, ^([a-z]+: pose des problèmes car il permet javascript://xxx .
Il faut donc pouvoir affiner cette partie. Je vois deux pistes.
1. Filtre positif : on n'accepte que des protocoles duement identifiés.
Cela donnerait quelquechose du genre : ^(http|https|ftp|ftps|gopher|irc|file|nfs):
2. Filtre négatif : on accepte tout sauf ce que l'on sait être dangereux.
Cela donnerait quelquechose du genre : ^([a-z]+|^javascript|^jscript|^script):

Le motif est reconnu dans /formatters/wakka.php par l'expression \b[[:lower:]]+:\/\/\S+ qui signifie :
Or, ce motif, pour isoler correctement une url ne devraient pas reconnaître les caractères donnés comme "unsafe" par la RFC 1738 :
Note : les signes "%" et "#", notés "unsafe" sont particuliers dans le sens où ils sont utilisés comme caractères ayant une valeur sémantique dans l'URL : le "#" représente une ancre et "%" permet d'encoder d'autres caractères. Ces deux signes doivent donc êtres reconnus par WikiNi.


Annexe 1 : note sur l'encodage des liens

Tant que l'on utilise des liens qui contiennent des caractères alphanumériques non accentués, il n'y a pas de problèmes.
Mais si nous souhaitons utiliser des caractères accentués ou des caractères non permis par la norme, il faut alors encoder les caractères (cf. fonction PHP urlencode) et éventuellement les décoder à la réception des URL (cf. fonction PHP urldecode).


Annexe 2 : liens qui seraient dangereux

Pour éviter qu'un lien soit dangereux, il faut éviter que ce dernier puisse s'exécuter côté client, sur le navigateur de l'internaute.
Exemples de liens dangeureux :
Note : j'y ai pensé aussi, mais je me suis dit qu'on pouvait de toutes façons le faire via du HTML pur (entre double-guillemets), donc... -- ProgFou
Note : Au sujet des doubles guillemets, on pourrait faire un option de WikiNi pour deux interprétations possibles : texte pur sans conversion (=> complètement ouvert) ou bien texte non interprété mais recodé pour s'afficher tel que saisis (=> fermé à l'interprétation HTML) via un fonction telle que htmlentities. -- ProgFou


Annexe 3 : références



Il n'y a pas de commentaire sur cette page. [Afficher commentaires/formulaire]