« Fonctionnement technique de Jeuxvideo.com » : différence entre les versions

De JVFlux
user: 78d3936 (?)
(Ajout d'information technique de la partie forum)
user: 23ec76d (?)
(JvCare JavaScript fonctionnel)
 
(41 versions intermédiaires par 15 utilisateurs non affichées)
Ligne 1 : Ligne 1 :
== Fonctionnement technique basique ==
{{Bannière Info|Contenu=Co-rédacteur de l'[[API|article sur l'API de JVC]], j'aurais besoin de l'aide d'un khey calé sur l'API de JVC et/ou le fonctionnement technique de jeuxvideo.com. J'ai plusieurs questions à poser en vue de la réalisation d'un projet informatique. (Edwado si tu passes par là…)<br>


JVC utilise 2 serveurs frontaux qui sont depuis le 7 mai 2022 protégés par le service "Cloudflare". Chaque serveur frontal utilise un serveur HTTP Apache2, tout ce qu'il y a de plus classique. En revanche, avant d'arriver sur le serveur Apache, on a plusieurs mailles dans la chaîne. En effet, lorsque vous faites une requête auprès de JVC, la chaîne suivante est effectuée avant d'arriver jusqu'au back-end :
Merci de me contacter sur JVC (pseudo '''ContrapunctusI'''{{CDV|Pseudo=ContrapunctusI}}). Toute aide sera appréciée.}}


'''Cloudflare => Round-robin entre les 2 serveurs frontaux => HAProxy => Apache2 => PHP / Express (Node.js)'''
== Introduction ==
[[Jeuxvideo.com]] utilise 2 serveurs frontaux qui sont depuis le 7 mai 2022 protégés par le service [https://cloudflare.com Cloudflare]. Chaque serveur frontal utilise un serveur HTTP Apache, tout ce qu'il y a de plus classique. En revanche, avant d'arriver sur le serveur Apache, on a plusieurs mailles dans la chaîne. En effet, lorsque vous faites une requête auprès de JVC, la chaîne suivante est effectuée avant d'arriver jusqu'au back-end :
Cloudflare Round-robin entre les 2 serveurs frontaux HAProxy → Varnish → Apache → PHP / Express (Node.js)


== Processus d'une requête HTTP ==
== Processus d'une requête HTTP ==


- Cloudflare est le premier point d'entrée pour accéder à JVC. Il gère les enregistrements DNS du site et ses IPs sont majoritairement aléatoires et anycastées/géocastées. Ce service touche la couche réseau/transport tout comme la couche applicative du modèle OSI : il fait office d'anti-DDoS à forte valeur (bien que JVC utilise le service "Volterra" en tant qu'anti-DDoS sur couches basses du côté des IPs de son AS 35717). Une partie de la couche applicative est protégée par Cloudflare, via des règles éditées manuellement par Webedia (entre autre, blocages de pools IPv4 de VPN connus, et de certains pays d'après certains retours d'utilisateurs).<br><br>
'''Cloudflare''' est le premier point d'entrée pour accéder à JVC. Il gère les enregistrements DNS du site et ses IPs sont majoritairement aléatoires et anycastées/géocastées. Ce service touche la couche réseau/transport tout comme la couche applicative du modèle OSI : il fait office d'anti-DDoS à forte valeur (bien que JVC utilise le service "Volterra" en tant qu'anti-DDoS sur couches basses du côté des IPs de son AS 35717). Une partie de la couche applicative est protégée par Cloudflare, via des règles éditées manuellement par [[Webedia]] (entre autre, blocages de pools IPv4 de VPN connus, et de certains pays d'après certains retours d'utilisateurs).
- Un round-robin est effectué via Cloudflare auprès des serveurs DNS de Webedia. Le but est de déterminer de façon algorithmique quel serveur frontal va être utilisé pour la requête HTTP.<br><br>
- HAProxy est un proxy et load-balancer TCP d'une efficacité remarquable, il est utilisé sur la totalité des environnements de production gérés par Webedia. C'est entre autre ce service qui peut vous retourner de sombres erreurs noires sur fond blanc comme "403 Forbidden". En effet, HAProxy fait aussi office de protection applicative (on peut donc en déduire que JVC utilisent plusieurs services sur couche haute pour protéger l'applicatif). On peut notamment remarquer le blacklistage des IPs du réseau "Tor", mais également le blacklistage des pools de l'AS 16276 (appartenant à la société OVH et n'étant utilisé que dans des contextes d'hébergement) - blocage mené suite à l'utilisation massive des services de la société OVH dans le but de scrapper / attaquer JVC.<br><br>
- Apache2 est un serveur HTTP. Il a été optimisé par l'équipe technique actuelle de Webedia, mais également par l'ancienne équipe du site (on peut notamment citer [[Dargor]] et [[Haazel]] en tant que personnes ayant participées à l'élaboration de tunning du serveur HTTP).<br><br>
- Le dernier point est selon la page qui est demandée. Des parties du site sont développées en PHP, et d'autres en Node.js. Pour anecdote, le site est hébergé côté serveur dans le dossier /opt/datas/sites/JEUXVIDEO.COM/. Il n'y a quasiment aucune protection de ce côté (si ce n'est une protection contre les IPs Tor).


== Protection applicative Cloudflare ==
Un round-robin est effectué via Cloudflare auprès des serveurs DNS de Webedia. Le but est de déterminer de façon algorithmique quel serveur frontal va être utilisé pour la requête HTTP.
 
'''HAProxy''' est un proxy et load-balancer TCP d'une efficacité remarquable, il est utilisé sur la totalité des environnements de production gérés par Webedia. C'est entre autre ce service à l'origine de l'erreur 403 Forbidden. En effet, HAProxy fait aussi office de protection applicative (on peut donc en déduire que JVC utilise plusieurs services sur couche haute pour protéger l'applicatif). On peut notamment remarquer le blacklistage des IPs du réseau "Tor", mais également le blacklistage des pools de l'AS 16276 (appartenant à la société OVH et n'étant utilisé que dans des contextes d'hébergement) - blocage mené suite à l'utilisation massive des services de la société OVH dans le but de scrapper/attaquer JVC.
 
'''Apache''' est un serveur HTTP. Il a été optimisé par l'équipe technique actuelle de Webedia, mais également par l'ancienne équipe du site (on peut notamment citer [[Dargor]] et [[Haazel]] en tant que personnes ayant participées à l'élaboration de tunning du serveur HTTP).
 
Le dernier point est selon la page qui est demandée. Des parties du site sont développées en PHP, et d'autres en Node.js. Pour l'anecdote, le site est hébergé côté serveur dans le dossier /opt/datas/sites/JEUXVIDEO.COM/<ref>La norme [https://fr.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] n’incluait pas <code>/srv</code>, qui est plus approprié, avant 2004.</ref>. Il n'y a quasiment aucune protection de ce côté (si ce n'est une protection contre les IPs Tor).
 
=== Protection applicative Cloudflare ===


L'applicatif est donc, comme on a pu le voir, protégé par Cloudflare en premier point d'entrée. Cloudflare est binaire : si l'IP source est blacklistée, une HTTP 403 est retournée et l'accès à l'URI est refusé.<br>Le blocage est en outre simple à bypasser, pour le moment, on peut constater que l'usage d'IPs géolocalisées en France est un bon bypass.
L'applicatif est donc, comme on a pu le voir, protégé par Cloudflare en premier point d'entrée. Cloudflare est binaire : si l'IP source est blacklistée, une HTTP 403 est retournée et l'accès à l'URI est refusé.<br>Le blocage est en outre simple à bypasser, pour le moment, on peut constater que l'usage d'IPs géolocalisées en France est un bon bypass.


= JVC avant Respawn =
=== Domaine de fichiers statiques ===


Avant Respawn, JVC était développé sur plusieurs langages différents côté back-end : on peut citer le C, et le PHP. La base de données finale utilisait le moteur de base de données PostgreSQL. L'anarchie technique du back-end a menée au développement de [[Respawn]] (qui est également anarchique).
'''static.jvc.gg''' est notamment utilisé pour servir les feuilles de styles et scripts et utilise comme serveur '''nginx''' au lieu d'Apache. N’étant pas protégé par Cloudflare en janvier 2023 il permet d’avoir un aperçu technique de comment était servi l’ensemble du site avant la mise en place de Cloudflare.


== Les profils (CDV) ==
Côté DNS, cinq serveurs de noms sont utilisés : ns1.webedia-group.org, ns2.webedia-group.net, ns3.webedia-group.com, ns4.webedia-group.biz, ns5.webedia-group.app. Les deux premiers sont sur leur AS 35717 ; les trois derniers sont respectivement hébergés chez Scaleway, OVH, Gandi.


Les profils ("cartes de visite" / "CDV") étaient développés en PHP et avaient la particularité notable de stocker les données publiques de chaque utilisateur (par exemple, sa description personnelle) dans de simples fichiers HTML stockés sur disque : il n'y avait pas de requête SQL d'invoquée pour obtenir certaines données liées aux CDV. Lors de certains floods d'avis utilisateurs (notamment menés par [[UnifiedLinux]] et [[edwado]]), les CDV retournaient aléatoirement des pages blanches. La cause est toujours inconnue.
== Avant Respawn ==


== Les forums ==
Avant [[Projet Respawn|Respawn]], JVC était développé sur plusieurs langages différents côté back-end : on peut citer le C et le PHP. La base de données finale utilisait le moteur de base de données PostgreSQL. L'anarchie technique du back-end a menée au développement de [[Respawn]] (qui est également anarchique).
 
=== Les Cartes de visite ===
 
Les [[Carte de Visite|Cartes de visite]] étaient développés en PHP et avaient la particularité notable de stocker les données publiques de chaque utilisateur (par exemple, sa description personnelle) dans de simples fichiers HTML stockés sur disque : il n'y avait pas de requête SQL d'invoquée pour obtenir certaines données liées aux CDV. Lors de certains floods d'avis utilisateurs (notamment menés par ''UnifiedLinux''), les CDV retournaient aléatoirement des pages blanches. La cause est toujours inconnue.
 
=== Les forums ===


Les forums étaient en C, et [[Dargor]] les nommaient "modulaires".
Les forums étaient en C, et [[Dargor]] les nommaient "modulaires".


== Les articles ==
=== Les articles ===


Les articles n'étaient pas mis en ligne immédiatement après leur rédaction. Un système de "compilation" était nécessaire et à effectuer manuellement afin que le site "compile" les articles pour qu'ils deviennent accessibles au public. On peut imaginer que ce système de compilation a été développé dans un but de gestion de charge applicative.
Les articles n'étaient pas mis en ligne immédiatement après leur rédaction. Un système de "compilation" était nécessaire et à effectuer manuellement afin que le site "compile" les articles pour qu'ils deviennent accessibles au public. On peut imaginer que ce système de compilation a été développé dans un but de gestion de charge applicative.


== Modération ==
=== Modération ===


La modération des forums était liée à une authentification à 2 étapes, menant à l'attribution du cookie [[mocoedivxuejdom]] permettant la modération de certains forums selon les permissions attribuées à chaque modérateur. Cette deuxième étape était une page spéciale réclamant 5 mots de passe, qui avaient la particularité d'être remplis de caractères aléatoires et spéciaux.
La modération des forums était liée à une authentification à 2 étapes, menant à l'attribution du cookie [[mocoedivxuejdom]] permettant la modération de certains forums selon les permissions attribuées à chaque modérateur. Cette deuxième étape était une page spéciale réclamant 5 mots de passe, qui avaient la particularité d'être remplis de caractères aléatoires et spéciaux.


== Authentification ==
=== Authentification ===
 
Le cookie [[wenvjgol]] était utilisé pour l'authentification.
 
=== La recherche des forums ===
 
La recherche des forums était connue pour être atrocement lente et affichant incorrectement la liste des résultats, des topics étaient manquants et s'affichaient une fois sur deux.
 
=== Sécurité informatique ===
 
Lorsqu'une IP tentait d'envoyer trop de requêtes HTTP (HTTPS n'était pas déployé à ce moment-là), le site redirigeait chaque requête HTTP vers une erreur 404. La page d'erreur 404 étant très peu consommatrice techniquement, cela permettait de désaturer la charge serveur en cas de DoS/DDoS.


Le cookie "wenvjgol" était utilisé pour l'authentification. Voir [[wenvjgol]].
Sur les CDV et les forums, il y a eu un grand nombre de failles XSS, notamment exploitées en masse par [[PyjamaSam]].


= Respawn =
Le [[Captcha]] était également tout le temps cassé, permettant des floods de topics/messages/contributions. Cela a permis par exemple de créer un pseudo rang rubis en moins d'un jour, dont le pseudo était ''RubyOne'' (par ''UnifiedLinux'', qui a également créé un pseudo rang diamant en moins d'un jour via un flood de contributions).


Respawn a été développé entièrement en PHP côté back-end. Il utilise notamment des frameworks tels que Symfony côté forums, et des moteurs de templates tel que Twig. Respawn semble être divisé techniquement en plusieurs parties : en effet, on peut constater que certaines parties du site respectent le modèle vue-contrôleur (on peut citer les forums), bien que d'autres parties du site n'utilisent pas ce modèle et utilisent de l'url rewriting hardcodé dans des fichiers .htaccess. Respawn semble posséder une base de code identique entre JVC et [[ForumJV]] (désormais fermé), on pouvait constater de nettes interactions entre les 2 sites lorsque ForumJV était ouvert, interactions ayant menées à certains abus (ForumJV accordait des droits de modération sur son forum personnel, des failles de sécurité était donc existantes derrière ce privilège).
== Respawn ==


== Schéma de base de données ==
[[Respawn]] a été développé entièrement en PHP côté back-end. Il utilise notamment des frameworks tels que Symfony côté forums, et des moteurs de templates tel que Twig. Respawn semble être divisé techniquement en plusieurs parties : en effet, on peut constater que certaines parties du site respectent le modèle vue-contrôleur (on peut citer les forums), bien que d'autres parties du site n'utilisent pas ce modèle et utilisent de l'url rewriting hardcodé dans des fichiers .htaccess. Respawn semble posséder une base de code identique entre JVC et [[ForumJV]] (désormais fermé), on pouvait constater de nettes interactions entre les 2 sites lorsque ForumJV était ouvert, interactions ayant menées à certains abus (ForumJV accordait des droits de modération sur son forum personnel, des failles de sécurité était donc existantes derrière ce privilège).


Le schéma de base de données de Respawn semble anarchique et composé de mélange entre le Français et l'Anglais. Exemples de tables appartenant à Respawn : "get_compte_infos", "session_renew_v2", "jeu_get_v7". Notez le "v" à la fin de chaque table, laissant penser qu'il existe plusieurs versions de celles-ci.<br>
=== Schéma de base de données ===


=== Exemple d'appel en base de données ===
Le schéma de base de données de Respawn semble anarchique et composé de mélange entre le Français et l'Anglais. Exemples de tables appartenant à Respawn : "get_compte_infos", "session_renew_v2", "jeu_get_v7". Notez le "v" à la fin de chaque table, laissant penser qu'il existe plusieurs versions de celles-ci.


''SELECT out_id_type, out_nom_type, out_dirname_type, out_affichage, out_date_publication, out_date_modification, out_id_alias_auteur, out_id_groupe_auteur, out_ip, out_titre, out_texte, out_commentaire, out_visibilite, out_liaisons, out_tags, out_medias, out_version, out_fiche, out_jeu, out_data, out_url, out_id_jeux FROM jeu_get_v7 WHERE id_contenu = xxx''
==== Exemple d'appel en base de données ====
''SELECT out_id_type, out_nom_type, out_dirname_type, out_affichage, out_date_publication, out_date_modification, out_id_alias_auteur, out_id_groupe_auteur, out_ip, out_titre, out_texte, out_commentaire, out_visibilite, out_liaisons, out_tags, out_medias, out_version, out_fiche, out_jeu, out_data, out_url, out_id_jeux FROM jeu_get_v7 WHERE id_contenu = xxx''


== Organisation technique ==
=== Organisation technique ===


Comme dit précédemment, Respawn semble être un mélange de MVC et de code classique sans modèle particulier de respecté. Les fichiers du back-end sont également mitigés du côté de leur appellation, laissant encore droit au mélange entre Français et Anglais. Exemples de fichiers côté back-end :<br>
Comme dit précédemment, Respawn semble être un mélange de MVC et de code classique sans modèle particulier de respecté. Les fichiers du back-end sont également mitigés du côté de leur appellation, laissant encore droit au mélange entre Français et Anglais. Exemples de fichiers côté back-end :


''/opt/datas/JEUXVIDEO.COM/htdocs/forums/liste_topic.php''<br>
''/opt/datas/JEUXVIDEO.COM/htdocs/forums/liste_topic.php''<br>
Ligne 66 : Ligne 89 :
''/opt/datas/JEUXVIDEO.COM/app/vendor/...''
''/opt/datas/JEUXVIDEO.COM/app/vendor/...''


== Nommage des fonctions ==
=== Nommage des fonctions ===


Pour une énième fois, Respawn possède aussi des fonctions dont le nommage est entre le Français et l'Anglais. Exemples de fonctions côté back-end :<br>
Respawn possède aussi des fonctions dont le nommage est entre le Français et l'Anglais. Exemples de fonctions côté back-end :


''getInfoFromIdForum''<br>
''getInfoFromIdForum''<br>
Ligne 77 : Ligne 100 :
''blocHtmlBoutiqueRandom''
''blocHtmlBoutiqueRandom''


== Optimisations ==
=== Optimisations ===


Le back-end PHP utilise Memcache (https://www.php.net/manual/fr/book.memcache.php) afin de faire baisser la charge technique de l'applicatif.
Le back-end PHP utilise Memcache (https://www.php.net/manual/fr/book.memcache.php) afin de faire baisser la charge technique de l'applicatif.


== Stockage des utilisateurs ==
=== Stockage des utilisateurs ===


Depuis Respawn, les utilisateurs de JVC sont référencés sous un identifiant numérique côté base de données, contrairement au fonctionnement de l'ancien JVC où les utilisateurs étaient référencés par leur pseudo (pouvant mener à des posts sur les forums avec des pseudos identiques organisés différemment côté minuscules/majuscules).
Depuis Respawn, les utilisateurs de JVC sont référencés sous un identifiant numérique côté base de données, contrairement au fonctionnement de l'ancien JVC où les utilisateurs étaient référencés par leur pseudo (pouvant mener à des posts sur les forums avec des pseudos identiques organisés différemment côté minuscules/majuscules).
Vous pouvez obtenir votre ID via la page permettant d'éditer votre profil, l'ID est à la fin de l'URI.


== Les forums ==
Il est possible d'obtenir son ID via la page permettant d'éditer votre profil, l'ID est à la fin de l'URL.


Les posts des forums sont déclarés sur plusieurs serveurs différents. Les IDs de ceux-ci semblent aléatoires (bien qu'un offset était attribué pour les posts présents sur ForumJV). Les IDs sont choisis selon le serveur dans lequel la ressource sera stockée, il semblerait qu'il y ait 8 emplacements. ID + 8 pour accéder à la ressource suivante, et ID - 8 pour accéder à la ressource précédente.
=== Les forums ===
 
Les posts des forums sont déclarés sur plusieurs serveurs différents. Les IDs de ceux-ci semblent aléatoires (bien qu'un offset était attribué pour les posts présents sur ForumJV). Les IDs sont choisis selon l'emplacement dans lequel la ressource sera stockée lors de la création du topic. Le choix de l'emplacement se fait à la création du topic, les messages dans le topic sont alors stockés dans le même emplacement. Il semblerait qu'il y ait 8 emplacements. ID + 8 pour accéder à la ressource suivante, et ID - 8 pour accéder à la ressource précédente.


Exemple de messages séquentiels:
Exemple de messages séquentiels:
Ligne 96 : Ligne 120 :
* https://www.jeuxvideo.com/forums/message/905193398
* https://www.jeuxvideo.com/forums/message/905193398


L'ID est incrémenté de 8 à chaque fois. Tous ces messages sont répertoriés dans le 7ème serveur.
L'ID est incrémenté de 8 à chaque fois. Tous ces messages sont répertoriés dans le 7ème serveur (<code>ID % 8</code>, donc <code>905193382 % 8 = 6</code>, 7ème).


À noter toutefois que les messages datant d'avant respawn sont complètement désordonnés, certainement dû à la migration durant respawn où la migration de ces messages a été effectué en parallèle.
À noter toutefois que les messages datant d'avant respawn sont complètement désordonnés, certainement dû à la migration durant respawn où la migration de ces messages a été effectué en parallèle.


== Modération ==
=== Modération ===


La modération sur Respawn se nomme "Accès étendu". L'accès étendu peut être appelé via la page qui lui est dédiée : https://www.jeuxvideo.com/sso/auth.php ; il nécessite en revanche également un mot de passe, qui est envoyé via un lien sécurisé utilisable une seule fois par MP à chaque modérateur. A noter que le [[103]] est accessible à n'importe quel modérateur même sans authentification à l'accès étendu.
La modération sur Respawn se nomme "Accès étendu". L'accès étendu peut être appelé via la page qui lui est dédiée : https://www.jeuxvideo.com/sso/auth.php ; il nécessite en revanche également un mot de passe, qui est envoyé via un lien sécurisé utilisable une seule fois par MP à chaque modérateur. A noter que le [[103]] est accessible à n'importe quel modérateur même sans authentification à l'accès étendu.


== Authentification ==
=== Authentification ===
 
Le cookie [[coniunctio]] est utilisé pour l'authentification.
 
=== Recherche des forums ===
 
La recherche des forums utilise le moteur de recherche Sphinx qui est intégré au site. La recherche des forums est limitée à 1 mois sur les blablas, elle peut être contournée via https://jvarchive.com/.
 
=== Sécurité informatique ===
 
Dans les débuts de Respawn, le site était rempli de failles permettant de faire exploser la charge du site. Il existait également de nombreuses failles sur [[ForumJV]] qui permettaient de modérer sans être modérateur, sur n'importe quel forum. Les failles ici citées ont en majorité été exploitées par [[edwado]].
 
Il a également existé une faille RCE (Remote Code Execution) exploitée par [[Tsain]], qui permettait d'injecter du CSS sur n'importe quelle partie du site (la faille fut très mal exploitée étant-donné que celle-ci n'était pas qu'une simple injection CSS mais bien une RCE où il était possible d'injecter un shell PHP).
 
=== JvCare ===
 
JvCare est un algorithme d'obfuscation des liens externes postés sur le site. Il a été développé depuis Respawn. Il permet d'éviter la création de backlinks qui pourraient optimiser indirectement le SEO de sites externes à Jeuxvideo.com.
 
Les codes ci-après permettent de décoder une chaîne obfusquée.
 
==== PHP ====
 
function jvCare(string $classe) : string {
  static $base16 = "0A12B34C56D78E9F";
  $lien = "";
  $s = explode(" ", $classe)[1];
  for ($i = 0; $i < strlen($s); $i += 2) {
    $lien .= chr(strrpos($base16, $s[$i]) * 16 + strrpos($base16, $s[$i + 1]));
  }
  return $lien;
}
 
==== JavaScript ====
 
function jvCake(classe) {
  const base16 = '0A12B34C56D78E9F';
  let lien = <nowiki>''</nowiki>;
  const s = classe.split(' ')[1];
  for (let i = 0; i < s.length; i += 2) {
    lien += String.fromCharCode(base16.indexOf(s.at(i)) * 16 + base16.indexOf(s.at(i + 1)));
  }
  return lien;
}
 
===== Fonctionnel =====
 
function jvCake(classe) {
  const base16 = '0A12B34C56D78E9F';
  const s = classe.split(' ')[1];
  const codeUnits = s
    .match(/../g)
    .map((i) => base16.indexOf(i[0]) * 16 + base16.indexOf(i[1]));
  return String.fromCharCode(...codeUnits);
}
 
==== Python ====
 
def jvcare(classe: str) -> str:
    base16 = '0A12B34C56D78E9F'
    s = classe.split()[1]
    url = <nowiki>''</nowiki>
    for i, j in zip(s[0::2], s[1::2]):
        url += chr(base16.index(i) * 16 + base16.index(j))
    return url
 
===== Liste en compréhension =====
 
def jvcare(classe: str) -> str:
    base16 = '0A12B34C56D78E9F'
    s = classe.split()[1]
    return <nowiki>''</nowiki>.join([chr(base16.index(i) * 16 + base16.index(j)) for i, j in zip(s[0::2], s[1::2])])
 
==== C ====
 
#include <stdlib.h>
#include <string.h>
const char *__jvcarebase16 = "0A12B34C56D78E9F";
char *jvcare(const char *class) {
    char *s = strchr(class, ' ') + 1;
    int urllen = strlen(s) / 2;
    char *url = malloc(urllen + 1);
    for (int i = 0; i < urllen; i++) {
        char pos1 = strchr(__jvcarebase16, s[i * 2]) - __jvcarebase16;
        char pos2 = strchr(__jvcarebase16, s[i * 2 + 1]) - __jvcarebase16;
        url[i] = pos1 * 16 + pos2;
    }
    url[urllen] = '\0';
    return url;
}
 
==== Awk ====
 
BEGIN {
    base16 = "0A12B34C56D78E9F"
}
{
    s = $2
    for (i = 1; i < length(s); i += 2) {
        pos1 = index(base16, substr(s, i, 1))
        pos2 = index(base16, substr(s, i + 1, 1))
        url = url sprintf("%c", (pos1 - 1) * 16 + (pos2 - 1))
    }
    print url
}
 
== Phoenix ==
 
Phoenix est une partie de JVC développée en Node.js et utilisant React. Elle semble de plus en plus abandonnée, et nous n'avons pas beaucoup d'informations à son sujet. Phoenix utilise une API spéciale hébergée au sous-domaine [[Documentation_de_l%27API_Jeuxvideo.com#API_jvc.gg|''api.jvc.gg'']].
 
== Liens externes ==
 
* [http://www.journaldunet.com/solutions/itws/050426_it_jeuxvideo.shtml Interview sur l’architecture de jeuxvideo.com de 1997 à 2005] ([http://web.archive.org/web/20070629165914/http://www.journaldunet.com/solutions/itws/050426_it_jeuxvideo.shtml archive.org])
 
== Notes ==
 
<references />
 
== Voir aussi ==


Le cookie "coniunctio" est utilisé pour l'authentification.
* [[Documentation de l'API Jeuxvideo.com]]


= Phoenix =
{{SectionRéférences}}
{{TableauCatégorieFonctionnementJVC}}


Phoenix est une partie de JVC développée en Node.js. Elle semble de plus en plus abandonnée, et nous n'avons pas beaucoup d'informations à son sujet.
[[Catégorie:Fonctionnement technique de Jeuxvideo.com]]
[[Catégorie:Extensions et outils]]

Dernière version du 24 novembre 2024 à 18:16

Co-rédacteur de l'article sur l'API de JVC, j'aurais besoin de l'aide d'un khey calé sur l'API de JVC et/ou le fonctionnement technique de jeuxvideo.com. J'ai plusieurs questions à poser en vue de la réalisation d'un projet informatique. (Edwado si tu passes par là…)
Merci de me contacter sur JVC (pseudo ContrapunctusIBt forum profil.gif). Toute aide sera appréciée.

Introduction[modifier | modifier le wikicode]

Jeuxvideo.com utilise 2 serveurs frontaux qui sont depuis le 7 mai 2022 protégés par le service Cloudflare. Chaque serveur frontal utilise un serveur HTTP Apache, tout ce qu'il y a de plus classique. En revanche, avant d'arriver sur le serveur Apache, on a plusieurs mailles dans la chaîne. En effet, lorsque vous faites une requête auprès de JVC, la chaîne suivante est effectuée avant d'arriver jusqu'au back-end :

Cloudflare → Round-robin entre les 2 serveurs frontaux → HAProxy → Varnish → Apache → PHP / Express (Node.js)

Processus d'une requête HTTP[modifier | modifier le wikicode]

Cloudflare est le premier point d'entrée pour accéder à JVC. Il gère les enregistrements DNS du site et ses IPs sont majoritairement aléatoires et anycastées/géocastées. Ce service touche la couche réseau/transport tout comme la couche applicative du modèle OSI : il fait office d'anti-DDoS à forte valeur (bien que JVC utilise le service "Volterra" en tant qu'anti-DDoS sur couches basses du côté des IPs de son AS 35717). Une partie de la couche applicative est protégée par Cloudflare, via des règles éditées manuellement par Webedia (entre autre, blocages de pools IPv4 de VPN connus, et de certains pays d'après certains retours d'utilisateurs).

Un round-robin est effectué via Cloudflare auprès des serveurs DNS de Webedia. Le but est de déterminer de façon algorithmique quel serveur frontal va être utilisé pour la requête HTTP.

HAProxy est un proxy et load-balancer TCP d'une efficacité remarquable, il est utilisé sur la totalité des environnements de production gérés par Webedia. C'est entre autre ce service à l'origine de l'erreur 403 Forbidden. En effet, HAProxy fait aussi office de protection applicative (on peut donc en déduire que JVC utilise plusieurs services sur couche haute pour protéger l'applicatif). On peut notamment remarquer le blacklistage des IPs du réseau "Tor", mais également le blacklistage des pools de l'AS 16276 (appartenant à la société OVH et n'étant utilisé que dans des contextes d'hébergement) - blocage mené suite à l'utilisation massive des services de la société OVH dans le but de scrapper/attaquer JVC.

Apache est un serveur HTTP. Il a été optimisé par l'équipe technique actuelle de Webedia, mais également par l'ancienne équipe du site (on peut notamment citer Dargor et Haazel en tant que personnes ayant participées à l'élaboration de tunning du serveur HTTP).

Le dernier point est selon la page qui est demandée. Des parties du site sont développées en PHP, et d'autres en Node.js. Pour l'anecdote, le site est hébergé côté serveur dans le dossier /opt/datas/sites/JEUXVIDEO.COM/[1]. Il n'y a quasiment aucune protection de ce côté (si ce n'est une protection contre les IPs Tor).

Protection applicative Cloudflare[modifier | modifier le wikicode]

L'applicatif est donc, comme on a pu le voir, protégé par Cloudflare en premier point d'entrée. Cloudflare est binaire : si l'IP source est blacklistée, une HTTP 403 est retournée et l'accès à l'URI est refusé.
Le blocage est en outre simple à bypasser, pour le moment, on peut constater que l'usage d'IPs géolocalisées en France est un bon bypass.

Domaine de fichiers statiques[modifier | modifier le wikicode]

static.jvc.gg est notamment utilisé pour servir les feuilles de styles et scripts et utilise comme serveur nginx au lieu d'Apache. N’étant pas protégé par Cloudflare en janvier 2023 il permet d’avoir un aperçu technique de comment était servi l’ensemble du site avant la mise en place de Cloudflare.

Côté DNS, cinq serveurs de noms sont utilisés : ns1.webedia-group.org, ns2.webedia-group.net, ns3.webedia-group.com, ns4.webedia-group.biz, ns5.webedia-group.app. Les deux premiers sont sur leur AS 35717 ; les trois derniers sont respectivement hébergés chez Scaleway, OVH, Gandi.

Avant Respawn[modifier | modifier le wikicode]

Avant Respawn, JVC était développé sur plusieurs langages différents côté back-end : on peut citer le C et le PHP. La base de données finale utilisait le moteur de base de données PostgreSQL. L'anarchie technique du back-end a menée au développement de Respawn (qui est également anarchique).

Les Cartes de visite[modifier | modifier le wikicode]

Les Cartes de visite étaient développés en PHP et avaient la particularité notable de stocker les données publiques de chaque utilisateur (par exemple, sa description personnelle) dans de simples fichiers HTML stockés sur disque : il n'y avait pas de requête SQL d'invoquée pour obtenir certaines données liées aux CDV. Lors de certains floods d'avis utilisateurs (notamment menés par UnifiedLinux), les CDV retournaient aléatoirement des pages blanches. La cause est toujours inconnue.

Les forums[modifier | modifier le wikicode]

Les forums étaient en C, et Dargor les nommaient "modulaires".

Les articles[modifier | modifier le wikicode]

Les articles n'étaient pas mis en ligne immédiatement après leur rédaction. Un système de "compilation" était nécessaire et à effectuer manuellement afin que le site "compile" les articles pour qu'ils deviennent accessibles au public. On peut imaginer que ce système de compilation a été développé dans un but de gestion de charge applicative.

Modération[modifier | modifier le wikicode]

La modération des forums était liée à une authentification à 2 étapes, menant à l'attribution du cookie mocoedivxuejdom permettant la modération de certains forums selon les permissions attribuées à chaque modérateur. Cette deuxième étape était une page spéciale réclamant 5 mots de passe, qui avaient la particularité d'être remplis de caractères aléatoires et spéciaux.

Authentification[modifier | modifier le wikicode]

Le cookie wenvjgol était utilisé pour l'authentification.

La recherche des forums[modifier | modifier le wikicode]

La recherche des forums était connue pour être atrocement lente et affichant incorrectement la liste des résultats, des topics étaient manquants et s'affichaient une fois sur deux.

Sécurité informatique[modifier | modifier le wikicode]

Lorsqu'une IP tentait d'envoyer trop de requêtes HTTP (HTTPS n'était pas déployé à ce moment-là), le site redirigeait chaque requête HTTP vers une erreur 404. La page d'erreur 404 étant très peu consommatrice techniquement, cela permettait de désaturer la charge serveur en cas de DoS/DDoS.

Sur les CDV et les forums, il y a eu un grand nombre de failles XSS, notamment exploitées en masse par PyjamaSam.

Le Captcha était également tout le temps cassé, permettant des floods de topics/messages/contributions. Cela a permis par exemple de créer un pseudo rang rubis en moins d'un jour, dont le pseudo était RubyOne (par UnifiedLinux, qui a également créé un pseudo rang diamant en moins d'un jour via un flood de contributions).

Respawn[modifier | modifier le wikicode]

Respawn a été développé entièrement en PHP côté back-end. Il utilise notamment des frameworks tels que Symfony côté forums, et des moteurs de templates tel que Twig. Respawn semble être divisé techniquement en plusieurs parties : en effet, on peut constater que certaines parties du site respectent le modèle vue-contrôleur (on peut citer les forums), bien que d'autres parties du site n'utilisent pas ce modèle et utilisent de l'url rewriting hardcodé dans des fichiers .htaccess. Respawn semble posséder une base de code identique entre JVC et ForumJV (désormais fermé), on pouvait constater de nettes interactions entre les 2 sites lorsque ForumJV était ouvert, interactions ayant menées à certains abus (ForumJV accordait des droits de modération sur son forum personnel, des failles de sécurité était donc existantes derrière ce privilège).

Schéma de base de données[modifier | modifier le wikicode]

Le schéma de base de données de Respawn semble anarchique et composé de mélange entre le Français et l'Anglais. Exemples de tables appartenant à Respawn : "get_compte_infos", "session_renew_v2", "jeu_get_v7". Notez le "v" à la fin de chaque table, laissant penser qu'il existe plusieurs versions de celles-ci.

Exemple d'appel en base de données[modifier | modifier le wikicode]

SELECT out_id_type, out_nom_type, out_dirname_type, out_affichage, out_date_publication, out_date_modification, out_id_alias_auteur, out_id_groupe_auteur, out_ip, out_titre, out_texte, out_commentaire, out_visibilite, out_liaisons, out_tags, out_medias, out_version, out_fiche, out_jeu, out_data, out_url, out_id_jeux FROM jeu_get_v7 WHERE id_contenu = xxx

Organisation technique[modifier | modifier le wikicode]

Comme dit précédemment, Respawn semble être un mélange de MVC et de code classique sans modèle particulier de respecté. Les fichiers du back-end sont également mitigés du côté de leur appellation, laissant encore droit au mélange entre Français et Anglais. Exemples de fichiers côté back-end :

/opt/datas/JEUXVIDEO.COM/htdocs/forums/liste_topic.php
/opt/datas/JEUXVIDEO.COM/app/modeles/core/OiPDOStatement.php
/opt/datas/JEUXVIDEO.COM/app/modeles/sso/Transaction.php
/opt/datas/JEUXVIDEO.COM/app/modeles/GoogleTagManager.php
/opt/datas/JEUXVIDEO.COM/app/modeles/sso/Compte.php
/opt/datas/JEUXVIDEO.COM/app/controllers/forum/liste_topic.php
/opt/datas/JEUXVIDEO.COM/app/modeles/sso/Session.php
/opt/datas/JEUXVIDEO.COM/app/vendor/...

Nommage des fonctions[modifier | modifier le wikicode]

Respawn possède aussi des fonctions dont le nommage est entre le Français et l'Anglais. Exemples de fonctions côté back-end :

getInfoFromIdForum
loadMenu
checkMenuItem
getSingleton
getHtmlJeuForum
blocHtmlBoutiqueRandom

Optimisations[modifier | modifier le wikicode]

Le back-end PHP utilise Memcache (https://www.php.net/manual/fr/book.memcache.php) afin de faire baisser la charge technique de l'applicatif.

Stockage des utilisateurs[modifier | modifier le wikicode]

Depuis Respawn, les utilisateurs de JVC sont référencés sous un identifiant numérique côté base de données, contrairement au fonctionnement de l'ancien JVC où les utilisateurs étaient référencés par leur pseudo (pouvant mener à des posts sur les forums avec des pseudos identiques organisés différemment côté minuscules/majuscules).

Il est possible d'obtenir son ID via la page permettant d'éditer votre profil, l'ID est à la fin de l'URL.

Les forums[modifier | modifier le wikicode]

Les posts des forums sont déclarés sur plusieurs serveurs différents. Les IDs de ceux-ci semblent aléatoires (bien qu'un offset était attribué pour les posts présents sur ForumJV). Les IDs sont choisis selon l'emplacement dans lequel la ressource sera stockée lors de la création du topic. Le choix de l'emplacement se fait à la création du topic, les messages dans le topic sont alors stockés dans le même emplacement. Il semblerait qu'il y ait 8 emplacements. ID + 8 pour accéder à la ressource suivante, et ID - 8 pour accéder à la ressource précédente.

Exemple de messages séquentiels:

L'ID est incrémenté de 8 à chaque fois. Tous ces messages sont répertoriés dans le 7ème serveur (ID % 8, donc 905193382 % 8 = 6, 7ème).

À noter toutefois que les messages datant d'avant respawn sont complètement désordonnés, certainement dû à la migration durant respawn où la migration de ces messages a été effectué en parallèle.

Modération[modifier | modifier le wikicode]

La modération sur Respawn se nomme "Accès étendu". L'accès étendu peut être appelé via la page qui lui est dédiée : https://www.jeuxvideo.com/sso/auth.php ; il nécessite en revanche également un mot de passe, qui est envoyé via un lien sécurisé utilisable une seule fois par MP à chaque modérateur. A noter que le 103 est accessible à n'importe quel modérateur même sans authentification à l'accès étendu.

Authentification[modifier | modifier le wikicode]

Le cookie coniunctio est utilisé pour l'authentification.

Recherche des forums[modifier | modifier le wikicode]

La recherche des forums utilise le moteur de recherche Sphinx qui est intégré au site. La recherche des forums est limitée à 1 mois sur les blablas, elle peut être contournée via https://jvarchive.com/.

Sécurité informatique[modifier | modifier le wikicode]

Dans les débuts de Respawn, le site était rempli de failles permettant de faire exploser la charge du site. Il existait également de nombreuses failles sur ForumJV qui permettaient de modérer sans être modérateur, sur n'importe quel forum. Les failles ici citées ont en majorité été exploitées par edwado.

Il a également existé une faille RCE (Remote Code Execution) exploitée par Tsain, qui permettait d'injecter du CSS sur n'importe quelle partie du site (la faille fut très mal exploitée étant-donné que celle-ci n'était pas qu'une simple injection CSS mais bien une RCE où il était possible d'injecter un shell PHP).

JvCare[modifier | modifier le wikicode]

JvCare est un algorithme d'obfuscation des liens externes postés sur le site. Il a été développé depuis Respawn. Il permet d'éviter la création de backlinks qui pourraient optimiser indirectement le SEO de sites externes à Jeuxvideo.com.

Les codes ci-après permettent de décoder une chaîne obfusquée.

PHP[modifier | modifier le wikicode]

function jvCare(string $classe) : string {
  static $base16 = "0A12B34C56D78E9F";
  $lien = "";
  $s = explode(" ", $classe)[1];
  for ($i = 0; $i < strlen($s); $i += 2) {
    $lien .= chr(strrpos($base16, $s[$i]) * 16 + strrpos($base16, $s[$i + 1]));
  }
  return $lien;
}

JavaScript[modifier | modifier le wikicode]

function jvCake(classe) {
  const base16 = '0A12B34C56D78E9F';
  let lien = '';
  const s = classe.split(' ')[1];
  for (let i = 0; i < s.length; i += 2) {
    lien += String.fromCharCode(base16.indexOf(s.at(i)) * 16 + base16.indexOf(s.at(i + 1)));
  }
  return lien;
}
Fonctionnel[modifier | modifier le wikicode]
function jvCake(classe) {
  const base16 = '0A12B34C56D78E9F';
  const s = classe.split(' ')[1];
  const codeUnits = s
    .match(/../g)
    .map((i) => base16.indexOf(i[0]) * 16 + base16.indexOf(i[1]));
  return String.fromCharCode(...codeUnits);
}

Python[modifier | modifier le wikicode]

def jvcare(classe: str) -> str:
    base16 = '0A12B34C56D78E9F'
    s = classe.split()[1]
    url = ''
    for i, j in zip(s[0::2], s[1::2]):
        url += chr(base16.index(i) * 16 + base16.index(j))
    return url
Liste en compréhension[modifier | modifier le wikicode]
def jvcare(classe: str) -> str:
    base16 = '0A12B34C56D78E9F'
    s = classe.split()[1]
    return ''.join([chr(base16.index(i) * 16 + base16.index(j)) for i, j in zip(s[0::2], s[1::2])])

C[modifier | modifier le wikicode]

#include <stdlib.h>
#include <string.h>

const char *__jvcarebase16 = "0A12B34C56D78E9F";

char *jvcare(const char *class) {
    char *s = strchr(class, ' ') + 1;

    int urllen = strlen(s) / 2;
    char *url = malloc(urllen + 1);
    for (int i = 0; i < urllen; i++) {
        char pos1 = strchr(__jvcarebase16, s[i * 2]) - __jvcarebase16;
        char pos2 = strchr(__jvcarebase16, s[i * 2 + 1]) - __jvcarebase16;
        url[i] = pos1 * 16 + pos2;
    }
    url[urllen] = '\0';
    return url;
}

Awk[modifier | modifier le wikicode]

BEGIN {
    base16 = "0A12B34C56D78E9F"
}
{
    s = $2
    for (i = 1; i < length(s); i += 2) {
        pos1 = index(base16, substr(s, i, 1))
        pos2 = index(base16, substr(s, i + 1, 1))
        url = url sprintf("%c", (pos1 - 1) * 16 + (pos2 - 1))
    }
    print url
}

Phoenix[modifier | modifier le wikicode]

Phoenix est une partie de JVC développée en Node.js et utilisant React. Elle semble de plus en plus abandonnée, et nous n'avons pas beaucoup d'informations à son sujet. Phoenix utilise une API spéciale hébergée au sous-domaine api.jvc.gg.

Liens externes[modifier | modifier le wikicode]

Notes[modifier | modifier le wikicode]

  1. La norme Filesystem Hierarchy Standard n’incluait pas /srv, qui est plus approprié, avant 2004.

Voir aussi[modifier | modifier le wikicode]

Références[modifier le wikicode]