New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

chch

Package Overview
Dependencies
Maintainers
1
Versions
45
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

chch - npm Package Compare versions

Comparing version
2.4.1
to
2.4.2
+4
-4
dist/cli.js

@@ -94,4 +94,4 @@ #!/usr/bin/env node

newPosts
.filter(p => p.number <= 1000)
.forEach(post => {
.filter((p) => p.number <= 1000)
.forEach((post) => {
console.log(`${post.number}:${post.userId.substr(0, 3)}: ${post.message}`);

@@ -114,3 +114,3 @@ });

case "dump":
dump_1.getThread(cli.input[1]).then(ress => {
dump_1.getThread(cli.input[1]).then((ress) => {
console.log(JSON.stringify(ress, null, "\t"));

@@ -120,3 +120,3 @@ });

case "dump-threads":
dump_1.getThreads().then(res => {
dump_1.getThreads(cli.input[1]).then((res) => {
console.log(JSON.stringify(res, null, "\t"));

@@ -123,0 +123,0 @@ });

import { Thread, ThreadMin } from "./types";
export declare const client: import("axios").AxiosInstance;
export declare function getThreads(): Promise<{
export declare function getThreads(url: any): Promise<{
threads: ThreadMin[];

@@ -5,0 +5,0 @@ }>;

@@ -6,2 +6,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.postMessage = exports.getThread = exports.getThreadVip = exports.getThreadPart4Vip = exports.getThreads = exports.client = void 0;
const cheerio_1 = __importDefault(require("cheerio"));

@@ -13,6 +14,6 @@ const axios_1 = __importDefault(require("axios"));

const host = "http://hebi.5ch.net";
const makeThreadUrl = id => `${host}/test/read.cgi/news4vip/${id}`;
const makeThreadUrl = (id) => `${host}/test/read.cgi/news4vip/${id}`;
const listPageUrl = `${host}/news4vip/subback.html`;
axios_1.default.defaults.responseType = "arraybuffer";
axios_1.default.defaults.transformResponse = data => encoding_japanese_1.default.convert(data, { to: "UNICODE", from: "SJIS", type: "string" });
axios_1.default.defaults.transformResponse = (data) => encoding_japanese_1.default.convert(data, { to: "UNICODE", from: "SJIS", type: "string" });
exports.client = axios_1.default.create({ withCredentials: true });

@@ -38,7 +39,7 @@ const sizeRegex = /\d+KB/;

};
async function getThreads() {
const res = await exports.client.get(listPageUrl);
async function getThreads(url) {
const res = await exports.client.get(url || listPageUrl);
const $ = cheerio_1.default.load(res.data);
const threads = [];
$("#trad > a").map((i, elA) => {
$("#trad > a").each((i, elA) => {
const a = $(elA);

@@ -51,2 +52,4 @@ const res = titleParse(a.text());

const href = a.attr("href");
if (!href)
throw new Error("parse html error");
const id = href.split("/")[0];

@@ -61,9 +64,7 @@ const url = makeThreadUrl(id);

const $ = cheerio_1.default.load((await exports.client.get(`${url}${from}-`)).data);
const title = $("h1")
.text()
.trim();
const title = $("h1").text().trim();
const size = $("font > b").text();
const posts = [];
// console.log(_.zip($("dl > dt"), $("dl > dd")))
lodash_1.default.zip($("dl > dt"), $("dl > dd")).map(([dt, dd], i) => {
lodash_1.default.zip($("dl > dt"), $("dl > dd")).forEach(([dt, dd], i) => {
if (!dd || !dt) {

@@ -94,27 +95,22 @@ return;

const $ = cheerio_1.default.load((await exports.client.get(`${url}${from}-`)).data);
const title = $(".title")
.text()
.trim();
const title = $(".title").text().trim();
const m = sizeRegex.exec($(".metastats.meta.centered").text());
const size = m ? m[0] : "";
const posts = [];
$(".post").map((i, elA) => {
$(".post").each((i, elA) => {
const div = $(elA);
const number = Number(div.find(".number").text());
const name = toName(div.find(".name").text());
const userId = div
.find(".uid")
.text()
.split(":")[1];
const userId = div.find(".uid").text().split(":")[1];
const dateStr = div.find(".date").text();
const timestamp = util_1.dateParse(dateStr);
const comma = Number(dateStr.split(".")[1]);
const message = div
.find(".message")
.text()
.trim();
const message = div.find(".message").text().trim();
const img = div.find(".message img").eq(0);
const images = util_1.getImgUrls(message);
if (img.length > 0) {
images.push(img.attr("src"));
const imgurl = img.attr("src");
if (imgurl) {
images.push(imgurl);
}
}

@@ -157,3 +153,3 @@ posts.push({

}
return headers["set-cookie"].map(v => v.split(";")[0]);
return headers["set-cookie"].map((v) => v.split(";")[0]);
};

@@ -172,5 +168,5 @@ async function postMessage(url, message) {

const headers = {
accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"accept-encoding": "gzip, deflate, br",
"accept-language": "ja,en-US;q=0.9,en;q=0.8,es;q=0.7",
"accept-language": "ja,en-US;q=0.9,en;q=0.8",
"cache-control": "max-age=0",

@@ -181,6 +177,7 @@ "content-type": "application/x-www-form-urlencoded",

"sec-fetch-mode": "navigate",
"sec-fetch-site": "same-origin",
"sec-fetch-site": "cross-site",
"sec-fetch-dest": "document",
"sec-fetch-user": "?1",
"upgrade-insecure-requests": "1",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 OPR/73.0.3856.284",
cookie: cookies.join("; "),

@@ -201,6 +198,7 @@ };

const form = generateForm(makeForm);
const post = headers => exports.client.post(bbsUrl, form, { headers });
const post = (headers) => exports.client.post(bbsUrl, form, { headers });
const res = await post(headers);
console.log(res.data);
if (res.data && res.data.includes("書き込み確認")) {
parseSetCookies(res.headers).forEach(s => cookies.push(s));
parseSetCookies(res.headers).forEach((s) => cookies.push(s));
headers.cookie = cookies.join("; ");

@@ -207,0 +205,0 @@ await post(headers);

@@ -10,3 +10,3 @@ import hosyu from "./hosyu";

};
watchSmart: (threadURL: string, crawledCallback?: import("./types").CrawledCallback) => {
watchSmart: (threadURL: string, crawledCallback: import("./types").CrawledCallback) => {
start: () => Promise<void>;

@@ -13,0 +13,0 @@ restart: () => Promise<void>;

@@ -9,3 +9,3 @@ "use strict";

const util_1 = require("./util");
const sleep = (msec) => new Promise(resolve => setTimeout(resolve, msec));
const sleep = (msec) => new Promise((resolve) => setTimeout(resolve, msec));
// ◆のマッチに適用する

@@ -12,0 +12,0 @@ function regexPatch(str) {

@@ -1,2 +0,2 @@

/// <reference types="node" />
declare type Timeout = ReturnType<typeof setTimeout>;
export declare type Wacchoi = {

@@ -44,4 +44,5 @@ raw: string;

nextCallMs: number;
timeout: NodeJS.Timeout | null;
timeout: Timeout | null;
finish: boolean;
}) => void;
export {};

@@ -7,3 +7,3 @@ import { Wacchoi } from "./types";

export declare const dateParse: (str: string) => number;
export declare const parseWacchoi: (name: string) => [false | Wacchoi, string];
export declare const parseWacchoi: (name: string) => [Wacchoi | false, string];
export declare function getImgUrls(text: string): string[];

@@ -6,2 +6,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.getImgUrls = exports.parseWacchoi = exports.dateParse = exports.easyRegex = exports.normalizeUrl = exports.increment = exports.hosyuIntervalTimeMinute = void 0;
const lodash_1 = __importDefault(require("lodash"));

@@ -47,5 +48,5 @@ function hosyuIntervalTimeMinute(hour, holiday = false) {

function* increment(start = "a") {
const nexts = start.split("").map(v => chars.indexOf(v));
const nexts = start.split("").map((v) => chars.indexOf(v));
while (true) {
const r = lodash_1.default.reverse(nexts.map(i => chars[i])).join("");
const r = lodash_1.default.reverse(nexts.map((i) => chars[i])).join("");
const noUp = nexts.find((v, i) => {

@@ -67,6 +68,8 @@ const nv = v + 1;

exports.increment = increment;
exports.normalizeUrl = (url) => url + (url.endsWith("/") ? "" : "/");
exports.easyRegex = (pattern) => pattern.replace(/%d/g, "(\\d+)").replace(/%s/g, "(.+)");
const normalizeUrl = (url) => url + (url.endsWith("/") ? "" : "/");
exports.normalizeUrl = normalizeUrl;
const easyRegex = (pattern) => pattern.replace(/%d/g, "(\\d+)").replace(/%s/g, "(.+)");
exports.easyRegex = easyRegex;
// 2019/10/26(土) 00:00:07.589
exports.dateParse = (str) => {
const dateParse = (str) => {
const er = exports.easyRegex("%d/%d/%d\\(.+\\) %d:%d:%d\\.%d");

@@ -82,4 +85,5 @@ const m = new RegExp(er).exec(str);

};
exports.dateParse = dateParse;
// 以下、5ちゃんねるからVIPがお送りします (ワッチョイWW 8f70-cmdO)
exports.parseWacchoi = (name) => {
const parseWacchoi = (name) => {
const m = /(.*) (\((.*) ((..)(..)-(....))\))/.exec(name);

@@ -92,2 +96,3 @@ if (!m) {

};
exports.parseWacchoi = parseWacchoi;
function getImgUrls(text) {

@@ -94,0 +99,0 @@ const rex = /(https?:\/\/.*?\.(?:png|jpg|gif))/g;

import { CrawledCallback } from "./types";
export declare const nextTime: (num: number) => number;
export declare const watchSmart: (threadURL: string, crawledCallback?: CrawledCallback) => {
export declare const watchSmart: (threadURL: string, crawledCallback: CrawledCallback) => {
start: () => Promise<void>;

@@ -5,0 +5,0 @@ restart: () => Promise<void>;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.watch = exports.watchSmart = exports.nextTime = void 0;
const dump_1 = require("./dump");
const min10 = 10 * 60 * 1000;
const recentPostCount = (posts) => posts.filter(post => post.timestamp >= +Date.now() - min10).length;
function watcher(threadURL, crawledCallback = () => { }, crawlTimeFunc) {
const recentPostCount = (posts) => posts.filter((post) => post.timestamp >= +Date.now() - min10).length;
function watcher(threadURL, crawledCallback, crawlTimeFunc) {
const readed = {};

@@ -23,3 +24,3 @@ const memo = { nthCall: 0, next: 1, timeout: null };

const newPosts = thread.posts;
newPosts.forEach(post => {
newPosts.forEach((post) => {
readed[post.number] = post;

@@ -48,4 +49,9 @@ });

}
exports.nextTime = (num) => Math.min(min10 / (num + 1), 60000);
exports.watchSmart = (threadURL, crawledCallback = () => { }) => watcher(threadURL, crawledCallback, exports.nextTime);
exports.watch = (threadURL, crawledCallback = () => { }, intervalMs = 1 * 60 * 1000) => watcher(threadURL, crawledCallback, () => intervalMs);
const nextTime = (num) => Math.min(min10 / (num + 1), 60000);
exports.nextTime = nextTime;
const watchSmart = (threadURL, crawledCallback) => watcher(threadURL, crawledCallback, exports.nextTime);
exports.watchSmart = watchSmart;
const watch = (threadURL, crawledCallback = () => {
// default empty
}, intervalMs = 1 * 60 * 1000) => watcher(threadURL, crawledCallback, () => intervalMs);
exports.watch = watch;
{
"name": "chch",
"version": "2.4.1",
"version": "2.4.2",
"author": "vipzero",

@@ -5,0 +5,0 @@ "repository": "vipzero/chch",