<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: relayshieldadmin</title>
    <description>The latest articles on DEV Community by relayshieldadmin (@relayshield).</description>
    <link>https://dev.to/relayshield</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3933321%2Fd546320c-b664-4cca-b592-7d7d456e4619.png</url>
      <title>DEV Community: relayshieldadmin</title>
      <link>https://dev.to/relayshield</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/relayshield"/>
    <language>en</language>
    <item>
      <title>Who can publish into your dependencies?</title>
      <dc:creator>relayshieldadmin</dc:creator>
      <pubDate>Thu, 13 Aug 2026 16:43:40 +0000</pubDate>
      <link>https://dev.to/relayshield/who-can-publish-into-your-dependencies-12mo</link>
      <guid>https://dev.to/relayshield/who-can-publish-into-your-dependencies-12mo</guid>
      <description>&lt;p&gt;Install Next.js, React, TypeScript, ESLint, Jest, axios, Tailwind, Prettier and dotenv into an empty&lt;br&gt;
directory. That is not an unusual project. That is Tuesday.&lt;/p&gt;

&lt;p&gt;You get 433 packages. Behind those 433 packages are &lt;strong&gt;275 distinct accounts that can publish code&lt;br&gt;
into them&lt;/strong&gt;, and &lt;strong&gt;126 of those accounts are on consumer webmail&lt;/strong&gt;. 118 of the 126 are &lt;code&gt;gmail.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Nobody is doing anything wrong in that sentence. That is the part worth sitting with.&lt;/p&gt;

&lt;p&gt;We built the thing that counts it, we are releasing it under MIT today, and you can reproduce every&lt;br&gt;
number in this post in about a minute.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;rsscan
rsscan &lt;span class="nt"&gt;--deps&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It reads &lt;code&gt;package-lock.json&lt;/code&gt; or &lt;code&gt;package.json&lt;/code&gt; from the current directory, resolves each package to&lt;br&gt;
the accounts that can publish it, and prints counts. It runs locally. There is no account, no API&lt;br&gt;
key, and no network call to us: the only host it contacts is &lt;code&gt;registry.npmjs.org&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  What we measured
&lt;/h2&gt;

&lt;p&gt;Six manifests, generated with &lt;code&gt;npm install --package-lock-only --ignore-scripts&lt;/code&gt;, which resolves the&lt;br&gt;
full transitive tree from registry metadata without downloading a tarball or running an install&lt;br&gt;
script. Then &lt;code&gt;rsscan --deps&lt;/code&gt; over each.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Install&lt;/th&gt;
&lt;th&gt;Packages&lt;/th&gt;
&lt;th&gt;Publisher accounts&lt;/th&gt;
&lt;th&gt;On consumer webmail&lt;/th&gt;
&lt;th&gt;Role or automation&lt;/th&gt;
&lt;th&gt;Unresolved&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;npm i express&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;65&lt;/td&gt;
&lt;td&gt;85&lt;/td&gt;
&lt;td&gt;46 (54%)&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;npm i webpack&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;67&lt;/td&gt;
&lt;td&gt;95&lt;/td&gt;
&lt;td&gt;40 (42%)&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;npm i eslint&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;68&lt;/td&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;51 (50%)&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;npm i jest&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;289&lt;/td&gt;
&lt;td&gt;208&lt;/td&gt;
&lt;td&gt;96 (46%)&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;npm i next&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;54&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;td&gt;10 (34%)&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;the nine packages above, together&lt;/td&gt;
&lt;td&gt;433&lt;/td&gt;
&lt;td&gt;275&lt;/td&gt;
&lt;td&gt;126 (46%)&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Measured 13 August 2026. These numbers will drift as maintainer lists change, which is rather the&lt;br&gt;
point.&lt;/p&gt;

&lt;p&gt;Three things about the method, because a number nobody can check is not a finding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Publisher account" means a distinct email in the registry's &lt;code&gt;maintainers&lt;/code&gt; array, plus &lt;code&gt;_npmUser&lt;/code&gt;&lt;br&gt;
on the version you would actually install.&lt;/strong&gt; That second field matters: &lt;code&gt;maintainers&lt;/code&gt; lists everyone&lt;br&gt;
who &lt;em&gt;could&lt;/em&gt; have published, while &lt;code&gt;_npmUser&lt;/code&gt; is whoever &lt;em&gt;did&lt;/em&gt; push the bytes sitting in your&lt;br&gt;
&lt;code&gt;node_modules&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Email is a proxy for account, and it is imperfect in both directions.&lt;/strong&gt; One human with two&lt;br&gt;
addresses counts twice. Two humans sharing an address count once. We report distinct addresses and&lt;br&gt;
call them accounts because that is what the registry exposes, and pretending otherwise would be&lt;br&gt;
worse than the caveat.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Consumer webmail" is a fixed domain list&lt;/strong&gt;, and we checked it was not inflated before publishing&lt;br&gt;
this. No GitHub &lt;code&gt;noreply&lt;/code&gt; addresses landed in the count. Role and automation addresses like&lt;br&gt;
&lt;code&gt;security@&lt;/code&gt; or &lt;code&gt;oss-bot@&lt;/code&gt; are counted in their own column and excluded from the webmail figure, so&lt;br&gt;
nothing is double counted.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Unresolved&lt;/strong&gt; column is zero across all six, and it exists because it is the column that keeps&lt;br&gt;
the rest honest. A package whose publishers we could not look up is not a package with no&lt;br&gt;
publishers. If a run cannot reach the registry, &lt;code&gt;--deps&lt;/code&gt; prints that count in red rather than&lt;br&gt;
quietly folding it into a reassuring total.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why this number is the one that matters
&lt;/h2&gt;

&lt;p&gt;Every package security tool on the market reads the artifact. Socket, Snyk, Aikido, Endor: they&lt;br&gt;
fetch the tarball, look at what the code does, and tell you whether it is dangerous. They are good&lt;br&gt;
at it, and if you are not running one you should be.&lt;/p&gt;

&lt;p&gt;They share a blind spot, and it is not a bug in any of them. It is structural.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A self-replicating npm worm does not begin with malicious code. It begins with a maintainer&lt;br&gt;
account.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reconstruct one from the end and the sequence is always roughly this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A maintainer's laptop gets infostealer malware on it. Not a targeted attack. The usual route: a
cracked tool, a fake browser update, a malicious ad.&lt;/li&gt;
&lt;li&gt;The stealer takes everything the browser and the filesystem will give it. Saved passwords,
session cookies, and, on a developer machine, the contents of &lt;code&gt;.npmrc&lt;/code&gt;. That file holds a
long-lived npm publish token.&lt;/li&gt;
&lt;li&gt;The token is sold in a log, usually within days.&lt;/li&gt;
&lt;li&gt;The buyer publishes a new patch version of a package that maintainer owns. The code is not
subtle. It does not need to be, because nobody is reading a patch bump.&lt;/li&gt;
&lt;li&gt;That version runs on install, in CI, on machines belonging to everyone who depends on it. It
harvests &lt;em&gt;their&lt;/em&gt; npm tokens.&lt;/li&gt;
&lt;li&gt;It publishes itself into their packages. Now it is a worm.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Look at where the detectable code appears in that list. &lt;strong&gt;Step four.&lt;/strong&gt; By the time there is a&lt;br&gt;
malicious artifact for a scanner to analyse, the compromise is four steps old and propagation is one&lt;br&gt;
step away. Everything before step four is an identity problem, and none of it is visible in a&lt;br&gt;
tarball, because none of it has happened in a tarball yet.&lt;/p&gt;

&lt;p&gt;Shai-Hulud, in September 2025, is the version of this most people have now heard of. It is worth&lt;br&gt;
being precise about why it spread: not because the payload was clever, but because the credential&lt;br&gt;
that lets you publish to npm is a bearer token that usually lives in a plaintext file on a laptop,&lt;br&gt;
and laptops get infostealers.&lt;/p&gt;

&lt;p&gt;Which is why 126 is a more interesting number than 433. A publish credential on a company domain&lt;br&gt;
sits behind SSO, and when that person leaves or gets compromised there is an IT function that can&lt;br&gt;
revoke it centrally. A publish credential on a personal Gmail has none of that. There is no&lt;br&gt;
offboarding, no central revocation, no device management, and no security team. &lt;strong&gt;That is not a&lt;br&gt;
criticism of the maintainers. It is a description of how open source actually gets published&lt;/strong&gt;, by&lt;br&gt;
people doing it on their own machines, on their own time, with their own accounts, largely for free,&lt;br&gt;
in code that the rest of us then put in production.&lt;/p&gt;
&lt;h2&gt;
  
  
  What &lt;code&gt;--deps&lt;/code&gt; deliberately does not do
&lt;/h2&gt;

&lt;p&gt;It does not screen anybody. It counts.&lt;/p&gt;

&lt;p&gt;That is a design decision and not a roadmap gap, so it is worth being direct about where the line&lt;br&gt;
is. &lt;code&gt;rsscan --deps&lt;/code&gt; tells you the size and shape of your publisher surface. It cannot tell you&lt;br&gt;
whether any of those 275 accounts is compromised right now, because answering that means checking&lt;br&gt;
identities against infostealer corpora and breach data, and that is a different job with real costs&lt;br&gt;
attached. We sell that part. This part is free, and it is free in the way that matters: no account,&lt;br&gt;
no key, no rate limit, and no telemetry.&lt;/p&gt;

&lt;p&gt;It also &lt;strong&gt;names nobody&lt;/strong&gt;. Not in the output, not in a log, not in a debug field. You do not need any&lt;br&gt;
individual's identity in order to pin a version and require review on its updates, and naming an&lt;br&gt;
uninvolved third party as a risk carries real legal exposure for zero benefit. The tool prints&lt;br&gt;
integers.&lt;/p&gt;

&lt;p&gt;On telemetry specifically, since this is a security tool asking to be run on your machine:&lt;br&gt;
&lt;code&gt;rsscan --deps&lt;/code&gt; sends nothing anywhere. The wider &lt;code&gt;rsscan&lt;/code&gt; secret scanner has an &lt;code&gt;--org&lt;/code&gt; flag that&lt;br&gt;
reports a domain and severity counts so we can see adoption at a company, and it is &lt;strong&gt;opt-in, off by&lt;br&gt;
default&lt;/strong&gt;. We wrote a version that inferred it from your git commit email and turned it on by&lt;br&gt;
default. We held that version back and shipped this one instead.&lt;/p&gt;
&lt;h2&gt;
  
  
  The honest limit
&lt;/h2&gt;

&lt;p&gt;A count is not a verdict, and registry metadata is not always current. If a maintainer changed their&lt;br&gt;
email and the registry still lists the old one, &lt;code&gt;--deps&lt;/code&gt; counts an address that is not theirs any&lt;br&gt;
more. That inflates the count in one direction and hides a real account in the other. We would&lt;br&gt;
rather you hear that from us than find it yourself.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rsscan&lt;/code&gt; is MIT licensed, on &lt;a href="https://pypi.org/project/rsscan/" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt; and&lt;br&gt;
&lt;a href="https://github.com/RelayShield/rsscan" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, and also ships as a pre-commit hook, a GitHub&lt;br&gt;
Action, a GitLab CI component, a CircleCI orb and a Docker image. The dependency counting is new in&lt;br&gt;
this release. The secret scanning has been there since the start, matches 31 credential patterns&lt;br&gt;
entirely on your machine, and never transmits your code or a matched value.&lt;/p&gt;

&lt;p&gt;If you want the part that answers "and is any of them compromised", that is&lt;br&gt;
&lt;a href="https://api.relayshield.net/developers?source=rsscan-deps-devto" rel="noopener noreferrer"&gt;our dependency-risk API&lt;/a&gt;, included flat&lt;br&gt;
in a bundle rather than metered per manifest, because re-screening 400 maintainers costs us about&lt;br&gt;
what re-screening four does.&lt;/p&gt;

&lt;p&gt;But run the free one first. Point it at your own lockfile and see how many people can publish into&lt;br&gt;
your production build. Most teams have never counted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;rsscan &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; rsscan &lt;span class="nt"&gt;--deps&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>security</category>
      <category>npm</category>
      <category>opensource</category>
      <category>devops</category>
    </item>
    <item>
      <title>The npm Worm Does Not Start With Malicious Code</title>
      <dc:creator>relayshieldadmin</dc:creator>
      <pubDate>Wed, 12 Aug 2026 18:32:50 +0000</pubDate>
      <link>https://dev.to/relayshield/the-npm-worm-does-not-start-with-malicious-code-4a7g</link>
      <guid>https://dev.to/relayshield/the-npm-worm-does-not-start-with-malicious-code-4a7g</guid>
      <description>&lt;p&gt;Every package security tool on the market reads the artifact. Socket, Snyk, Aikido, Endor: they&lt;br&gt;
fetch the tarball, look at what the code does, and tell you whether it is dangerous. They are good&lt;br&gt;
at it, and if you are not running one you should be.&lt;/p&gt;

&lt;p&gt;They all share a blind spot, and it is not a bug in any of them. It is structural.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A self-replicating npm worm does not begin with malicious code. It begins with a maintainer&lt;br&gt;
account.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The actual chain
&lt;/h2&gt;

&lt;p&gt;Reconstruct one of these from the end and the sequence is always roughly this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A maintainer's laptop gets infostealer malware on it. Not a targeted attack. The usual route:
a cracked tool, a fake browser update, a malicious ad.&lt;/li&gt;
&lt;li&gt;The stealer takes everything the browser and the filesystem will give it. Saved passwords,
session cookies, and, on a developer machine, the contents of &lt;code&gt;.npmrc&lt;/code&gt;. That file holds a
long-lived npm publish token.&lt;/li&gt;
&lt;li&gt;The token is sold in a log, usually within days.&lt;/li&gt;
&lt;li&gt;The buyer publishes a new patch version of a package that maintainer owns. The code is not
subtle. It does not need to be, because nobody is reading a patch bump.&lt;/li&gt;
&lt;li&gt;That version runs on install, in CI, on machines belonging to everyone who depends on it. It
harvests &lt;strong&gt;their&lt;/strong&gt; npm tokens.&lt;/li&gt;
&lt;li&gt;It publishes itself into their packages. Now it is a worm.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Look at where the detectable code appears in that list. &lt;strong&gt;Step four.&lt;/strong&gt; By the time there is a&lt;br&gt;
malicious artifact for a scanner to analyse, the compromise is four steps old and the propagation&lt;br&gt;
is one step away.&lt;/p&gt;

&lt;p&gt;Everything before step four is an identity problem. None of it is visible in a tarball, because&lt;br&gt;
none of it has happened in a tarball yet.&lt;/p&gt;

&lt;p&gt;Shai-Hulud, in September 2025, is the version of this most people have now heard of. It is worth&lt;br&gt;
being precise about why it spread: not because the payload was clever, but because the credential&lt;br&gt;
that lets you publish to npm is a bearer token that usually lives in a plaintext file on a laptop,&lt;br&gt;
and laptops get infostealers.&lt;/p&gt;
&lt;h2&gt;
  
  
  The question nobody can answer
&lt;/h2&gt;

&lt;p&gt;Here is the question a security lead actually wants answered before a release:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Of the 412 packages we install, is any of them currently maintained by an account that has been&lt;br&gt;
compromised?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ask your SCA tool. It cannot answer, and not because it is bad. It analyses code, and this is not a&lt;br&gt;
question about code. It is a question about people, and specifically about whether a particular&lt;br&gt;
human's machine is currently owned.&lt;/p&gt;

&lt;p&gt;We can answer it, because that is what we already do. Screening an identity against infostealer&lt;br&gt;
corpora, breach data and session records is the thing RelayShield was built to do. This is that&lt;br&gt;
same engine pointed at a different input: instead of your employees, the maintainers of your&lt;br&gt;
dependencies.&lt;/p&gt;
&lt;h2&gt;
  
  
  What we shipped
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;POST /v1/metered/dependency-risk&lt;/code&gt;. Send a list of package names, or a &lt;code&gt;package.json&lt;/code&gt; or&lt;br&gt;
&lt;code&gt;package-lock.json&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.relayshield.net/v1/metered/dependency-risk &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RS-API-KEY: YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"packages": ["left-pad", "chalk", "@types/node"]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each package is resolved to the accounts that can publish it, including the account that actually&lt;br&gt;
published the version you are installing. Those accounts are screened against our infostealer&lt;br&gt;
corpus. You get back findings at the dependency level:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"packages_checked"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;412&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"maintainer_accounts_screened"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;148&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"role_accounts_excluded"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies_at_risk"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"high_severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"findings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"package"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"left-pad"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HIGH"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"signal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"maintainer_in_recent_stealer_log"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"most_recent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-07-28T04:12:00.000Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"detail"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"An account able to publish this package appears in an infostealer log dated within the last 90 days."&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"recommended_action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Pin the flagged versions, require review on their updates, and do not auto-merge their releases until the exposure ages out."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the whole product. Three of your dependencies are maintained by an account in a recent&lt;br&gt;
stealer log. Pin them, review their updates, do not auto-merge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four decisions worth explaining
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;We never tell you who the maintainer is.&lt;/strong&gt; Not in the response, not in a log, not in a debug&lt;br&gt;
field. You do not need someone's identity in order to pin a version and require review, and naming&lt;br&gt;
an uninvolved third party as compromised carries real legal exposure for zero product benefit. We&lt;br&gt;
did not build a version that names people even internally, because internal fields have a way of&lt;br&gt;
ending up in support conversations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recency is the signal. Breaches are not.&lt;/strong&gt; A maintainer's address turning up in a 2013 breach&lt;br&gt;
tells you nothing about whether their laptop is owned today, and alerting on it would bury the real&lt;br&gt;
finding under a decade of noise. A stealer log within 90 days is HIGH. Older is MEDIUM, and we call&lt;br&gt;
it context rather than an incident.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Role addresses are excluded from alerting, not just from display.&lt;/strong&gt; Around 9% of npm maintainer&lt;br&gt;
emails are shared inboxes: &lt;code&gt;security@&lt;/code&gt;, &lt;code&gt;dev@&lt;/code&gt;, &lt;code&gt;oss-bot@&lt;/code&gt;. A hit on a mailing list tells you&lt;br&gt;
nothing about whether one person's machine is compromised, and a false positive on a product whose&lt;br&gt;
entire pitch is the opposite of false positives is worse than no product.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;npm first, PyPI later.&lt;/strong&gt; We measured both. About 91% of npm maintainer emails are individual&lt;br&gt;
humans; on PyPI it is closer to 69%, because PyPI returns a lot of &lt;code&gt;contact@&lt;/code&gt; and mailing list&lt;br&gt;
addresses. npm is both the better join and where the self-replicating worms actually are.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part that matters more than the scan
&lt;/h2&gt;

&lt;p&gt;A one-time dependency scan is close to decorative. Your tree is clean today and a maintainer gets&lt;br&gt;
phished in March. &lt;strong&gt;The compromise happens at a random future moment, which means this is a&lt;br&gt;
continuous product or it is a decoration.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So &lt;code&gt;dependency&lt;/code&gt; is now a subject type in Verdict Watch, alongside addresses, emails, domains and&lt;br&gt;
phone numbers. Register a package, and you are notified when the answer &lt;strong&gt;changes&lt;/strong&gt;, not on a&lt;br&gt;
schedule and not when the same known exposure gets a new log entry. Flat rate, because the marginal&lt;br&gt;
cost of re-screening 400 maintainers is approximately the same as re-screening four.&lt;/p&gt;

&lt;h2&gt;
  
  
  One honest caveat
&lt;/h2&gt;

&lt;p&gt;A clean result means nothing was found &lt;strong&gt;in the sources we queried&lt;/strong&gt;. It is not proof that your&lt;br&gt;
dependencies are safe.&lt;/p&gt;

&lt;p&gt;The specific gap worth knowing about: registry metadata is not always current. If a maintainer&lt;br&gt;
changed their email and the registry still lists the old one, we screen an address that is not&lt;br&gt;
theirs any more, and it comes back clean. That is a false clean, and we would rather you hear it&lt;br&gt;
from us than discover it.&lt;/p&gt;

&lt;p&gt;When an upstream source is unavailable, we say so explicitly and the response tells you the run was&lt;br&gt;
incomplete rather than printing a reassuring sentence underneath a degraded flag. Nobody's threat&lt;br&gt;
feed proves absence. Anyone selling you that is selling certainty that does not exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting it
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;dependency-risk&lt;/code&gt; is &lt;strong&gt;included at no per-call charge&lt;/strong&gt; in the &lt;strong&gt;Agentic Attack Surface&lt;/strong&gt; bundle at&lt;br&gt;
$299/mo, alongside LLM credential exposure, MCP registry risk, prompt injection breach exposure,&lt;br&gt;
tech stack CVE and bulk identity risk. Scan a 400-package manifest as often as you like; it costs&lt;br&gt;
the same as scanning four, because that is roughly what it costs us. Buy it on&lt;br&gt;
&lt;a href="https://aws.amazon.com/marketplace/pp/prodview-6p6csngrcg3zq" rel="noopener noreferrer"&gt;AWS Marketplace&lt;/a&gt;, which draws down&lt;br&gt;
your existing AWS committed spend, or directly by card at&lt;br&gt;
&lt;a href="https://api.relayshield.net/developers?source=npm-worm-devto" rel="noopener noreferrer"&gt;api.relayshield.net/developers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Outside the bundle it is pay-as-you-go at $0.50 a call, priced against what it costs to serve: one&lt;br&gt;
call fans out to as many as 100 registry lookups and 150 identity screens.&lt;/p&gt;

&lt;p&gt;Point it at your own &lt;code&gt;package-lock.json&lt;/code&gt;. If it comes back clean, you have lost a minute. If it&lt;br&gt;
does not, you have found the thing four steps before the scanner would.&lt;/p&gt;

</description>
      <category>security</category>
      <category>npm</category>
      <category>opensource</category>
      <category>devops</category>
    </item>
    <item>
      <title>34 malicious packages discovered targeting Solana developers: Steals wallet credentials and SSH keys</title>
      <dc:creator>relayshieldadmin</dc:creator>
      <pubDate>Sun, 31 May 2026 22:10:58 +0000</pubDate>
      <link>https://dev.to/relayshield/34-malicious-packages-discovered-targeting-solana-developers-steals-wallet-credentials-and-ssh-keys-53db</link>
      <guid>https://dev.to/relayshield/34-malicious-packages-discovered-targeting-solana-developers-steals-wallet-credentials-and-ssh-keys-53db</guid>
      <description>&lt;p&gt;Socket Security just published research on TrapDoor malware: 34 malicious packages targeting developers building on Solana, Aptos, and Sui. If you've installed any npm or PyPI packages from these ecosystems recently, your wallet may already be at risk even if nothing looks wrong yet.&lt;/p&gt;

&lt;p&gt;How it works:&lt;/p&gt;

&lt;p&gt;The packages execute on install. They silently harvest crypto wallet credentials, SSH keys, cloud credentials, browser-saved passwords, and environment variables — then exfiltrate everything to attacker infrastructure. The theft of your wallet doesn't happen immediately. Attackers wait for the right moment: a large deposit, a token unlock, a liquidity event.&lt;/p&gt;

&lt;p&gt;Three things to do right now:&lt;/p&gt;

&lt;p&gt;Check if your developer email appeared in an infostealer log: Stealer logs from infected machines are actively traded on criminal Telegram channels. If your email is in one, your credentials from that machine are compromised regardless of whether your wallet looks fine today&lt;/p&gt;

&lt;p&gt;Audit your browser extensions: TrapDoor harvests browser data. Malicious extensions re-harvest credentials on every login after initial infection. Remove anything you don't actively use or can't verify&lt;/p&gt;

&lt;p&gt;Move assets to a fresh wallet on a clean device if you installed packages from affected ecosystems in the last 30 days and can't confirm they were clean&lt;/p&gt;

&lt;p&gt;The on-chain monitoring fires after the transfer is already out. The attack starts in your dev environment, not on the blockchain.&lt;/p&gt;

&lt;p&gt;Full breakdown with remediation steps: &lt;a href="https://medium.com/p/a4343023b319" rel="noopener noreferrer"&gt;https://medium.com/p/a4343023b319&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>infosec</category>
      <category>npm</category>
      <category>security</category>
    </item>
    <item>
      <title>Your Okta Is Only As Strong As Your SIM Card</title>
      <dc:creator>relayshieldadmin</dc:creator>
      <pubDate>Mon, 18 May 2026 21:32:52 +0000</pubDate>
      <link>https://dev.to/relayshield/your-okta-is-only-as-strong-as-your-sim-card-373</link>
      <guid>https://dev.to/relayshield/your-okta-is-only-as-strong-as-your-sim-card-373</guid>
      <description>&lt;p&gt;Most security teams sleep well knowing MFA is enforced in Okta, &lt;br&gt;
Azure AD, or Duo. Then someone ports an employee's phone number to &lt;br&gt;
a burner SIM in under 10 minutes and the identity perimeter &lt;br&gt;
unravels silently.&lt;/p&gt;

&lt;p&gt;This is the SIM swap blind spot in enterprise identity. Almost &lt;br&gt;
nobody is talking about it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The attack chain&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Attacker identifies target via LinkedIn&lt;/li&gt;
&lt;li&gt;Calls carrier, provides scraped personal data (DOB, address, 
last 4 SSN — all available from prior breaches)&lt;/li&gt;
&lt;li&gt;Carrier ports the number. Target loses mobile service.&lt;/li&gt;
&lt;li&gt;Attacker hits the Okta portal, triggers SMS OTP or recovery&lt;/li&gt;
&lt;li&gt;Code arrives on attacker's device. Session established.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Total time: under 30 minutes. No malware. No zero-day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where Okta and SMS intersect&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SMS OTP as primary factor&lt;/strong&gt; — Many Okta deployments enable SMS &lt;br&gt;
because app-based authenticators create support tickets. If SMS is &lt;br&gt;
an allowed factor, a SIM-swapped number gives the attacker a live &lt;br&gt;
OTP delivery channel. Your policy is satisfied. Access granted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Account recovery fallback&lt;/strong&gt; — Even if primary MFA uses Okta &lt;br&gt;
Verify or TOTP, recovery often falls back to SMS. That single &lt;br&gt;
fallback path is all an attacker needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Downstream email compromise&lt;/strong&gt; — Gmail and Outlook offer SMS &lt;br&gt;
account recovery. SIM swap the employee → reset their Google &lt;br&gt;
account → own the email Okta is registered to. Game over.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The carrier layer is outside Okta's scope&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Okta, Microsoft, and Duo will tell you to use phishing-resistant &lt;br&gt;
MFA. They're right. But the carrier layer is invisible to every &lt;br&gt;
identity platform — always has been.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Detecting it with code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SIM swap detection requires querying carrier data directly. Here's &lt;br&gt;
how to check whether a number has been ported before triggering &lt;br&gt;
account recovery or a high-risk action:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;REST API (Python)&lt;/strong&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
python
import requests

def check_sim_swap(phone: str) -&amp;gt; dict:
    """
    Returns swapped (bool), swap timestamp, and current carrier.
    Call before any high-risk action gated by SMS-based auth.
    """
    response = requests.post(
        "https://xhh3tfrhng.execute-api.us-east-1.amazonaws.com/prod/v1/sim-swap",
        headers={"x-api-key": "YOUR_RAPIDAPI_KEY"},
        json={"phone": phone}
    )
    return response.json()

result = check_sim_swap("+14155551234")

if result.get("swapped"):
    print(f"⚠️  SIM swap detected at {result['swap_timestamp']}")
    print(f"   Current carrier: {result['carrier']}")
    # Block account recovery, alert security team
else:
    print("✓ No SIM swap detected — safe to proceed")

**MCP Server (for AI agents)**
If you're building agents that handle user identity or account
actions, add SIM swap detection as a pre-flight check:

pip install relayshield_mcp

from plugins.relayshield.relayshield_game_plugin import relayshield_functions
# Drop into any GAME agent worker — check_sim_swap is ready to call

**Where to gate it in your stack**
def okta_account_recovery_hook(user_phone: str) -&amp;gt; bool:
    """
    Pre-recovery hook — block if SIM swap detected in last 24hrs.
    Wire this into your Okta inline hook or recovery flow.
    """
    result = check_sim_swap(user_phone)

    if result.get("swapped"):
        # Log security event, require in-person verification
        security_alert(user_phone, result)
        return False  # Block recovery

    return True  # Safe to proceed

**What to fix right now**
**Audit factor enrollment** — find every Okta user with SMS
enabled
**Disable SMS as primary factor** — enforce Okta Verify or TOTP
**Harden recovery flows** — no SMS fallback for privileged
accounts
**Add detection** — query carrier data before account recovery
or high-risk actions
**Brief your help desk** — social engineering is the human
version of the same attack

**The bottom line**
Enterprise MFA is only as strong as its weakest factor. For most
organizations, that weakest factor is a phone number on a carrier
database that can be socially engineered in minutes.

The carrier layer is invisible to every identity platform. That's
the gap. Now you know where it is — and how to close it.

*SIM swap detection API: [RelayShield on RapidAPI](https://rapidapi.com/relayshielduser/api/relayshield-security-intelligence) — free tier available.*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>security</category>
      <category>identity</category>
      <category>mfa</category>
      <category>appsec</category>
    </item>
    <item>
      <title>5 Crypto Security Signals in One API Call — Wallet Risk, Token Honeypots, SIM Swap and More</title>
      <dc:creator>relayshieldadmin</dc:creator>
      <pubDate>Fri, 15 May 2026 14:12:03 +0000</pubDate>
      <link>https://dev.to/relayshield/5-crypto-security-signals-in-one-api-call-wallet-risk-token-honeypots-sim-swap-and-more-3eah</link>
      <guid>https://dev.to/relayshield/5-crypto-security-signals-in-one-api-call-wallet-risk-token-honeypots-sim-swap-and-more-3eah</guid>
      <description>&lt;p&gt;If you're building a crypto app, a trading bot, a DeFi dashboard, or an AI agent that touches wallets or tokens, you need security signals baked in — not bolted on after something goes wrong.&lt;/p&gt;

&lt;p&gt;RelayShield Security Intelligence is a single REST API that gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Wallet risk scoring&lt;/strong&gt;: Multi-chain (EVM, Solana, TON)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token honeypot + rug pull detection&lt;/strong&gt;: Before your users ape in&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NFT contract risk scanning&lt;/strong&gt;: Ownership, minting, verification flags&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SIM swap detection&lt;/strong&gt;: Live carrier-layer data via Twilio Lookup v2&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email breach checking&lt;/strong&gt;: 13B+ compromised records&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No SDKs. Plain JSON in, plain JSON out. Available on RapidAPI (subscription) or x402 USDC micropayments on Base (pay per call, no subscription needed).&lt;/p&gt;

&lt;p&gt;Quickstart — Wallet Risk in Python&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://relayshield-security-intelligence.p.rapidapi.com/v1/wallet-risk&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;address&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0xYourWalletAddress&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x-rapidapi-key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_RAPIDAPI_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x-rapidapi-host&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;relayshield-security-intelligence.p.rapidapi.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Works with EVM addresses, Solana public keys, and TON wallet addresses — the API auto-detects chain type.&lt;/p&gt;

&lt;p&gt;Quickstart — Token Security (Honeypot Check)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chain_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# Ethereum mainnet — use 8453 for Base
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contract_address&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0xTokenContractAddress&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://relayshield-security-intelligence.p.rapidapi.com/v1/token-security&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Returns honeypot status, buy/sell tax flags, ownership renounced, hidden owner, and more.&lt;/p&gt;

&lt;p&gt;Pay Per Call with x402 (No Subscription Needed)&lt;/p&gt;

&lt;p&gt;If you're building an agent or a low-volume integration and don't want a monthly subscription, the PAYG endpoints accept x402 USDC micropayments on Base:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Price&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/v1/payg/wallet-risk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;$0.15 USDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/v1/payg/token-security&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;$0.10 USDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/v1/payg/nft-security&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;$0.10 USDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/v1/payg/wallet-screen-batch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;$0.50 USDC (up to 10 addresses)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/v1/payg/breach&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;$0.10 USDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/v1/payg/sim-swap&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;$0.25 USDC&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;x402 flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Call the endpoint with no payment header → receive &lt;code&gt;402&lt;/code&gt; + &lt;code&gt;PAYMENT-REQUIRED&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Pay USDC on Base to the address in the response&lt;/li&gt;
&lt;li&gt;Retry with &lt;code&gt;X-PAYMENT&lt;/code&gt; header containing payment proof&lt;/li&gt;
&lt;li&gt;API verifies via Coinbase x402 facilitator → returns result&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Use Cases&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DeFi dashboard&lt;/strong&gt;: Screen every inbound token for honeypots automatically&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trading bot&lt;/strong&gt;: Run wallet-risk on counterparties before executing swaps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI agent&lt;/strong&gt;: Give your Claude/GPT agent live security intelligence via MCP or direct API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wallet app&lt;/strong&gt;: Alert users when their SIM is swapped before their 2FA is compromised&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portfolio tracker&lt;/strong&gt;: Flag high-risk wallets and scam tokens in real time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MCP Server (Claude / AI Agents)&lt;/p&gt;

&lt;p&gt;If you're building with Claude or want to use these signals inside Claude Desktop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;relayshield-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exposes all endpoints as native MCP tools — no API calls to write.&lt;/p&gt;

&lt;p&gt;Links&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RapidAPI listing&lt;/strong&gt; (subscribe + test in browser): &lt;a href="https://rapidapi.com/relayshield/api/relayshield-security-intelligence" rel="noopener noreferrer"&gt;RelayShield Security Intelligence&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API docs + landing page&lt;/strong&gt;: &lt;a href="https://relayshield.net" rel="noopener noreferrer"&gt;relayshield.net&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP package&lt;/strong&gt;: &lt;a href="https://pypi.org/project/relayshield-mcp" rel="noopener noreferrer"&gt;pypi.org/project/relayshield-mcp&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Built by a 25-year telecom security professional. Questions welcome in the comments.&lt;/p&gt;

</description>
      <category>security</category>
      <category>cryptocurrency</category>
      <category>api</category>
      <category>python</category>
    </item>
  </channel>
</rss>
