SocialSisterYi / bilibili-API-collect

哔哩哔哩-API收集整理【不断更新中....】
https://socialsisteryi.github.io/bilibili-API-collect/
Other
14.53k stars 1.64k forks source link

[Web API Risk Control] `dm_img` series risk control params collection #951

Open cxw620 opened 7 months ago

cxw620 commented 7 months ago

The BAC community noticed that Bilibili has officially deployed increasingly stringent risk control measures. This issue is for collecting details of dm_img series risk control params.

[!CAUTION]

  • Examples may be out of date. DO NOT JUST COPY THEM
  • New risk control params may be added at any time. When meet with -352 or -403 please open your browser's dev tool and check if there were any new dm_img series params not listed here. If not, feel free to leave comment in this issue. Take with details of the request!

Last updated: 2024/2/14 14:13

Must-added params

Description of each and corresponded generation algorithm

dm_img_list & dm_img_str

The two params are your brower's webgl fingerprint infos.

For personal usage, feel free to use const value from your browser.

let version;
let rendererAndVendor;
const gl = document.createElement("canvas").getContext("webgl");
if (gl) {
  version = gl.getParameter(gl.VERSION);
  const debugInfo = gl.getExtension("WEBGL_debug_renderer_info");
  if (debugInfo) {
    rendererAndVendor = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) +
      gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
  }
}
if (version === undefined) { // 禁用了 WebGL
  console.log("dm_img_str", "bm8gd2ViZ2");
  console.log("dm_cover_img_str", "bm8gd2ViZ2");
} else {
  console.log("dm_img_str", btoa(version).slice(0, -2));
  if (rendererAndVendor === undefined) { // 禁用了 WEBGL_debug_renderer_info 扩展
    console.log("dm_cover_img_str", "bm8gd2ViZ2wgZXh0ZW5zaW");
  } else {
    console.log("dm_cover_img_str", btoa(rendererAndVendor).slice(0, -2));
  }
}

Originally posted by @0f-0b in https://github.com/SocialSisterYi/bilibili-API-collect/issues/868#issuecomment-1823819692

dm_img_inter

This param represents your mouse move and click event before the request.

The following example may be outdated.

const { floor, random } = Math;

function f114i(a, b, i) {
  const t = floor(random() * (114 * i));
  return [3 * a + 2 * b + t, 4 * a - 5 * b + t, t];
}

function f114(a, b) {
  const t = floor(random() * 114);
  return [2 * a + 2 * b + 3 * t, 4 * a - b + t, t];
}

function f514(a, b) {
  const t = floor(random() * 514);
  return [3 * a + 2 * b + t, 4 * a - 4 * b + 2 * t, t];
}

const eventTypes = ["mousemove", "click"];

/**
 * @param {Iterable<MouseEvent>} events 最近 50 次 `mousemove` 和 `click` 事件。
 * @returns {string} `dm_img_list` 的值。
 */
export function getDmImgList(events) {
  return JSON.stringify(Array.from(events, (event, index) => {
    const [x, y, z] = f114i(event.x, event.y, index);
    return {
      x,
      y,
      z,
      timestamp: floor(event.timeStamp),
      k: floor(random() * 67) + 60,
      type: eventTypes.indexOf(event.type),
    };
  }));
}

const tagNames = [
  "span", "div", "p", "a", "img", "input", "button", "ul", "ol", "li",
  "h1", "h2", "h3", "h4", "h5", "h6", "form", "textarea", "select", "option",
  "table", "tr", "td", "th", "label", "strong", "em", "section", "article",
];

/**
 * @param {DOMRectReadOnly} windowBounds
 *   初始全零,窗口大小和滚动位置都没变则保持全零;
 *   窗口大小改变时 `width` 和 `height` 属性分别更新为 `innerWidth` 和 `innerHeight`;
 *   滚动位置改变时 `x` 和 `y` 属性分别更新为 `scrollX` 和 `scrollY`。
 * @param {Iterable<Element>} elements
 *   初值是 `document.querySelectorAll("div[data-v-risk=fingerprint]")` 返回的两个元素;
 *   `mousemove` 或 `click` 时更新为只含事件的 `target` 一个元素。
 * @returns {string} `dm_img_inter` 的值。
 */
export function getDmImgInter(windowBounds, elements) {
  return JSON.stringify({
    ds: Array.from(elements, (element) => {
      const bounds = element.getBoundingClientRect();
      const [x1, y1, z1] = f114(bounds.y | 0, bounds.x | 0);
      const [x2, y2, z2] = f514(bounds.width | 0, bounds.height | 0);
      return {
        t: tagNames.indexOf(element.tagName.toLowerCase()) + 1,
        c: btoa(element.className).slice(0, -2),
        p: [x1, z1, y1],
        s: [z2, x2, y2],
      };
    }),
    wh: f114(windowBounds.width, windowBounds.height),
    of: f514(windowBounds.y, windowBounds.x),
  });
}

Originally posted by @0f-0b in https://github.com/SocialSisterYi/bilibili-API-collect/issues/868#issuecomment-1908690516

dm_cover_img_str

See webglVendorAndRenderer from fingerprintjs2. Just base64 encoded.

APIs using dm_img series risk control params

More details are wanted.

MoranTn commented 7 months ago

这个dm_img_list算法貌似不行

z0z0r4 commented 6 months ago

dm_cover_img_str 呢?这里好像没提及

0f-0b commented 4 months ago

windowBounds 初始全零,窗口大小和滚动位置都没变则保持全零

B 站更新了算法。现在 windowBounds 总是等于 new DOMRect(scrollX, scrollY, innerWidth, innerHeight),不再全零。

但浏览器不登录正常使用也触发风控,或许必须带 SESSDATA cookie。