Back to skill

Security audit

Amazing PsyCoder

Security checks across malware telemetry and agentic risk

Overview

This psychology coding skill is mostly coherent, but it should be reviewed because its installer can overwrite existing agent skills and some experiment templates collect participant IP/location/browser metadata.

Install only if you are comfortable with it replacing existing same-named skill folders. Before using generated online experiments, review the output for participant privacy: remove IP/location/user-agent collection unless explicitly consented and needed, and do not copy eval/exec-based demo snippets into production experiments.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (462)

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Content
print(f"Python 版本: {sys.version}")
for pkg in ['pandas', 'numpy', 'scipy', 'statsmodels',
             'pingouin', 'matplotlib', 'seaborn']:
    mod = __import__(pkg)
    print(f"  {pkg}: {mod.__version__}")
Confidence
75% confidence
Finding
mod = __import__(pkg)

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Content
print(f"分析生成时间: {pd.Timestamp.now()}")
print(f"Python 版本: {sys.version}")
for pkg in ['pandas', 'numpy', 'scipy', 'pingouin', 'matplotlib', 'seaborn']:
    mod = __import__(pkg)
    print(f"  {pkg}: {mod.__version__}")
Confidence
75% confidence
Finding
mod = __import__(pkg)

exec() call detected

High
Category
Dangerous Code Execution
Content
# abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb)
if thisTrial != None:
    for paramName in thisTrial:
        exec('{} = thisTrial[paramName]'.format(paramName))

for thisTrial in trials:
    currentLoop = trials
Confidence
85% confidence
Finding
exec('{} = thisTrial[paramName]'.format(paramName))

exec() call detected

High
Category
Dangerous Code Execution
Content
# abbreviate parameter names if possible (e.g. rgb = thisShowMeTrial.rgb)
if thisShowMeTrial != None:
    for paramName in thisShowMeTrial:
        exec('{} = thisShowMeTrial[paramName]'.format(paramName))

for thisShowMeTrial in showMeTrials:
    currentLoop = showMeTrials
Confidence
85% confidence
Finding
exec('{} = thisShowMeTrial[paramName]'.format(paramName))

exec() call detected

High
Category
Dangerous Code Execution
Content
# abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb)
    if thisTrial != None:
        for paramName in thisTrial:
            exec('{} = thisTrial[paramName]'.format(paramName))
    
    # ------Prepare to start Routine "trial"-------
    t = 0
Confidence
85% confidence
Finding
exec('{} = thisTrial[paramName]'.format(paramName))

exec() call detected

High
Category
Dangerous Code Execution
Content
# abbreviate parameter names if possible (e.g. rgb = thisShowMeTrial.rgb)
    if thisShowMeTrial != None:
        for paramName in thisShowMeTrial:
            exec('{} = thisShowMeTrial[paramName]'.format(paramName))
    
    # ------Prepare to start Routine "showMeHow"-------
    t = 0
Confidence
85% confidence
Finding
exec('{} = thisShowMeTrial[paramName]'.format(paramName))

exec() call detected

High
Category
Dangerous Code Execution
Content
# abbreviate parameter names if possible (e.g. rgb = thisPracticeTrial.rgb)
if thisPracticeTrial != None:
    for paramName in thisPracticeTrial:
        exec('{} = thisPracticeTrial[paramName]'.format(paramName))

for thisPracticeTrial in practiceTrials:
    currentLoop = practiceTrials
Confidence
85% confidence
Finding
exec('{} = thisPracticeTrial[paramName]'.format(paramName))

exec() call detected

High
Category
Dangerous Code Execution
Content
# abbreviate parameter names if possible (e.g. rgb = thisMainTrial.rgb)
if thisMainTrial != None:
    for paramName in thisMainTrial:
        exec('{} = thisMainTrial[paramName]'.format(paramName))

for thisMainTrial in mainTrials:
    currentLoop = mainTrials
Confidence
85% confidence
Finding
exec('{} = thisMainTrial[paramName]'.format(paramName))

exec() call detected

High
Category
Dangerous Code Execution
Content
# abbreviate parameter names if possible (e.g. rgb = thisPracticeTrial.rgb)
    if thisPracticeTrial != None:
        for paramName in thisPracticeTrial:
            exec('{} = thisPracticeTrial[paramName]'.format(paramName))
    
    # ------Prepare to start Routine "main"-------
    t = 0
Confidence
85% confidence
Finding
exec('{} = thisPracticeTrial[paramName]'.format(paramName))

exec() call detected

High
Category
Dangerous Code Execution
Content
# abbreviate parameter names if possible (e.g. rgb = thisMainTrial.rgb)
    if thisMainTrial != None:
        for paramName in thisMainTrial:
            exec('{} = thisMainTrial[paramName]'.format(paramName))
    
    # ------Prepare to start Routine "main"-------
    t = 0
Confidence
85% confidence
Finding
exec('{} = thisMainTrial[paramName]'.format(paramName))

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The top-level description explicitly says 'Does NOT generate code', yet the document later describes this phase as 'the critical foundation for code generation' and says the seed is 'injected into the generated code'. This is an active contradiction in the skill's own documentation about whether code generation is part of the skill's behavior or responsibilities.

Intent-Code Divergence

Low
Confidence
88% confidence
Finding
The Phase 2 goal says this stage is 'the critical foundation for code generation', which conflicts with the earlier explicit statement that this skill does not generate code. While the likely intent is handoff to another skill, the wording still contradicts the documented boundary of this skill.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
This line says the seed is 'injected into the generated code as set.seed() / np.random.seed()', which directly contradicts the earlier statement that the skill does not generate code. The issue is documentary intent divergence rather than implementation behavior, but it is explicit and material.

Intent-Code Divergence

Low
Confidence
97% confidence
Finding
The section label says it computes Cohen's d_z for the paired design, but `repeated_measures_d(rt ~ condition | subject_id, data = df)` references `subject_id`, which does not exist in the constructed data frame where the subject column is `id`. This makes the documented example contradict the actual code behavior, because the code as written will not perform the described paired effect-size calculation.

Context-Inappropriate Capability

Low
Confidence
86% confidence
Finding
With no manifest available, the code documentation and UI present this as a bilingual Stroop task, but the implementation also captures OS/platform information and imports arbitrary URL parameters into experiment metadata. Those telemetry-style capabilities are not justified by the task instructions shown to the participant and go beyond the obvious needs of presenting stimuli and recording responses.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The prose explicitly states that correctness is computed by comparing the participant response to the `corr_ans` column from the condition file. In the code, keyboard correctness is checked with `if (key_resp.keys == answer)` and mouse/hover logic uses `answer_mouse`, which contradicts the documented scoring logic rather than merely omitting detail.

Intent-Code Divergence

High
Confidence
97% confidence
Finding
The markdown describes a canonical antisaccade sequence with fixation, cue flash, cue disappearance, and target onset. The included PsychoJS code defines routines for instructions, trial, feedback, and thanks, but the trial routine only draws `target` and `opposite_location`; no fixation-cross or cue component appears anywhere, so the documented task flow actively conflicts with the implemented behavior.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The on-screen instructions tell participants to 'Use the arrow keys to identify the text color' and the code later enforces arrow-key responses (`left`, `down`, `right`), but the higher-level experiment description and design notes state the task uses `r`, `g`, and `b` keys. This is an active documentation contradiction within the file about how participants respond, which can misrepresent the implemented behavior.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The prose description explicitly states that practice trials include feedback and the main experimental trials do not. However, the main trial scheduler adds `feedbackRoutineBegin/EachFrame/End` after every trial in the main `trials` loop, so participants still receive correctness feedback during the main phase.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The participant-facing text says users will see 'six colored squares' and judge whether 'that colored square' appeared, while the surrounding documentation at L0010-L0017 describes colored circles rendered as ShapeStim elements. The code also implements Rect stimuli rather than circles, so the documentation actively misstates the implemented task stimuli.

Intent-Code Divergence

Low
Confidence
98% confidence
Finding
The participant-facing instructions say the task starts with '3 lit squares', but the code at L0216 initializes `nBlocks = 3` and then the sequence loop uses `nReps: nBlocks` over zero-based indices into the 9 blocks, which results in the first trial presenting three blocks only because of current code state; however the task description above states sequence length starts at 2, creating an internal documentation contradiction within this file. This is an intent/documentation inconsistency rather than a low-level bug, because the prose and embedded code comments/documentation do not agree on the experiment's actual starting behavior.

Intent-Code Divergence

Medium
Confidence
99% confidence
Finding
The file's Experiment Logic section states sequence length 'increases with successful reproduction ... or decreases with failure', but the implementation only increments `nBlocks` on correct trials at L1467-L1469 and never decreases it after incorrect trials. Instead, incorrect responses are counted and the task ends after more than three failures at L1593-L1598, which directly contradicts the documented adaptive behavior.

Intent-Code Divergence

Medium
Confidence
94% confidence
Finding
The instruction text tells the participant that the other players 'will get to choose who to toss a ball to,' implying live choices by those players. However, the experiment logic imports throw sequences from spreadsheets and uses `ball_to`/`ball_from` values to drive throws deterministically, so the documentation shown in code contradicts the implemented behavior in a way that matters to the experiment's intent.

Intent-Code Divergence

Low
Confidence
90% confidence
Finding
The on-screen instructions describe ending the trial by pressing the button, implying that button interaction is the way to proceed. However, the puzzle routine also ends on keys ['y', 'n', 'left', 'right', 'space'] at L0633-L0641, which contradicts the documented interaction flow and can bypass the intended button-driven completion path.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The documented purpose of this file is to present an Implicit Association Test, randomize blocks, and compute D-scores from response times. Collecting network-derived location/IP metadata and browser fingerprinting data is not necessary to run or score the task, making it an unjustified extra capability relative to the experiment logic described here.

VirusTotal

64/64 vendors flagged this skill as clean.

View on VirusTotal

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
psy-exp-coder/jspsych/demo/_raw/antisaccade__antisaccade.js:645

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
psy-exp-coder/jspsych/demo/_raw/butterfly_simon__Simon.js:964

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
psy-exp-coder/jspsych/demo/_raw/climate_reflection_task__Climate_Reflection_Task.js:886

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
psy-exp-coder/jspsych/demo/_raw/cyberball__cyberball.js:1233

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
psy-exp-coder/jspsych/demo/_raw/phone_a_friend__phone_a_friend.js:1006