Teaching Web Code Plagiarism Detection With Real Student Cases

Web code plagiarism detection works by comparing a student's source file against publicly indexed code from Stack Overflow, GitHub, tutorial sites, and peer submissions, then measuring structural similarity through tokens, ASTs, and fingerprints. Most university plagiarism checkers only compare within a class, so a student who copies from a 2019 blog post often produces zero peer matches. The trick is to teach detection as a skill and design assignments that make the copied web code visible before you even open a report.

What Web Code Plagiarism Actually Looks Like

Consider a Java method submitted in a data structures course. It reads cleanly, handles edge cases, and the student can explain the algorithm in office hours. But look closer:

def get_middle(s):
    index = len(s) // 2
    if len(s) % 2 == 0:
        return s[index-1:index+1]
    else:
        return s[index]

This is almost certainly copied from a Stack Overflow answer. The original post used the same variable name index, checked the even case before the odd case, and returned the same slice boundaries. The student changed the function name from get_middle_char to get_middle, removed the type hints, and deleted the author's explanatory comment. The surface text changed. The structure did not.

Web code plagiarism is not just pasting an entire file. It is copying a six-line sorting snippet, a regex pattern for email validation, or a backtracking template from a blog without attribution. In my experience, the most common source is not GitHub but niche tutorial sites: GeeksforGeeks, Programiz, W3Schools, and decade-old personal blogs. Students search, find a function that matches the assignment, change the names, and submit.

Why Peer-Only Tools Miss Most Web-Sourced Copying

MOSS and JPlag are excellent at finding two students who copied from each other. They compare submissions inside a class archive and look for unusual shared structure. But if only one student in the section copied a quicksort helper from a GeeksforGeeks page, MOSS will not flag it. There is no peer match because no peer submitted the same code.

This is the blind spot that catches instructors off guard. The copied submission looks completely original within the local set. It only becomes detectable when you compare against a web corpus.

Peer-only comparison creates a dangerous blind spot: the student who copies from the web produces a one-of-one submission inside the class, so no peer match ever fires.

A code plagiarism checker that also scans the open web and public GitHub will surface the original Stack Overflow page, the tutorial article, or the GitHub gist where the code appeared. The report shows the matched URL, the similarity percentage, and the overlapping regions. That evidence changes the conversation from "I think this looks familiar" to "here is the source."

ToolCompares AgainstDetects Web Copies
MOSSPeer submissions in the same archiveNo
JPlag / DolosPeer submissions, sometimes a local repositoryRarely
CodequiryPeer submissions, open web, GitHub, public tutorialsYes
Codequiry web results tracing copied code to GitHub, Stack Overflow and the open web
Web results — Codequiry traces copied code back to GitHub, Stack Overflow and the open web.

When I switched a spring 2024 operating systems course to a web-aware checker, 14 of 31 flagged assignments were traced to public online sources, not to classmates. The students had not copied from each other. They had copied from the internet.

Assigning a Web Plagiarism Diagnosis Exercise

The best way to teach students where the line is between reuse and plagiarism is to make them diagnose examples themselves. I use a one-hour exercise in the second week of CS2. Students receive three versions of a binary search function and must annotate them.

# Version A: original student submission
def search(arr, target):
    low = 0
    high = len(arr) - 1
    while low <= high:
        mid = (low + high) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            low = mid + 1
        else:
            high = mid - 1
    return -1

# Version B: copied from a tutorial with variable renaming
def binary(a, x):
    lo = 0
    hi = len(a) - 1
    while lo <= hi:
        m = (lo + hi) // 2
        if a[m] == x:
            return m
        elif a[m] < x:
            lo = m + 1
        else:
            hi = m - 1
    return -1

Version A and Version B look different at first glance. But the token sequence after removing identifiers is identical, and the AST is a perfect match. Students who complete the exercise themselves start to understand why changing low to lo and target to x does not create original work. They also learn to write proper attribution comments for the cases where they are allowed to adapt an external solution.

This exercise does more than any policy lecture. It gives students the same vocabulary you will use when a plagiarism report lands on their desk.

How Token and AST Fingerprinting Survives Renaming

Detection tools convert source code into tokens, remove comments and whitespace, and then build an abstract syntax tree. A variable rename changes the token text but not the token role. low becomes lo, but both are still identifiers in the same syntactic positions. Reordering independent statements changes the source text but leaves the AST largely intact. Refactoring a for loop into a while loop may change the tree shape, but the control-flow fingerprint often remains similar enough to produce a high confidence match.

A robust source code plagiarism checker uses multiple layers: token-based comparison for fast exact matching, AST comparison for renamed or reformatted code, and fingerprinting that captures function-level semantic signatures. This is why a student cannot hide a copied function by changing names, adding notes, or swapping two independent parameter checks.

Side-by-side source code comparison in Codequiry showing an 84% match between two submissions
Side-by-side comparison — Codequiry lines up matching code between two submissions and scores the overlap.

The important practical limit is that no tool can prove cheating with 100 percent certainty. What these structural signals do is produce a ranked list of suspicious matches. An instructor still reviews the report, looks at the original source, and applies academic judgment.

AI-Generated Code Often Inherits Web Code Characteristics

Large language models are trained on the same public web corpora that students copy from. When a student asks ChatGPT to generate a binary search, the output often resembles a common tutorial implementation. Sometimes it reproduces variable names and comments from public repositories with only small changes. This means AI-generated code and web-plagiarized code are not separate problems. They overlap.

The strongest workflow is to run both checks together. A submission may trip an AI detector for low perplexity, then show a web-source match to a GitHub file, then reveal that the student edited only the top-level function name. None of those signals alone would be enough. Combined, they form a coherent picture.

Codequiry approaches this by checking copied or AI-written code in the same report, so you are not juggling three different tools with three different thresholds.

A Syllabus Policy That Reduces Web Plagiarism Early

Detection is only half the work. A clear attribution policy prevents many cases before they happen. I now include this policy in every syllabus:

  • Allowed sources only. The assignment specifies whether Stack Overflow, GitHub, or AI assistants may be consulted.
  • Attribution comments are mandatory. Any adapted code must include a comment with the URL and a one-line description of what changed.
  • Oral explanation is part of the grade. Ten percent of each assignment requires explaining any non-original fragment in office hours or a short recorded video.
  • Automated checks are disclosed. Students know their submissions will run through a web-aware plagiarism checker and an AI detector.

A proper attribution comment looks like this:

# Based on binary search implementation from GeeksforGeeks
# (https://www.geeksforgeeks.org/binary-search/)
# Modified to return -1 when target not found and handle duplicate indices.

When students know that the instructor will see the original URL in the report, the incentive to hide a source drops. They realize that citing the source is usually less costly than being caught without it.