bahmutov / csrf-login Goto Github PK
View Code? Open in Web Editor NEWLogin from command line to the websites that use CSRF protection
Login from command line to the websites that use CSRF protection
HTTPS serves usually need this header for security. Make sure to send one
Hello,
I did not have time to test it on other websites, I gave you @bahmutov access to my private repo.
I will publish publicly my work later on with more features and prolly also an interface made with Vue 2.
I created my own User Interface so that I can replace the .env config file with the data coming from an external API or from a DB connection.
However, I tested the code also with the config file with the default name.
Thank you for your help.
All the best,
Davide
The error I have using this on Linkedin is:
node:26190) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Could not find login form
This is the important portion of the code in regard to csrf-login.
----user.service.ts-------------
/**
* Created by Davide Pugliese on 31/03/17.
*/
import {Observable, Subscribable} from "rxjs/Observable";
import "rxjs/add/observable/from";
import "rxjs/add/observable/fromPromise";
import "rxjs/add/observable/of";
import "rxjs/add/operator/map";
import "rxjs/add/observable/defer";
import * as path from 'path';
import {Observer, Subject} from "rxjs";
// const request = require('request');
const fs = require('fs');
const Promise = require('promise');
interface IUser {
host: String;
username: String;
password: String;
loginFormSelector: String;
loginUsernameField: String;
loginPasswordField: String;
tokenFieldName: String;
loginPath: String;
}
class User <Observable> implements IUser {
public host;
public username;
public password;
public loginFormSelector;
public loginUsernameField;
public loginPasswordField;
public tokenFieldName;
public loginPath;
}
class UserFactory {
build() {
//We create a promise inside a factory class in order to decouple this precise "user feed" from the rest of the code.
//In other words the code is ready for multiple "user feeds" as for example an API without having to refactor
//later on.
let readFile = Promise.denodeify(require('fs').readFile);
return readFile(path.join(__dirname, '..', '../.env.json'), 'utf8')
.then(
(x) => {
let a = JSON.parse(x);
let user = new User();
user.host = a.host;
user.username = a.username;
user.password = a.password;
user.loginFormSelector = a.loginFormSelector;
user.loginUsernameField = a.loginUsernameField;
user.loginPasswordField = a.loginPasswordField;
user.tokenFieldName = a.tokenFieldName;
user.loginPath = a.loginPath;
console.log(JSON.stringify(user));
return user;
}
);
}
}
let user = new UserFactory();
// // var user = Observable.of(new User()).map(o => JSON.stringify(o));
export let userObservable: Observable<any> = Observable.from(user.build());
// userObservable.subscribe(x => console.log(JSON.stringify(x)));
--------linkedin.data.service.ts---------------------
/**
* Created by Davide Pugliese on 31/03/17.
*/
import { Observable } from "rxjs/Observable";
import "rxjs/add/observable/from";
import "rxjs/add/observable/fromPromise";
import "rxjs/add/operator/do";
import "rxjs/add/operator/map";
let request = require('request');
import { userObservable } from "./user.service";
import * as path from 'path';
let FileCookieStore = require('tough-cookie-filestore');
let csrfLogin = require('csrf-login');
// const fs = require('fs');
// const Promise = require("bluebird");
// let fs = Promise.promisifyAll(require("fs"));
const Promise = require('promise');
let readFile = Promise.denodeify(require('fs').readFile);
const efs = require('extfs');
class LinkedinDataService {
constructor() {
}
getCookie = function () {
efs.isEmpty(path.join(__dirname, '..', '../dist/cookies/cookies.json'), function (empty) {
//this is executed only if the file is empty, this avoids having the same file written multiple times
//hence a file that contains invalid JSON.
if (empty) {
let j = request.jar(new FileCookieStore(path.join(__dirname, '..', '../dist/cookies/cookies.json')));
request = request.defaults({ jar : j });
console.log(empty);
return request('https://www.linkedin.com', function() {
request('https://www.linkedin.com/uas/login-submit');
});
}
});
};
createCookieObject (callback): Promise<any> {
callback();
return readFile(path.join(__dirname, '..', '../dist/cookies/cookies.json'), 'utf8')
.then(
(x) => {
let a = JSON.parse(x);
return a;
}
);
}
getData<T>(firstname:string, lastname: string) {
let createCookie: Promise<any> = this.createCookieObject(() => {
this.getCookie();
}
);
// let cookieObservable: Observable<any> = Observable.fromPromise(createCookie);
//
// return cookieObservable.subscribe(
// x => console.log(JSON.stringify(x))
// );
return userObservable.subscribe(
(user) => {
csrfLogin(user)
.then(function (info) {
console.log(Object.keys(info));
// [ 'request', 'requestAsync', 'response', 'config', 'jar' ]
})
}
);
}
}
export { LinkedinDataService };
--------.env.json------
{
"host": "https://www.linkedin.com",
"username": "Linkedin Username",
"password": "Linkedin Password",
"loginFormSelector": "class='login-form'",
"loginUsernameField": "session_key",
"loginPasswordField": "session_password",
"tokenFieldName": "loginCsrfParam",
"loginPath": "/uas/login-submit/"
}
To enable modules that use this module via API to have their config file
For clarity and easy debugging
Hey bahmutov,
I just experimented in accessing a CSRF protected ASPX Login form - unfortunately I was not able to do any successfull login.
The ASPX Login seems to have more than one hidden field so in the first steps I simply enhanced your code to gather up to three tokens from the page and add it to the form during the post.
I checked and saw they were successfully added with wireshark by inspecting the POST.
Anyhow I always get referred back to the login page.
As my understanding of ASPX is pretty almost nothing more than what I have already found out and written here I thought maybe you have an idea and perhaps this could be a nice feature for csrf-login.
For example, changed url
Hello. I have some question. How can i use again data from info.jar on next use crsfLogin() ? I have to scrapping site more than one times and after ~30 requests that will give Captcha. So i think do not login on every crsfLogin()
And have a server to work against as an example / demo
To show / test programmatic login to given website
Hi
WHen running the code below with:
DEBUG=csrf node csrfloginshort.js
I get hints of success:
csrf trying to login 72352249 +5ms csrf success login to undefined +52ms csrf jar RequestJar { _jar: CookieJar { enableLooseMode: true, store: { idx: { 'blablaserver.internal': { '/': { clientsession: Cookie="clientsession=uirs7e3lv6jrug24s8g37tjvt2; Path=/; hostOnly=true; aAge=50ms; cAge=113ms" } }, null: { '/': { csrftoken: Cookie="csrftoken=a9745bba2dd251258eaf02634d954754f2b278a47a1b1cd151417f1d7f44fa39; Path=/; hostOnly=true; aAge=52ms; cAge=52ms" } } } } } } +0ms
But the html in response.body is a new login page (the site redirects to a login page if you are not logged in), showing the login did not work.
The site also redirect to another page if the login was successful.
So I really want to chain getting
result.request(/customer/interestingpage', function (error, response, body)
after logging in.
Code for csrfloginshort.js
var csrfLogin = require('csrf-login'); process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
var options = { loginFormId: 'login-form', tokenFieldName: 'csrfToken', loginPath: '/customer/login', loginUsernameField : "user_name", loginPasswordField : "user_password", username: "myuser", password: "123456", host: "https://blablaserver.internal:8469" };
console.log('trying to login', options.username, 'to', options.host); csrfLogin(options) .then(function (result) { result.request('/customer/login', function (error, response, body) { console.log(response.body); console.log(result.jar._jar.store); }) })
Any suggestion would be appreciated
From the outside in addition to reading in the JSON file
Using new version of bahmutov/first-existing#1
And document
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.